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/header-service-hints.test.ts

104 lines
4.2 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 {
applyServiceFromModules,
applyServiceFromText,
normalizeCabinetType,
stripOrChoiceNoise,
} from "@/services/parse/header-service-hints";
import { extractContainerHeaderFromText } from "@/services/parse/extract-container-header";
import { mapBlModulesToHeader } from "@/services/parse/bl-plus-template";
import { extractOpsSubjectFromMail } from "@/services/parse/ops-subject-template";
import { buildCcForecastFormValue } from "@/components/CcForecastFormOrder";
describe("header-service-hints (AI assistant parity)", () => {
it("strips 海运或空运 / 提拆派或直送 option noise", () => {
const t = stripOrChoiceNoise("运输方式(海运或空运)操作类型(提拆派或直送)");
expect(t).not.toMatch(/海运或空运|提拆派或直送/);
});
it("normalizeCabinetType 40HC → 40HQ", () => {
expect(normalizeCabinetType("40HC")).toBe("40HQ");
expect(normalizeCabinetType("40HQ")).toBe("40HQ");
});
it("拆柜清单 / 提拆派 / 直送 / 只清关", () => {
expect(applyServiceFromText("拆柜清单").F_OperationType).toBe(0);
expect(applyServiceFromText("提拆派组合柜-不带托架")).toMatchObject({
F_OperationType: 0,
F_Classis: 0,
F_Instruction: "提拆派",
});
expect(applyServiceFromText("本票直送").F_OperationType).toBe(2);
expect(applyServiceFromText("只清关").F_OperationType).toBe(4);
expect(
applyServiceFromText("提拆派,说明另有直送类型").F_OperationType,
).toBe(0);
});
it("ops_hints 拆柜清单 → modules path", () => {
expect(
applyServiceFromModules({ ops_hints: ["拆柜清单", "派送要求"] })
.F_OperationType,
).toBe(0);
expect(
applyServiceFromModules({ ops_hints: ["直送"] }).F_OperationType,
).toBe(2);
});
});
describe("extractContainerHeaderFromText assistant parity", () => {
it("mail3 channel summary → 拆柜 + 海运 + OOCL 船司别名", () => {
const h = extractContainerHeaderFromText(
"WHSU5574991+WHL063G550810+船名航次:OOCL SINGAPORE / 065W+ETA:6/28+FedEx-29件+UPS-102件+亚马逊卡派-289件+私人地址-166件+拦截-209件+拆柜清单",
);
expect(h.F_OperationType).toBe(0);
expect(h.F_TransMode).toBe(0);
expect(h.F_ETA).toBe("2026-06-28");
expect(h.F_BLCopyCode).toBe("WHL063G550810");
expect(h.shipping_line_hint).toMatch(/WHL/i);
expect(h.F_Instruction).toMatch(/船名航次.*OOCL SINGAPORE/);
// 禁止 WAN/OOCL 船名首词误当船司时:有提单前缀则用 WHL
});
it("does not take vessel first token as shipping line (WAN HAI)", () => {
const h = extractContainerHeaderFromText(
"船名航次:WAN HAI 511-V.E110 柜号 TCNU4412465",
);
expect(h.shipping_line_hint?.toUpperCase()).not.toBe("WAN");
expect(h.shipping_line_hint?.toUpperCase()).toMatch(/WAN\s*HAI|WHL|WAN HAI/i);
});
it("ignores 提拆派或直送 as selected operation", () => {
const h = extractContainerHeaderFromText(
"请选择操作类型(提拆派或直送)柜号 WHSU8127240",
);
expect(h.F_OperationType).toBeUndefined();
});
});
describe("ops subject → form full chain", () => {
it("mail3 subject fills OperationType via map + form", () => {
const subject =
"Fw: 转发:派送要求更新: 拆柜清单更新: DO请查收+拆柜清单更新: WHSU5574991+WHL063G550810+船名航次:OOCL SINGAPORE / 065W+ETA:6/28+FedEx-29件+UPS-102件+亚马逊卡派-289件+私人地址-166件+拦截-209件+拆柜清单";
const ops = extractOpsSubjectFromMail(subject, { defaultYear: 2026 })!;
const header = mapBlModulesToHeader(
{
F_ContainerNo: ops.modules.container_no || "",
container_no_valid: true,
},
ops.modules,
);
expect(header.F_OperationType).toBe(0);
expect(header.F_TransMode).toBe(0);
expect(header.F_ETA).toBe("2026-06-28");
const form = buildCcForecastFormValue({
header: {},
modules: ops.modules,
});
expect(form.F_OperationType).toBe(0);
expect(form.F_TransMode).toBe(0);
expect(form.F_ETA).toBe("2026-06-28");
expect(form.F_Instruction).toMatch(/船名航次/);
});
});