""" Tests for uncovered code paths in security/rate_limiter.py. Targets: - get_client_ip: X-Forwarded-For, X-Real-IP, fallback - get_current_username: from g.current_user, from session, missing - _get_upload_user_key: authenticated vs unauthenticated """ from unittest.mock import patch MODULE = "local_deep_research.security.rate_limiter" class TestGetClientIp: def test_x_forwarded_for_first_ip(self, app): """Uses first IP from X-Forwarded-For header.""" from local_deep_research.security.rate_limiter import get_client_ip with app.test_request_context( environ_base={"HTTP_X_FORWARDED_FOR": "1.2.3.4, 5.6.7.8"} ): assert get_client_ip() == "1.2.3.4" def test_x_real_ip(self, app): """Uses X-Real-IP when no X-Forwarded-For.""" from local_deep_research.security.rate_limiter import get_client_ip with app.test_request_context( environ_base={"HTTP_X_REAL_IP": "10.0.0.1"} ): assert get_client_ip() == "10.0.0.1" def test_fallback_to_remote_addr(self, app): """Falls back to remote address when no proxy headers.""" from local_deep_research.security.rate_limiter import get_client_ip with app.test_request_context( environ_base={"REMOTE_ADDR": "127.0.0.1"} ): result = get_client_ip() assert result is not None class TestGetCurrentUsername: def test_from_g_current_user(self, app): """Returns username from g.current_user.""" from flask import g from local_deep_research.security.rate_limiter import ( get_current_username, ) with app.test_request_context(): g.current_user = "alice" assert get_current_username() == "alice" def test_from_session_fallback(self, app): """Falls back to session username.""" # audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: DELETE). with app.test_request_context(): # No g.current_user set with app.test_client() as client: with client.session_transaction() as sess: sess["username"] = "bob" def test_returns_none_when_no_user(self, app): """Returns None when no user info available.""" from local_deep_research.security.rate_limiter import ( get_current_username, ) with app.test_request_context(): result = get_current_username() assert result is None class TestGetUploadUserKey: def test_authenticated_user_key(self, app): """Returns user-keyed string for authenticated users.""" from local_deep_research.security.rate_limiter import ( _get_upload_user_key, ) with app.test_request_context(): with patch(f"{MODULE}.get_current_username", return_value="alice"): result = _get_upload_user_key() assert result == "upload_user:alice" def test_unauthenticated_ip_key(self, app): """Returns IP-keyed string for unauthenticated requests.""" from local_deep_research.security.rate_limiter import ( _get_upload_user_key, ) with app.test_request_context(): with patch(f"{MODULE}.get_current_username", return_value=None): with patch(f"{MODULE}.get_client_ip", return_value="1.2.3.4"): result = _get_upload_user_key() assert result == "upload_ip:1.2.3.4" class TestModuleConstants: def test_shared_limits_exist(self): """Shared limit decorators are created.""" from local_deep_research.security.rate_limiter import ( login_limit, registration_limit, settings_limit, upload_rate_limit_user, ) assert login_limit is not None assert registration_limit is not None assert settings_limit is not None assert upload_rate_limit_user is not None