Files
Jyotisha/frontend/tests/rectification-history-open-20260909.test.ts
T
jesse-ux e4e73f56c0
Independent Staging Quality Gate / publish (push) Canceled after 0s
Independent Staging Quality Gate / validate (push) Canceled after 9m33s
fix(web): 四个页面共用一份会话列表,空会话不入列
对话、星盘、星历、报告进同一 (app) 外壳,列表只拉一次。服务端不再列出空咨询;新建复用已有空会话。新标题改成「生时校正 · M月D日」,侧栏副标题用创建时间。
2026-09-17 21:27:40 +08:00

75 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { cssDeclarations } from "./css-contract-test-support.ts";
import { homeSurface as page } from "./home-surface.ts";
const read = (relativePath: string) => readFileSync(new URL(relativePath, import.meta.url), "utf8");
const sidebar = read("../src/components/app-sidebar.tsx");
const sidebarRow = read("../src/components/sidebar-session-row.tsx");
const starter = read("../src/components/starter-home.tsx");
const styles = read("../src/app/globals.css");
const pageSource = read("../src/app/(app)/page.tsx");
const hook = read("../src/hooks/use-rectification-surface.ts");
const sessions = read("../src/hooks/use-session-management.ts");
const caseService = read("../src/lib/rectification-agentic/v9/case-service.ts");
test("history session open uses the bound skill identity instead of the live registry version", () => {
// 原值:openRectificationCase 对 session 也把 resolveActiveSkillPackage() 交给 v2
// 新值:session 先 v1 取 Case,再读绑定身份,注册表核验后把绑定身份交给 v2
// 决策 1:打开 RPC 不再要求等于当前版本
assert.match(caseService, /request\.intent === "session"/);
assert.match(caseService, /open_agentic_rectification_case"/);
assert.match(caseService, /get_agentic_rectification_skill_identity"/);
assert.match(caseService, /resolveExactSkillPackage\(/);
assert.match(caseService, /skill_identity_missing/);
const homepageOpen = caseService.slice(
caseService.indexOf("export async function openRectificationCase"),
caseService.indexOf("export async function getRectificationEntrySummary"),
);
assert.match(homepageOpen, /intent === "homepage" \|\| request\.intent === "new"/);
assert.match(homepageOpen, /open_agentic_rectification_case_v2/);
});
test("skill_identity_mismatch maps to 409 instead of the 500 fallback", () => {
// 原值:KNOWN_RPC_ERROR_CODES 没有 mismatch,落到 校正服务暂时不可用
// 新值:409 skill_identity_mismatch,文案要求刷新
// 决策 2:修完决策 1 后不应再出现;映射只为不再露 500
assert.match(
caseService,
/"agentic_rectification_skill_identity_mismatch", \{ status: 409, code: "skill_identity_mismatch", message: "该校正绑定的规则版本与当前不一致,请刷新后重试" \}/,
);
});
test("a history-list open failure shows under the clicked row, not on the starter card", () => {
// 原值:rectificationError 只由 starter-home 画;selectSession 不切会话,表现为点了没反应
// 新值:session 失败绑到被点的那一行;首页起始卡不重复同一条
// 决策 3:错误就地显示
// 原值:const [rectificationErrorSessionId, setRectificationErrorSessionId] = useState(...)
// 新值:外壳 9 个校正字段合成一个 rectification 对象;errorSessionId 仍叫 rectificationErrorSessionIdsetter 仍叫 setRectificationErrorSessionId
// 原因:外壳也要读的校正状态合并成一个对象,散装 useState 下降
assert.match(pageSource, /errorSessionId: rectificationErrorSessionId,/);
assert.match(pageSource, /setRectificationErrorSessionId,/);
assert.match(
pageSource,
/rectificationError=\{rectificationErrorSessionId \? "" : rectificationError\}/,
);
assert.match(pageSource, /openErrorSessionId=\{rectificationErrorSessionId\}/);
assert.match(
pageSource,
/openErrorMessage=\{rectificationErrorSessionId \? rectificationErrorMessage : ""\}/,
);
assert.match(starter, /rectificationError && !rectificationSurfaceOpen && \(/);
assert.match(sidebar, /openErrorSessionId/);
assert.match(sidebarRow, /error \? \(/);
assert.match(sidebarRow, /className="session-open-error"/);
assert.match(sidebarRow, /role="alert"/);
assert.match(hook, /setRectificationErrorSessionId\(intent === "session" \? exactSessionId : null\)/);
assert.match(sessions, /setRectificationErrorSessionId\(null\)/);
const notice = cssDeclarations(".session-open-error", styles);
assert.match(notice, /color:\s*var\(--color-danger\)/);
assert.match(notice, /font-size:\s*var\(--type-overline\)/);
assert.match(page, /openErrorSessionId=\{rectificationErrorSessionId\}/);
});