from __future__ import annotations import json import unittest from datetime import UTC, datetime from sqlalchemy import create_engine from sqlalchemy.orm import Session from govoplan_core.core.dsar import DsarProvider, DsarSubjectRef from govoplan_core.db.base import Base from govoplan_mandates.backend.db.models import MandateRevision from govoplan_mandates.backend.dsar_provider import ( MANDATES_DSAR_CAPABILITY, MandatesDsarProvider, ) from govoplan_mandates.backend.manifest import manifest NOW = datetime(2026, 8, 22, 13, 0, tzinfo=UTC) class MandatesDsarProviderTests(unittest.TestCase): def setUp(self) -> None: self.engine = create_engine("sqlite+pysqlite:///:memory:") Base.metadata.create_all(self.engine) self.session = Session(self.engine) self.provider = MandatesDsarProvider() self.session.add_all( ( MandateRevision( id="revision-1", tenant_id="tenant-1", mandate_id="mandate-1", revision="2", status="active", valid_from=NOW, recorded_at=NOW, payload={ "person_ref": "payload-person-do-not-correlate", "legal_basis": "legal-basis-do-not-export", "change_reason": "change-reason-do-not-export", }, created_by="account-1", ), MandateRevision( id="revision-other", tenant_id="tenant-2", mandate_id="mandate-other", revision="1", status="active", recorded_at=NOW, payload={}, created_by="account-1", ), ) ) self.session.commit() def tearDown(self) -> None: self.session.close() self.engine.dispose() def test_search_is_minimized_tenant_safe_and_narrowable(self) -> None: self.assertIsInstance(self.provider, DsarProvider) records = self.provider.search_subject( self.session, tenant_id="tenant-1", subject=DsarSubjectRef(account_id="account-1"), ) self.assertEqual(["revision-1"], [record.resource_id for record in records]) exported = json.dumps([record.to_dict() for record in records]) self.assertNotIn("payload-person-do-not-correlate", exported) self.assertNotIn("legal-basis-do-not-export", exported) self.assertNotIn("change-reason-do-not-export", exported) narrowed = self.provider.search_subject( self.session, tenant_id="tenant-1", subject=DsarSubjectRef( account_id="account-1", external_references={"mandates.mandate": "mandate-1"}, ), ) self.assertEqual(1, len(narrowed)) def test_account_is_required_and_history_is_retained(self) -> None: self.assertEqual( (), self.provider.search_subject( self.session, tenant_id="tenant-1", subject=DsarSubjectRef( external_references={"mandates.mandate": "mandate-1"} ), ), ) subject = DsarSubjectRef(account_id="account-1") records = self.provider.search_subject( self.session, tenant_id="tenant-1", subject=subject ) actions = self.provider.plan_erasure( self.session, tenant_id="tenant-1", subject=subject, records=records, ) self.assertTrue(all(action.kind == "retain" for action in actions)) def test_manifest_registers_provider_and_documentation(self) -> None: self.assertIn(MANDATES_DSAR_CAPABILITY, manifest.capability_factories) self.assertIn( "mandates.data-subject-requests", {topic.id for topic in manifest.documentation}, ) if __name__ == "__main__": unittest.main()