diff --git a/tests/conftest.py b/tests/conftest.py index 9920564..133f726 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,6 +18,7 @@ from sqlalchemy.types import CHAR from cartsnitch_api.config import settings as cartsnitch_settings from cartsnitch_api.database import get_db from cartsnitch_api.main import create_app +from cartsnitch_api.middleware import rate_limit as _rate_limit_module from cartsnitch_api.models import Base @@ -140,12 +141,39 @@ TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:" @pytest.fixture(autouse=True) def disable_rate_limiting(): - """Disable rate limiting for all tests to prevent 429 interference.""" + """Disable rate limiting for all tests to prevent 429 interference. + + The rate_limit module creates its Redis client at import time when + ``settings.rate_limit_redis_enabled`` is true. We can't undo that by + flipping the setting inside the fixture — the client and the + Redis-backed limiters are already constructed. So we swap them out + for the in-memory limiters directly on the module, which also + prevents "Event loop is closed" errors when the redis client tries + to disconnect after the test event loop ends. + """ cartsnitch_settings.rate_limit_enabled = False cartsnitch_settings.rate_limit_redis_enabled = False + original_public = _rate_limit_module._public_limiter + original_auth = _rate_limit_module._auth_limiter + original_auth_strict = _rate_limit_module._auth_strict_limiter + _rate_limit_module._redis_client = None + _rate_limit_module._use_redis = False + _rate_limit_module._public_limiter = _rate_limit_module.InMemorySlidingWindow( + cartsnitch_settings.rate_limit_requests, cartsnitch_settings.rate_limit_window_seconds + ) + _rate_limit_module._auth_limiter = _rate_limit_module.InMemorySlidingWindow( + cartsnitch_settings.rate_limit_requests * 5, cartsnitch_settings.rate_limit_window_seconds + ) + _rate_limit_module._auth_strict_limiter = _rate_limit_module.InMemorySlidingWindow( + cartsnitch_settings.rate_limit_auth_requests, + cartsnitch_settings.rate_limit_auth_window_seconds, + ) yield cartsnitch_settings.rate_limit_enabled = True cartsnitch_settings.rate_limit_redis_enabled = True + _rate_limit_module._public_limiter = original_public + _rate_limit_module._auth_limiter = original_auth + _rate_limit_module._auth_strict_limiter = original_auth_strict @pytest.fixture