Skip to content

Commit 94247ce

Browse files
test: add sliding-window expiry test for utility
1 parent db1e794 commit 94247ce

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

lib/rate-limit.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,38 @@ describe('rateLimit', () => {
8484
});
8585
});
8686

87+
it('keys expire exactly at the window limit with sliding time advances', async () => {
88+
vi.useFakeTimers();
89+
const ip = '9.9.9.9';
90+
const windowMs = 1000;
91+
const limit = 5;
92+
93+
// First request: creates the tracker with 1s TTL
94+
let res = await rateLimit(ip, limit, windowMs);
95+
expect(res.success).toBe(true);
96+
expect(res.remaining).toBe(limit - 1);
97+
98+
// Advance half the window and make another request
99+
vi.advanceTimersByTime(500);
100+
res = await rateLimit(ip, limit, windowMs);
101+
expect(res.success).toBe(true);
102+
103+
// Advance to exactly the original window boundary (total = 1000ms)
104+
vi.advanceTimersByTime(500);
105+
106+
// At the exact boundary the entry should still be considered valid
107+
res = await rateLimit(ip, limit, windowMs);
108+
expect(res.success).toBe(true);
109+
110+
// Move just past the window expiry
111+
vi.advanceTimersByTime(1);
112+
113+
// Now the key must have expired and a fresh window starts
114+
res = await rateLimit(ip, limit, windowMs);
115+
expect(res.success).toBe(true);
116+
expect(res.remaining).toBe(limit - 1);
117+
});
118+
87119
it('allows requests after many expired IP entries', async () => {
88120
const windowMs = 1000;
89121

0 commit comments

Comments
 (0)