Files
flow-center-front/tests/flow-error.test.ts
T
chenxing c93313cdb7
build / build (push) Successful in 1m28s
feat(flow): 流程图入口/失败提示/指派预览/线级停发闭环/配置分层/选人宿主
- 修复办理页「查看流程图」双 hash URL:改 router.resolve + toAppHashUrl 单 hash
- 修复管理端办件抽屉「查看大图」域名尾点(origin + BASE_URL("./") 拼接)
- 新增 flowError 口径层与办理页内联失败条,审批失败提示可读、不泄漏堆栈
- 审批节点抽屉新增「预览候选人」真入口 + AssigneePreviewModal(只读,不写回定义)
- 线级停发/恢复失败改为单条错误面,避免同错双 toast
- 审批抽屉核心区/高级设置分层;插入菜单常用/高级分组
- 新增 FlowAssignEmbed 选人 iframe 父侧宿主(origin/source/信封/context 四校验)
- 修复 /diagram、/assign-preview 面包屑误显示「流程编辑器」
2026-10-28 03:18:54 +08:00

56 lines
2.8 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 { 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",
"<html><body>500 Internal Server Error</body></html>",
];
for (const raw of leaks) {
const out = describeFlowError(raw);
assert.equal(out, FLOW_GENERIC_FALLBACK, raw);
assert.ok(!/java\.|Exception|SQL|Bearer|<html>/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("已同意"));
});