Scaffold app/ package, pinned requirements.txt, multi-stage Dockerfile,
docker-compose.yml, and .env.example. Add typed pydantic-settings loader
with full env contract and a production validator that refuses the
dev-sentinel SECRET_KEY. Wire structlog with an APP_ENV-driven renderer
(console in dev, JSON in prod). Ship a minimal unauthenticated /healthz
returning {status, version, commit_sha} with commit SHA fed through a
GIT_COMMIT_SHA build arg.
Also mark Phase 0 complete in docs/ROADMAP.md.
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""Tests for the ``/healthz`` endpoint.
|
|
|
|
Kept deliberately small in Phase 0: we verify contract and shape, not
|
|
content beyond what the response model guarantees.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app import __version__
|
|
from app.main import app
|
|
|
|
|
|
def test_healthz_returns_ok_and_version() -> None:
|
|
"""``GET /healthz`` returns 200 with status=ok and the app version.
|
|
|
|
Also asserts ``commit_sha`` is present as a non-empty string — it
|
|
defaults to ``"unknown"`` in dev, which still satisfies the contract
|
|
surfaced to uptime probes.
|
|
"""
|
|
# TestClient uses the module-level app, which has already been wired
|
|
# by create_app() at import time — exactly the path uvicorn takes in
|
|
# production, so the test exercises real startup behavior.
|
|
client = TestClient(app)
|
|
|
|
response = client.get("/healthz")
|
|
|
|
assert response.status_code == 200, response.text
|
|
payload = response.json()
|
|
|
|
assert payload["status"] == "ok"
|
|
assert payload["version"] == __version__
|
|
assert isinstance(payload["commit_sha"], str)
|
|
assert payload["commit_sha"], "commit_sha must be a non-empty string"
|