import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { test } from "node:test"; import { fetchPinnedRecentCommits, getCodeActivity, parseTangledHistoryUrl, parseTangledRecentCommits } from "./code-activity.ts"; const fixture = readFileSync(new URL("./code-activity.fixture.html", import.meta.url), "utf8"); const repo = (name = "charter") => ({ repoDid: name, name, description: "", website: null, url: `https://tangled.org/cameron.stream/${name}` }); const landing = (name = "charter", branch = "main") => `
Commits
`; test("real history shape selects subjects rather than SHA links and pairs each row's time", () => { const commits = parseTangledRecentCommits(fixture); assert.equal(commits.length, 2); assert.equal(commits[0].subject, "Make Charter a Jazz-native distributed runtime."); assert.equal(commits[0].time, "2026-07-11T19:19:35-07:00"); assert.equal(commits[1].subject, "Make Charter runtime-first."); assert.notEqual(commits[0].time, commits[1].time); assert.equal(parseTangledRecentCommits(fixture, 1).length, 1); assert.equal(parseTangledRecentCommits(fixture, 0).length, 0); assert.deepEqual(parseTangledRecentCommits(fixture + fixture), commits); }); test("invalid and missing time never borrow from the next row or outside the history", () => { for (const replacement of ["", '']) { const html = fixture.replace(/]*>[\s\S]*?<\/time>/, replacement); const result = parseTangledRecentCommits(html + ''); assert.equal(result.length, 1); assert.equal(result[0].subject, "Make Charter runtime-first."); } }); test("HTML entities and nested subject markup decode without losing text", () => { const html = fixture.replace("Make Charter a Jazz-native distributed runtime.", "fix & <parser> 'quote' —") .replace("2026-07-11T19:19:35-07:00", "2026-07-11T19:19:35+00:00"); assert.equal(parseTangledRecentCommits(html)[0].subject, "fix & 'quote' —"); assert.equal(parseTangledRecentCommits(html)[0].time, "2026-07-11T19:19:35+00:00"); }); test("default history navigation supports non-main branches and rejects unrelated links", () => { assert.equal(parseTangledHistoryUrl(landing("charter", "trunk"), repo().url), `${repo().url}/commits/trunk`); assert.equal(parseTangledHistoryUrl(landing("charter", "feature%2Fnext"), repo().url), `${repo().url}/commits/feature%2Fnext`); for (const html of ["", '', landing("other"), '']) { assert.equal(parseTangledHistoryUrl(html, repo().url), null); } }); test("mocked fetch bounds to four unique repos, deduplicates and sorts, fails soft", async (t) => { const calls: string[] = []; t.mock.method(globalThis, "fetch", async (input: string, init: RequestInit) => { calls.push(input); assert.ok(init.signal); if (input === repo("broken").url) throw new Error("timeout"); if (input.includes("/commits/")) return new Response(fixture.replaceAll("/charter/", "/other/").replaceAll("2026-07-11", "2026-09-08") + fixture + fixture); if (input === repo("empty").url) return new Response("unavailable", { status: 503 }); return new Response(landing(input.split("/").at(-1), "trunk")); }); const result = await fetchPinnedRecentCommits([repo(), repo(), repo("other"), repo("broken"), repo("empty"), repo("fifth")]); assert.equal(result.length, 4); assert.equal(result[0].repository, "cameron.stream/other"); assert.equal(new Set(result.map((c) => c.url)).size, 4); assert.equal(calls.length, 6); assert.ok(calls.includes(`${repo().url}/commits/trunk`)); assert.ok(!calls.some((url) => url.includes("fifth"))); }); test("getCodeActivity fetches public records without defaultBranch and caches the populated result", async (t) => { let calls = 0; t.mock.method(globalThis, "fetch", async (input: string) => { calls++; if (input.includes("plc.directory")) return Response.json({ service: [{ type: "AtprotoPersonalDataServer", serviceEndpoint: "https://public.example" }] }); if (input.includes("getRecord")) return Response.json({ value: { pinnedRepositories: ["charter"] } }); if (input.includes("listRecords")) return Response.json({ records: [{ uri: "at://did:plc:example/sh.tangled.repo/charter", value: { repoDid: "charter" } }] }); if (input === repo().url) return new Response(landing()); if (input === `${repo().url}/commits/main`) return new Response(fixture); return new Response("", { status: 503 }); }); const first = await getCodeActivity(); assert.equal(first.tangledRecent.length, 2); const before = calls; assert.deepEqual(await getCodeActivity(), first); assert.equal(calls, before); });