import { describe, it, expect } from "vitest";
import { RecordingRateLimit } from "@/rate-limit/recording-rate-limit";

describe("RecordingRateLimit", () => {
  it("starts with empty call arrays", () => {
    const rl = new RecordingRateLimit();
    expect(rl.consumeCalls).toHaveLength(0);
    expect(rl.resetCalls).toHaveLength(0);
  });

  it("captures consume call arguments verbatim including optional weight", async () => {
    const rl = new RecordingRateLimit();
    await rl.consume("api", "user:123");
    await rl.consume("api", "user:456", 2);
    expect(rl.consumeCalls).toEqual([
      { budgetName: "api", key: "user:123", weight: undefined },
      { budgetName: "api", key: "user:456", weight: 2 },
    ]);
  });

  it("captures reset call arguments verbatim", async () => {
    const rl = new RecordingRateLimit();
    await rl.reset("api", "user:123");
    await rl.reset("auth", "ip:1.2.3.4");
    expect(rl.resetCalls).toEqual([
      { budgetName: "api", key: "user:123" },
      { budgetName: "auth", key: "ip:1.2.3.4" },
    ]);
  });

  it("returns allowed decision by default", async () => {
    const rl = new RecordingRateLimit();
    const decision = await rl.consume("api", "user:123");
    expect(decision).toEqual({
      allowed: true,
      remaining: Infinity,
      resetAt: new Date(0),
    });
  });

  it("returns configured decision after withDecision", async () => {
    const rl = new RecordingRateLimit();
    const blocked = { allowed: false, remaining: 0, resetAt: new Date(9999) };
    rl.withDecision(blocked);
    const decision = await rl.consume("api", "user:123");
    expect(decision).toEqual(blocked);
  });
});
