from __future__ import annotations from datetime import UTC, datetime, timedelta import unittest from govoplan_core.core.form_evidence import ( FormEvidenceContractError, FormEvidenceGrantRequest, FormEvidenceInspection, FormEvidenceInspectionRequest, form_evidence_capability, form_evidence_provider, ) from govoplan_core.core.institutional import EvidenceReference, InstitutionalReference NOW = datetime(2026, 8, 7, 9, 0, tzinfo=UTC) class Provider: provider_id = "files" def supported_kinds(self): return ("document",) def create_upload_grant(self, session, principal, *, request): raise NotImplementedError def inspect_evidence(self, session, principal, *, request): return FormEvidenceInspection( provider_id=self.provider_id, reference=request.evidence, state="accepted", observed_at=NOW, ) class Registry: def __init__(self) -> None: self.provider = Provider() def has_capability(self, name: str) -> bool: return name == "forms_runtime.evidence.files" def require_capability(self, name: str): return self.provider class FormEvidenceContractTests(unittest.TestCase): def setUp(self) -> None: self.definition = InstitutionalReference( kind="form", owner_module="forms", object_id="permit", tenant_id="tenant-1", version="2", ) self.evidence = EvidenceReference( kind="document", owner_module="files", evidence_id="asset-1", tenant_id="tenant-1", version="version-3", checksum="a" * 64, ) def test_grants_and_inspections_are_exact_and_tenant_bound(self) -> None: grant = FormEvidenceGrantRequest( tenant_id="tenant-1", instance_id="form-1", definition_ref=self.definition, evidence_kind="document", purpose="attach application evidence", idempotency_key="grant-1", expires_at=NOW + timedelta(minutes=10), max_size_bytes=1024, ) inspection = FormEvidenceInspectionRequest( tenant_id="tenant-1", instance_id="form-1", definition_ref=self.definition, evidence=self.evidence, purpose="submit application", final=True, ) self.assertEqual("2", grant.definition_ref.version) self.assertEqual("version-3", inspection.evidence.version) def test_cross_tenant_evidence_is_rejected(self) -> None: with self.assertRaisesRegex(FormEvidenceContractError, "cross tenants"): FormEvidenceInspectionRequest( tenant_id="tenant-2", instance_id="form-1", definition_ref=self.definition, evidence=self.evidence, purpose="submit", final=True, ) def test_provider_resolution_is_optional_and_runtime_checked(self) -> None: registry = Registry() self.assertEqual( "forms_runtime.evidence.files", form_evidence_capability("files"), ) self.assertIs(registry.provider, form_evidence_provider(registry, "files")) self.assertIsNone(form_evidence_provider(registry, "missing")) def test_accepted_evidence_is_not_retryable(self) -> None: with self.assertRaisesRegex(FormEvidenceContractError, "cannot require"): FormEvidenceInspection( provider_id="files", reference=self.evidence, state="accepted", observed_at=NOW, retryable=True, ) if __name__ == "__main__": unittest.main()