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.
391 lines
12 KiB
391 lines
12 KiB
import { describe, expect, it } from "vitest";
|
|
import {
|
|
FLOCK_ADDITIONAL_SERVICES,
|
|
FLOCK_DEFAULT_VEHICLES,
|
|
FLOCK_FREIGHT_CLASSES,
|
|
FLOCK_LOCATION_TYPES,
|
|
FLOCK_PACKAGING_TYPES,
|
|
FLOCK_VEHICLE_TYPES,
|
|
getFlockLocationAccessorials,
|
|
mapFlockLoggedInToApiInput,
|
|
validateFlockLoggedInCargoLine,
|
|
type FlockLoggedInQuotePayload,
|
|
} from "@/components/flock/flock-logged-in-quote-form";
|
|
import { FLOCK_VALIDATION_MESSAGES } from "@/lib/constants/flock-limits";
|
|
|
|
describe("flock logged-in quote form constants", () => {
|
|
it("地点类型恰 12 项且无虚构 Grocery/Prison 等", () => {
|
|
const ids = FLOCK_LOCATION_TYPES.map((x) => x.id);
|
|
expect(ids).toHaveLength(12);
|
|
expect(ids).toEqual(
|
|
expect.arrayContaining([
|
|
"business_with_dock",
|
|
"business_without_dock",
|
|
"limited_school",
|
|
"limited_airport",
|
|
"limited_military",
|
|
"trade_show",
|
|
"residential",
|
|
"limited_other",
|
|
]),
|
|
);
|
|
expect(ids).not.toContain("limited_grocery");
|
|
expect(ids).not.toContain("limited_mini_storage");
|
|
expect(ids).not.toContain("limited_prison");
|
|
expect(ids).not.toContain("limited_utility");
|
|
});
|
|
|
|
it("地点类型含 Business / School / Airport / Trade Show 等", () => {
|
|
const ids = FLOCK_LOCATION_TYPES.map((x) => x.id);
|
|
expect(ids).toEqual(
|
|
expect.arrayContaining([
|
|
"business_with_dock",
|
|
"business_without_dock",
|
|
"limited_school",
|
|
"limited_airport",
|
|
"trade_show",
|
|
"residential",
|
|
]),
|
|
);
|
|
});
|
|
|
|
it("调度选项按总重 >5000 动态启用", async () => {
|
|
const mod = await import("@/components/flock/flock-logged-in-quote-form");
|
|
expect(mod.flockSchedulingWeightLockedHint()).toBe(
|
|
"整票总重须大于 5000 lb 才可选用",
|
|
);
|
|
expect(
|
|
mod.isFlockSchedulingOptionLocked(4000, true),
|
|
).toBe(true);
|
|
expect(
|
|
mod.isFlockSchedulingOptionLocked(5001, true),
|
|
).toBe(false);
|
|
expect(
|
|
mod.isFlockSchedulingOptionLocked(4000, false),
|
|
).toBe(false);
|
|
expect(
|
|
mod.FLOCK_PICKUP_SERVICES.find((s) => s.id === "during_window")
|
|
?.weightLocked,
|
|
).toBe(true);
|
|
expect(
|
|
mod.FLOCK_PICKUP_SERVICES.find((s) => s.id === "standard_fcfs")
|
|
?.weightLocked,
|
|
).toBe(false);
|
|
expect(
|
|
mod.FLOCK_DELIVERY_SERVICES.find((s) => s.id === "need_appointment")
|
|
?.weightLocked,
|
|
).toBe(false);
|
|
expect(
|
|
mod.FLOCK_DELIVERY_SERVICES.find((s) => s.id === "must_arrive_by")
|
|
?.weightLocked,
|
|
).toBe(true);
|
|
expect(mod.FLOCK_SCHEDULING_TIME_OPTIONS[0]).toBe("12:00 am");
|
|
expect(
|
|
mod.FLOCK_PICKUP_SERVICES.find((s) => s.id === "during_window")?.detail,
|
|
).toContain("预设时段");
|
|
});
|
|
|
|
it("mapFlockLoggedInToApiInput 透传调度子字段", () => {
|
|
const payload: FlockLoggedInQuotePayload = {
|
|
mode: "quick",
|
|
pickupDate: "2026-07-16",
|
|
pickupZip: "60611",
|
|
pickupType: "business_with_dock",
|
|
pickupLiftgate: false,
|
|
pickupInside: false,
|
|
pickupPalletJack: false,
|
|
deliveryZip: "78701",
|
|
deliveryType: "business_without_dock",
|
|
deliveryLiftgate: false,
|
|
deliveryInside: false,
|
|
deliveryPalletJack: false,
|
|
items: [
|
|
{
|
|
quantity: 4,
|
|
packagingType: "pallets_48x40",
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 48,
|
|
totalWeightLb: 6000,
|
|
freightClass: "100",
|
|
description: "papers",
|
|
stackable: true,
|
|
turnable: false,
|
|
},
|
|
],
|
|
additionalServices: [],
|
|
vehicleTypes: ["dry_van"],
|
|
pickupService: "during_window",
|
|
deliveryService: "must_arrive_by",
|
|
pickupWindowStartTime: "8:00 am",
|
|
pickupWindowEndTime: "5:00 pm",
|
|
deliveryMustArriveByDate: "2026-07-20",
|
|
callForDeliveryAppointment: true,
|
|
callBeforePickup: false,
|
|
callBeforeDelivery: false,
|
|
additionalInsurance: false,
|
|
};
|
|
const mapped = mapFlockLoggedInToApiInput(payload);
|
|
expect(mapped.pickup_service).toBe("during_window");
|
|
expect(mapped.pickup_window_start_time).toBe("8:00 am");
|
|
expect(mapped.pickup_window_end_time).toBe("5:00 pm");
|
|
expect(mapped.delivery_service).toBe("must_arrive_by");
|
|
expect(mapped.delivery_must_arrive_by_date).toBe("2026-07-20");
|
|
expect(mapped.call_for_delivery_appointment).toBe(true);
|
|
});
|
|
|
|
it("mapFlockLoggedInToApiInput 总重 ≤5000 时强制关闭提货前致电", () => {
|
|
const payload: FlockLoggedInQuotePayload = {
|
|
mode: "quick",
|
|
pickupDate: "2026-07-16",
|
|
pickupZip: "60611",
|
|
pickupType: "business_with_dock",
|
|
pickupLiftgate: false,
|
|
pickupInside: false,
|
|
pickupPalletJack: false,
|
|
deliveryZip: "78701",
|
|
deliveryType: "business_without_dock",
|
|
deliveryLiftgate: false,
|
|
deliveryInside: false,
|
|
deliveryPalletJack: false,
|
|
items: [
|
|
{
|
|
quantity: 4,
|
|
packagingType: "pallets_48x40",
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 48,
|
|
totalWeightLb: 1000,
|
|
freightClass: "100",
|
|
description: "papers",
|
|
stackable: true,
|
|
turnable: false,
|
|
},
|
|
],
|
|
additionalServices: [],
|
|
vehicleTypes: ["dry_van"],
|
|
pickupService: "standard_fcfs",
|
|
deliveryService: "standard_fcfs",
|
|
callBeforePickup: true,
|
|
callBeforeDelivery: false,
|
|
additionalInsurance: false,
|
|
};
|
|
expect(mapFlockLoggedInToApiInput(payload).call_before_pickup).toBe(false);
|
|
payload.items[0]!.totalWeightLb = 6000;
|
|
expect(mapFlockLoggedInToApiInput(payload).call_before_pickup).toBe(true);
|
|
});
|
|
|
|
it("各地点类型附加选项矩阵对齐官网截图", () => {
|
|
expect(getFlockLocationAccessorials("business_without_dock")).toEqual({
|
|
liftgate: true,
|
|
inside: true,
|
|
palletJack: true,
|
|
});
|
|
expect(getFlockLocationAccessorials("residential")).toEqual({
|
|
liftgate: true,
|
|
inside: true,
|
|
palletJack: false,
|
|
});
|
|
expect(getFlockLocationAccessorials("limited_construction")).toEqual({
|
|
liftgate: true,
|
|
inside: false,
|
|
palletJack: true,
|
|
});
|
|
expect(getFlockLocationAccessorials("trade_show")).toEqual({
|
|
liftgate: false,
|
|
inside: false,
|
|
palletJack: true,
|
|
});
|
|
expect(getFlockLocationAccessorials("limited_worship")).toEqual({
|
|
liftgate: true,
|
|
inside: true,
|
|
palletJack: false,
|
|
});
|
|
expect(getFlockLocationAccessorials("business_with_dock")).toEqual({
|
|
liftgate: false,
|
|
inside: false,
|
|
palletJack: false,
|
|
});
|
|
});
|
|
|
|
it("官网提示文案中文齐全", async () => {
|
|
const tips = await import("@/components/flock/flock-logged-in-quote-form");
|
|
expect(tips.FLOCK_LOCATION_TIP_ITEMS).toHaveLength(7);
|
|
expect(tips.FLOCK_ADDITIONAL_SERVICE_TIP_ITEMS).toHaveLength(5);
|
|
expect(tips.FLOCK_VEHICLE_TIP_ITEMS).toHaveLength(4);
|
|
expect(tips.FLOCK_FREIGHT_CLASS_TIP).toContain("件数");
|
|
expect(tips.FLOCK_INSURANCE_YES_TIP).toContain("责任限额");
|
|
expect(tips.FLOCK_NMFC_NOTICE).toContain("NMFC");
|
|
});
|
|
|
|
it("货物尺寸与重量硬限同 FLOCK_LIMITS", () => {
|
|
const ok = validateFlockLoggedInCargoLine({
|
|
quantity: 2,
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 48,
|
|
totalWeightLb: 1000,
|
|
description: "ok",
|
|
});
|
|
expect(ok).toEqual({});
|
|
|
|
expect(
|
|
validateFlockLoggedInCargoLine({
|
|
quantity: 1,
|
|
lengthIn: 637,
|
|
widthIn: 40,
|
|
heightIn: 48,
|
|
totalWeightLb: 100,
|
|
description: "x",
|
|
}).len,
|
|
).toBe(FLOCK_VALIDATION_MESSAGES.length);
|
|
|
|
expect(
|
|
validateFlockLoggedInCargoLine({
|
|
quantity: 1,
|
|
lengthIn: 48,
|
|
widthIn: 103,
|
|
heightIn: 48,
|
|
totalWeightLb: 100,
|
|
description: "x",
|
|
}).wid,
|
|
).toBe(FLOCK_VALIDATION_MESSAGES.width);
|
|
|
|
expect(
|
|
validateFlockLoggedInCargoLine({
|
|
quantity: 1,
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 109,
|
|
totalWeightLb: 100,
|
|
description: "x",
|
|
}).hei,
|
|
).toBe(FLOCK_VALIDATION_MESSAGES.height);
|
|
|
|
expect(
|
|
validateFlockLoggedInCargoLine({
|
|
quantity: 1,
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 48,
|
|
totalWeightLb: 45_001,
|
|
description: "x",
|
|
}).wt,
|
|
).toBe(FLOCK_VALIDATION_MESSAGES.totalWeight);
|
|
});
|
|
|
|
it("包装类型含标准托盘尺寸", () => {
|
|
const ids = FLOCK_PACKAGING_TYPES.map((x) => x.id);
|
|
expect(ids).toEqual(
|
|
expect.arrayContaining([
|
|
"pallets_48x40",
|
|
"pallets_48x48",
|
|
"pallets_60x48",
|
|
"pallets_custom",
|
|
]),
|
|
);
|
|
const p48 = FLOCK_PACKAGING_TYPES.find((p) => p.id === "pallets_48x40");
|
|
expect(p48?.length).toBe(48);
|
|
expect(p48?.width).toBe(40);
|
|
});
|
|
|
|
it("货运等级含密度计算与数值档", () => {
|
|
expect(FLOCK_FREIGHT_CLASSES[0]).toBe("density");
|
|
expect(FLOCK_FREIGHT_CLASSES).toEqual(
|
|
expect.arrayContaining(["50", "70", "100", "500"]),
|
|
);
|
|
});
|
|
|
|
it("附加服务与车型对齐截图", () => {
|
|
expect(FLOCK_ADDITIONAL_SERVICES.map((s) => s.id)).toEqual([
|
|
"blind_shipment",
|
|
"food_grade",
|
|
"load_to_ride",
|
|
"temperature_control",
|
|
"unloading",
|
|
]);
|
|
expect(FLOCK_VEHICLE_TYPES.map((v) => v.id)).toEqual([
|
|
"box_truck",
|
|
"dry_van",
|
|
"refrigerated",
|
|
"sprinter",
|
|
]);
|
|
expect([...FLOCK_DEFAULT_VEHICLES]).toEqual([
|
|
"box_truck",
|
|
"dry_van",
|
|
"refrigerated",
|
|
]);
|
|
});
|
|
|
|
it("mapFlockLoggedInToApiInput 汇总首行尺寸与多行数量/重量", () => {
|
|
const payload: FlockLoggedInQuotePayload = {
|
|
mode: "quick",
|
|
pickupDate: "2026-07-16",
|
|
pickupZip: "60611",
|
|
pickupType: "business_with_dock",
|
|
pickupLiftgate: false,
|
|
pickupInside: false,
|
|
pickupPalletJack: false,
|
|
deliveryZip: "78701",
|
|
deliveryType: "business_without_dock",
|
|
deliveryLiftgate: true,
|
|
deliveryInside: false,
|
|
deliveryPalletJack: false,
|
|
items: [
|
|
{
|
|
quantity: 2,
|
|
packagingType: "pallets_48x40",
|
|
lengthIn: 48,
|
|
widthIn: 40,
|
|
heightIn: 50,
|
|
totalWeightLb: 500,
|
|
freightClass: "100",
|
|
description: "papers",
|
|
stackable: true,
|
|
turnable: false,
|
|
},
|
|
{
|
|
quantity: 1,
|
|
packagingType: "boxes",
|
|
lengthIn: 20,
|
|
widthIn: 20,
|
|
heightIn: 20,
|
|
totalWeightLb: 100,
|
|
freightClass: "70",
|
|
description: "parts",
|
|
stackable: false,
|
|
turnable: false,
|
|
},
|
|
],
|
|
additionalServices: ["blind_shipment"],
|
|
vehicleTypes: ["box_truck", "dry_van"],
|
|
pickupService: "standard_fcfs",
|
|
deliveryService: "standard_fcfs",
|
|
callBeforePickup: false,
|
|
callBeforeDelivery: false,
|
|
additionalInsurance: false,
|
|
};
|
|
const mapped = mapFlockLoggedInToApiInput(payload);
|
|
expect(mapped.pickup_date).toBe("07/16/2026");
|
|
expect(mapped.pickup_zip).toBe("60611");
|
|
expect(mapped.delivery_zip).toBe("78701");
|
|
expect(mapped.pallet_count).toBe(3);
|
|
expect(mapped.total_weight).toEqual({ value: 600, unit: "lb" });
|
|
expect(mapped.dimensions).toEqual({
|
|
length: 48,
|
|
width: 40,
|
|
height: 50,
|
|
unit: "in",
|
|
});
|
|
expect(mapped.form_mode).toBe("logged_in_quick");
|
|
expect(mapped.packaging_type).toBe("pallets_48x40");
|
|
expect(mapped.freight_class).toBe("100");
|
|
expect(mapped.description).toBe("papers");
|
|
expect(mapped.stackable).toBe(true);
|
|
expect(mapped.additional_services).toEqual(["blind_shipment"]);
|
|
expect(mapped.vehicle_types).toEqual(["box_truck", "dry_van"]);
|
|
expect(mapped.delivery_liftgate).toBe(true);
|
|
expect(mapped.pickup_liftgate).toBe(false);
|
|
});
|
|
});
|