from __future__ import annotations import unittest from types import SimpleNamespace from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from govoplan_core.core.change_sequence import ChangeSequenceEntry from govoplan_core.db.base import Base from govoplan_organizations.backend.api.v1.routes import ( get_organization_settings, update_organization_settings, ) from govoplan_organizations.backend.api.v1.schemas import ( OrganizationSettingsUpdateRequest, ) from govoplan_organizations.backend.db.models import OrganizationTenantSettings class OrganizationSettingsRouteTests(unittest.TestCase): def setUp(self) -> None: self.engine = create_engine("sqlite:///:memory:") Base.metadata.create_all( self.engine, tables=[ ChangeSequenceEntry.__table__, OrganizationTenantSettings.__table__, ], ) self.Session = sessionmaker(bind=self.engine, expire_on_commit=False) self.session: Session = self.Session() def tearDown(self) -> None: self.session.close() Base.metadata.drop_all( self.engine, tables=[ OrganizationTenantSettings.__table__, ChangeSequenceEntry.__table__, ], ) self.engine.dispose() @staticmethod def _principal(tenant_id: str) -> object: return SimpleNamespace(tenant_id=tenant_id) def test_missing_settings_row_returns_tenant_defaults(self) -> None: result = get_organization_settings( session=self.session, principal=self._principal("tenant-1"), ) self.assertEqual(result.tenant_id, "tenant-1") self.assertTrue(result.allow_tenant_model_customization) self.assertFalse(result.require_model_change_requests) self.assertEqual(result.audit_detail_level, "standard") self.assertIsNone(result.change_retention_days) self.assertEqual(result.settings, {}) self.assertEqual(self.session.query(OrganizationTenantSettings).count(), 0) def test_first_update_creates_only_the_active_tenant_settings(self) -> None: result = update_organization_settings( OrganizationSettingsUpdateRequest( allow_tenant_model_customization=False, require_model_change_requests=True, audit_detail_level="full", change_retention_days=365, settings={"template": {"id": "municipality", "version": "2"}}, ), session=self.session, principal=self._principal("tenant-1"), ) self.assertEqual(result.tenant_id, "tenant-1") self.assertFalse(result.allow_tenant_model_customization) self.assertTrue(result.require_model_change_requests) self.assertEqual(result.change_retention_days, 365) self.assertEqual( result.settings, {"template": {"id": "municipality", "version": "2"}}, ) self.assertIsNone( self.session.query(OrganizationTenantSettings) .filter(OrganizationTenantSettings.tenant_id == "tenant-2") .one_or_none() ) def test_settings_reads_are_tenant_isolated(self) -> None: self.session.add( OrganizationTenantSettings( tenant_id="tenant-1", allow_tenant_model_customization=False, require_model_change_requests=True, audit_detail_level="detailed", settings={"private": "tenant-1"}, ) ) self.session.commit() other = get_organization_settings( session=self.session, principal=self._principal("tenant-2"), ) self.assertEqual(other.tenant_id, "tenant-2") self.assertTrue(other.allow_tenant_model_customization) self.assertEqual(other.settings, {}) if __name__ == "__main__": unittest.main()