docs(report): record MD-page push SHA and keep markdown view locks
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import assert from "node:assert/strict";
|
||||
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 {
|
||||
buildLongformOutline,
|
||||
extractLongformSummary,
|
||||
personalReportMarkdownFilename,
|
||||
} from "../src/lib/personal-report-longform-outline.ts";
|
||||
import { buildLongformCoverDocument } from "../src/lib/personal-report-longform-cover.ts";
|
||||
import { safeParseServerReportDocument } from "../src/lib/personal-report-contract.server-core.ts";
|
||||
|
||||
Object.assign(globalThis, { React });
|
||||
|
||||
const SAMPLE = `# 标题
|
||||
|
||||
<script>alert(1)</script>
|
||||
<img src="https://evil.example/x.png">
|
||||
[外链](https://evil.example)
|
||||
|
||||
## 成品阅读导航
|
||||
|
||||
导航应立即出现。
|
||||
|
||||
### 质量验收矩阵
|
||||
|
||||
| 段落 | 状态 |
|
||||
| --- | --- |
|
||||
| KP | blocked |
|
||||
|
||||
## 主题解读与时间展开
|
||||
|
||||
### 解读摘要
|
||||
|
||||
这是摘要正文,用于卡片截取。
|
||||
|
||||
### 本命主轴
|
||||
|
||||
懒加载段落不应出现在首屏。
|
||||
|
||||
## 后段
|
||||
|
||||
后段正文。
|
||||
`;
|
||||
|
||||
test("outline keeps 导航 and 摘要 eager and extracts the card summary", () => {
|
||||
const outline = buildLongformOutline(SAMPLE);
|
||||
assert.ok(outline.headings.some((heading) => heading.title === "成品阅读导航"));
|
||||
assert.ok(outline.headings.some((heading) => heading.title === "质量验收矩阵"));
|
||||
assert.ok(outline.headings.some((heading) => heading.title === "解读摘要"));
|
||||
assert.match(outline.leadMarkdown, /成品阅读导航/);
|
||||
assert.match(outline.leadMarkdown, /质量验收矩阵/);
|
||||
assert.match(outline.leadMarkdown, /解读摘要/);
|
||||
assert.equal(extractLongformSummary(SAMPLE), "这是摘要正文,用于卡片截取。");
|
||||
const lazy = outline.sections.filter((section) => !section.eager);
|
||||
assert.ok(lazy.some((section) => section.title === "主题解读与时间展开"));
|
||||
assert.doesNotMatch(lazy.find((section) => section.title === "主题解读与时间展开")?.markdown ?? "", /解读摘要/);
|
||||
});
|
||||
|
||||
test("markdown view skips HTML, blocks remote resources, wraps tables, and lazy-renders later H2s", () => {
|
||||
const started = Date.now();
|
||||
const markup = renderToStaticMarkup(React.createElement(PersonalReportMarkdownView, { markdown: SAMPLE }));
|
||||
const elapsed = Date.now() - started;
|
||||
assert.ok(elapsed < 1500, `first paint ${elapsed}ms`);
|
||||
assert.doesNotMatch(markup, /<script>/);
|
||||
assert.doesNotMatch(markup, /src="https:\/\/evil\.example/);
|
||||
assert.doesNotMatch(markup, /href="https:\/\/evil\.example"/);
|
||||
assert.match(markup, /personal-report-table-wrap/);
|
||||
assert.match(markup, /成品阅读导航/);
|
||||
assert.match(markup, /质量验收矩阵/);
|
||||
assert.match(markup, /解读摘要/);
|
||||
assert.match(markup, /这是摘要正文/);
|
||||
assert.doesNotMatch(markup, /懒加载段落不应出现在首屏/);
|
||||
assert.doesNotMatch(markup, /后段正文/);
|
||||
assert.match(markup, /aria-label="报告目录"/);
|
||||
});
|
||||
|
||||
test("export filename includes the report date", () => {
|
||||
assert.equal(personalReportMarkdownFilename("2026-09-06T12:00:00.000Z"), "个人报告-2026-09-06");
|
||||
});
|
||||
|
||||
test("cover stub is a legal v2 document and is not the reading body", () => {
|
||||
const document = buildLongformCoverDocument({
|
||||
report: {
|
||||
id: "123e4567-e89b-12d3-a456-426614174000",
|
||||
reportType: "personal_full",
|
||||
presentationMode: "default",
|
||||
depth: "standard",
|
||||
requestedThemes: ["career", "wealth"],
|
||||
skillName: "jyotish-personal-report",
|
||||
skillVersion: "1.0.0",
|
||||
skillSourceCommit: null,
|
||||
skillSnapshotSha256: "a".repeat(64),
|
||||
},
|
||||
subject: {
|
||||
displayName: "测试对象",
|
||||
birthTimeStatus: "confirmed",
|
||||
birthPlaceLabel: "测试地点",
|
||||
},
|
||||
markdown: SAMPLE,
|
||||
generatedAt: "2026-09-06T12:00:00.000Z",
|
||||
});
|
||||
const parsed = safeParseServerReportDocument(document);
|
||||
assert.equal(parsed.ok, true);
|
||||
assert.equal(document.executiveSummary.summary, "这是摘要正文,用于卡片截取。");
|
||||
assert.equal(document.charts.filter((chart) => chart.id === "D1").length, 1);
|
||||
assert.equal(document.blockedConflictDisclosure.length, 2);
|
||||
assert.equal(document.thematicNarrative.length, 0);
|
||||
assert.equal(document.executiveSummary.overallClaimStatus, "parameter_sensitive");
|
||||
});
|
||||
Reference in New Issue
Block a user