"""Tests for the security headers middleware.""" import pytest from httpx import ASGITransport, AsyncClient from src.main import create_app @pytest.fixture def app(): return create_app() @pytest.fixture async def client(app): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as ac: yield ac class TestSecurityHeaders: @pytest.mark.asyncio async def test_x_content_type_options(self, client): resp = await client.get("/health") assert resp.headers["x-content-type-options"] == "nosniff" @pytest.mark.asyncio async def test_x_frame_options(self, client): resp = await client.get("/health") assert resp.headers["x-frame-options"] == "DENY" @pytest.mark.asyncio async def test_x_xss_protection(self, client): resp = await client.get("/health") assert resp.headers["x-xss-protection"] == "0" @pytest.mark.asyncio async def test_referrer_policy(self, client): resp = await client.get("/health") assert resp.headers["referrer-policy"] == "strict-origin-when-cross-origin" @pytest.mark.asyncio async def test_content_security_policy(self, client): resp = await client.get("/health") assert resp.headers["content-security-policy"] == "default-src 'none'" @pytest.mark.asyncio async def test_no_hsts_on_http(self, client): resp = await client.get("/health") assert "strict-transport-security" not in resp.headers @pytest.mark.asyncio async def test_hsts_on_https(self, app): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="https://test") as client: resp = await client.get("/health") assert "strict-transport-security" in resp.headers assert "max-age=63072000" in resp.headers["strict-transport-security"] @pytest.mark.asyncio async def test_headers_present_on_non_existent_route(self, client): # Even 404s on unknown routes should have security headers resp = await client.get("/this-does-not-exist") assert resp.headers["x-content-type-options"] == "nosniff" assert resp.headers["x-frame-options"] == "DENY"