from unittest.mock import patch from app.rate_limit import RateLimiter def test_allows_up_to_limit_then_blocks(): limiter = RateLimiter(max_requests=3, window_seconds=60) assert limiter.allow("user-1") is True assert limiter.allow("user-1") is True assert limiter.allow("user-1") is True assert limiter.allow("user-1") is False def test_different_keys_tracked_independently(): limiter = RateLimiter(max_requests=1, window_seconds=60) assert limiter.allow("user-1") is True assert limiter.allow("user-2") is True assert limiter.allow("user-1") is False def test_hits_expire_after_window_elapses(): limiter = RateLimiter(max_requests=2, window_seconds=10) with patch("app.rate_limit.time.monotonic", return_value=100.0): assert limiter.allow("user-1") is True assert limiter.allow("user-1") is True assert limiter.allow("user-1") is False # at limit with patch("app.rate_limit.time.monotonic", return_value=111.0): # 11 seconds later, both prior hits (at t=100) are older than window_start (111 - 10 = 101) assert limiter.allow("user-1") is True