import test from "node:test"; import assert from "node:assert/strict"; import { rateLimit, semaphore } from "../server/limits.js"; test("Импорт: не больше двух разборов сразу, лишние ждут или получают 429", async () => { const run = semaphore({ limit: 2, queue: 1, message: "Занято" }); let active = 0, peak = 0; const release = []; const task = () => run(async () => { peak = Math.max(peak, ++active); await new Promise((resolve) => release.push(resolve)); active--; }); const running = [task(), task(), task()]; await assert.rejects(task(), (e) => e.status === 429 && e.code === "busy" && e.message === "Занято"); // Each finished task hands its slot to the one waiting. while (release.length) { release.shift()(); await new Promise((resolve) => setImmediate(resolve)); } await Promise.all(running); assert.equal(peak, 2); // All slots are free again. assert.equal(await run(async () => "ok"), "ok"); }); test("Импорт: лимит запросов считается по адресу клиента", () => { const limit = rateLimit({ max: 2, windowMs: 60_000, message: "Подождите" }); const call = (ip) => { let status = 200, body = null, passed = false; const res = { set() {}, status(code) { status = code; return this; }, json(value) { body = value; }, }; limit({ ip }, res, () => (passed = true)); return { status, body, passed }; }; assert.ok(call("10.0.0.1").passed); assert.ok(call("10.0.0.1").passed); assert.deepEqual(call("10.0.0.1"), { status: 429, body: { error: "Подождите", code: "too_many_requests" }, passed: false, }); assert.ok(call("10.0.0.2").passed); });