feat(reports): add professional reference export
This commit is contained in:
@@ -279,3 +279,21 @@ test("legacy consultation Markdown export is untouched and still works", () => {
|
||||
assert.match(pageSource, /consultation-report-export/);
|
||||
assert.doesNotMatch(pageSource, /consultationReportMarkdown[\s\S]{0,200}生成个人报告/);
|
||||
});
|
||||
|
||||
|
||||
test("ready reports expose the professional Markdown reference export only in the ready branch", () => {
|
||||
assert.match(reportCenterSource, /专业参考版(导出)/);
|
||||
assert.match(reportCenterSource, /professional-reference/);
|
||||
assert.match(reportCenterSource, /downloadMarkdownReport\("个人专业参考版", payload\.markdown\)/);
|
||||
const readyActionStart = reportCenterSource.indexOf(
|
||||
'{report.status === "ready" ? (',
|
||||
);
|
||||
const generatingActionStart = reportCenterSource.indexOf(
|
||||
') : report.status === "generating" ? (',
|
||||
readyActionStart,
|
||||
);
|
||||
assert.ok(readyActionStart >= 0 && generatingActionStart > readyActionStart);
|
||||
const readyBranch = reportCenterSource.slice(readyActionStart, generatingActionStart);
|
||||
assert.match(readyBranch, /专业参考版(导出)/);
|
||||
assert.doesNotMatch(reportCenterSource.slice(generatingActionStart), /专业参考版(导出)/);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
|
||||
const routeSource = readFileSync(
|
||||
new URL("../src/app/api/reports/[reportId]/professional-reference/route.ts", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
test("professional reference route authenticates, checks origin, owner and ready status", () => {
|
||||
assert.match(routeSource, /createServerSupabaseClient/);
|
||||
assert.match(routeSource, /supabase\.auth\.getUser\(\)/);
|
||||
assert.match(routeSource, /checkSameOrigin/);
|
||||
assert.match(routeSource, /resolveAllowedReportOrigins/);
|
||||
assert.match(routeSource, /getOwnedById\(user\.id, reportId\)/);
|
||||
assert.match(routeSource, /report\.status !== "ready"/);
|
||||
assert.match(routeSource, /status: 401/);
|
||||
assert.match(routeSource, /status: 403/);
|
||||
assert.match(routeSource, /status: 404/);
|
||||
assert.match(routeSource, /status: 409/);
|
||||
});
|
||||
|
||||
test("birth data stays server-owned and the route calls only the public Python export", () => {
|
||||
assert.match(routeSource, /\.from\("profiles"\)/);
|
||||
assert.match(routeSource, /select\(ACCOUNT_BIRTH_SELECT\)/);
|
||||
assert.match(routeSource, /globalBirthProfileFromAccountRow/);
|
||||
assert.match(routeSource, /\/api\/professional_report_reference/);
|
||||
assert.match(routeSource, /format: "markdown"/);
|
||||
assert.match(routeSource, /packs: \["full"\]/);
|
||||
assert.doesNotMatch(routeSource, /request\.json\(/);
|
||||
assert.doesNotMatch(routeSource, /mastra|writer|billing|personal_report_sections/i);
|
||||
assert.doesNotMatch(routeSource, /\.insert\(|\.update\(|\.delete\(/);
|
||||
});
|
||||
|
||||
test("busy upstream responses preserve 429 and Retry-After", () => {
|
||||
assert.match(routeSource, /upstream\.status/);
|
||||
assert.match(routeSource, /upstream\.headers\.get\("retry-after"\)/);
|
||||
assert.match(routeSource, /"Retry-After": retryAfter/);
|
||||
});
|
||||
Reference in New Issue
Block a user