feat(task-013): add draft assembly API, immutable versioning, and editor preview
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import ts from "typescript";
|
||||
|
||||
const testDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const sourcePath = path.resolve(testDir, "../src/features/article-draft/model.ts");
|
||||
const source = readFileSync(sourcePath, "utf8");
|
||||
const compiled = ts.transpileModule(source, {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 },
|
||||
});
|
||||
|
||||
const moduleExports = {};
|
||||
new Function("exports", compiled.outputText)(moduleExports);
|
||||
|
||||
const { compareDraftVersions, parseDraftPreview, selectDraftById } = moduleExports;
|
||||
|
||||
const baseDraft = {
|
||||
id: "11111111-1111-1111-1111-111111111111",
|
||||
article_id: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
|
||||
version: 1,
|
||||
title: "Draft One",
|
||||
slug: "draft-one",
|
||||
meta_title: "Meta One",
|
||||
meta_description: "Description One",
|
||||
body_object_key: "articles/a/drafts/v1.md",
|
||||
body_markdown: [
|
||||
"# Draft One",
|
||||
"",
|
||||
"## Intro",
|
||||
"See [guide](https://example.com/guide).",
|
||||
"",
|
||||
"| A | B |",
|
||||
"| --- | --- |",
|
||||
"| 1 | 2 |",
|
||||
"",
|
||||
"",
|
||||
].join("\n"),
|
||||
faq_items: [{ question: "What is this?", answer: "Preview draft." }],
|
||||
visual_placeholders: [""],
|
||||
evidence_references: ["evidence-id-1"],
|
||||
unsupported_claim_warnings: [],
|
||||
based_on_draft_id: null,
|
||||
status: "DRAFT_ASSEMBLED",
|
||||
created_at: "2026-05-21T00:00:00Z",
|
||||
updated_at: "2026-05-21T00:00:00Z",
|
||||
};
|
||||
|
||||
const secondDraft = {
|
||||
...baseDraft,
|
||||
id: "22222222-2222-2222-2222-222222222222",
|
||||
version: 2,
|
||||
title: "Draft Two",
|
||||
meta_title: "Meta Two",
|
||||
body_markdown: `${baseDraft.body_markdown}\n\nRevision note.`,
|
||||
based_on_draft_id: baseDraft.id,
|
||||
};
|
||||
|
||||
const previewBlocks = parseDraftPreview(baseDraft.body_markdown, baseDraft.faq_items);
|
||||
assert.ok(previewBlocks.some((block) => block.type === "heading" && block.text === "Draft One"));
|
||||
assert.ok(previewBlocks.some((block) => block.type === "table"));
|
||||
assert.ok(previewBlocks.some((block) => block.type === "image" && block.src === "placeholder://mock/1"));
|
||||
assert.ok(previewBlocks.some((block) => block.type === "paragraph" && block.links.length === 1));
|
||||
assert.ok(previewBlocks.some((block) => block.type === "faq" && block.items.length === 1));
|
||||
|
||||
const selected = selectDraftById([secondDraft, baseDraft], baseDraft.id);
|
||||
assert.equal(selected.id, baseDraft.id);
|
||||
|
||||
const comparison = compareDraftVersions(secondDraft, baseDraft);
|
||||
assert.equal(comparison.titleChanged, true);
|
||||
assert.equal(comparison.metaTitleChanged, true);
|
||||
assert.equal(comparison.bodyChanged, true);
|
||||
assert.ok(comparison.changedLineCount >= 1);
|
||||
Reference in New Issue
Block a user