Files
erika/lib/share/rate-limit-core.test.ts

54 lines
1.4 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { enforceFixedWindowRateLimit } from "@/lib/share/rate-limit-core";
function memoryIncrement() {
const counts = new Map<string, number>();
return async (key: string) => {
const count = (counts.get(key) ?? 0) + 1;
counts.set(key, count);
return count;
};
}
describe("share fixed-window rate limits", () => {
for (const [name, limit] of [
["sender shares", 10],
["bot requests", 60],
["comments", 30],
] as const) {
test(`allows ${limit} ${name} and rejects request ${limit + 1}`, async () => {
const increment = memoryIncrement();
const options = {
key: name,
limit,
windowSeconds: 3_600,
increment,
now: 3_601_000,
};
for (let request = 1; request <= limit; request += 1) {
await expect(enforceFixedWindowRateLimit(options)).resolves.toBeUndefined();
}
await expect(enforceFixedWindowRateLimit(options)).rejects.toMatchObject({
status: 429,
retryAfter: 3_599,
});
});
}
test("fails closed when Redis is unavailable", async () => {
await expect(
enforceFixedWindowRateLimit({
key: "sender:1",
limit: 10,
windowSeconds: 3_600,
increment: async () => {
throw new Error("offline");
},
}),
).rejects.toEqual(
expect.objectContaining({ status: 503 }),
);
});
});