"""Contract tests — agent execution via API.""" import pytest from tests.base import ContractHelpers as H from tests.endpoints import Endpoints as E from tests.helpers import set_scenario, trigger_fce, trigger_handover class TestFCEAgent: @pytest.mark.asyncio async def test_trigger_returns_run_id(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") res = await agent_client.post(E.AGENT_FCE, json={"flight_id": "UA432"}) H.assert_status(res, 200) H.assert_has_fields(res.json(), "run_id", "status") assert res.json()["status"] == "running" @pytest.mark.asyncio async def test_completes_with_notification(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_fce(agent_client, "UA432") result = await H.poll_run(agent_client, run_id) assert result["status"] == "completed" r = result["result"] H.assert_has_fields(r, "type", "status", "notification_text", "data_sources", "duration_ms") assert r["type"].endswith("_NOTIFICATION") assert len(r["notification_text"]) > 0 assert r["duration_ms"] > 0 @pytest.mark.asyncio async def test_includes_live_data(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_fce(agent_client, "UA432") result = await H.poll_run(agent_client, run_id) sources = result["result"]["data_sources"] assert "weather_live" in sources assert "faa_status_live" in sources @pytest.mark.asyncio async def test_notification_mentions_flight(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_fce(agent_client, "UA432") result = await H.poll_run(agent_client, run_id) text = result["result"]["notification_text"] assert "UA432" in text assert "ORD" in text or "SFO" in text class TestHandoverAgent: @pytest.mark.asyncio async def test_trigger_returns_run_id(self, agent_client): res = await agent_client.post(E.AGENT_HANDOVER, json={}) H.assert_status(res, 200) H.assert_has_fields(res.json(), "run_id", "status") @pytest.mark.asyncio async def test_completes_with_brief(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_handover(agent_client, hubs=["ORD"]) result = await H.poll_run(agent_client, run_id) assert result["status"] == "completed" r = result["result"] H.assert_has_fields(r, "type", "brief_text", "summary", "items", "duration_ms") assert r["type"] == "HANDOVER_BRIEF" assert len(r["brief_text"]) > 0 @pytest.mark.asyncio async def test_identifies_disruptions(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_handover(agent_client, hubs=["ORD"]) result = await H.poll_run(agent_client, run_id) items = result["result"]["items"] assert len(items["immediate"]) > 0, "Should find immediate items in disruption scenario" @pytest.mark.asyncio async def test_hub_filtering(self, agent_client): await set_scenario(agent_client, "weather_disruption_ord") run_id = await trigger_handover(agent_client, hubs=["ORD"]) result = await H.poll_run(agent_client, run_id) assert result["result"]["hubs"] == ["ORD"] class TestAgentRuns: @pytest.mark.asyncio async def test_list_runs(self, agent_client): res = await agent_client.get(E.AGENT_RUNS) H.assert_status(res, 200) H.assert_is_list(res.json()) @pytest.mark.asyncio async def test_unknown_run(self, agent_client): res = await agent_client.get(E.run("nonexistent")) H.assert_status(res, 404)