新报告用围栏画出大运和事业、财富、婚恋,标题下写名字与日期。旧报告不变。 自测:pytest test_report_full_data_fix.py 10 通过;相关四份报告测试退出码 0;前端相关测试 147 通过、0 失败、0 取消;tsc 退出码 0;lint 0 error。 Co-Authored-By: Grok (agent loop)
113 lines
5.2 KiB
TypeScript
113 lines
5.2 KiB
TypeScript
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, "虚构甲");
|
|
});
|