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.
chajia/__tests__/components/flock-logged-in-quote-form....

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);
});
});