From 6a8b41cd383e3e17ec5cdd3b50c68933612500c8 Mon Sep 17 00:00:00 2001 From: Johan Lundberg Date: Thu, 12 Feb 2026 15:09:27 +0100 Subject: [PATCH] feat: add app factory with health endpoint and test infrastructure --- src/fastapi_oidc_op/app.py | 23 +++++++++++++++++++++++ tests/conftest.py | 20 ++++++++++++++++++++ tests/test_app.py | 15 +++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/fastapi_oidc_op/app.py create mode 100644 tests/conftest.py create mode 100644 tests/test_app.py diff --git a/src/fastapi_oidc_op/app.py b/src/fastapi_oidc_op/app.py new file mode 100644 index 0000000..908dede --- /dev/null +++ b/src/fastapi_oidc_op/app.py @@ -0,0 +1,23 @@ +from fastapi import FastAPI + +from fastapi_oidc_op.config import Settings + + +def create_app(settings: Settings | None = None) -> FastAPI: + if settings is None: + settings = Settings() # type: ignore[call-arg] + + app = FastAPI( + title="FastAPI OIDC OP", + version="0.1.0", + docs_url="/docs" if settings.debug else None, + redoc_url=None, + ) + + app.state.settings = settings + + @app.get("/health") + async def health() -> dict[str, str]: + return {"status": "ok"} + + return app diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..9649412 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,20 @@ +from collections.abc import AsyncIterator + +import pytest +from httpx import ASGITransport, AsyncClient + +from fastapi_oidc_op.app import create_app +from fastapi_oidc_op.config import Settings + + +@pytest.fixture +def settings() -> Settings: + return Settings(issuer="http://localhost:8000") + + +@pytest.fixture +async def client(settings: Settings) -> AsyncIterator[AsyncClient]: + app = create_app(settings) + transport = ASGITransport(app=app) + async with AsyncClient(transport=transport, base_url=settings.issuer) as ac: + yield ac diff --git a/tests/test_app.py b/tests/test_app.py new file mode 100644 index 0000000..232969d --- /dev/null +++ b/tests/test_app.py @@ -0,0 +1,15 @@ +from httpx import AsyncClient + + +async def test_health_endpoint(client: AsyncClient) -> None: + response = await client.get("/health") + assert response.status_code == 200 + data = response.json() + assert data["status"] == "ok" + + +async def test_app_has_title(client: AsyncClient) -> None: + response = await client.get("/openapi.json") + assert response.status_code == 200 + data = response.json() + assert data["info"]["title"] == "FastAPI OIDC OP"