/** * @file Tests server/update-scheduler.js — the default interval is an hour * (the env override and its 60 s floor still apply), a scheduled tick with no * browser connected runs no check, and a browser connecting after that gets * one catch-up check (only when the last check is stale). The check, the * connection count and the connection event are injected; nothing touches git * or the network. * @author Nguyễn Ngọc Trí Vĩ */ const { describe, it, afterEach } = require("node:test"); const assert = require("node:assert/strict"); delete process.env.DASHBOARD_UPDATE_CHECK; const { startUpdateScheduler, intervalMs } = require("../update-scheduler"); const wait = (ms) => new Promise((r) => setTimeout(r, ms)); let handle = null; afterEach(() => { handle?.stop(); handle = null; delete process.env.DASHBOARD_UPDATE_CHECK_INTERVAL_MS; }); function harness(clients) { const h = { checks: 0, clients, listeners: [] }; handle = startUpdateScheduler({ broadcast: () => {}, getConnectionCount: () => h.clients, onConnection: (fn) => { h.listeners.push(fn); return () => {}; }, getStatus: async () => { h.checks++; return { update_available: false }; }, initialDelayMs: 10, }); h.connect = () => h.listeners.forEach((fn) => fn()); return h; } describe("intervalMs", () => { it("defaults to one hour and keeps the override with its floor", () => { delete process.env.DASHBOARD_UPDATE_CHECK_INTERVAL_MS; assert.equal(intervalMs(), 60 * 60 * 1000); process.env.DASHBOARD_UPDATE_CHECK_INTERVAL_MS = "120000"; assert.equal(intervalMs(), 120000); process.env.DASHBOARD_UPDATE_CHECK_INTERVAL_MS = "1000"; assert.equal(intervalMs(), 60 * 60 * 1000); }); }); describe("startUpdateScheduler", () => { it("checks on the first tick when a browser is connected", async () => { const h = harness(1); await wait(40); assert.equal(h.checks, 1); }); it("skips the tick with no browser, then checks once when one connects", async () => { const h = harness(0); await wait(40); assert.equal(h.checks, 0); h.clients = 1; h.connect(); h.connect(); // a second tab in the same window: still one check await wait(3_300); assert.equal(h.checks, 1); h.connect(); // fresh check: no catch-up await wait(3_300); assert.equal(h.checks, 1); }); });