44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
|
|
import { rateLimit } from "@/lib/rate-limit";
|
|
|
|
describe("rateLimit", () => {
|
|
it("allows up to limit calls in window", () => {
|
|
const key = "test:" + Math.random();
|
|
for (let i = 0; i < 5; i++) {
|
|
const r = rateLimit({ key, windowMs: 60_000, limit: 5 });
|
|
expect(r.ok).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("blocks the (limit+1)th call with retryAfter > 0", () => {
|
|
const key = "test:" + Math.random();
|
|
for (let i = 0; i < 3; i++) {
|
|
rateLimit({ key, windowMs: 60_000, limit: 3 });
|
|
}
|
|
const r = rateLimit({ key, windowMs: 60_000, limit: 3 });
|
|
expect(r.ok).toBe(false);
|
|
expect(r.retryAfter).toBeGreaterThan(0);
|
|
expect(r.remaining).toBe(0);
|
|
});
|
|
|
|
it("isolates different keys", () => {
|
|
const k1 = "test:" + Math.random();
|
|
const k2 = "test:" + Math.random();
|
|
for (let i = 0; i < 5; i++) {
|
|
rateLimit({ key: k1, windowMs: 60_000, limit: 5 });
|
|
}
|
|
const r = rateLimit({ key: k2, windowMs: 60_000, limit: 5 });
|
|
expect(r.ok).toBe(true);
|
|
});
|
|
|
|
it("resets after window expires", async () => {
|
|
const key = "test:" + Math.random();
|
|
rateLimit({ key, windowMs: 10, limit: 1 });
|
|
const blocked = rateLimit({ key, windowMs: 10, limit: 1 });
|
|
expect(blocked.ok).toBe(false);
|
|
await new Promise((r) => setTimeout(r, 15));
|
|
const after = rateLimit({ key, windowMs: 10, limit: 1 });
|
|
expect(after.ok).toBe(true);
|
|
});
|
|
});
|