"""Phase 2 API contracts (no Redis; geofences ≠ /api/alerts).""" from __future__ import annotations import asyncio import httpx from main import app BASE = "http://test" async def _req(method: str, path: str, **kw) -> httpx.Response: transport = httpx.ASGITransport(app=app) async with httpx.AsyncClient(transport=transport, base_url=BASE) as client: return await client.request(method, path, **kw) def test_geofence_post_rejects_point(): resp = asyncio.run(_req( "POST", "/api/geofences", json={"name": "nope", "geojson": {"type": "Point", "coordinates": [-79, 35]}}, )) assert resp.status_code == 422 def test_geofences_list_does_not_collide_with_alerts(): resp = asyncio.run(_req("GET", "/api/geofences")) assert resp.status_code == 200 assert isinstance(resp.json(), list) def test_aircraft_timestamp_returns_list_not_live_error(): resp = asyncio.run(_req( "GET", "/api/aircraft", params={"bbox": "-80,35,-78,36", "timestamp": "2026-08-28T12:04:00Z"}, )) assert resp.status_code == 200 assert isinstance(resp.json(), list) def test_tracks_range_has_bounds(): body = asyncio.run(_req("GET", "/api/tracks/range")).json() assert "min" in body and "max" in body def test_fire_aircraft_reload_endpoint(): resp = asyncio.run(_req("GET", "/api/fire-aircraft")) assert resp.status_code == 200 assert isinstance(resp.json(), list)