From 5dd9389c2524c1fff9d7edcdc6939cda051a16c1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 18:49:41 +0000 Subject: [PATCH] test: tighten fixed window limiter coverage --- src/infra/fixed-window-rate-limit.test.ts | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/infra/fixed-window-rate-limit.test.ts b/src/infra/fixed-window-rate-limit.test.ts index 1afc50974d0..8290c1d4176 100644 --- a/src/infra/fixed-window-rate-limit.test.ts +++ b/src/infra/fixed-window-rate-limit.test.ts @@ -18,6 +18,35 @@ describe("fixed-window rate limiter", () => { expect(limiter.consume()).toMatchObject({ allowed: true, remaining: 1 }); }); + it("clamps maxRequests and windowMs to at least one", () => { + let nowMs = 100; + const limiter = createFixedWindowRateLimiter({ + maxRequests: 0.2, + windowMs: 0.4, + now: () => nowMs, + }); + + expect(limiter.consume()).toMatchObject({ allowed: true, remaining: 0, retryAfterMs: 0 }); + expect(limiter.consume()).toMatchObject({ allowed: false, remaining: 0, retryAfterMs: 1 }); + + nowMs += 1; + expect(limiter.consume()).toMatchObject({ allowed: true, remaining: 0 }); + }); + + it("reports the remaining retry window after later blocked attempts", () => { + let nowMs = 1_000; + const limiter = createFixedWindowRateLimiter({ + maxRequests: 1, + windowMs: 1_000, + now: () => nowMs, + }); + + expect(limiter.consume()).toMatchObject({ allowed: true, remaining: 0 }); + + nowMs += 250; + expect(limiter.consume()).toMatchObject({ allowed: false, retryAfterMs: 750 }); + }); + it("supports explicit reset", () => { const limiter = createFixedWindowRateLimiter({ maxRequests: 1,