Initial commit : monorepo seiche (serveur Fastify + web Vite/React, Docker, config VS Code)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { RateLimiter } from "../src/auth/rate-limit";
|
||||
|
||||
const T0 = new Date("2026-01-01T00:00:00Z");
|
||||
const at = (ms: number) => new Date(T0.getTime() + ms);
|
||||
|
||||
describe("RateLimiter (fenêtre glissante)", () => {
|
||||
it("autorise jusqu'à maxHits puis bloque", () => {
|
||||
const rl = new RateLimiter(3, 60_000);
|
||||
expect(rl.hit("a", T0)).toBe(true);
|
||||
expect(rl.hit("a", at(1000))).toBe(true);
|
||||
expect(rl.hit("a", at(2000))).toBe(true);
|
||||
expect(rl.hit("a", at(3000))).toBe(false);
|
||||
});
|
||||
|
||||
it("les hits anciens sortent de la fenêtre", () => {
|
||||
const rl = new RateLimiter(2, 60_000);
|
||||
expect(rl.hit("a", T0)).toBe(true);
|
||||
expect(rl.hit("a", at(30_000))).toBe(true);
|
||||
expect(rl.hit("a", at(31_000))).toBe(false);
|
||||
// Le hit de T0 a expiré de la fenêtre (60 s).
|
||||
expect(rl.hit("a", at(61_001))).toBe(true);
|
||||
});
|
||||
|
||||
it("reset vide la clé", () => {
|
||||
const rl = new RateLimiter(1, 60_000);
|
||||
expect(rl.hit("a", T0)).toBe(true);
|
||||
expect(rl.hit("a", at(1000))).toBe(false);
|
||||
rl.reset("a");
|
||||
expect(rl.hit("a", at(2000))).toBe(true);
|
||||
});
|
||||
|
||||
it("remaining reflète les tentatives restantes", () => {
|
||||
const rl = new RateLimiter(2, 60_000);
|
||||
expect(rl.remaining("a", T0)).toBe(2);
|
||||
rl.hit("a", T0);
|
||||
expect(rl.remaining("a", at(1000))).toBe(1);
|
||||
});
|
||||
|
||||
it("les clés sont isolées", () => {
|
||||
const rl = new RateLimiter(1, 60_000);
|
||||
expect(rl.hit("a", T0)).toBe(true);
|
||||
expect(rl.hit("b", T0)).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user