"""US-001: API endpoint tests covering all 10 routers.""" import pytest from fastapi.testclient import TestClient class TestRootAndHealth: def test_root_returns_status(self, client: TestClient): resp = client.get("/") assert resp.status_code == 200 data = resp.json() assert data["status"] == "running" assert data["version"] == "1.0.0" def test_health_check(self, client: TestClient): resp = client.get("/health") assert resp.status_code == 200 assert resp.json()["status"] == "healthy" class TestRiskEndpoints: def test_current_risk_map(self, client: TestClient): resp = client.get("/api/risk/current") assert resp.status_code == 200 data = resp.json() assert "grids" in data assert isinstance(data["grids"], list) assert "total_count" in data assert "timestamp" in data if data["grids"]: g = data["grids"][0] assert "grid_id" in g assert "risk_value" in g assert "risk_level" in g assert g["risk_level"] in ("high", "medium_high", "medium", "medium_low", "low") def test_risk_map_with_date(self, client: TestClient): resp = client.get("/api/risk/map?date=20231201") assert resp.status_code == 200 data = resp.json() assert data["total_count"] > 0 def test_risk_map_missing_date(self, client: TestClient): resp = client.get("/api/risk/map?date=20990101") assert resp.status_code == 404 def test_forecast_1d(self, client: TestClient): resp = client.get("/api/risk/forecast/1") assert resp.status_code == 200 data = resp.json() assert "grids" in data def test_forecast_3d(self, client: TestClient): resp = client.get("/api/risk/forecast/3") assert resp.status_code == 200 def test_forecast_7d(self, client: TestClient): resp = client.get("/api/risk/forecast/7") assert resp.status_code == 200 def test_stats(self, client: TestClient): resp = client.get("/api/risk/stats") assert resp.status_code == 200 data = resp.json() assert "total_grids" in data assert "avg_risk" in data assert "distribution" in data assert "high_risk_count" in data dist = data["distribution"] for k in ("high", "medium_high", "medium", "medium_low", "low"): assert k in dist def test_lod_grid(self, client: TestClient): resp = client.get("/api/risk/lod-grid?zoom=10&forecast_day=1") assert resp.status_code == 200 data = resp.json() assert "lod" in data assert "grids" in data assert "total_count" in data def test_lod_tile(self, client: TestClient): resp = client.get("/api/risk/lod-grid/tile?zoom=14&tile_x=0&tile_y=0&forecast_day=1") assert resp.status_code in (200, 422) def test_fullgrid(self, client: TestClient): resp = client.get("/api/risk/fullgrid") assert resp.status_code == 200 data = resp.json() assert "columns" in data assert data["columns"] == ["lat", "lon", "risk_1d", "risk_3d", "risk_7d"] def test_precomputed(self, client: TestClient): resp = client.get("/api/risk/precomputed") assert resp.status_code in (200, 404) def test_risk_history(self, client: TestClient): resp = client.get("/api/risk/history/r0_c0?days=7") assert resp.status_code in (200, 404) if resp.status_code == 200: data = resp.json() assert "grid_id" in data assert "history" in data class TestAlertEndpoints: def test_list_alerts(self, client: TestClient): resp = client.get("/api/alerts") assert resp.status_code == 200 data = resp.json() assert "alerts" in data assert "total" in data assert isinstance(data["alerts"], list) def test_alerts_with_min_risk_filter(self, client: TestClient): resp_all = client.get("/api/alerts") resp_filtered = client.get("/api/alerts?min_risk=0.9") assert resp_filtered.status_code == 200 assert resp_filtered.json()["total"] <= resp_all.json()["total"] def test_alerts_with_priority_filter(self, client: TestClient): resp = client.get("/api/alerts?priority=P1") assert resp.status_code == 200 for alert in resp.json()["alerts"]: assert alert["priority"] == "P1" def test_p1_alerts(self, client: TestClient): resp = client.get("/api/alerts/priority/p1") assert resp.status_code == 200 for alert in resp.json()["alerts"]: assert alert["priority"] == "P1" def test_p2_alerts(self, client: TestClient): resp = client.get("/api/alerts/priority/p2") assert resp.status_code == 200 for alert in resp.json()["alerts"]: assert alert["priority"] == "P2" def test_get_single_alert(self, client: TestClient): alerts_resp = client.get("/api/alerts") alerts = alerts_resp.json().get("alerts", []) if alerts: alert_id = alerts[0]["alert_id"] resp = client.get(f"/api/alerts/{alert_id}") assert resp.status_code == 200 assert resp.json()["alert_id"] == alert_id def test_alert_not_found(self, client: TestClient): resp = client.get("/api/alerts/nonexistent_alert_id") assert resp.status_code == 404 class TestGridEndpoints: def test_grids_geojson(self, client: TestClient): resp = client.get("/api/grids/geojson?date=2022-12-15") assert resp.status_code in (200, 500, 503) def test_grid_history(self, client: TestClient): resp = client.get("/api/grids/r100_c200/history?days=7") assert resp.status_code in (200, 404, 500, 503) def test_historical_aggregated(self, client: TestClient): resp = client.get("/api/history/aggregated?start_date=2022-12-01&end_date=2022-12-31") assert resp.status_code in (200, 500, 503) def test_multi_day_prediction(self, client: TestClient): resp = client.post("/api/predict/multi-day", json={"date": "2022-12-15", "days": 3}) assert resp.status_code in (200, 500, 503) class TestCaseEndpoints: def test_case_trend(self, client: TestClient): resp = client.get("/api/cases/trend") assert resp.status_code in (200, 500, 503) def test_case_trend_with_params(self, client: TestClient): resp = client.get( "/api/cases/trend?start_date=2022-12-01&end_date=2022-12-31&group_by=week" ) assert resp.status_code in (200, 500, 503) def test_case_districts(self, client: TestClient): resp = client.get("/api/cases/districts") assert resp.status_code in (200, 500, 503) def test_case_stats(self, client: TestClient): resp = client.get("/api/cases/stats") assert resp.status_code in (200, 500, 503) def test_case_diagnoses(self, client: TestClient): resp = client.get("/api/cases/diagnoses") assert resp.status_code in (200, 500, 503) class TestGeocodedEndpoints: def test_geocoded_grid(self, client: TestClient): resp = client.get("/api/geocoded/grid") assert resp.status_code == 200 data = resp.json() assert "grids" in data def test_geocoded_cases(self, client: TestClient): resp = client.get("/api/geocoded/geocoded?limit=10") assert resp.status_code == 200 data = resp.json() assert "cases" in data def test_geocoded_count(self, client: TestClient): resp = client.get("/api/geocoded/geocoded/count") assert resp.status_code == 200 data = resp.json() assert "total" in data class TestInsightsEndpoints: def test_insights_overview(self, client: TestClient): resp = client.get("/api/insights/overview") assert resp.status_code in (200, 404, 500) def test_insights_cards(self, client: TestClient): resp = client.get("/api/insights/cards") assert resp.status_code in (200, 404, 500) class TestReportsEndpoints: def test_reports_list(self, client: TestClient): resp = client.get("/api/reports/list") assert resp.status_code == 200 data = resp.json() assert "reports" in data assert "total" in data def test_report_by_id(self, client: TestClient): list_resp = client.get("/api/reports/list") reports = list_resp.json().get("reports", []) if reports: rid = reports[0]["report_id"] resp = client.get(f"/api/reports/{rid}") assert resp.status_code == 200 data = resp.json() assert "metadata" in data def test_report_not_found(self, client: TestClient): resp = client.get("/api/reports/nonexistent") assert resp.status_code in (400, 404) def test_report_summary_latest(self, client: TestClient): resp = client.get("/api/reports/summary/latest") assert resp.status_code in (200, 404) class TestAnalysisEndpoints: def test_analysis_trend(self, client: TestClient): resp = client.get("/api/analysis/trend?days=7") assert resp.status_code == 200 def test_analysis_districts(self, client: TestClient): resp = client.get("/api/analysis/districts") assert resp.status_code == 200 class TestChatEndpoint: def test_chat_post(self, client: TestClient): resp = client.post("/api/chat", json={ "messages": [{"role": "user", "content": "你好"}] }) assert resp.status_code in (200, 401, 403, 503)