import { test } from "node:test"; import assert from "node:assert/strict"; import { describeFlowError, flowFailTip, FLOW_GENERIC_FALLBACK, FLOW_NETWORK_FALLBACK } from "../src/utils/flowError"; /** 审批失败文案单测:口径=具体业务话原样透出,通用/异常形态换兜底话术且不外泄内部信息 */ test("后端给出通用 code=6 占位文案:换成不误导的兜底话术,不猜原因", () => { assert.equal(describeFlowError("内部服务错误"), FLOW_GENERIC_FALLBACK); assert.equal(describeFlowError("内部服务错误!"), FLOW_GENERIC_FALLBACK); assert.equal(describeFlowError("业务错误"), FLOW_GENERIC_FALLBACK); assert.equal(describeFlowError(""), FLOW_GENERIC_FALLBACK); assert.ok(!FLOW_GENERIC_FALLBACK.includes("成功")); }); test("契约内的具体业务 msg 原样透出,不改写不误导", () => { assert.equal(describeFlowError("流程线不存在:8d07f049"), "流程线不存在:8d07f049"); assert.equal(describeFlowError("该任务已被他人办理"), "该任务已被他人办理"); assert.equal( describeFlowError("该待办缺少流程推进记录,需管理员回填后办理"), "该待办缺少流程推进记录,需管理员回填后办理", ); }); test("异常/SQL/令牌形态不回显:堆栈与凭据不进页面", () => { const leaks = [ "java.lang.IllegalStateException: D09 task has no proven activation; audited backfill required", "at com.yunhai.flowcenter.service.FlowTaskService.handle(FlowTaskService.java:100)", "Caused by: SQLException error code [1064]", "refresh token=Bearer abcdef123456", "500 Internal Server Error", ]; for (const raw of leaks) { const out = describeFlowError(raw); assert.equal(out, FLOW_GENERIC_FALLBACK, raw); assert.ok(!/java\.|Exception|SQL|Bearer|/i.test(out)); } }); test("网络/登录态失败:按网络口径提示,不与业务失败混说", () => { assert.equal(describeFlowError("网络错误"), FLOW_NETWORK_FALLBACK); assert.equal(describeFlowError("Failed to fetch"), FLOW_NETWORK_FALLBACK); assert.equal(describeFlowError("timeout of 20000ms exceeded"), FLOW_NETWORK_FALLBACK); }); test("Error 对象可直接传入(取 message)", () => { assert.equal(describeFlowError(new Error("流程线不存在:g1")), "流程线不存在:g1"); assert.equal(describeFlowError(new Error("内部服务错误")), FLOW_GENERIC_FALLBACK); }); test("页面内联提示带动作名,明确「未生效」而不是成功", () => { const tip = flowFailTip("同意", new Error("内部服务错误")); assert.ok(tip.startsWith("同意未完成:")); assert.ok(tip.includes(FLOW_GENERIC_FALLBACK)); assert.ok(!tip.includes("已同意")); });