import { describe, expect, it } from "vitest"; import { emptyFlockCheckoutDetailsDraft, flockDetailsHasErrors, isPlausibleUsPhone, normalizeUsPhoneDisplay, toFlockCheckoutApiDetails, validateFlockCheckoutDetailsDraft, } from "@/lib/flock/flock-checkout-details-rules"; import { validateFlockCheckoutSelection } from "@/lib/flock/flock-checkout-selection"; describe("flock-checkout-details-rules", () => { it("rejects empty required fields", () => { const errors = validateFlockCheckoutDetailsDraft( emptyFlockCheckoutDetailsDraft(), ); expect(flockDetailsHasErrors(errors)).toBe(true); expect(errors.pickup?.company_name).toBeTruthy(); expect(errors.delivery?.contact_email).toBeTruthy(); expect(errors.delivery?.address1).toBeTruthy(); }); it("rejects 555 and invalid phones", () => { expect(isPlausibleUsPhone("(555) 123-4567")).toBe(false); expect(isPlausibleUsPhone("123")).toBe(false); expect(isPlausibleUsPhone("(626) 595-1180")).toBe(true); }); it("normalizes and accepts a complete draft (billing pickup)", () => { const draft = emptyFlockCheckoutDetailsDraft(); draft.use_billing_for_pickup = true; draft.use_billing_for_delivery = false; draft.pickup = { company_name: "Acme Pickup", address1: "", address2: "", city: "", state: "", zip: "", contact_name: "Alice", contact_phone: "16265951180", contact_email: "a@example.com", opens_at: "9:00 AM", closes_at: "5:00 PM", }; draft.delivery = { company_name: "Acme Delivery", address1: "233 S Wacker Dr", address2: "Dock 1", city: "Chicago", state: "IL", zip: "60601", contact_name: "Bob", contact_phone: "(415) 621-8840", contact_email: "b@example.com", opens_at: "9:00 AM", closes_at: "5:00 PM", weekend_delivery: false, }; draft.nmfc = "100240-01"; draft.po_number = "PO-1"; draft.bol_remarks = "fragile"; draft.declaration_statement = "call on arrival"; draft.notes = "gate code 1"; const errors = validateFlockCheckoutDetailsDraft(draft); expect(flockDetailsHasErrors(errors)).toBe(false); const api = toFlockCheckoutApiDetails(draft); expect(api.role).toBe("shipper"); expect(api.use_billing_for_pickup).toBe(true); expect(api.use_billing_for_delivery).toBe(false); expect(api.pickup.contact_phone).toBe( normalizeUsPhoneDisplay("16265951180"), ); expect(api.po_number).toBe("PO-1"); expect(api.declaration_statement).toBe("call on arrival"); expect(api.notes).toBe("gate code 1"); expect(api.delivery.weekend_delivery).toBe(false); }); it("skips delivery address when use_billing_for_delivery", () => { const draft = emptyFlockCheckoutDetailsDraft(); draft.use_billing_for_pickup = true; draft.use_billing_for_delivery = true; draft.pickup = { company_name: "A", address1: "", address2: "", city: "", state: "", zip: "", contact_name: "A", contact_phone: "(626) 595-1180", contact_email: "a@example.com", opens_at: "9:00 AM", closes_at: "5:00 PM", }; draft.delivery = { company_name: "B", address1: "", address2: "", city: "", state: "", zip: "", contact_name: "B", contact_phone: "(415) 621-8840", contact_email: "b@example.com", opens_at: "9:00 AM", closes_at: "5:00 PM", }; const errors = validateFlockCheckoutDetailsDraft(draft); expect(errors.delivery?.address1).toBeUndefined(); expect(flockDetailsHasErrors(errors)).toBe(false); }); it("rejects same open/close hours", () => { const draft = emptyFlockCheckoutDetailsDraft(); draft.use_billing_for_pickup = true; draft.pickup = { company_name: "A", address1: "", address2: "", city: "", state: "", zip: "", contact_name: "A", contact_phone: "(626) 595-1180", contact_email: "a@example.com", opens_at: "9:00 AM", closes_at: "9:00 AM", }; draft.delivery = { company_name: "B", address1: "1 Main", address2: "", city: "Dallas", state: "TX", zip: "75201", contact_name: "B", contact_phone: "(415) 621-8840", contact_email: "b@example.com", opens_at: "9:00 AM", closes_at: "5:00 PM", }; const errors = validateFlockCheckoutDetailsDraft(draft); expect(errors.pickup?.closes_at).toMatch(/晚于/); }); }); describe("flock sidebar tier selection", () => { it("requires preferred_tier and flexibility before checkout", () => { expect( validateFlockCheckoutSelection({ preferredTier: "flock_direct", preferredFlexibility: "2_day", }), ).toBeNull(); expect( validateFlockCheckoutSelection({ preferredTier: "standard", preferredFlexibility: "1_day", }), ).toBeNull(); expect( validateFlockCheckoutSelection({ preferredTier: "other" as "standard", preferredFlexibility: "none", }), ).toBeTruthy(); expect( validateFlockCheckoutSelection({ preferredTier: "standard" }), ).toMatch(/灵活性/); }); });