from __future__ import annotations from dataclasses import dataclass from datetime import UTC, datetime, timedelta import unittest from sqlalchemy import create_engine from sqlalchemy.orm import Session from govoplan_core.core.institutional import ( FormDefinition, FormFieldDefinition, InstitutionalReference, TemporalRevision, ) from govoplan_forms.backend.db.models import FormDefinitionRevision from govoplan_forms.backend.service import ( FormDefinitionStoreError, SqlFormDefinitionProvider, form_definition_history, record_form_definition, ) NOW = datetime(2026, 8, 1, 10, 0, tzinfo=UTC) @dataclass class Principal: tenant_id: str = "tenant-1" account_id: str = "account-1" def definition( *, revision: str = "1", state: str = "published", tenant_id: str = "tenant-1", ) -> FormDefinition: recorded_at = NOW + timedelta(minutes=int(revision) - 1) return FormDefinition( reference=InstitutionalReference( kind="form", owner_module="forms", object_id="permit-application", tenant_id=tenant_id, version=revision, ), key="permit-application", temporal=TemporalRevision( revision=revision, recorded_at=recorded_at, change_reason="Initial schema." if revision == "1" else "Revise schema.", ), title="Permit application", fields=( FormFieldDefinition( key="name", label="Name", required=True, constraints={"min_length": 2, "max_length": 200}, ), FormFieldDefinition( key="delivery", label="Delivery", value_type="choice", options=("portal", "mail"), ), ), publication_state=state, # type: ignore[arg-type] allow_drafts=True, max_attachments=2, handoff_kinds=("case",), ) class FormsTests(unittest.TestCase): def setUp(self) -> None: self.engine = create_engine("sqlite+pysqlite:///:memory:") FormDefinitionRevision.__table__.create(self.engine) self.session = Session(self.engine) self.principal = Principal() def tearDown(self) -> None: self.session.close() self.engine.dispose() def test_provider_returns_exact_published_revision_and_history(self) -> None: first = record_form_definition( self.session, self.principal, definition=definition(), ) provider = SqlFormDefinitionProvider() self.assertEqual( (first,), tuple( provider.list_form_definitions( self.session, self.principal, tenant_id="tenant-1", ) ), ) exact = provider.get_form_definition( self.session, self.principal, reference=first.reference, effective_at=NOW, ) self.assertEqual("1", exact.temporal.revision if exact else None) record_form_definition( self.session, self.principal, definition=definition(revision="2"), expected_revision="1", ) self.assertEqual( ["2", "1"], [ item.temporal.revision for item in form_definition_history( self.session, self.principal, form_id="permit-application", ) ], ) def test_replay_occ_and_tenant_boundaries_fail_closed(self) -> None: first = record_form_definition( self.session, self.principal, definition=definition(), ) replay = record_form_definition( self.session, self.principal, definition=definition(), ) self.assertEqual(first, replay) with self.assertRaisesRegex(FormDefinitionStoreError, "stale"): record_form_definition( self.session, self.principal, definition=definition(revision="2"), expected_revision="0", ) with self.assertRaisesRegex(FormDefinitionStoreError, "cross tenants"): record_form_definition( self.session, self.principal, definition=definition(tenant_id="tenant-2"), ) with self.assertRaisesRegex(Exception, "cross tenants"): SqlFormDefinitionProvider().list_form_definitions( self.session, Principal("tenant-2"), tenant_id="tenant-1", ) if __name__ == "__main__": unittest.main()