123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
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()
|