Files
nova/tests/test_agents.py
2026-04-12 10:02:17 -03:00

102 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, 200)
assert "error" in res.json()