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.
mail-yubao/tests/unit/instruction-product-rules.t...

98 lines
4.0 KiB

import { describe, expect, it } from "vitest";
import { classifyMail } from "@/services/parse/classify";
import { extractMailInstructions } from "@/services/parse/split-instructions";
describe("product rules: latest confirmable + WO fallback", () => {
it("mail1-like: classify WORK_ORDER; UI via workOrderActions record", () => {
const subject = "Fw: TIIU8073522-90022";
const body = [
"\u53d1\u81ea\u6211\u7684iPhone",
"------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------",
"\u4e3b\u9898 TIIU8073522-90022",
"BAZUS001787430-90022 4PX \u9884\u7ea6\u7801: ==CNF26070717 \u9884\u7ea6\u7801",
].join("\n");
const ev = classifyMail({ subject, body, filenames: [] });
expect(ev.mail_type).toBe("WORK_ORDER");
// 详情页传入 mail_record.work_order_actions 时补当前工单单元
const units = extractMailInstructions({
subject,
body,
workOrderActions: ["\u5de5\u5355"],
});
expect(units.some((u) => u.uiKind === "work_order" && u.isCurrent)).toBe(
true,
);
});
it("only newest instruction segment isCurrent", () => {
const body = [
"\u65b0\u589e\u8f6c\u4ed3\uff0c\u8bf7\u7559\u610f",
"------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------",
"\u53d1\u4ef6\u4eba\uff1aa@b.com",
"\u4e3b\u9898\uff1a\u66f4\u65b0\u6d3e\u9001\u5355",
"\u67dc\u53f7\uff1aMATU2745683 \u66f4\u65b0\u6d3e\u9001\u5355\uff0c\u8bf7\u67e5\u6536",
].join("\n");
const units = extractMailInstructions({
subject: "MATU2745683",
body,
});
const current = units.filter((u) => u.isCurrent);
expect(current.some((u) => u.uiKind === "transfer")).toBe(true);
// 已有当前转仓时,历史软词「更新派送单」不出客户指令卡
expect(units.some((u) => u.uiKind === "customer_instruction")).toBe(false);
expect(current.every((u) => u.segmentIndex === current[0].segmentIndex)).toBe(
true,
);
});
it("LINK EVER: transfer only; no WO from work_order_actions=转仓", () => {
const subject =
"Fw: \u8f6c\u53d1\uff1aLINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1aMATU2745683+ ETA : 7/13";
const body = [
"\u53d1\u81ea\u6211\u7684iPhone",
"------------------ \u539f\u59cb\u7535\u5b50\u90ae\u4ef6 ------------------",
"\u5bc4\u4ef6\u4eba\uff1a date <date@usasinogroup.com>",
"---- \u8f6c\u53d1\u7684\u90ae\u4ef6 ----",
"\u53d1\u4ef6\u4ebaop7<op7@xinfenginc.com>",
"\u65e5\u671f 2026\u5e7407\u670810\u65e5 16:44",
"\u4e3b\u9898 \u56de\u590d: LINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1aMATU2745683+ ETA : 7/13",
"\u65b0\u589e\u8f6c\u4ed3\uff0c\u8bf7\u7559\u610f",
"\u67dc\u53f7\uff1aMATU2745683\u5361\u6d3e\u8d44\u6599.xlsx",
"",
"\u53d1\u4ef6\u4eba\uff1a op7",
"\u53d1\u9001\u65f6\u95f4\uff1a 2026-07-02 18:09",
"\u4e3b\u9898\uff1a LINK EVER INC + MATS4583030000+ \u67dc\u53f7\uff1a MATU2745683+ ETA : 7/13",
"\u67dc\u53f7\uff1aMATU2745683 \u66f4\u65b0\u6d3e\u9001\u5355\uff0c\u8bf7\u67e5\u6536",
].join("\n");
const units = extractMailInstructions({
subject,
body,
filenames: ["\u67dc\u53f7\uff1aMATU2745683\u5361\u6d3e\u8d44\u6599.xlsx"],
workOrderActions: ["\u8f6c\u4ed3"],
});
expect(units.map((u) => u.uiKind)).toEqual(["transfer"]);
expect(units[0].isCurrent).toBe(true);
expect(units.some((u) => u.uiKind === "work_order")).toBe(false);
expect(units.some((u) => u.uiKind === "customer_instruction")).toBe(false);
});
it("soft keywords map to customer_instruction (not work_order)", () => {
for (const kw of [
"\u66f4\u65b0\u6d3e\u9001\u5355",
"\u6539\u81ea\u63d0",
"\u62c6\u67dc\u6e05\u5355",
"\u5361\u8f6c\u6d77",
]) {
const units = extractMailInstructions({
subject: kw,
body: kw,
});
expect(units.some((u) => u.uiKind === "customer_instruction")).toBe(
true,
);
expect(units.some((u) => u.uiKind === "work_order")).toBe(false);
}
});
});