from __future__ import annotations import pytest from src.api.v1.platform import events, operator_runs, truth_chain @pytest.mark.asyncio async def test_quality_summary_returns_source_unavailable_when_read_model_fails(monkeypatch): async def broken_fetch(**kwargs): raise RuntimeError("quality read model unavailable") observations: list[dict] = [] monkeypatch.setattr(truth_chain, "fetch_automation_quality_summary", broken_fetch) monkeypatch.setattr( truth_chain, "record_quality_summary_observation", lambda **kwargs: observations.append(kwargs), ) response = await truth_chain.get_automation_quality_summary( project_id="awoooi", hours=24, limit=30, ) assert response["source_status"] == "source_unavailable" assert response["evaluated_total"] == 0 assert response["verified_auto_repair_total"] == 0 assert response["production_claim"]["can_claim_full_auto_repair"] is False assert observations[0]["success"] is False @pytest.mark.asyncio async def test_recurrence_endpoint_returns_empty_summary_when_read_model_fails(monkeypatch): async def broken_fetch(**kwargs): raise RuntimeError("recurrence read model unavailable") monkeypatch.setattr(events, "fetch_channel_event_dossier_recurrence", broken_fetch) response = await events.get_event_dossier_recurrence( project_id="awoooi", provider=None, limit=100, ) assert response["source_status"] == "source_unavailable" assert response["project_id"] == "awoooi" assert response["items"] == [] assert response["summary"]["source_event_total"] == 0 assert response["summary"]["open_work_item_group_total"] == 0 validated = events.ChannelEventRecurrenceResponse.model_validate(response) assert validated.summary.source_event_total == 0 @pytest.mark.asyncio async def test_runs_list_endpoint_returns_empty_page_when_read_model_fails(monkeypatch): async def broken_fetch(**kwargs): raise RuntimeError("runs read model unavailable") monkeypatch.setattr(operator_runs, "list_runs_svc", broken_fetch) response = await operator_runs.list_runs( project_id="awoooi", state=None, remediation_status=None, callback_reply_status=None, incident_id=None, page=1, per_page=50, ) assert response["source_status"] == "source_unavailable" assert response["runs"] == [] assert response["total"] == 0 assert response["page"] == 1 assert response["per_page"] == 50 validated = operator_runs.ListRunsResponse.model_validate(response) assert validated.total == 0 @pytest.mark.asyncio async def test_callback_replies_endpoint_returns_empty_page_when_read_model_fails(monkeypatch): async def broken_fetch(**kwargs): raise RuntimeError("callback reply read model unavailable") monkeypatch.setattr(operator_runs, "list_callback_replies_svc", broken_fetch) response = await operator_runs.list_callback_replies( project_id="awoooi", callback_reply_status=None, action=None, incident_id=None, page=1, per_page=100, refresh=False, ) assert response["source_status"] == "source_unavailable" assert response["items"] == [] assert response["total"] == 0 assert response["page"] == 1 assert response["per_page"] == 100 assert response["summary"] is None validated = operator_runs.ListCallbackRepliesResponse.model_validate(response) assert validated.total == 0