import { describe, it, expect, beforeEach } from 'vitest'; import { rateLimit, _clearRateLimits } from './v2-rate-limit'; describe('rateLimit', () => { beforeEach(() => { _clearRateLimits(); }); it('allows requests up to the limit', () => { for (let i = 0; i < 3; i++) { const r = rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 }); expect(r.ok).toBe(true); } }); it('rejects once the limit is exceeded and reports Retry-After', () => { for (let i = 0; i < 3; i++) { rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 }); } const r = rateLimit({ key: 'k', limit: 3, windowMs: 60_000, now: 1000 }); expect(r.ok).toBe(false); expect(r.retryAfterMs).toBeGreaterThan(0); }); it('treats keys independently', () => { rateLimit({ key: 'a', limit: 1, windowMs: 60_000, now: 1000 }); expect(rateLimit({ key: 'a', limit: 1, windowMs: 60_000, now: 1000 }).ok).toBe(false); expect(rateLimit({ key: 'b', limit: 1, windowMs: 60_000, now: 1000 }).ok).toBe(true); }); it('lets the window expire before allowing again', () => { for (let i = 0; i < 2; i++) { rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 }); } expect(rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 }).ok).toBe(false); expect(rateLimit({ key: 'k', limit: 2, windowMs: 10_000, now: 1000 + 10_000 + 1 }).ok).toBe( true ); }); });