teteffd / apps /api /tests /unit /test_middleware.py
Developer
WormGPT - production-grade AI chat platform
276ef31
Raw History Blame Contribute Delete
1.86 kB
"""Unit tests for middleware components (no DB needed)."""
from __future__ import annotations
from unittest.mock import Mock
import pytest
from fastapi import Request
from starlette.datastructures import Headers, MutableHeaders
from starlette.responses import Response
from app.core.middleware import RequestContextMiddleware, SecurityHeadersMiddleware
@pytest.mark.anyio
async def test_security_headers_on_api():
"""Verify CSP and other security headers are set on API responses."""
_app = Mock()
middleware = SecurityHeadersMiddleware(_app)
request = Mock(spec=Request)
request.url.path = "/api/v1/health"
response = Response(status_code=200)
async def call_next(_req):
return response
result = await middleware.dispatch(request, call_next)
assert result.headers.get("x-content-type-options") == "nosniff"
assert result.headers.get("x-frame-options") == "DENY"
assert result.headers.get("referrer-policy") == "strict-origin-when-cross-origin"
assert "content-security-policy" in result.headers
csp = result.headers["content-security-policy"]
assert "default-src 'self'" in csp
assert "frame-ancestors 'none'" in csp
assert "form-action 'self'" in csp
@pytest.mark.anyio
async def test_request_id_is_set():
"""Verify request ID is attached to response."""
_app = Mock()
middleware = RequestContextMiddleware(_app)
request = Mock(spec=Request)
request.headers = {}
request.state = Mock()
request.method = "GET"
request.url.path = "/test"
response = Response(status_code=200)
async def call_next(_req):
return response
result = await middleware.dispatch(request, call_next)
assert "x-request-id" in result.headers
assert len(result.headers["x-request-id"]) > 0
assert "x-response-time-ms" in result.headers