import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import React from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { PersonalReportMarkdownView } from "../src/components/personal-report/personal-report-markdown-view.tsx"; import { classifyReportEnvelope } from "../src/components/personal-report/personal-report-page.tsx"; import { buildReportExportBlocks, joinExportBlocks } from "../src/lib/report-export-blocks.ts"; import { parseReportFocusBlock } from "../src/lib/report-focus-block.ts"; import { projectOrdinaryReportDocument, projectOrdinaryReportMarkdown } from "../src/lib/report-public-projection.ts"; Object.assign(globalThis, { React }); const fixture = JSON.parse(readFileSync(new URL("./fixtures/report-focus-fictional-day.json", import.meta.url), "utf8")) as { fixtureProvenance: { fictional: boolean; command: string; edition: string }; zh: string; en: string; }; const OLD_MARKDOWN = `# 印度占星星盘报告 重点:当前主运 MD 北交点,子运 AD 木星,次子运 PD 木星。 ## 重点 - 事业第10宫主 土星 落在第9宫,尊贵为入庙,功能吉凶为功能吉星。 ## 出生资料与图盘 旧正文仍在。 `; function markup(markdown: string, props: { subjectName?: string; createdAt?: string; language?: "zh" | "en" } = {}) { return renderToStaticMarkup(React.createElement(PersonalReportMarkdownView, { markdown, drawnThrough: 0, ...props })); } test("fictional day-chart golden renders the focus card without MD labels", () => { assert.equal(fixture.fixtureProvenance.fictional, true); assert.match(fixture.fixtureProvenance.command, /full_data/); assert.equal(fixture.fixtureProvenance.edition, "full_data"); const html = markup(fixture.zh); assert.match(html, /现在走的大运/); assert.match(html, /主运/); assert.match(html, /子运/); assert.match(html, /次子运/); assert.match(html, /事业/); assert.match(html, /财富/); assert.match(html, /婚恋/); assert.match(html, /这段时间可能突出这些宫主所守护的主题,不是确定会发生的事。/); assert.doesNotMatch(html, /\bMD\b|\bAD\b|\bPD\b/); assert.doesNotMatch(html, /\{"version"/); const english = markup(fixture.en, { language: "en" }); assert.match(english, /Current period/); assert.match(english, /Career/); assert.match(english, /This period may bring those house-lord topics forward/); assert.equal(parseReportFocusBlock("{"), null); assert.match(markup("## 重点\n\n```jyotish-focus\n{not-json}\n```\n"), /重点数据无效/); assert.match(markup("## Focus\n\n```jyotish-focus\n{not-json}\n```\n", { language: "en" }), /Focus data is invalid/); }); test("export writes the focus as words and the public projection keeps the fence", () => { const blocks = buildReportExportBlocks({ markdown: fixture.zh }); const text = joinExportBlocks(blocks); assert.doesNotMatch(text, /\{"version"/); assert.match(text, /现在走的大运/); assert.match(text, /这段时间可能突出这些宫主所守护的主题/); const projected = projectOrdinaryReportMarkdown(fixture.zh); assert.match(projected, /```jyotish-focus/); const document = projectOrdinaryReportDocument({ schemaVersion: "report_document.v2", subject: { displayName: "虚构甲" }, executiveSummary: { headline: "摘要", summary: "正文" }, }); assert.equal(JSON.stringify(document).includes("虚构甲"), false); }); test("old prose without a fence is unchanged", () => { const html = markup(OLD_MARKDOWN); assert.match(html, /重点:当前主运 MD 北交点,子运 AD 木星,次子运 PD 木星。/); assert.match(html, /事业第10宫主 土星 落在第9宫,尊贵为入庙,功能吉凶为功能吉星。/); assert.doesNotMatch(html, /重点数据无效|personal-report-focus-card|现在走的大运/); }); test("title byline covers a name, no name, and a title that already includes the name", () => { const createdAt = "2026-10-13T08:00:00.000Z"; const named = markup("# 印度占星星盘报告\n", { subjectName: "虚构甲", createdAt }); assert.match(named, /虚构甲 · 生成于 2026-10-13/); const unnamed = markup("# 印度占星星盘报告\n", { createdAt }); assert.match(unnamed, /生成于 2026-10-13/); assert.doesNotMatch(unnamed, /虚构甲/); const already = markup("# 虚构甲的印度占星星盘报告\n", { subjectName: "虚构甲", createdAt }); assert.match(already, /生成于 2026-10-13/); assert.doesNotMatch(already, /虚构甲 · 生成于/); const english = markup("# Vedic Astrology Chart Report\n", { subjectName: "Fictional", createdAt, language: "en" }); assert.match(english, /Fictional · Generated 2026-10-13/); }); test("the signed-in envelope carries the display name onto the reader", () => { const ready = classifyReportEnvelope(200, { report: { id: "11111111-1111-1111-1111-111111111111", status: "ready", failureCode: null, createdAt: "2026-10-13T00:00:00Z", }, longformMarkdown: "# 印度占星星盘报告\n", subjectDisplayName: "虚构甲", }); assert.equal(ready.phase, "markdown-ready"); if (ready.phase === "markdown-ready") assert.equal(ready.subjectDisplayName, "虚构甲"); });