"""Unit tests for api/security_headers.py.""" from starlette.testclient import TestClient from starlette.applications import Starlette from starlette.requests import Request from starlette.responses import JSONResponse from starlette.routing import Route from api.security_headers import SecurityHeadersMiddleware async def _ok_endpoint(request: Request) -> JSONResponse: return JSONResponse({"ok": True}) def _build_app() -> Starlette: app = Starlette(routes=[Route("/test", _ok_endpoint)]) app.add_middleware(SecurityHeadersMiddleware) return app class TestSecurityHeaders: """Tests for SecurityHeadersMiddleware.""" def test_x_content_type_options(self) -> None: client = TestClient(_build_app()) resp = client.get("/test") assert resp.headers["X-Content-Type-Options"] == "nosniff" def test_x_frame_options(self) -> None: client = TestClient(_build_app()) resp = client.get("/test") assert resp.headers["X-Frame-Options"] == "DENY" def test_referrer_policy(self) -> None: client = TestClient(_build_app()) resp = client.get("/test") assert resp.headers["Referrer-Policy"] == "strict-origin-when-cross-origin" def test_content_security_policy(self) -> None: client = TestClient(_build_app()) resp = client.get("/test") assert "Content-Security-Policy" in resp.headers csp = resp.headers["Content-Security-Policy"] assert "default-src 'self'" in csp assert "frame-ancestors 'none'" in csp def test_hsts_set_for_https(self) -> None: client = TestClient(_build_app()) resp = client.get("/test", headers={"x-forwarded-proto": "https"}) assert "Strict-Transport-Security" in resp.headers assert "max-age=" in resp.headers["Strict-Transport-Security"] def test_hsts_not_set_for_http(self) -> None: client = TestClient(_build_app()) resp = client.get("/test") assert "Strict-Transport-Security" not in resp.headers