diff --git a/src/app.py b/src/app.py index b27982a..9318445 100644 --- a/src/app.py +++ b/src/app.py @@ -60,11 +60,16 @@ async def lifespan(app: FastAPI): @app.get("/api/war/status", tags=["War"]) async def get_war_status(): - """Get current war status""" + """Get current war status. If DB is empty, fetches live and saves so Data Console/MCP get data on first request.""" data = db.get_latest_war_status() if data: return data - raise HTTPException(status_code=404, detail="No war status data available") + # No data yet (e.g. before first collector run): try live fetch so UI/MCP get something + data = scraper.get_war_status() + if data: + db.save_war_status(data) + return data + raise HTTPException(status_code=404, detail="No war status data available (upstream API may be unreachable)") @app.post("/api/war/status/refresh", tags=["War"]) @@ -316,11 +321,15 @@ async def get_planet_history(planet_index: int, limit: int = Query(10, ge=1, le= @app.get("/api/statistics", tags=["Statistics"]) async def get_statistics(): - """Get latest global statistics""" + """Get latest global statistics. If DB is empty, fetches live and saves so Data Console/MCP get data.""" data = db.get_latest_statistics() if data: return data - raise HTTPException(status_code=404, detail="No statistics available") + data = scraper.get_statistics() + if data: + db.save_statistics(data) + return data + raise HTTPException(status_code=404, detail="No statistics available (upstream API may be unreachable)") @app.get("/api/statistics/history", tags=["Statistics"]) diff --git a/tests/test_app.py b/tests/test_app.py index 2b20914..aafc5a6 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -50,14 +50,30 @@ def test_get_war_status_success(self, mock_get, client): data = response.json() assert data["war_id"] == 1 + @patch("src.app.scraper.get_war_status") @patch("src.app.db.get_latest_war_status") - def test_get_war_status_not_found(self, mock_get, client): - """Test getting war status when none exists""" + def test_get_war_status_not_found(self, mock_get, mock_scraper, client): + """Test getting war status when DB empty and live fetch fails""" mock_get.return_value = None + mock_scraper.return_value = None response = client.get("/api/war/status") assert response.status_code == 404 + @patch("src.app.scraper.get_war_status") + @patch("src.app.db.save_war_status") + @patch("src.app.db.get_latest_war_status") + def test_get_war_status_live_when_db_empty(self, mock_get, mock_save, mock_scraper, client): + """When DB has no row yet, GET uses live fetch and persists""" + mock_get.return_value = None + mock_scraper.return_value = {"war_id": 42, "status": "active"} + mock_save.return_value = True + + response = client.get("/api/war/status") + assert response.status_code == 200 + assert response.json()["war_id"] == 42 + mock_save.assert_called_once() + @patch("src.app.scraper.get_war_status") @patch("src.app.db.save_war_status") def test_refresh_war_status_success(self, mock_save, mock_scraper, client): @@ -173,14 +189,30 @@ def test_get_statistics_success(self, mock_get, client): response = client.get("/api/statistics") assert response.status_code == 200 + @patch("src.app.scraper.get_statistics") @patch("src.app.db.get_latest_statistics") - def test_get_statistics_not_found(self, mock_get, client): - """Test getting statistics when none exists""" + def test_get_statistics_not_found(self, mock_get, mock_scraper, client): + """Test getting statistics when DB empty and live fetch fails""" mock_get.return_value = None + mock_scraper.return_value = None response = client.get("/api/statistics") assert response.status_code == 404 + @patch("src.app.scraper.get_statistics") + @patch("src.app.db.save_statistics") + @patch("src.app.db.get_latest_statistics") + def test_get_statistics_live_when_db_empty(self, mock_get, mock_save, mock_scraper, client): + """When DB has no row yet, GET uses live fetch and persists""" + mock_get.return_value = None + mock_scraper.return_value = {"total_players": 999} + mock_save.return_value = True + + response = client.get("/api/statistics") + assert response.status_code == 200 + assert response.json()["total_players"] == 999 + mock_save.assert_called_once() + @patch("src.app.db.get_latest_statistics") def test_get_statistics_history(self, mock_get, client): """Test getting statistics history""" diff --git a/tests/test_coverage_gaps.py b/tests/test_coverage_gaps.py index 4d6a71d..7e21301 100644 --- a/tests/test_coverage_gaps.py +++ b/tests/test_coverage_gaps.py @@ -187,10 +187,12 @@ def test_refresh_statistics_none(self, mock_save, mock_scraper, client): class TestDatabaseCoveragePaths: """Test database error and edge case paths""" + @patch("src.app.scraper.get_statistics") @patch("src.app.db.get_latest_statistics") - def test_statistics_not_found(self, mock_get, client): - """Test getting statistics when not found""" + def test_statistics_not_found(self, mock_get, mock_scraper, client): + """Test getting statistics when DB empty and live fetch fails""" mock_get.return_value = None + mock_scraper.return_value = None response = client.get("/api/statistics") assert response.status_code == 404