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.

115 lines
3.7 KiB

import { describe, expect, it } from "vitest";
import {
buildPriority1StoredQuotes,
inferPriority1DisplayMode,
parsePriority1StoredQuotes,
resolvePriority1StoredQuotes,
} from "@/modules/priority1/quote-storage";
import type { Priority1QuoteLine } from "@/workers/rpa/priority1/quote-extract";
import { buildPriority1CalendarGrid } from "@/lib/priority1/calendar-grid";
const ltlLine = (overrides: Partial<Priority1QuoteLine> = {}): Priority1QuoteLine => ({
rank: 1,
carrier: "Old Dominion Freight Line",
totalUsd: 557.04,
transitDays: 2,
serviceLevel: "STANDARD LTL",
source: "visible-dom",
...overrides,
});
describe("priority1 quote storage", () => {
it("infers ltl_cards for standard LTL lines", () => {
expect(inferPriority1DisplayMode([ltlLine()])).toBe("ltl_cards");
expect(inferPriority1DisplayMode([ltlLine()], "ltl")).toBe("ltl_cards");
});
it("infers ftl_calendar for FTL shipment or calendar source", () => {
expect(inferPriority1DisplayMode([ltlLine()], "ftl")).toBe("ftl_calendar");
expect(
inferPriority1DisplayMode([
ltlLine({ source: "ftl-calendar", carrier: "FTL 日历报价" }),
]),
).toBe("ftl_calendar");
});
it("builds stored quotes with markup applied", () => {
const stored = buildPriority1StoredQuotes(
[ltlLine({ totalUsd: 100 })],
{ type: "percent", percent: 10, fixedAmount: 0 },
"ltl",
);
expect(stored.provider).toBe("priority1");
expect(stored.display_mode).toBe("ltl_cards");
expect(stored.lines[0]!.final_total_usd).toBe(110);
expect(stored.lines[0]!.markup_amount).toBe(10);
});
it("round-trips parsePriority1StoredQuotes", () => {
const stored = buildPriority1StoredQuotes(
[ltlLine()],
{ type: "fixed", percent: 0, fixedAmount: 5 },
"ltl",
);
expect(parsePriority1StoredQuotes(stored)).toEqual(stored);
expect(parsePriority1StoredQuotes([{ rank: 1 }])).toBeNull();
});
it("converts legacy MotherShip tier array for display", () => {
const resolved = resolvePriority1StoredQuotes(
[
{
service_level: "standard",
rate_option: "lowest",
carrier: "Old Dominion",
transit_days: "2",
raw_total: 557.04,
final_total: 557.04,
markup_amount: 0,
},
],
{ priority1_shipment_type: "ltl" },
);
expect(resolved?.display_mode).toBe("ltl_cards");
expect(resolved?.lines[0]?.final_total_usd).toBe(557.04);
expect(resolved?.lines[0]?.source).toBe("legacy-tier");
});
it("does not treat MotherShip tier array as Priority1 without shipment meta", () => {
const resolved = resolvePriority1StoredQuotes(
[
{
service_level: "standard",
rate_option: "lowest",
carrier: "Frontline Freight",
transit_days: "3",
raw_total: 332.6,
final_total: 332.6,
markup_amount: 0,
},
],
{ zip: "90001" },
);
expect(resolved).toBeNull();
});
});
describe("priority1 calendar grid", () => {
it("places prices on consecutive days from pickup date", () => {
const lines = buildPriority1StoredQuotes(
[
ltlLine({ rank: 1, totalUsd: 1652.16 }),
ltlLine({ rank: 2, totalUsd: 1650.78 }),
],
{ type: "percent", percent: 0, fixedAmount: 0 },
"ftl",
).lines;
const { cells } = buildPriority1CalendarGrid("2026-07-01", lines);
const inMonth = cells.filter((c) => c.inMonth && c.priceUsd != null);
expect(inMonth.length).toBe(2);
expect(inMonth[0]!.date.getDate()).toBe(1);
expect(inMonth[0]!.priceUsd).toBe(1652.16);
expect(inMonth[1]!.date.getDate()).toBe(2);
});
});