import { describe, test } from "node:test"; import assert from "node:assert/strict"; import { mintContentId } from "../src/id.js"; import type { PublishedRecord } from "../src/ingest.js"; import { assemblePostGraph, type AnalyticsRowInput } from "../src/assemble.js"; const DATE = "2026-05-26"; function rec(body: string, over: Partial = {}): PublishedRecord { return { id: mintContentId(body), provenance: "published", published_date: DATE, captured_at: "2026-06-23", source: "manual", specifics: [], trends: [], body, ...over, }; } function row(title: string, over: Partial = {}): AnalyticsRowInput { return { title, publishedDate: DATE, metrics: { engagementRate: 4.2 }, ...over }; } // A body whose normalized opener is ≥ PREFIX_FLOOR (24) chars. const BODY = "Jeg lærte noe viktig om dømmekraft i dag.\n\nDel 1 av serien."; const FULL_TITLE = "Jeg lærte noe viktig om dømmekraft i dag."; describe("SB-S3c assembler — assemblePostGraph (SC6/SC7/SC8)", () => { // SC6 — high confidence: body begins with the row title (≥floor) + same date. test("SC6: prefix-match + same date → high, whole row attached, specifics/trends surfaced", () => { const r = rec(BODY, { specifics: ["aaaaaaaaaaaa"], trends: ["bbbbbbbbbbbb"] }); const graph = assemblePostGraph({ records: [r], analytics: [row(FULL_TITLE)] }); assert.equal(graph.length, 1); assert.equal(graph[0].contentId, r.id); assert.equal(graph[0].match.confidence, "high"); assert.deepEqual(graph[0].match.row, row(FULL_TITLE)); // the whole row reference (FIX 4) assert.deepEqual(graph[0].specifics, ["aaaaaaaaaaaa"]); assert.deepEqual(graph[0].trends, ["bbbbbbbbbbbb"]); }); // SC7 — low / none / below-floor / ellipsis near-miss. test("SC7a: no prefix match → none", () => { const graph = assemblePostGraph({ records: [rec(BODY)], analytics: [row("Completely unrelated opening sentence here")], }); assert.equal(graph[0].match.confidence, "none"); assert.equal(graph[0].match.row, undefined); }); test("SC7b: a too-short (< floor) title that is a literal prefix → none (floor guards false high)", () => { const graph = assemblePostGraph({ records: [rec(BODY)], analytics: [row("Jeg lærte")] }); assert.equal(graph[0].match.confidence, "none"); }); test("SC7c: a LinkedIn-truncated '…' title + same date → high (ellipsis stripped)", () => { const graph = assemblePostGraph({ records: [rec(BODY)], analytics: [row("Jeg lærte noe viktig om dømmekraft i…")], }); assert.equal(graph[0].match.confidence, "high"); }); test("SC7d: prefix match but a different date → low (surfaced, not hidden)", () => { const graph = assemblePostGraph({ records: [rec(BODY)], analytics: [row(FULL_TITLE, { publishedDate: "2026-05-20" })], }); assert.equal(graph[0].match.confidence, "low"); assert.ok(graph[0].match.row, "row still attached on a low match"); }); // SC8 — pure + total. test("SC8: empty records → empty graph", () => { assert.deepEqual(assemblePostGraph({ records: [], analytics: [row(FULL_TITLE)] }), []); }); test("SC8: empty analytics → every post present with match none, no throw", () => { const graph = assemblePostGraph({ records: [rec(BODY), rec("another post body here")], analytics: [] }); assert.equal(graph.length, 2); assert.ok(graph.every((g) => g.match.confidence === "none")); }); test("SC8: best-of prefers high over low and is deterministic", () => { const r = rec(BODY); const high = row(FULL_TITLE); // same date const low = row(FULL_TITLE, { publishedDate: "2026-01-01" }); // different date const graph = assemblePostGraph({ records: [r], analytics: [low, high] }); assert.equal(graph[0].match.confidence, "high", "high beats low regardless of input order"); }); });