Skip to content

Commit bb9d3e4

Browse files
test(RateLimiter): add unit tests for RateLimiter class
1 parent 7e3d6a5 commit bb9d3e4

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

lib/rate-limit.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, it, expect, beforeEach, vi } from 'vitest';
22
import { rateLimit } from './rate-limit';
3+
import { RateLimiter } from './rate-limit';
34

45
describe('rateLimit', () => {
56
beforeEach(() => {
@@ -60,3 +61,48 @@ describe('rateLimit', () => {
6061
expect(rateLimit(ip2, 60, 60000).success).toBe(true);
6162
});
6263
});
64+
65+
describe('RateLimiter', () => {
66+
beforeEach(() => {
67+
vi.useFakeTimers();
68+
});
69+
70+
it('allows requests within the limit', () => {
71+
// Each check() within the limit should return true
72+
const limiter = new RateLimiter(3, 60000);
73+
expect(limiter.check('1.1.1.1')).toBe(true);
74+
expect(limiter.check('1.1.1.1')).toBe(true);
75+
expect(limiter.check('1.1.1.1')).toBe(true);
76+
});
77+
78+
it('blocks requests after exceeding the limit', () => {
79+
// 4th request should be denied when limit is 3
80+
const limiter = new RateLimiter(3, 60000);
81+
limiter.check('2.2.2.2');
82+
limiter.check('2.2.2.2');
83+
limiter.check('2.2.2.2');
84+
expect(limiter.check('2.2.2.2')).toBe(false);
85+
});
86+
87+
it('tracks multiple IPs independently', () => {
88+
// Exhausting one IP's limit should not affect another IP
89+
const limiter = new RateLimiter(2, 60000);
90+
limiter.check('3.3.3.3');
91+
limiter.check('3.3.3.3');
92+
expect(limiter.check('3.3.3.3')).toBe(false);
93+
expect(limiter.check('4.4.4.4')).toBe(true);
94+
});
95+
96+
it('allows requests again after the window resets', () => {
97+
// TTL expiry should clear the count, allowing the IP through again
98+
const windowMs = 60000;
99+
const limiter = new RateLimiter(2, windowMs);
100+
limiter.check('5.5.5.5');
101+
limiter.check('5.5.5.5');
102+
expect(limiter.check('5.5.5.5')).toBe(false);
103+
104+
vi.advanceTimersByTime(windowMs + 1);
105+
106+
expect(limiter.check('5.5.5.5')).toBe(true);
107+
});
108+
});

0 commit comments

Comments
 (0)