From a5567f41cff2b4cbcaf3b8c12888bd023623497b Mon Sep 17 00:00:00 2001 From: SJCoetz Date: Mon, 3 Aug 2026 16:08:03 +0200 Subject: [PATCH] test(stock-items): assert expand: supplier on stocktake calls The mock's getFullList is now a vi.fn so the call args can be inspected. Each test asserts expand: 'supplier' was passed, so a regression that drops the expand (e.g. a copy-paste from the dashboard read) fails fast instead of silently shipping rows without supplier names. Co-authored-by: Orca --- src/lib/server/stock-items-service.test.ts | 44 ++++++++++++---------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/lib/server/stock-items-service.test.ts b/src/lib/server/stock-items-service.test.ts index f198b25..7e2c9c5 100644 --- a/src/lib/server/stock-items-service.test.ts +++ b/src/lib/server/stock-items-service.test.ts @@ -7,26 +7,28 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; const items = new Map>(); +const getFullList = vi.fn(async (opts: { filter?: string; sort?: string; expand?: string } = {}) => { + let rows = Array.from(items.values()); + if (opts.filter?.includes("is_active = true")) { + rows = rows.filter((r) => r.is_active === true); + } + if (opts.sort) { + const dir = opts.sort.startsWith("-") ? -1 : 1; + const key = opts.sort.replace(/^-/, ""); + rows = [...rows].sort((a, b) => { + const av = String(a[key] ?? ""); + const bv = String(b[key] ?? ""); + return dir * av.localeCompare(bv); + }); + } + return rows; +}); + const pb = { - collection: (id: string) => ({ - getFullList: async (opts: { filter?: string; sort?: string; expand?: string } = {}) => { - if (id !== "stock_items") throw new Error(`unexpected collection: ${id}`); - let rows = Array.from(items.values()); - if (opts.filter?.includes("is_active = true")) { - rows = rows.filter((r) => r.is_active === true); - } - if (opts.sort) { - const dir = opts.sort.startsWith("-") ? -1 : 1; - const key = opts.sort.replace(/^-/, ""); - rows = [...rows].sort((a, b) => { - const av = String(a[key] ?? ""); - const bv = String(b[key] ?? ""); - return dir * av.localeCompare(bv); - }); - } - return rows; - }, - }), + collection: (id: string) => { + if (id !== "stock_items") throw new Error(`unexpected collection: ${id}`); + return { getFullList }; + }, }; vi.mock("@/lib/server/pocketbase-admin", () => ({ @@ -41,6 +43,7 @@ function seed(id: string, fields: Record) { beforeEach(() => { items.clear(); + getFullList.mockClear(); }); // --- Tests ------------------------------------------------------------------- @@ -52,12 +55,14 @@ describe("listStockItemsForStocktake", () => { const result = await listStockItemsForStocktake(pb as never); expect(result.map((r) => r.name)).toEqual(["Bracket", "Widget"]); + expect(getFullList).toHaveBeenCalledWith(expect.objectContaining({ expand: "supplier" })); }); it("returns an empty array when there are no active stock items", async () => { seed("si-a", { name: "Widget", sku: "WID-1", location: "A1", unit: "ea", current_qty: 10, is_active: false, supplier: "sup-1" }); const result = await listStockItemsForStocktake(pb as never); expect(result).toEqual([]); + expect(getFullList).toHaveBeenCalledWith(expect.objectContaining({ expand: "supplier" })); }); it("excludes items with is_active = false", async () => { @@ -65,5 +70,6 @@ describe("listStockItemsForStocktake", () => { seed("si-b", { name: "Bracket", sku: "BRK-1", location: "A2", unit: "ea", current_qty: 20, is_active: false, supplier: "sup-1" }); const result = await listStockItemsForStocktake(pb as never); expect(result.map((r) => r.name)).toEqual(["Widget"]); + expect(getFullList).toHaveBeenCalledWith(expect.objectContaining({ expand: "supplier" })); }); });