from __future__ import annotations from datetime import datetime, timedelta, timezone from sqlalchemy import create_engine from sqlalchemy.orm import Session from app.database import Base from app.models import ImportStatus, CommunityImportRun, OfficialRecordImport from app.readiness import readiness_report class AvailableStorage: def list_buckets(self) -> dict[str, list[object]]: return {"Buckets": []} class UnavailableStorage: def list_buckets(self) -> None: raise ConnectionError("fixture unavailable") def test_optional_import_does_not_block_dependencies() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) with Session(engine) as session: ready, components = readiness_report( session, AvailableStorage(), import_required=False, import_interval_seconds=3600, ) assert ready is True assert components["postgresql"]["status"] == "ready" assert components["minio"]["status"] == "ready" assert components["official_import"]["status"] == "optional" assert components["official_import"]["last_run_status"] is None assert "community_scheduler" in components def test_required_import_must_be_recent_and_successful() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) now = datetime.now(timezone.utc) with Session(engine) as session: session.add(OfficialRecordImport( started_at=now - timedelta(minutes=30), finished_at=now - timedelta(minutes=29), status=ImportStatus.success, source_url="fixture://records", rows_seen=1, rows_created=1, rows_updated=0, )) session.commit() ready, components = readiness_report( session, AvailableStorage(), import_required=True, import_interval_seconds=3600, now=now, ) assert ready is True assert components["official_import"]["status"] == "ready" def test_unavailable_storage_and_stale_import_fail_readiness() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) now = datetime.now(timezone.utc) with Session(engine) as session: session.add(OfficialRecordImport( started_at=now - timedelta(hours=3), finished_at=now - timedelta(hours=3), status=ImportStatus.success, source_url="fixture://records", rows_seen=1, rows_created=1, rows_updated=0, )) session.commit() ready, components = readiness_report( session, UnavailableStorage(), import_required=True, import_interval_seconds=3600, now=now, ) assert ready is False assert components["minio"]["status"] == "unavailable" assert components["official_import"]["status"] == "stale" def test_community_scheduler_success_does_not_block_readiness() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) now = datetime.now(timezone.utc) with Session(engine) as session: session.add(CommunityImportRun( source_system="rf4db", started_at=now - timedelta(minutes=30), status="success", source_url="fixture://rf4db", rows_seen=5, rows_created=5, rows_updated=0, error_summary=None, )) session.commit() ready, components = readiness_report( session, AvailableStorage(), import_required=False, import_interval_seconds=3600, community_import_interval_seconds=1800, now=now, ) assert ready is True assert components["community_scheduler"]["status"] == "ready" def test_community_scheduler_stale_or_failed_blocks_readiness() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) now = datetime.now(timezone.utc) with Session(engine) as session: # Stale run session.add(CommunityImportRun( source_system="rf4db", started_at=now - timedelta(hours=2), status="success", source_url="fixture://rf4db", rows_seen=5, rows_created=5, rows_updated=0, error_summary=None, )) session.commit() ready, components = readiness_report( session, AvailableStorage(), import_required=False, import_interval_seconds=3600, community_import_interval_seconds=1800, now=now, ) assert ready is False assert components["community_scheduler"]["status"] == "stale" def test_community_scheduler_failed_status_blocks_readiness() -> None: engine = create_engine("sqlite://") Base.metadata.create_all(engine) now = datetime.now(timezone.utc) with Session(engine) as session: session.add(CommunityImportRun( source_system="rf4db", started_at=now - timedelta(minutes=30), status="failed", source_url="fixture://rf4db", rows_seen=0, rows_created=0, rows_updated=0, error_summary="ConnectionError", )) session.commit() ready, components = readiness_report( session, AvailableStorage(), import_required=False, import_interval_seconds=3600, community_import_interval_seconds=1800, now=now, ) assert ready is False assert components["community_scheduler"]["status"] == "failed"