Initial public release
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
BACKEND = ROOT / "backend"
|
||||
|
||||
|
||||
def test_no_untyped_fastapi_response_models_remain() -> None:
|
||||
route_root = BACKEND / "app" / "api" / "routes"
|
||||
route_sources = "\n".join(
|
||||
path.read_text(encoding="utf-8")
|
||||
for path in sorted(route_root.glob("*.py"))
|
||||
)
|
||||
|
||||
assert "response_model=dict" not in route_sources
|
||||
|
||||
|
||||
def test_every_json_success_response_has_a_concrete_canonical_schema() -> None:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
sys.path.insert(0, str(BACKEND))
|
||||
from app.main import create_app
|
||||
|
||||
from scripts.audit_api_contracts import (
|
||||
ALLOWED_NON_ENVELOPE_ENDPOINTS,
|
||||
_validate_response_contracts,
|
||||
)
|
||||
|
||||
openapi = create_app().openapi()
|
||||
assert _validate_response_contracts(openapi) == []
|
||||
|
||||
untyped_successes: set[tuple[str, str]] = set()
|
||||
for path, path_item in openapi["paths"].items():
|
||||
for method, operation in path_item.items():
|
||||
if method.upper() not in {"GET", "POST", "PATCH", "DELETE"}:
|
||||
continue
|
||||
has_json_schema = any(
|
||||
response.get("content", {})
|
||||
.get("application/json", {})
|
||||
.get("schema")
|
||||
for code, response in operation.get("responses", {}).items()
|
||||
if str(code).startswith("2")
|
||||
)
|
||||
if not has_json_schema:
|
||||
untyped_successes.add((method.upper(), path))
|
||||
|
||||
assert untyped_successes == ALLOWED_NON_ENVELOPE_ENDPOINTS - {
|
||||
("GET", "/health"),
|
||||
("GET", "/health/live"),
|
||||
("GET", "/health/ready"),
|
||||
}
|
||||
Reference in New Issue
Block a user