Files
psu-schedule/test/limits.test.js

57 lines
1.8 KiB
JavaScript

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);
});