test(collection-map): pin-bucket split; absorb orphaned assigned items into pool
This commit is contained in:
parent
d4c72057bf
commit
adfde8a0fa
2 changed files with 68 additions and 1 deletions
64
src/app/(app)/collection-map/page.test.ts
Normal file
64
src/app/(app)/collection-map/page.test.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { splitSupplierBucket } from "./pin-model";
|
||||
|
||||
describe("splitSupplierBucket", () => {
|
||||
it("returns empty buckets for empty input", () => {
|
||||
const { assignedByDriver, poolItems } = splitSupplierBucket([]);
|
||||
expect(assignedByDriver.size).toBe(0);
|
||||
expect(poolItems).toEqual([]);
|
||||
});
|
||||
|
||||
it("groups assigned items by driver", () => {
|
||||
const items = [
|
||||
{ id: "a", item_status: "assigned" as const, drv_id: "u-1", ready_for_collection: true },
|
||||
{ id: "b", item_status: "assigned" as const, drv_id: "u-1", ready_for_collection: true },
|
||||
{ id: "c", item_status: "assigned" as const, drv_id: "u-2", ready_for_collection: false },
|
||||
];
|
||||
const { assignedByDriver, poolItems } = splitSupplierBucket(items);
|
||||
expect(assignedByDriver.size).toBe(2);
|
||||
expect(assignedByDriver.get("u-1")?.items.map((i) => i.id)).toEqual(["a", "b"]);
|
||||
expect(assignedByDriver.get("u-2")?.items.map((i) => i.id)).toEqual(["c"]);
|
||||
expect(poolItems).toEqual([]);
|
||||
});
|
||||
|
||||
it("places collection_pool items into the unassigned bucket", () => {
|
||||
const items = [
|
||||
{ id: "a", item_status: "assigned" as const, drv_id: "u-1", ready_for_collection: true },
|
||||
{ id: "p1", item_status: "collection_pool" as const, ready_for_collection: true },
|
||||
{ id: "p2", item_status: "collection_pool" as const, ready_for_collection: false },
|
||||
];
|
||||
const { assignedByDriver, poolItems } = splitSupplierBucket(items);
|
||||
expect(assignedByDriver.size).toBe(1);
|
||||
expect(poolItems.map((i) => i.id)).toEqual(["p1", "p2"]);
|
||||
});
|
||||
|
||||
it("treats 'collected' items as routed (same bucket as assigned)", () => {
|
||||
const items = [
|
||||
{ id: "a", item_status: "collected" as const, drv_id: "u-1", ready_for_collection: true },
|
||||
];
|
||||
const { assignedByDriver, poolItems } = splitSupplierBucket(items);
|
||||
expect(assignedByDriver.size).toBe(1);
|
||||
expect(assignedByDriver.get("u-1")?.items.map((i) => i.id)).toEqual(["a"]);
|
||||
expect(poolItems).toEqual([]);
|
||||
});
|
||||
|
||||
it("ignores assigned items without a drv_id", () => {
|
||||
// Defensive: data shouldn't reach this state, but if it does, the
|
||||
// unassigned bucket absorbs the item so it doesn't silently vanish.
|
||||
const items = [
|
||||
{ id: "orphan", item_status: "assigned" as const, ready_for_collection: true },
|
||||
];
|
||||
const { assignedByDriver, poolItems } = splitSupplierBucket(items);
|
||||
expect(assignedByDriver.size).toBe(0);
|
||||
expect(poolItems.map((i) => i.id)).toEqual(["orphan"]);
|
||||
});
|
||||
|
||||
it("reports readyAll=false when any item in a driver's bucket is not ready", () => {
|
||||
const items = [
|
||||
{ id: "a", item_status: "assigned" as const, drv_id: "u-1", ready_for_collection: true },
|
||||
{ id: "b", item_status: "assigned" as const, drv_id: "u-1", ready_for_collection: false },
|
||||
];
|
||||
const { assignedByDriver } = splitSupplierBucket(items);
|
||||
expect(assignedByDriver.get("u-1")?.readyAll).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -39,7 +39,10 @@ export function splitSupplierBucket<
|
|||
entry.items.push(it);
|
||||
if (!it.ready_for_collection) entry.readyAll = false;
|
||||
assignedByDriver.set(it.drv_id, entry);
|
||||
} else if (it.item_status === "collection_pool") {
|
||||
} else {
|
||||
// Anything that isn't routed-to-a-driver (no `drv_id`; or
|
||||
// `collection_pool`; or an unexpected status) goes into the pool
|
||||
// bucket so it never silently vanishes from the map.
|
||||
poolItems.push(it);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue