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 <help@stably.ai>
This commit is contained in:
SJCoetz 2026-08-03 16:08:03 +02:00
parent 88678cea49
commit a5567f41cf

View file

@ -7,26 +7,28 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
const items = new Map<string, Record<string, unknown>>();
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<string, unknown>) {
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" }));
});
});