G1 路由清单在 synastry 与 terms 之间加入 synastry/[reportId]。G2 把「同一对已经有报告时,仍打开原来那份」改成「同一对正在生成时,仍打开那份」。G3 删掉永远成立的侧栏断言,改为渲染 /synastry/<id> 并核对当前项是婚恋合盘。 Co-Authored-By: Grok (agent loop) Co-authored-by: Cursor <cursoragent@cursor.com>
91 lines
3.8 KiB
TypeScript
91 lines
3.8 KiB
TypeScript
import assert from "node:assert/strict";
|
||
import test from "node:test";
|
||
import { readFileSync } from "node:fs";
|
||
import { createElement } from "react";
|
||
import { renderToStaticMarkup } from "react-dom/server";
|
||
import { PathnameContext } from "next/dist/shared/lib/hooks-client-context.shared-runtime";
|
||
|
||
import { AppSidebar } from "../src/components/app-sidebar.tsx";
|
||
import { SidebarProvider } from "../src/components/ui/sidebar.tsx";
|
||
import { reportSurfaceRedirect } from "../src/lib/synastry-report-href.ts";
|
||
|
||
function renderSidebar(pathname: string) {
|
||
return renderToStaticMarkup(
|
||
createElement(
|
||
PathnameContext.Provider,
|
||
{ value: pathname },
|
||
createElement(
|
||
SidebarProvider,
|
||
null,
|
||
createElement(AppSidebar, {
|
||
sessions: [],
|
||
activeSessionId: null,
|
||
compatibilityEnabled: true,
|
||
account: {
|
||
name: "示例甲",
|
||
email: "fictional@example.invalid",
|
||
credits: 12,
|
||
initial: "示",
|
||
avatar: null,
|
||
},
|
||
}),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
function navAnchor(markup: string, label: string) {
|
||
const anchors = markup.match(/<a\b[^>]*\breport-nav-button\b[^>]*>[\s\S]*?<\/a>/g) ?? [];
|
||
const hit = anchors.find((anchor) => anchor.includes(`>${label}<`));
|
||
assert.ok(hit, `sidebar nav link missing: ${label}`);
|
||
return hit;
|
||
}
|
||
|
||
const read = (path: string) => readFileSync(new URL(path, import.meta.url), "utf8");
|
||
|
||
test("an old synastry url moves to the synastry route and keeps the language", () => {
|
||
assert.equal(
|
||
reportSurfaceRedirect({ surface: "personal", reportType: "synastry_full", reportId: "abc", language: "en" }),
|
||
"/synastry/abc?lang=en",
|
||
);
|
||
assert.equal(
|
||
reportSurfaceRedirect({ surface: "synastry", reportType: "personal_full", reportId: "abc", language: "zh" }),
|
||
"/reports/abc",
|
||
);
|
||
assert.equal(
|
||
reportSurfaceRedirect({ surface: "synastry", reportType: "synastry_full", reportId: "abc", language: "zh" }),
|
||
null,
|
||
);
|
||
assert.equal(
|
||
reportSurfaceRedirect({ surface: "personal", reportType: "personal_full", reportId: "abc", language: "en" }),
|
||
null,
|
||
);
|
||
});
|
||
|
||
test("the synastry route reuses the reader and the sidebar stays on 婚恋合盘", () => {
|
||
const page = read("../src/app/(app)/synastry/[reportId]/page.tsx");
|
||
const reader = read("../src/components/personal-report/personal-report-page.tsx");
|
||
const sidebar = read("../src/components/app-sidebar.tsx");
|
||
const picker = read("../src/components/synastry/synastry-picker.tsx");
|
||
const center = read("../src/components/personal-report/personal-report-center.tsx");
|
||
assert.match(page, /title: "婚恋合盘 · Jyotisha"/);
|
||
assert.match(page, /readReportLanguage\(lang\)/);
|
||
assert.match(page, /surface="synastry"/);
|
||
assert.match(reader, /window\.location\.replace\(redirectTo\)/);
|
||
assert.match(sidebar, /\{ href: "\/synastry", label: "婚恋合盘"/);
|
||
assert.match(sidebar, /pathname === href \|\| pathname\.startsWith\(`\$\{href\}\/`\)/);
|
||
// 原值: assert.equal("/synastry/abc".startsWith("/synastry/"), true)
|
||
// 新值: pathname 为 /synastry/<id> 时渲染侧栏,当前项(data-active="true")是「婚恋合盘」,不是「我的报告」
|
||
// 原因: 原断言永远成立,没有渲染侧栏(issue #85 G3)
|
||
const markup = renderSidebar("/synastry/abc");
|
||
const synastry = navAnchor(markup, "婚恋合盘");
|
||
const reports = navAnchor(markup, "我的报告");
|
||
assert.match(synastry, /\bdata-active="true"/);
|
||
assert.doesNotMatch(reports, /\bdata-active="true"/);
|
||
assert.doesNotMatch(reports, /aria-current="page"/);
|
||
assert.match(picker, /window\.location\.assign\(`\/synastry\/\$\{payload\.report\.id\}`\)/);
|
||
assert.match(picker, /href=\{`\/synastry\/\$\{report\.id\}`\}/);
|
||
assert.doesNotMatch(picker, /\/reports\/\$\{/);
|
||
assert.match(center, /reportType === "synastry_full" \? `\/synastry\/\$\{id\}` : `\/reports\/\$\{id\}`/);
|
||
});
|