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/transfer-instruction-table....

134 lines
3.8 KiB

import { describe, expect, it } from "vitest";
import {
parseTransferInstructionTable,
splitTaggedOcrBlocks,
transferRowsToPairs,
} from "@/services/parse/transfer-instruction-table";
import { buildTransferSegmentContexts } from "@/services/parse/match-transfer-segment-ocr";
import type { MailInstructionUnit } from "@/services/parse/split-instructions";
describe("parseTransferInstructionTable", () => {
it("parses 地址/箱数/仓库重定向 row", () => {
const rows = parseTransferInstructionTable(
"柜号 ZCSU6581068 ETA 2026/7/7 地址 PSC2 箱数 7 提柜时间 仓库重定向 POC2",
);
expect(rows).toEqual([
{
containerNo: "ZCSU6581068",
eta: "2026/7/7",
from: "PSC2",
to: "POC2",
ctns: 7,
},
]);
expect(transferRowsToPairs(rows)).toEqual([
{ from: "PSC2", to: "POC2", rows: 7 },
]);
});
it("parses FWA4 → VGT2", () => {
const rows = parseTransferInstructionTable(
"地址 FWA4 箱数 17 仓库重定向 VGT2 柜号 ZCSU6581068",
);
expect(rows[0]?.from).toBe("FWA4");
expect(rows[0]?.to).toBe("VGT2");
expect(rows[0]?.ctns).toBe(17);
});
it("parses noisy OCR table row", () => {
const rows = parseTransferInstructionTable(
"ZCSU6581068 20267777 PSC2 7 POC2",
);
expect(rows[0]?.from).toBe("PSC2");
expect(rows[0]?.to).toBe("POC2");
});
it("uses fallback header fields and ignores OCR noise codes", () => {
const rows = parseTransferInstructionTable(
"HES ETA Ek BH ZCSUB581068 2026/7/7 PSC2 7 POC2",
{
containerNo: "ZCSU6581068",
},
);
expect(rows).toEqual([
{
containerNo: "ZCSU6581068",
eta: "2026/7/7",
from: "PSC2",
to: "POC2",
ctns: 7,
},
]);
});
it("normalizes fuzzy FWA4 OCR row", () => {
const rows = parseTransferInstructionTable(
"155 EH ETA Spit AE RABE CEEEE zcsuessioes ozoze/r/7 Ewad 17 VGT2",
{
containerNo: "ZCSU6581068",
},
);
expect(rows).toEqual([
{
containerNo: "ZCSU6581068",
from: "FWA4",
to: "VGT2",
ctns: 17,
},
]);
});
});
describe("splitTaggedOcrBlocks", () => {
it("splits per attachment tag", () => {
const blocks = splitTaggedOcrBlocks(
"【OCR:a.jpg】\n地址 PSC2 箱数 7 仓库重定向 POC2\n\n【OCR:b.jpg】\n地址 FWA4 箱数 17 仓库重定向 VGT2",
);
expect(blocks).toHaveLength(2);
expect(blocks[0].tag).toBe("a.jpg");
expect(blocks[1].text).toMatch(/FWA4/);
});
});
describe("buildTransferSegmentContexts", () => {
it("assigns oldest transfer unit to first image OCR block", () => {
const units: MailInstructionUnit[] = [
{
id: "t-new",
uiKind: "transfer",
mailType: "TRANSFER",
label: "批量转仓",
summary: "",
keywords: [],
source: "body_segment",
segmentIndex: 3,
isCurrent: true,
segmentText: "新增转仓,请留意",
roundAt: "2026-07-07",
},
{
id: "t-old",
uiKind: "transfer",
mailType: "TRANSFER",
label: "批量转仓",
summary: "",
keywords: [],
source: "body_segment",
segmentIndex: 4,
isCurrent: false,
segmentText: "新增转仓,请留意",
roundAt: "2026-07-06",
},
];
const ctx = buildTransferSegmentContexts({
transferUnits: units,
imageFilenames: ["img-fwa.jpg", "img-psc.jpg"],
containerNo: "ZCSU6581068",
ocrText:
"【OCR:img-fwa.jpg】\n地址 FWA4 箱数 17 仓库重定向 VGT2\n【OCR:img-psc.jpg】\n地址 PSC2 箱数 7 仓库重定向 POC2",
});
expect(ctx.get("t-old")?.rows[0]?.from).toBe("FWA4");
expect(ctx.get("t-new")?.rows[0]?.from).toBe("PSC2");
});
});