import { describe, test, expect } from "vitest"; import { resolveShippingCostCents, getNextShippingTier, FALLBACK_SHIPPING_CENTS } from "./shipping-calc"; const tiers = [ { minQuantity: 0, maxQuantity: 3, priceCents: 700 }, { minQuantity: 4, maxQuantity: 9, priceCents: 850 }, { minQuantity: 10, maxQuantity: null, priceCents: 1100 }, ]; describe("resolveShippingCostCents", () => { test("returns 0 when the cart is empty", () => { expect(resolveShippingCostCents(tiers, 0)).toBe(0); }); test("falls back to a fixed price when no tiers are configured", () => { expect(resolveShippingCostCents([], 5)).toBe(FALLBACK_SHIPPING_CENTS); }); test("picks the lowest tier for a small quantity", () => { expect(resolveShippingCostCents(tiers, 2)).toBe(700); }); test("picks the middle tier at its lower boundary", () => { expect(resolveShippingCostCents(tiers, 4)).toBe(850); }); test("picks the middle tier at its upper boundary", () => { expect(resolveShippingCostCents(tiers, 9)).toBe(850); }); test("applies the open-ended top tier for large quantities", () => { expect(resolveShippingCostCents(tiers, 500)).toBe(1100); }); test("uses the topmost tier when the quantity exceeds every defined tier", () => { const closedTiers = [{ minQuantity: 0, maxQuantity: 3, priceCents: 700 }]; expect(resolveShippingCostCents(closedTiers, 50)).toBe(700); }); test("is unaffected by tier input order", () => { const shuffled = [...tiers].reverse(); expect(resolveShippingCostCents(shuffled, 4)).toBe(850); }); }); describe("getNextShippingTier", () => { test("returns null for an empty cart", () => { expect(getNextShippingTier(tiers, 0)).toBeNull(); }); test("returns null when no tiers are configured", () => { expect(getNextShippingTier([], 2)).toBeNull(); }); test("returns null when already in the topmost open-ended tier", () => { expect(getNextShippingTier(tiers, 15)).toBeNull(); }); test("reports units and price of the next tier", () => { expect(getNextShippingTier(tiers, 2)).toEqual({ unitsUntilNext: 2, priceCents: 850 }); }); test("reports 1 unit remaining right below a boundary", () => { expect(getNextShippingTier(tiers, 3)).toEqual({ unitsUntilNext: 1, priceCents: 850 }); }); test("is unaffected by tier input order", () => { const shuffled = [...tiers].reverse(); expect(getNextShippingTier(shuffled, 9)).toEqual({ unitsUntilNext: 1, priceCents: 1100 }); }); });