Coalesce quota refreshes and consolidate shared helpers
Some checks failed
Deploy Sokko G / deploy (push) Failing after 2s

This commit is contained in:
Shinuwa 2026-09-10 20:03:57 +02:00
parent a4cf633ab4
commit 748415082b
19 changed files with 216 additions and 64 deletions

4
tests/fixtures/project-env.txt vendored Normal file
View file

@ -0,0 +1,4 @@
# Rôle : fournit des variables non sensibles pour tester le chargement .env.
SOKKOG_ENV_FIXTURE_PORT=4321
SOKKOG_ENV_FIXTURE_QUOTED="value # inside"
SOKKOG_ENV_FIXTURE_COMMENT=value # outside

View file

@ -0,0 +1,20 @@
// Rôle : vérifie le parsing .env, la priorité du processus et les fichiers facultatifs.
import { test } from "node:test";
import assert from "node:assert/strict";
import { loadProjectEnv } from "../scripts/load-project-env.mjs";
for (const existing of ["9999", ""]) {
test(`project env preserves an existing ${existing ? "nonempty" : "empty"} value`, (t) => {
const keys = ["SOKKOG_ENV_FIXTURE_PORT", "SOKKOG_ENV_FIXTURE_QUOTED", "SOKKOG_ENV_FIXTURE_COMMENT"];
const previous = keys.map((key) => process.env[key]);
t.after(() => keys.forEach((key, index) => {
if (previous[index] === undefined) delete process.env[key];
else process.env[key] = previous[index];
}));
keys.forEach((key) => { delete process.env[key]; });
process.env.SOKKOG_ENV_FIXTURE_PORT = existing;
loadProjectEnv("tests/fixtures/project-env.txt");
loadProjectEnv("tests/fixtures/missing-env-file");
assert.deepEqual(keys.map((key) => process.env[key]), [existing, "value # inside", "value"]);
});
}

View file

@ -0,0 +1,90 @@
// Rôle : teste les rafales d'estimations, la concurrence et le nettoyage du quota.
import { test } from "node:test";
import assert from "node:assert/strict";
import { createQuotaRefresh } from "../website/src/features/toolboxes/storage/quotaRefresh.js";
function setup(estimate) {
const timers = new Map();
const results = [];
let id = 0;
const refresh = createQuotaRefresh({
estimate,
onResult: (result) => results.push(result),
schedule: (callback) => { timers.set(++id, callback); return id; },
cancel: (key) => timers.delete(key)
});
function tick() {
assert.equal(timers.size, 1);
const [key, callback] = timers.entries().next().value;
timers.delete(key);
return callback();
}
return { ...refresh, timers, results, tick };
}
test("one hundred refresh requests trigger one estimate", async () => {
let calls = 0;
const refresh = setup(async () => { calls++; return { usage: 12 }; });
for (let i = 0; i < 100; i++) refresh.request();
await refresh.tick();
assert.equal(calls, 1);
assert.deepEqual(refresh.results, [{ usage: 12 }]);
assert.equal(refresh.timers.size, 0);
});
test("writes during estimation schedule one follow-up and discard the stale result", async () => {
let finish;
let calls = 0;
const refresh = setup(() => {
calls++;
return new Promise((resolve) => { finish = resolve; });
});
refresh.request();
const first = refresh.tick();
for (let i = 0; i < 100; i++) refresh.request();
assert.equal(calls, 1);
assert.equal(refresh.timers.size, 0);
finish({ usage: 1 });
await first;
assert.deepEqual(refresh.results, []);
const second = refresh.tick();
finish({ usage: 2 });
await second;
assert.equal(calls, 2);
assert.deepEqual(refresh.results, [{ usage: 2 }]);
});
test("dispose cancels scheduled work and ignores in-flight results", async () => {
let finish;
const refresh = setup(() => new Promise((resolve) => { finish = resolve; }));
refresh.request();
refresh.dispose();
refresh.request();
assert.equal(refresh.timers.size, 0);
const active = setup(() => new Promise((resolve) => { finish = resolve; }));
active.request();
const task = active.tick();
active.dispose();
finish({ usage: 5 });
await task;
assert.deepEqual(active.results, []);
assert.equal(active.timers.size, 0);
});
test("a failed estimate preserves the last result and allows recovery", async () => {
let fail = false;
const refresh = setup(async () => {
if (fail) throw new Error("unavailable");
return { usage: 3 };
});
refresh.request();
await refresh.tick();
fail = true;
refresh.request();
await refresh.tick();
assert.deepEqual(refresh.results, [{ usage: 3 }]);
fail = false;
refresh.request();
await refresh.tick();
assert.equal(refresh.results.length, 2);
});

View file

@ -113,9 +113,9 @@ test("server and vite support local env configuration", async () => {
const viteConfig = await readFile("vite.config.js", "utf8");
const envExample = await readFile(".env.example", "utf8");
assert.match(server, /function loadEnvFile/);
assert.match(server, /load-project-env\.mjs/);
assert.match(server, /process\.env\.PORT/);
assert.match(viteConfig, /function loadEnvFile/);
assert.match(viteConfig, /load-project-env\.mjs/);
assert.match(viteConfig, /process\.env\.PORT/);
assert.match(envExample, /PORT=5173/);
});