from __future__ import annotations from datetime import UTC, datetime import unittest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from govoplan_connectors.backend.db.models import ( ConnectorSanctionsAcquisitionRun, ConnectorSanctionsSnapshot, ConnectorTabularSource, ) from govoplan_connectors.backend.manifest import manifest from govoplan_connectors.backend.provider_state import ( SANCTIONS_PROVIDER_ID, TABULAR_PROVIDER_ID, sanctions_provider_states, tabular_provider_states, ) from govoplan_core.core.provider_governance import ExternalProviderStateContext from govoplan_core.db.base import Base class ConnectorsProviderStateTests(unittest.TestCase): def setUp(self) -> None: self.engine = create_engine("sqlite+pysqlite:///:memory:", future=True) Base.metadata.create_all( self.engine, tables=( ConnectorTabularSource.__table__, ConnectorSanctionsAcquisitionRun.__table__, ConnectorSanctionsSnapshot.__table__, ), ) self.session = sessionmaker(bind=self.engine, expire_on_commit=False)() def tearDown(self) -> None: self.session.close() self.engine.dispose() def test_immutable_tabular_snapshot_reports_ready_state(self) -> None: self.session.add( ConnectorTabularSource( id="tabular-1", tenant_id="tenant-1", source_name="monthly", name="Monthly input", status="active", schema_version=1, schema_=[{"name": "id", "type": "string"}], rows=[{"id": "1"}], fingerprint="a" * 64, row_count=1, byte_count=10, ) ) self.session.commit() state = tabular_provider_states( ExternalProviderStateContext(session=self.session, tenant_id="tenant-1") )[0] self.assertEqual("healthy", state.health) self.assertEqual("ready", state.recovery) self.assertEqual("not_applicable", state.freshness) def test_sanctions_state_hashes_binding_and_manifest_registers_state(self) -> None: now = datetime.now(UTC) run = ConnectorSanctionsAcquisitionRun( id="run-1", tenant_id="tenant-1", provider_id="eu", source_id="secret-source-name", status="succeeded", attempt_count=1, started_at=now, finished_at=now, ) snapshot = ConnectorSanctionsSnapshot( id="snapshot-1", tenant_id="tenant-1", provider_id="eu", publisher="European Union", jurisdiction="EU", list_type="sanctions", source_id="secret-source-name", source_version="2026-08-01", acquired_at=now, source_url="https://source.example.test/list.xml", content_type="application/xml", byte_count=8, sha256="b" * 64, parser_version="1", connector_run_id=run.id, raw_content=b"", ) run.snapshot_id = snapshot.id self.session.add_all((run, snapshot)) self.session.commit() state = sanctions_provider_states( ExternalProviderStateContext(session=self.session, tenant_id="tenant-1") )[0] self.assertEqual("healthy", state.health) self.assertEqual("ready", state.recovery) rendered = str(state.to_dict()) self.assertNotIn("secret-source-name", rendered) self.assertNotIn("source.example.test", rendered) self.assertEqual( {TABULAR_PROVIDER_ID, SANCTIONS_PROVIDER_ID}, {item.provider_id for item in manifest.external_provider_state_providers}, ) if __name__ == "__main__": unittest.main()