You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { describe, expect, it } from "vitest";
import {
classifyCcFailure,
conflictCheckOperatorMessage,
describeCcFailureForOperator,
formatCcCause,
formatImapSkipReason,
formatMailLastError,
formatOAuthCallbackError,
formatOperatorError,
} from "@/constants/error-copy";
describe("formatOperatorError", () => {
it("translates last_error machine codes", () => {
expect(formatMailLastError("NO_SHIPMENT_ROWS")).toMatch(/未解析到货件/);
expect(formatMailLastError("NO_SUPPORTED_SPREADSHEET")).toMatch(/表格附件/);
expect(formatMailLastError("NO_BODY_NO_ATTACHMENT")).toMatch(/没有正文/);
expect(formatMailLastError("ATTACHMENT_TOO_LARGE")).toMatch(/过大/);
expect(formatMailLastError("MIME_PARSE_ERROR")).toMatch(/格式损坏/);
expect(formatMailLastError("missing_columns:仓库ID")).toMatch(/缺列/);
expect(formatMailLastError("INVALID_CONTAINER_NO:TRHU8524770")).toMatch(
/TRHU8524770/,
);
});
it("does not show Unauthorized / Invalid body to operators", () => {
expect(formatOperatorError("Unauthorized", "UNAUTHORIZED")).toMatch(/登录/);
expect(formatOperatorError("Unauthorized")).toMatch(/CarrierCentral|权限/);
expect(formatOperatorError("Invalid body")).toMatch(/提交内容|必填/);
expect(formatOperatorError("Mail not found")).toMatch(/邮件/);
expect(formatMailLastError("Unauthorized")).not.toMatch(/Unauthorized/i);
expect(formatMailLastError("Invalid body")).not.toMatch(/Invalid/i);
});
it("translates CC transport failures", () => {
expect(formatCcCause("CC request timeout")).toMatch(/超时/);
expect(formatCcCause("CC request failed")).toMatch(/无法连接/);
expect(formatCcCause("CC save failed with code 400")).toMatch(
/集装箱数据导入|拒绝|400/,
);
expect(formatCcCause("GetContainerList timeout")).toMatch(
/集装箱列表|超时/,
);
expect(formatMailLastError("CC_WRITE_OFF")).toMatch(/未开启/);
expect(formatMailLastError("WO_MOCK_OK")).toMatch(/模拟|未写入/);
expect(formatMailLastError("WO_MOCK_OK")).not.toMatch(/操作失败/);
expect(formatMailLastError("XFER_MOCK_OK")).toMatch(/模拟|未写入/);
expect(formatMailLastError("DO_MOCK_OK")).toMatch(/模拟|未写入/);
expect(formatCcCause("Unauthorized")).not.toMatch(/Unauthorized/i);
});
it("keeps CC Chinese info even when it embeds FBACode / charset lists", () => {
const raw =
"第60行的FBACode是空值或者只输入了正常英文字符[_- ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz]以外的字符。";
const out = formatCcCause(raw);
expect(out).toMatch(/第60行/);
expect(out).toMatch(/目的代码/);
expect(out).not.toMatch(/请稍后重试或到 CC 核对/);
});
it("keeps already-Chinese messages", () => {
expect(formatOperatorError("邮件不存在")).toBe("邮件不存在");
expect(formatOperatorError("柜号必填")).toBe("柜号必填");
});
it("rewrites English embedded in Chinese", () => {
expect(
formatOperatorError("查柜失败:GetContainerList timeout,默认降级工单"),
).toMatch(/集装箱列表|超时/);
});
it("keeps Chinese packing-list errors that mention Excel/xlsx", () => {
expect(
formatOperatorError(
"解析装箱表失败,请确认文件为有效的 Excel(xlsx)",
"PARSE_FAILED",
),
).toMatch(/装箱表|Excel|xlsx/);
expect(
formatOperatorError(
"未能从表格解析出货件行,请确认是卡派清单等含「渠道/件数/仓库」表头的 xlsx",
"PARSE_FAILED",
),
).toMatch(/货件行|卡派清单/);
});
it("maps OAuth and IMAP skip reasons", () => {
expect(formatOAuthCallbackError("missing_code")).toMatch(/授权码/);
expect(formatImapSkipReason("no_credentials")).toMatch(/邮箱/);
expect(formatImapSkipReason("SKIP_BLACKLIST")).toMatch(/黑名单/);
});
it("classifies conflict check failures for operators", () => {
expect(classifyCcFailure("CC_LOGIN_FAILED:账户或密码错误")).toBe("login");
expect(classifyCcFailure("访问次数限制,请稍后再试")).toBe("rate_limit");
expect(classifyCcFailure("GetContainerList timeout")).toBe("timeout");
expect(
conflictCheckOperatorMessage("login", "CC_LOGIN_FAILED:401"),
).toMatch(/账号|密码/);
expect(conflictCheckOperatorMessage("rate_limit")).toMatch(/每分钟|60/);
});
it("maps CC login credential errors", () => {
expect(formatCcCause("CC_CREDENTIALS_MISSING")).toMatch(/未配置/);
expect(formatCcCause("CC_LOGIN_FAILED:账户或密码错误")).toMatch(/密码/);
});
it("describeCcFailureForOperator exposes kind and message", () => {
const login = describeCcFailureForOperator("CC_LOGIN_FAILED:账户或密码错误");
expect(login.kind).toBe("login");
expect(login.kindLabel).toMatch(/登录/);
expect(login.message).toMatch(/账号|密码/);
const validation = describeCcFailureForOperator(
"以下字段未填写,不能保存:柜型",
);
expect(validation.kind).toBe("validation");
expect(validation.message).toMatch(/柜型|40HQ/);
});
});