57 lines
2 KiB
Python
57 lines
2 KiB
Python
|
|
"""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
|