import { describe, it, expect, beforeEach, afterAll } from "vitest"; import { checkRateLimit } from "./rate-limit"; import { db, pool } from "./db"; import { rateLimitBuckets } from "@cmbot/db"; import { sql } from "drizzle-orm"; describe("checkRateLimit", () => { beforeEach(async () => { await db.delete(rateLimitBuckets).where(sql`true`); }); afterAll(async () => { await pool.end(); }); it("allows requests under the limit", async () => { for (let i = 0; i < 5; i++) { const r = await checkRateLimit("test:1", { max: 5, windowSec: 10 }); expect(r.limited).toBe(false); } }); it("blocks the (max+1)th request within the window", async () => { for (let i = 0; i < 3; i++) { await checkRateLimit("test:2", { max: 3, windowSec: 10 }); } const r = await checkRateLimit("test:2", { max: 3, windowSec: 10 }); expect(r.limited).toBe(true); expect(r.count).toBeGreaterThan(3); }); it("isolates buckets by key", async () => { await checkRateLimit("a", { max: 1, windowSec: 10 }); await checkRateLimit("a", { max: 1, windowSec: 10 }); const aLimited = await checkRateLimit("a", { max: 1, windowSec: 10 }); const bFresh = await checkRateLimit("b", { max: 1, windowSec: 10 }); expect(aLimited.limited).toBe(true); expect(bFresh.limited).toBe(false); }); });