101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
"""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)
|