Files
xiaobaifupan/tests/test_http_governance.py
T

49 lines
2.0 KiB
Python

from __future__ import annotations
import unittest
from http import HTTPStatus
from api_access import ROUTES, required_role
from backend.http import correlation_id, normalize_error_payload
from tools.build_api_registry import build as build_api_registry
class HttpGovernanceTests(unittest.TestCase):
def test_runtime_registry_resolves_every_declared_route(self) -> None:
for item in build_api_registry()["routes"]:
path = (
item["path"]
.replace("(\\d{6})", "000001")
.replace("(\\d+)", "1")
.replace("(.+)", "sample")
)
resolved = ROUTES.resolve(item["method"], path)
self.assertIsNotNone(resolved, f"{item['method']} {path}")
self.assertEqual(resolved.feature, item["feature"])
self.assertEqual(resolved.access, item["access"])
def test_unknown_route_has_no_runtime_match(self) -> None:
self.assertIsNone(ROUTES.resolve("GET", "/api/not-registered"))
def test_compatibility_access_function_uses_runtime_registry(self) -> None:
self.assertEqual(required_role("GET", "/api/screener/setup"), "member")
self.assertEqual(required_role("POST", "/api/admin/settings"), "admin")
self.assertEqual(required_role("GET", "/api/dashboard"), "authenticated")
def test_errors_keep_legacy_field_and_add_stable_contract(self) -> None:
result = normalize_error_payload(
{"error": "invalid input"}, HTTPStatus.BAD_REQUEST, "request-123"
)
self.assertEqual(result["error"], "invalid input")
self.assertEqual(result["message"], "invalid input")
self.assertEqual(result["code"], "bad_request")
self.assertEqual(result["request_id"], "request-123")
def test_correlation_id_rejects_header_injection(self) -> None:
self.assertEqual(correlation_id("client-request-123"), "client-request-123")
self.assertRegex(correlation_id("bad\r\nheader"), r"^[0-9a-f]{32}$")
if __name__ == "__main__":
unittest.main()