import { createRateLimiter } from '../rate-limit' beforeEach(() => { jest.useFakeTimers() }) afterEach(() => { jest.useRealTimers() }) describe('createRateLimiter', () => { it('allows requests under the limit', () => { const limiter = createRateLimiter(5, 3_600_000) const ip = '1.2.3.4' for (let i = 0; i < 5; i++) { expect(limiter.isLimited(ip)).toBe(false) } }) it('blocks the 6th request within the window', () => { const limiter = createRateLimiter(5, 3_600_000) const ip = '10.0.0.1' for (let i = 0; i < 5; i++) limiter.isLimited(ip) expect(limiter.isLimited(ip)).toBe(true) }) it('resets after the window expires', () => { const limiter = createRateLimiter(5, 3_600_000) const ip = '10.0.0.2' for (let i = 0; i < 5; i++) limiter.isLimited(ip) expect(limiter.isLimited(ip)).toBe(true) jest.advanceTimersByTime(3_600_001) expect(limiter.isLimited(ip)).toBe(false) }) it('tracks different IPs independently', () => { const limiter = createRateLimiter(5, 3_600_000) const ipA = '192.168.1.1' const ipB = '192.168.1.2' for (let i = 0; i < 5; i++) limiter.isLimited(ipA) expect(limiter.isLimited(ipA)).toBe(true) expect(limiter.isLimited(ipB)).toBe(false) }) it('tracks separate limiter instances independently', () => { const limiterA = createRateLimiter(1, 3_600_000) const limiterB = createRateLimiter(1, 3_600_000) const ip = '5.5.5.5' expect(limiterA.isLimited(ip)).toBe(false) expect(limiterA.isLimited(ip)).toBe(true) expect(limiterB.isLimited(ip)).toBe(false) }) })