Files
resolutionflow/backend/tests/test_security_headers.py
2026-03-18 02:38:42 +00:00

42 lines
1.5 KiB
Python

"""Tests for security headers middleware."""
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_security_headers_present(client: AsyncClient):
"""Every response should include security headers."""
response = await client.get("/health")
assert response.status_code == 200
# Non-CSP headers always present
assert response.headers["x-content-type-options"] == "nosniff"
assert response.headers["x-frame-options"] == "DENY"
assert response.headers["referrer-policy"] == "strict-origin-when-cross-origin"
assert "camera=()" in response.headers["permissions-policy"]
assert "microphone=()" in response.headers["permissions-policy"]
assert "geolocation=()" in response.headers["permissions-policy"]
@pytest.mark.asyncio
async def test_csp_report_only_header(client: AsyncClient):
"""CSP should be in report-only mode."""
response = await client.get("/health")
assert response.status_code == 200
csp = response.headers.get("content-security-policy-report-only")
assert csp is not None
assert "default-src 'self'" in csp
assert "script-src 'self'" in csp
assert "style-src 'self' 'unsafe-inline'" in csp
assert "frame-ancestors 'none'" in csp
@pytest.mark.asyncio
async def test_hsts_only_in_production(client: AsyncClient):
"""HSTS should NOT be sent when DEBUG=true (test environment)."""
response = await client.get("/health")
assert response.status_code == 200
assert "strict-transport-security" not in response.headers