"""Tests for RateLimitMiddleware honoring proxy headers (X-Forwarded-For).""" from src.backend.api.middleware.rate_limit import RateLimitMiddleware class _FakeRequest: """Minimal stand-in for starlette.requests.Request.""" def __init__(self, headers: dict[str, str], host: str | None = "10.0.0.1"): self.headers = headers class _Client: pass if host is None: self.client = None else: self.client = _Client() self.client.host = host def test_client_ip_uses_x_forwarded_for_first_hop(): req = _FakeRequest( headers={"x-forwarded-for": "203.0.113.5, 10.0.0.2"}, host="10.0.0.1", ) assert RateLimitMiddleware._client_ip(req) == "203.0.113.5" def test_client_ip_strips_whitespace(): req = _FakeRequest(headers={"x-forwarded-for": " 198.51.100.7 "}) assert RateLimitMiddleware._client_ip(req) == "198.51.100.7" def test_client_ip_falls_back_to_x_real_ip(): req = _FakeRequest(headers={"x-real-ip": "203.0.113.99"}, host="10.0.0.1") assert RateLimitMiddleware._client_ip(req) == "203.0.113.99" def test_client_ip_falls_back_to_request_client_host(): req = _FakeRequest(headers={}, host="172.18.0.5") assert RateLimitMiddleware._client_ip(req) == "172.18.0.5" def test_client_ip_returns_unknown_without_client(): req = _FakeRequest(headers={}, host=None) assert RateLimitMiddleware._client_ip(req) == "unknown" def test_x_forwarded_for_overrides_x_real_ip(): req = _FakeRequest( headers={ "x-forwarded-for": "203.0.113.5", "x-real-ip": "10.0.0.2", }, host="10.0.0.1", ) assert RateLimitMiddleware._client_ip(req) == "203.0.113.5" def test_empty_x_forwarded_for_falls_through(): req = _FakeRequest( headers={"x-forwarded-for": "", "x-real-ip": "203.0.113.42"}, host="10.0.0.1", ) assert RateLimitMiddleware._client_ip(req) == "203.0.113.42"