import assert from "node:assert/strict"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { ArchiveCatalog, archiveFileNameForUrl, archiveIdForUrl, normalizeArchiveUrl } from "../src/archive-catalog.mjs"; test("normalizes only http and https archive URLs", () => { assert.equal(normalizeArchiveUrl(" https://example.com/path "), "https://example.com/path"); assert.throws(() => normalizeArchiveUrl("file:///tmp/page.html"), /Only http and https/); assert.throws(() => normalizeArchiveUrl("not a url"), /valid URL/); }); test("builds stable archive ids from the full URL", () => { const first = archiveIdForUrl("https://example.com/article?x=1"); const second = archiveIdForUrl("https://example.com/article?x=1"); const third = archiveIdForUrl("https://example.com/article?x=2"); assert.equal(first, second); assert.notEqual(first, third); assert.match(first, /^example-com-article-[a-f0-9]{16}$/); }); test("finds stable archive files without rerendering", async () => { const archivePath = await fs.mkdtemp(path.join(os.tmpdir(), "archive-catalog-")); const sourceUrl = "https://example.com/"; const fileName = archiveFileNameForUrl(sourceUrl); await fs.writeFile(path.join(archivePath, fileName), "", "utf8"); const catalog = new ArchiveCatalog({ archivePath }); const record = await catalog.findByUrl(sourceUrl); assert.equal(record.fileName, fileName); assert.equal(record.archiveUrl, `/archives/${encodeURIComponent(fileName)}`); }); test("indexes older timestamped archives from the archive comment", async () => { const archivePath = await fs.mkdtemp(path.join(os.tmpdir(), "archive-catalog-")); await fs.writeFile( path.join(archivePath, "example-com-2026-05-16T00-00-00-000Z.html"), '\n\n', "utf8" ); const catalog = new ArchiveCatalog({ archivePath }); const record = await catalog.findByUrl("https://example.com/story"); assert.equal(record.fileName, "example-com-2026-05-16T00-00-00-000Z.html"); assert.equal(record.sourceUrl, "https://example.com/story"); });