From 59a56f2e4f2a2c884bb87b7ef81cab2fef84c733 Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 7 Apr 2026 20:05:54 +0200 Subject: [PATCH] Use dependency injection for health status and add health router regression test --- backend/app/routers/health.py | 13 +++++-------- backend/tests/test_routers/test_health.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/backend/app/routers/health.py b/backend/app/routers/health.py index 18c733d..0c1dd9b 100644 --- a/backend/app/routers/health.py +++ b/backend/app/routers/health.py @@ -6,16 +6,16 @@ state so monitoring tools and Docker health checks can observe daemon status without probing the socket directly. """ -from fastapi import APIRouter, Request +from fastapi import APIRouter from fastapi.responses import JSONResponse -from app.models.server import ServerStatus +from app.dependencies import ServerStatusDep router: APIRouter = APIRouter(prefix="/api", tags=["Health"]) @router.get("/health", summary="Application health check") -async def health_check(request: Request) -> JSONResponse: +async def health_check(server_status: ServerStatusDep) -> JSONResponse: """Return 200 with application and fail2ban status. HTTP 200 is always returned so Docker health checks do not restart the @@ -23,15 +23,12 @@ async def health_check(request: Request) -> JSONResponse: ``fail2ban`` field in the body indicates the daemon's current state. Args: - request: FastAPI request (used to read cached server status). + server_status: Injected cached server status snapshot. Returns: A JSON object with ``{"status": "ok", "fail2ban": "online"|"offline"}``. """ - cached: ServerStatus = getattr( - request.app.state, "server_status", ServerStatus(online=False) - ) return JSONResponse(content={ "status": "ok", - "fail2ban": "online" if cached.online else "offline", + "fail2ban": "online" if server_status.online else "offline", }) diff --git a/backend/tests/test_routers/test_health.py b/backend/tests/test_routers/test_health.py index f24e83e..5817e5c 100644 --- a/backend/tests/test_routers/test_health.py +++ b/backend/tests/test_routers/test_health.py @@ -3,6 +3,8 @@ import pytest from httpx import AsyncClient +from app.models.server import ServerStatus + @pytest.mark.asyncio async def test_health_check_returns_200(client: AsyncClient) -> None: @@ -25,3 +27,14 @@ async def test_health_check_content_type_is_json(client: AsyncClient) -> None: """``GET /api/health`` must set the ``Content-Type`` header to JSON.""" response = await client.get("/api/health") assert "application/json" in response.headers.get("content-type", "") + + +@pytest.mark.asyncio +async def test_health_check_respects_cached_server_status(client: AsyncClient) -> None: + """The health response should reflect the injected cached server status.""" + client._transport.app.state.server_status = ServerStatus(online=True) + + response = await client.get("/api/health") + + assert response.status_code == 200 + assert response.json()["fail2ban"] == "online"