from __future__ import annotations from types import SimpleNamespace from fastapi.testclient import TestClient from app.api.routes import health from app.main import app READY_DATABASE = { "database": "ok", "postgis": "ok:3.4 USE_GEOS=1 USE_PROJ=1", "migration": "ok:202607160001", } def test_liveness_is_independent_from_database(monkeypatch) -> None: monkeypatch.setattr( health, "_database_checks", lambda: (_ for _ in ()).throw(AssertionError("must not query DB")), ) response = TestClient(app).get("/health/live") assert response.status_code == 200 assert response.json()["status"] == "ok" def test_readiness_returns_ok_only_when_all_checks_pass(monkeypatch) -> None: monkeypatch.setattr(health, "_database_checks", lambda: READY_DATABASE.copy()) monkeypatch.setattr(health, "_storage_check", lambda _: "ok") response = TestClient(app).get("/health/ready") assert response.status_code == 200 payload = response.json() assert payload["status"] == "ok" assert payload["service"] == "geointel-backend" assert payload["database"] == "ok" assert payload["postgis"].startswith("ok:") assert payload["migration"] == "ok:202607160001" assert payload["storage"] == "ok" def test_compatibility_health_is_fail_closed(monkeypatch) -> None: monkeypatch.setattr( health, "_database_checks", lambda: { "database": "degraded", "postgis": "degraded", "migration": "degraded", }, ) monkeypatch.setattr(health, "_storage_check", lambda _: "ok") response = TestClient(app).get("/health") assert response.status_code == 503 assert response.json()["status"] == "degraded" def test_system_capabilities_report_runtime_state(monkeypatch) -> None: monkeypatch.setattr( health, "_dependency_enabled", lambda module_name: module_name in {"rasterio", "geopandas"}, ) monkeypatch.setattr(health, "_database_checks", lambda: READY_DATABASE.copy()) monkeypatch.setattr( health.ModelRegistryService, "get_model_capability", lambda *args, **kwargs: SimpleNamespace( configured=True, status="configured", ), ) response = TestClient(app).get("/api/v1/system/capabilities") assert response.status_code == 200 payload = response.json()["data"] assert payload["postgis"] is True assert payload["rasterio"] is True assert payload["geopandas"] is True assert payload["yolo"] is True assert payload["yolo_status"] == "configured" assert payload["version"] def test_requests_receive_a_correlation_id() -> None: client = TestClient(app) generated = client.get("/health/live") retained = client.get("/health/live", headers={"x-request-id": "test-request"}) assert generated.headers["x-request-id"] assert retained.headers["x-request-id"] == "test-request"