dotb_ai-platform/old_repo/tests/test_openapi_cli.py

103 lines
3.6 KiB
Python

import json
from pathlib import Path
import pytest
from lead_scoring.cli.openapi import DEFAULT_OPENAPI_PATH, generate_openapi_json, run_openapi_cli
def test_generate_openapi_json_is_deterministic():
json_str_1 = generate_openapi_json()
json_str_2 = generate_openapi_json()
assert json_str_1 == json_str_2
data = json.loads(json_str_1)
assert data["info"]["title"] == "Lead Scoring Service"
assert "/health" in data["paths"]
assert "/v1/scoring-runs" in data["paths"]
assert "/v1/scoring-runs/{run_id}" in data["paths"]
assert "CreateScoringRunRequest" in data["components"]["schemas"]
assert "CreateScoringRunResponse" in data["components"]["schemas"]
assert "ScoringRunResponse" in data["components"]["schemas"]
assert "ErrorResponse" in data["components"]["schemas"]
# Security scheme assertions
assert "securitySchemes" in data["components"]
assert "HTTPBearer" in data["components"]["securitySchemes"]
bearer_scheme = data["components"]["securitySchemes"]["HTTPBearer"]
assert bearer_scheme["type"] == "http"
assert bearer_scheme["scheme"] == "bearer"
# Operation security assertions
post_security = data["paths"]["/v1/scoring-runs"]["post"].get("security", [])
assert any("HTTPBearer" in s for s in post_security)
get_security = data["paths"]["/v1/scoring-runs/{run_id}"]["get"].get("security", [])
assert any("HTTPBearer" in s for s in get_security)
def test_default_openapi_path_is_at_project_root():
assert DEFAULT_OPENAPI_PATH.name == "openapi.json"
assert (DEFAULT_OPENAPI_PATH.parent / "pyproject.toml").exists()
def test_openapi_generation_ignores_env_file_pollution(monkeypatch: pytest.MonkeyPatch):
# Setting an env var should not mutate deterministic contract generation
monkeypatch.setenv("APP_NAME", "mutated-name")
json_str_1 = generate_openapi_json()
json_str_2 = generate_openapi_json()
assert json_str_1 == json_str_2
data = json.loads(json_str_1)
assert data["info"]["title"] == "Lead Scoring Service"
def test_openapi_cli_generates_file_at_custom_path(tmp_path: Path):
out_file = tmp_path / "custom_openapi.json"
exit_code = run_openapi_cli(["--output", str(out_file)])
assert exit_code == 0
assert out_file.exists()
content = out_file.read_text(encoding="utf-8")
assert content == generate_openapi_json()
def test_openapi_cli_check_success_when_matching(tmp_path: Path):
out_file = tmp_path / "openapi.json"
out_file.write_text(generate_openapi_json(), encoding="utf-8")
exit_code = run_openapi_cli(["--output", str(out_file), "--check"])
assert exit_code == 0
def test_openapi_cli_check_fails_when_file_absent(tmp_path: Path):
out_file = tmp_path / "non_existent_openapi.json"
exit_code = run_openapi_cli(["--output", str(out_file), "--check"])
assert exit_code != 0
def test_openapi_cli_check_fails_when_file_stale(tmp_path: Path):
out_file = tmp_path / "openapi.json"
out_file.write_text('{"stale": true}\n', encoding="utf-8")
exit_code = run_openapi_cli(["--output", str(out_file), "--check"])
assert exit_code != 0
def test_generate_openapi_preserves_custom_app_openapi():
from lead_scoring.main import create_app
custom_app = create_app()
original_openapi = custom_app.openapi
def _custom_openapi():
schema = original_openapi()
schema["info"]["x-custom-extension"] = "pilot-test"
return schema
custom_app.openapi = _custom_openapi # type: ignore
json_str = generate_openapi_json(custom_app)
data = json.loads(json_str)
assert data["info"].get("x-custom-extension") == "pilot-test"