|
|
import { describe, expect, it } from "vitest";
|
|
|
import {
|
|
|
detectUiKindsFromText,
|
|
|
extractForecastInstructionText,
|
|
|
extractMailInstructions,
|
|
|
splitBodySegments,
|
|
|
} from "@/services/parse/split-instructions";
|
|
|
import { evaluateTransferGate } from "@/services/cc/container-status";
|
|
|
import { buildCcWorkOrderFormValue } from "@/components/CcWorkOrderForm";
|
|
|
import { buildCcDoUploadFormValue } from "@/components/CcDoUploadPanel";
|
|
|
|
|
|
const MAIL4_SUBJECT =
|
|
|
"Fw: 转发:新增预报136:新辰泽+WHLC027G597465+WHSU8127240+洛杉矶+40HQ+EDT2026.04-25 ETA2026.05-15船名航次HMM EMERALD 013E+提拆派组合柜-不带托架";
|
|
|
|
|
|
const MAIL4_BODY = [
|
|
|
"Dear,",
|
|
|
"原箱号YT2604021091=FBA199R49LD6-MDW2=76件操作指令",
|
|
|
"换标后单号:FBA19HW52S0L-2G1MCB6X-HIA1=76件",
|
|
|
"1:覆盖贴FBA标签,一箱贴两张",
|
|
|
"3:贴好拍照回传",
|
|
|
].join("\n");
|
|
|
|
|
|
describe("four-business extractMailInstructions", () => {
|
|
|
it("mail4: forecast + work_order + maybe do", () => {
|
|
|
const units = extractMailInstructions({
|
|
|
subject: MAIL4_SUBJECT,
|
|
|
body: MAIL4_BODY,
|
|
|
filenames: ["YT2604021091=76件换标走HIA1卡派出库操作指令.xlsx"],
|
|
|
});
|
|
|
const kinds = units.map((u) => u.uiKind);
|
|
|
expect(kinds).toContain("forecast");
|
|
|
expect(kinds).toContain("work_order");
|
|
|
});
|
|
|
|
|
|
it("transfer-only body → transfer", () => {
|
|
|
const units = extractMailInstructions({
|
|
|
subject: "MATU2745683",
|
|
|
body: "新增转仓,请留意",
|
|
|
filenames: [],
|
|
|
});
|
|
|
expect(units.some((u) => u.uiKind === "transfer")).toBe(true);
|
|
|
});
|
|
|
|
|
|
it("DO filename → do_upload", () => {
|
|
|
expect(
|
|
|
detectUiKindsFromText("WHSU5574991", "", ["柜DO.pdf"]),
|
|
|
).toContain("do_upload");
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("extractForecastInstructionText P4", () => {
|
|
|
it("does not use 换标 body as forecast instruction", () => {
|
|
|
const text = extractForecastInstructionText({
|
|
|
subject: MAIL4_SUBJECT,
|
|
|
body: MAIL4_BODY,
|
|
|
});
|
|
|
expect(text).not.toMatch(/覆盖贴/);
|
|
|
expect(text).toMatch(/船名航次|HMM|EMERALD|/);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("splitBodySegments", () => {
|
|
|
it("splits on quote header", () => {
|
|
|
const segs = splitBodySegments(
|
|
|
"当前换标\n------------------ 原始电子邮件 ------------------\n主题:新增预报\n历史",
|
|
|
);
|
|
|
expect(segs.length).toBeGreaterThanOrEqual(2);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("buildCcWorkOrderFormValue", () => {
|
|
|
it("mail actions stay in tags; 贴标映射 CC 留言类型「操作指令」", () => {
|
|
|
const v = buildCcWorkOrderFormValue({
|
|
|
subject: "操作",
|
|
|
body: "请贴标并拍照",
|
|
|
containerNo: "WHSU8127240",
|
|
|
});
|
|
|
expect(v.F_MessageType).toBe("操作指令");
|
|
|
expect(v.F_MessageType).not.toBe("贴标");
|
|
|
expect(v.mailActions).toEqual(expect.arrayContaining(["贴标", "拍照"]));
|
|
|
expect(v.F_Remark).toContain("邮件动作:");
|
|
|
expect(v.F_ReferCode).toBe("WHSU8127240");
|
|
|
});
|
|
|
|
|
|
it("拦截 → CC 留言类型「货件拦截」", () => {
|
|
|
const v = buildCcWorkOrderFormValue({
|
|
|
subject: "请拦截",
|
|
|
body: "柜号 WHSU8127240 拦截货件",
|
|
|
});
|
|
|
expect(v.F_MessageType).toBe("货件拦截");
|
|
|
expect(v.mailActions).toContain("拦截");
|
|
|
});
|
|
|
|
|
|
it("mail3 渠道拦截-N件 → 备注为拆柜清单而非拦截", () => {
|
|
|
const subject =
|
|
|
"Fw: 转发:派送要求更新: 拆柜清单更新: DO请查收+拆柜清单更新: WHSU5574991+WHL063G550810+船名航次:OOCL SINGAPORE / 065W+ETA:6/28+FedEx-29件+UPS-102件+亚马逊卡派-289件+私人地址-166件+拦截-209件+拆柜清单";
|
|
|
const v = buildCcWorkOrderFormValue({
|
|
|
subject,
|
|
|
body: "派送要求更新,请查收 DO 与拆柜清单。",
|
|
|
containerNo: "WHSU5574991",
|
|
|
actions: [],
|
|
|
});
|
|
|
expect(v.F_Remark).toContain("邮件动作:拆柜清单");
|
|
|
expect(v.F_Remark).not.toContain("拦截");
|
|
|
expect(v.F_MessageType).not.toBe("货件拦截");
|
|
|
expect(v.mailActions).toContain("拆柜清单");
|
|
|
expect(v.mailActions).not.toContain("拦截");
|
|
|
});
|
|
|
|
|
|
it("strips forward headers; keeps Dear instruction as F_MessageContent", () => {
|
|
|
const v = buildCcWorkOrderFormValue({
|
|
|
subject: "Fw: 新增预报136",
|
|
|
body: [
|
|
|
"---- 转发的邮件 ----",
|
|
|
"发件人新辰泽",
|
|
|
"主题 Re:Re:新增预报136",
|
|
|
"Dear,",
|
|
|
"原箱号 YT2604021091=FBA199R49LD6-MDW2=76 件操作指令",
|
|
|
"1:覆盖贴FBA标签,一箱贴两张",
|
|
|
"3:贴好拍照回传",
|
|
|
].join("\n"),
|
|
|
containerNo: "WHSU8127240",
|
|
|
});
|
|
|
expect(v.F_MessageContent).toMatch(/^Dear,/);
|
|
|
expect(v.F_MessageContent).toContain("覆盖贴");
|
|
|
expect(v.F_MessageContent).not.toContain("转发的邮件");
|
|
|
expect(v.mailActions).toEqual(expect.arrayContaining(["贴标", "拍照"]));
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("buildCcDoUploadFormValue", () => {
|
|
|
it("keeps DO pdf filenames", () => {
|
|
|
const v = buildCcDoUploadFormValue({
|
|
|
subject: "DO请查收 WHSU5574991",
|
|
|
filenames: ["WHSU5574991-DO.pdf", "其他.xlsx"],
|
|
|
});
|
|
|
expect(v.filenames.some((f) => /DO/i.test(f))).toBe(true);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("evaluateTransferGate mock", () => {
|
|
|
it("ARRIVED container → work_order fallback", async () => {
|
|
|
const g = await evaluateTransferGate("ARRIVED1234567");
|
|
|
expect(g.canTransfer).toBe(false);
|
|
|
if (!g.canTransfer) expect(g.fallback).toBe("work_order");
|
|
|
});
|
|
|
|
|
|
it("normal container → can transfer in mock", async () => {
|
|
|
const g = await evaluateTransferGate("WHSU8127240");
|
|
|
// depends on CC_MOCK; if live empty list may fallback
|
|
|
expect(typeof g.canTransfer).toBe("boolean");
|
|
|
});
|
|
|
});
|