import { test } from "node:test"; import assert from "node:assert/strict"; import { cacheBusted, liveCheckLines, liveCheckVerdict, liveUrl, runLiveCheck, type Probe, } from "./liveCheck"; // Run with: pnpm --filter yt-dlp-transcript-common test // // Every case runs over an injected fetch and sleep: no test reaches a network. const NEW = "2026-10-06T10:00:00.000Z"; const OLD = "2026-10-01T09:00:00.000Z"; const STAMP = "01J-built"; type Answer = { status: number; body?: unknown; headers?: Record } | Error; // A fetch that answers by URL: `plain` for the URL without a query, `busted` // for the cache-busted one; records every URL asked. function fakeFetch(route: (url: string, busted: boolean) => Answer) { const asked: string[] = []; const f = (async (input: string | URL | Request) => { const url = String(input); asked.push(url); const a = route(url, url.includes("?cb=")); if (a instanceof Error) throw a; return new Response(a.body === undefined ? "" : JSON.stringify(a.body), { status: a.status, headers: a.headers, }); }) as typeof fetch; return { f, asked }; } const noSleep = { calls: 0, fn: async () => {} }; function sleeper() { const s = { calls: 0, ms: [] as number[], fn: async (ms: number) => void (s.calls++, s.ms.push(ms)) }; return s; } const NOW = () => new Date("2026-10-06T10:05:00.000Z"); test("liveUrl and cacheBusted", () => { assert.equal(liveUrl("https://a.pages.dev/", "/corpus.json"), "https://a.pages.dev/corpus.json"); assert.equal(liveUrl("https://a.pages.dev", "posts/manifest.json"), "https://a.pages.dev/posts/manifest.json"); assert.equal(cacheBusted("https://a/corpus.json", "s 1"), "https://a/corpus.json?cb=s%201"); assert.equal(cacheBusted("https://a/c.json", "s", 3), "https://a/c.json?cb=s&try=3"); }); test("liveCheckVerdict: the table", () => { const ok: Probe = { status: 200, generatedAt: NEW }; const old: Probe = { status: 200, generatedAt: OLD, cfCacheStatus: "HIT" }; const down: Probe = { status: null, error: "ECONNREFUSED" }; const missing: Probe = { status: 404 }; assert.equal(liveCheckVerdict(ok, ok, NEW), "ok"); assert.equal(liveCheckVerdict(old, ok, NEW), "stale-edge"); // A plain read that fails is not staleness: a visitor gets nothing. assert.equal(liveCheckVerdict(missing, ok, NEW), "unreachable"); assert.equal(liveCheckVerdict(down, ok, NEW), "unreachable"); assert.equal(liveCheckVerdict(old, old, NEW), "mismatch"); assert.equal(liveCheckVerdict(ok, old, NEW), "mismatch"); assert.equal(liveCheckVerdict(down, down, NEW), "unreachable"); assert.equal(liveCheckVerdict(missing, missing, NEW), "unreachable"); assert.equal(liveCheckVerdict(ok, down, NEW), "ok"); // No expected generatedAt (a homepage): answering is all that is asked. assert.equal(liveCheckVerdict({ status: 200 }, { status: 200 }, null), "ok"); }); test("ok: both reads serve this build, on the first try", async () => { const { f, asked } = fakeFetch(() => ({ status: 200, body: { generatedAt: NEW }, headers: { "cf-cache-status": "MISS", age: "0", "cache-control": "public, max-age=0, must-revalidate" }, })); const s = sleeper(); const check = await runLiveCheck( { url: "https://jeralyzer.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: s.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "ok"); assert.equal(check.at, Date.parse("2026-10-06T10:05:00.000Z")); assert.equal(check.url, "https://jeralyzer.pages.dev"); assert.equal(check.expected, NEW); assert.deepEqual(check.plain, { status: 200, generatedAt: NEW, cfCacheStatus: "MISS", age: 0, cacheControl: "public, max-age=0, must-revalidate", }); assert.deepEqual(asked, [ "https://jeralyzer.pages.dev/corpus.json", `https://jeralyzer.pages.dev/corpus.json?cb=${STAMP}`, ]); assert.equal(s.calls, 0); assert.match(liveCheckLines(check)[0], /^\[live\] ok — https:\/\/jeralyzer\.pages\.dev serves this build/); }); test("stale-edge: the edge HITs an old corpus.json, the busted read is this build — three tries, 10 s apart", async () => { const { f, asked } = fakeFetch((_u, busted): Answer => busted ? { status: 200, body: { generatedAt: NEW }, headers: { "cf-cache-status": "MISS" } } : { status: 200, body: { generatedAt: OLD }, headers: { "cf-cache-status": "HIT", age: "86400", "cache-control": "public, s-maxage=604800" }, }, ); const s = sleeper(); const check = await runLiveCheck( { url: "https://archilyzer-hub.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: s.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "stale-edge"); assert.equal(check.plain.cfCacheStatus, "HIT"); assert.equal(check.plain.generatedAt, OLD); assert.equal(check.plain.age, 86400); assert.equal(check.plain.cacheControl, "public, s-maxage=604800"); assert.equal(check.busted.generatedAt, NEW); assert.equal(asked.length, 6); assert.deepEqual(s.ms, [10_000, 10_000]); // Each retry busts with a query the edge has not seen either. assert.ok(asked.includes(`https://archilyzer-hub.pages.dev/corpus.json?cb=${STAMP}&try=3`)); const [line] = liveCheckLines(check); assert.match(line, /^\[live\] WARNING stale-edge — /); assert.match(line, /cf-cache-status HIT/); }); test("a fresh deployment that answers on the second try is ok, after one sleep", async () => { let n = 0; const { f } = fakeFetch(() => { n++; return n <= 2 ? { status: 404 } : { status: 200, body: { generatedAt: NEW } }; }); const s = sleeper(); const check = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: s.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "ok"); assert.equal(s.calls, 1); }); test("mismatch: the deployment itself serves another build", async () => { const { f } = fakeFetch(() => ({ status: 200, body: { generatedAt: OLD } })); const check = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: noSleep.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "mismatch"); assert.match(liveCheckLines(check)[0], /^\[live\] WARNING mismatch — https:\/\/x\.pages\.dev does not serve this build/); }); test("unreachable: nothing answers; the error is recorded, never thrown", async () => { const { f } = fakeFetch(() => new Error("getaddrinfo ENOTFOUND x.pages.dev")); const check = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: noSleep.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "unreachable"); assert.equal(check.plain.status, null); assert.match(check.plain.error ?? "", /ENOTFOUND/); assert.match(liveCheckLines(check)[0], /^\[live\] WARNING unreachable — .*The deploy itself succeeded\.$/); }); test("skipped: E2E_LIVE_CHECK=skip asks nothing", async () => { const { f, asked } = fakeFetch(() => ({ status: 200 })); const check = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: noSleep.fn, now: NOW, env: { E2E_LIVE_CHECK: "skip" } }, ); assert.equal(check.verdict, "skipped"); assert.deepEqual(check.plain, { status: null }); assert.deepEqual(asked, []); assert.deepEqual(liveCheckLines(check), ["[live] skipped (E2E_LIVE_CHECK=skip)."]); }); test("the hub's tombstones: each path read plain and busted; an old shard at the edge is stale-edge", async () => { const tombstones = [ "posts/manifest.json", "posts/thequartering-X/manifest.json", "posts/thequartering-X/page-0000.json", ]; const body = (url: string, stale: boolean): unknown => { if (url.includes("/corpus.json")) return { generatedAt: NEW }; if (url.includes("/posts/manifest.json")) return stale ? { channels: [{ slug: "thequartering-X" }] } : { channels: [] }; if (url.includes("/manifest.json")) return { pageCount: stale ? 1 : 0 }; return stale ? [{ id: "1" }] : []; }; // The deployment has the tombstones; the edge still serves the old shard // page at its plain URL. const { f, asked } = fakeFetch((url, busted) => ({ status: 200, body: body(url, !busted && url.endsWith("page-0000.json")), })); const check = await runLiveCheck( { url: "https://archilyzer-hub.pages.dev", builtStampId: STAMP, expected: NEW, tombstones }, { fetch: f, sleep: noSleep.fn, now: NOW, env: {} }, ); assert.equal(check.verdict, "stale-edge"); assert.deepEqual( check.tombstones?.map((t) => [t.path, t.ok]), [ ["posts/manifest.json", true], ["posts/thequartering-X/manifest.json", true], ["posts/thequartering-X/page-0000.json", false], ], ); assert.ok(asked.includes(`https://archilyzer-hub.pages.dev/posts/thequartering-X/page-0000.json?cb=${STAMP}`)); const lines = liveCheckLines(check); assert.match(lines[0], /^\[live\] WARNING stale-edge — .* 1 withdrawn path\(s\) do not read as tombstones/); assert.match(lines[1], /^\[live\] tombstone posts\/thequartering-X\/page-0000\.json: /); // All three read as tombstones: ok. const good = fakeFetch((url) => ({ status: 200, body: body(url, false) })); const ok = await runLiveCheck( { url: "https://archilyzer-hub.pages.dev", builtStampId: STAMP, expected: NEW, tombstones }, { fetch: good.f, sleep: noSleep.fn, now: NOW, env: {} }, ); assert.equal(ok.verdict, "ok"); assert.match(liveCheckLines(ok)[0], /3 withdrawn path\(s\) read as tombstones\.$/); // The deployment itself lacks a tombstone (busted reads the old shard): mismatch. const bad = fakeFetch((url) => ({ status: 200, body: body(url, url.includes("page-0000")) })); const mm = await runLiveCheck( { url: "https://archilyzer-hub.pages.dev", builtStampId: STAMP, expected: NEW, tombstones }, { fetch: bad.f, sleep: noSleep.fn, now: NOW, env: {} }, ); assert.equal(mm.verdict, "mismatch"); }); test("Cancel stops the check: no read after the abort, no sleep waited out", async () => { const cancel = new AbortController(); let reads = 0; const { f } = fakeFetch((_u, busted): Answer => { reads++; // The first pair reads an old edge copy; Cancel arrives during the busted read. if (busted) cancel.abort(); return { status: 200, body: { generatedAt: busted ? NEW : OLD } }; }); const s = sleeper(); const check = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: s.fn, now: NOW, env: {}, signal: cancel.signal }, ); assert.equal(reads, 2, "no retry after Cancel"); assert.equal(s.calls, 0); assert.equal(check.verdict, "stale-edge", "what was read is kept"); // Cancelled before anything was read: unreachable, naming the cancel. const early = new AbortController(); early.abort(); const none = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: f, sleep: s.fn, now: NOW, env: {}, signal: early.signal }, ); assert.equal(none.verdict, "unreachable"); assert.equal(none.plain.error, "cancelled"); // The default sleep wakes on the abort rather than waiting its 10 s out. const mid = new AbortController(); const old = fakeFetch(() => ({ status: 200, body: { generatedAt: OLD } })); const started = Date.now(); setTimeout(() => mid.abort(), 50); const stopped = await runLiveCheck( { url: "https://x.pages.dev", builtStampId: STAMP, expected: NEW }, { fetch: old.f, now: NOW, env: {}, signal: mid.signal }, ); assert.ok(Date.now() - started < 5_000, "the 10 s interval was not waited out"); assert.equal(stopped.verdict, "mismatch"); });