import { describe, expect, test } from "bun:test"; import { enforceFixedWindowRateLimit } from "@/lib/share/rate-limit-core"; function memoryIncrement() { const counts = new Map(); 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 }), ); }); });