"""Integration tests for GET /api/fires (bbox + since filters, JSON contract).""" import asyncio import httpx from conftest import make_fire_msg, requires_db from ingestor import ingest_fire_row from main import app BASE = "http://test" def _seed(*msgs) -> None: """Insert fire rows through the real ingestor path (idempotent).""" async def run(): for m in msgs: await ingest_fire_row(m) asyncio.run(run()) def _get(path: str) -> httpx.Response: return asyncio.run(_get_async(path)) async def _get_async(path: str) -> httpx.Response: transport = httpx.ASGITransport(app=app) async with httpx.AsyncClient(transport=transport, base_url=BASE) as client: return await client.get(path) @requires_db def test_api_fires_bbox_filter(clean_fires): _seed( make_fire_msg(latitude=39.45678, longitude=-121.12345, satellite="N"), make_fire_msg(latitude=34.00000, longitude=-118.20000, satellite="N20"), make_fire_msg(latitude=10.00000, longitude=20.00000, satellite="N"), ) # bbox covering only the California-ish points resp = _get("/api/fires?bbox=-125,30,-115,42") assert resp.status_code == 200 body = resp.json() assert isinstance(body, list) assert len(body) == 2 lats = sorted(p["latitude"] for p in body) assert lats == [34.0, 39.45678] @requires_db def test_api_fires_since_filter(clean_fires): _seed( make_fire_msg(acq_time="2026-08-24T18:10:00+00:00"), make_fire_msg(acq_time="2026-08-24T19:10:00+00:00"), ) resp = _get("/api/fires?since=2026-08-24T18:30:00Z") assert resp.status_code == 200 body = resp.json() assert len(body) == 1 assert body[0]["acq_time"].startswith("2026-08-24T19:10") @requires_db def test_api_fires_json_contract(clean_fires): _seed(make_fire_msg()) body = _get("/api/fires").json() assert len(body) == 1 point = body[0] # The exact fields the frontend heatmap needs — nothing more, nothing less. assert set(point.keys()) == { "latitude", "longitude", "brightness", "confidence", "acq_time", "satellite", "instrument", "bright_ti5", "frp", "daynight", } assert point["latitude"] == 39.45678 assert point["confidence"] == "h" assert point["satellite"] == "N" @requires_db def test_api_fires_invalid_bbox_422(clean_fires): assert _get("/api/fires?bbox=-125,30").status_code == 422 assert _get("/api/fires?bbox=-125,abc,-115,42").status_code == 422 @requires_db def test_api_fires_empty(clean_fires): resp = _get("/api/fires") assert resp.status_code == 200 assert resp.json() == []