@flowselections/logistiek-engine 1.0.108 → 1.0.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/FlowOrders.js +1 -1
- package/dist-lib/components/MisluktVerzendbrievenCard.js +1 -1
- package/dist-lib/hooks/useAfrondWachtrij.js +1 -1
- package/dist-lib/hooks/useBeladingsafwijkingen.js +1 -1
- package/dist-lib/hooks/useGeblokkeerdeOrders.js +1 -1
- package/dist-lib/hooks/useLogisticsTrace.js +1 -1
- package/dist-lib/hooks/useMinuutronde.js +1 -1
- package/dist-lib/hooks/useOrderTrace.js +1 -1
- package/dist-lib/hooks/useOrderVersies.js +1 -1
- package/dist-lib/hooks/usePlanWachtrij.js +1 -1
- package/dist-lib/hooks/useRecalcJob.js +1 -1
- package/dist-lib/hooks/useTaakGezondheid.js +1 -1
- package/dist-lib/hooks/useWerktijden.js +1 -1
- package/dist-lib/hooks/useWerkwijzeStatus.js +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/lib/attachAuthToken.js +1 -1
- package/dist-lib/lib/cartCoverage.functions.d.ts +1 -1
- package/dist-lib/lib/cartCoverage.functions.js +3 -3
- package/dist-lib/lib/floridayDocuments.functions.d.ts +3 -3
- package/dist-lib/lib/floridayDocuments.functions.js +5 -5
- package/dist-lib/lib/floridayPush.functions.d.ts +1 -1
- package/dist-lib/lib/floridayPush.functions.js +3 -3
- package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +5 -5
- package/dist-lib/lib/loadCarrierPlanning.functions.js +7 -7
- package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +2 -2
- package/dist-lib/lib/logisticsRecalcJob.functions.js +4 -4
- package/dist-lib/lib/logisticsRecalculate.functions.d.ts +1 -1
- package/dist-lib/lib/logisticsRecalculate.functions.js +2 -2
- package/dist-lib/lib/moduleVersion.d.ts +1 -1
- package/dist-lib/lib/moduleVersion.js +1 -1
- package/dist-lib/lib/plannerDiff.functions.d.ts +1 -1
- package/dist-lib/lib/plannerDiff.functions.js +3 -3
- package/package.json +1 -1
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +0 -2
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +0 -1
- package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +0 -41
- package/dist-lib/hooks/useShippingNoteStatus.test.d.ts +0 -2
- package/dist-lib/hooks/useShippingNoteStatus.test.d.ts.map +0 -1
- package/dist-lib/hooks/useShippingNoteStatus.test.js +0 -20
- package/dist-lib/integrations/supabase/client.d.ts +0 -20293
- package/dist-lib/integrations/supabase/client.d.ts.map +0 -1
- package/dist-lib/integrations/supabase/client.js +0 -13
- package/dist-lib/lib/bufferDecision.test.d.ts +0 -2
- package/dist-lib/lib/bufferDecision.test.d.ts.map +0 -1
- package/dist-lib/lib/bufferDecision.test.js +0 -104
- package/dist-lib/lib/expandGroups.test.d.ts +0 -2
- package/dist-lib/lib/expandGroups.test.d.ts.map +0 -1
- package/dist-lib/lib/expandGroups.test.js +0 -80
- package/dist-lib/lib/floridayCancellation.test.d.ts +0 -2
- package/dist-lib/lib/floridayCancellation.test.d.ts.map +0 -1
- package/dist-lib/lib/floridayCancellation.test.js +0 -42
- package/dist-lib/lib/floridayCartCarriers.test.d.ts +0 -2
- package/dist-lib/lib/floridayCartCarriers.test.d.ts.map +0 -1
- package/dist-lib/lib/floridayCartCarriers.test.js +0 -66
- package/dist-lib/lib/handlers/logistics-tick.test.d.ts +0 -2
- package/dist-lib/lib/handlers/logistics-tick.test.d.ts.map +0 -1
- package/dist-lib/lib/handlers/logistics-tick.test.js +0 -70
- package/dist-lib/lib/layerUtilization.test.d.ts +0 -2
- package/dist-lib/lib/layerUtilization.test.d.ts.map +0 -1
- package/dist-lib/lib/layerUtilization.test.js +0 -11
- package/dist-lib/lib/layoutPrint.test.d.ts +0 -2
- package/dist-lib/lib/layoutPrint.test.d.ts.map +0 -1
- package/dist-lib/lib/layoutPrint.test.js +0 -47
- package/dist-lib/lib/plannerDiff.test.d.ts +0 -2
- package/dist-lib/lib/plannerDiff.test.d.ts.map +0 -1
- package/dist-lib/lib/plannerDiff.test.js +0 -41
- package/dist-lib/lib/quarantineFilter.test.d.ts +0 -2
- package/dist-lib/lib/quarantineFilter.test.d.ts.map +0 -1
- package/dist-lib/lib/quarantineFilter.test.js +0 -18
- package/dist-lib/lib/resolveBuffer.test.d.ts +0 -2
- package/dist-lib/lib/resolveBuffer.test.d.ts.map +0 -1
- package/dist-lib/lib/resolveBuffer.test.js +0 -38
- package/dist-lib/lib/taskCounts.test.d.ts +0 -2
- package/dist-lib/lib/taskCounts.test.d.ts.map +0 -1
- package/dist-lib/lib/taskCounts.test.js +0 -12
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
const tickJob = vi.fn(async () => null);
|
|
3
|
-
const runPlanQueue = vi.fn(async () => ({}));
|
|
4
|
-
vi.mock("../logisticsRecalcJob.server.js", () => ({ tickJob }));
|
|
5
|
-
vi.mock("../planQueue.server.js", () => ({ runPlanQueue, prunePlanQueue: vi.fn() }));
|
|
6
|
-
import { handleLogisticsTick, TICK_ROUND_LOCK_KEY } from "./logistics-tick.server";
|
|
7
|
-
const KEY = "test-key";
|
|
8
|
-
function makeClient(acquire) {
|
|
9
|
-
const calls = [];
|
|
10
|
-
const rpc = vi.fn(async (fn, args) => {
|
|
11
|
-
calls.push({ fn, args });
|
|
12
|
-
if (fn === "logistics_plan_lock_acquire")
|
|
13
|
-
return acquire();
|
|
14
|
-
return { data: null, error: null };
|
|
15
|
-
});
|
|
16
|
-
return { client: { rpc }, calls };
|
|
17
|
-
}
|
|
18
|
-
const req = () => new Request("http://x/api/public/hooks/logistics-recalc-tick", {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: { apikey: KEY },
|
|
21
|
-
});
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
process.env["SUPABASE_PUBLISHABLE_KEY"] = KEY;
|
|
24
|
-
tickJob.mockClear();
|
|
25
|
-
runPlanQueue.mockClear();
|
|
26
|
-
});
|
|
27
|
-
describe("tick-rondeslot", () => {
|
|
28
|
-
it("slaat een tweede ronde over als er al een ronde loopt", async () => {
|
|
29
|
-
const { client, calls } = makeClient(async () => ({ data: false, error: null }));
|
|
30
|
-
const res = await handleLogisticsTick(req(), client);
|
|
31
|
-
expect(await res.json()).toMatchObject({ skipped: "ronde_loopt_al" });
|
|
32
|
-
expect(tickJob).not.toHaveBeenCalled();
|
|
33
|
-
expect(runPlanQueue).not.toHaveBeenCalled();
|
|
34
|
-
const fns = calls.map((c) => c.fn);
|
|
35
|
-
expect(fns).not.toContain("logistics_buffer_detach_late_orders");
|
|
36
|
-
expect(fns).not.toContain("logistics_sync_pick_queue");
|
|
37
|
-
expect(fns).not.toContain("logistics_plan_lock_release");
|
|
38
|
-
});
|
|
39
|
-
it("slaat over (fail-closed) als het slot niet kan worden vastgesteld", async () => {
|
|
40
|
-
const { client } = makeClient(async () => ({ data: null, error: { message: "boom" } }));
|
|
41
|
-
const res = await handleLogisticsTick(req(), client);
|
|
42
|
-
expect(await res.json()).toMatchObject({ skipped: "slot_onbekend" });
|
|
43
|
-
expect(tickJob).not.toHaveBeenCalled();
|
|
44
|
-
expect(runPlanQueue).not.toHaveBeenCalled();
|
|
45
|
-
});
|
|
46
|
-
it("draait de ronde met slot en geeft het slot daarna vrij, ook bij een fout", async () => {
|
|
47
|
-
tickJob.mockImplementationOnce(async () => {
|
|
48
|
-
throw new Error("stap faalt");
|
|
49
|
-
});
|
|
50
|
-
const { client, calls } = makeClient(async () => ({ data: true, error: null }));
|
|
51
|
-
await expect(handleLogisticsTick(req(), client)).rejects.toThrow("stap faalt");
|
|
52
|
-
const acq = calls.find((c) => c.fn === "logistics_plan_lock_acquire");
|
|
53
|
-
const rel = calls.find((c) => c.fn === "logistics_plan_lock_release");
|
|
54
|
-
expect(rel).toBeTruthy();
|
|
55
|
-
expect(rel.args._key).toBe(TICK_ROUND_LOCK_KEY);
|
|
56
|
-
expect(rel.args._owner).toBe(acq.args._owner);
|
|
57
|
-
});
|
|
58
|
-
it("voert de planwachtrij uit als het slot is verkregen", async () => {
|
|
59
|
-
const { client } = makeClient(async () => ({ data: true, error: null }));
|
|
60
|
-
await handleLogisticsTick(req(), client);
|
|
61
|
-
expect(runPlanQueue).toHaveBeenCalledTimes(1);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
describe("herkenning in het antwoord", () => {
|
|
65
|
-
it("noemt de Engine, de versie en of het het moduleproject is", async () => {
|
|
66
|
-
const { client } = makeClient(async () => ({ data: false, error: null }));
|
|
67
|
-
const res = await handleLogisticsTick(req(), client, { moduleProject: true });
|
|
68
|
-
expect(await res.json()).toMatchObject({ engine: "logistiek-engine", moduleProject: true });
|
|
69
|
-
});
|
|
70
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"layerUtilization.test.d.ts","sourceRoot":"","sources":["../../src/lib/layerUtilization.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { layerUtilizationPct } from "./layerUtilization";
|
|
3
|
-
describe("layerUtilizationPct", () => {
|
|
4
|
-
it("1 van 5 lagen = 20%", () => expect(layerUtilizationPct(1, 5)).toBe(20));
|
|
5
|
-
it("4 van 5 lagen = 80%", () => expect(layerUtilizationPct(4, 5)).toBe(80));
|
|
6
|
-
it("drager zonder lagen geeft geen cijfer", () => {
|
|
7
|
-
expect(layerUtilizationPct(1, 0)).toBeNull();
|
|
8
|
-
expect(layerUtilizationPct(1, null)).toBeNull();
|
|
9
|
-
expect(layerUtilizationPct(null, 5)).toBeNull();
|
|
10
|
-
});
|
|
11
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"layoutPrint.test.d.ts","sourceRoot":"","sources":["../../src/lib/layoutPrint.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { printViaLayout, foutcode } from "./layoutPrint.server";
|
|
3
|
-
function sbMet(result) {
|
|
4
|
-
const rpc = vi.fn().mockResolvedValue(result);
|
|
5
|
-
const from = vi.fn();
|
|
6
|
-
return { sb: { rpc, from }, rpc, from };
|
|
7
|
-
}
|
|
8
|
-
const basis = {
|
|
9
|
-
documenttype: "afleverbrief",
|
|
10
|
-
documentnaam: "Afleverbrief FO-1",
|
|
11
|
-
pdfBase64: "QUJD",
|
|
12
|
-
printPlekId: "plek-1",
|
|
13
|
-
herkomst: "floriday",
|
|
14
|
-
payload: { order_id: "o1", ordernummer: "FO-1", cart_id: "c1", print_plek_id: "plek-1" },
|
|
15
|
-
idempotentieSleutel: "controle-scan:1",
|
|
16
|
-
};
|
|
17
|
-
describe("printViaLayout", () => {
|
|
18
|
-
it("roept layout_print_document aan met snake_case en sleutel, zonder directe insert", async () => {
|
|
19
|
-
const { sb, rpc, from } = sbMet({ data: [{ job_id: "j1", printer_id: "p1", bestaand: false }], error: null });
|
|
20
|
-
const r = await printViaLayout(sb, basis);
|
|
21
|
-
expect(r).toEqual({ ok: true, jobId: "j1", printerId: "p1", bestaand: false });
|
|
22
|
-
expect(from).not.toHaveBeenCalled();
|
|
23
|
-
const [naam, args] = rpc.mock.calls[0];
|
|
24
|
-
expect(naam).toBe("layout_print_document");
|
|
25
|
-
expect(args._idempotentie_sleutel).toBe("controle-scan:1");
|
|
26
|
-
expect(args._print_plek_id).toBe("plek-1");
|
|
27
|
-
expect(Object.keys(args._payload)).not.toContain("cartId");
|
|
28
|
-
expect(Object.keys(args._payload)).not.toContain("printPlekId");
|
|
29
|
-
});
|
|
30
|
-
it("geeft bij een tweede aanroep dezelfde opdracht terug", async () => {
|
|
31
|
-
const { sb } = sbMet({ data: [{ job_id: "j1", printer_id: "p1", bestaand: true }], error: null });
|
|
32
|
-
const r = await printViaLayout(sb, basis);
|
|
33
|
-
expect(r.ok && r.bestaand && r.jobId === "j1").toBe(true);
|
|
34
|
-
});
|
|
35
|
-
it.each(["GEEN_PRINTER", "GEEN_LAYOUT", "GEEN_EXTERN_DOCUMENT"])("vertaalt %s naar een leesbare fout", async (code) => {
|
|
36
|
-
const { sb } = sbMet({ data: null, error: { message: `${code}: iets ontbreekt` } });
|
|
37
|
-
const r = await printViaLayout(sb, basis);
|
|
38
|
-
expect(r.ok).toBe(false);
|
|
39
|
-
if (!r.ok) {
|
|
40
|
-
expect(r.errorCode).toBe(code);
|
|
41
|
-
expect(r.error).toContain("Opnieuw proberen");
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
it("onbekende fout wordt PRINTFOUT", () => {
|
|
45
|
-
expect(foutcode("netwerk weg")).toBe("PRINTFOUT");
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plannerDiff.test.d.ts","sourceRoot":"","sources":["../../src/lib/plannerDiff.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { compareSnapshots } from "./plannerDiff";
|
|
3
|
-
const kar = (n, items, id = `c${n}`) => ({
|
|
4
|
-
cartId: id,
|
|
5
|
-
cartNumber: n,
|
|
6
|
-
items: items.map(([orderItemId, crates]) => ({ orderItemId, crates })),
|
|
7
|
-
});
|
|
8
|
-
describe("compareSnapshots", () => {
|
|
9
|
-
it("negeert kar-id's en volgorde: zelfde inhoud per positie is identiek", () => {
|
|
10
|
-
const r = compareSnapshots([kar(1, [["a", 10], ["b", 5]]), kar(2, [["c", 3]])], [kar(2, [["c", 3]], "x"), kar(1, [["b", 5], ["a", 10]], "y")]);
|
|
11
|
-
expect(r.identical).toBe(true);
|
|
12
|
-
});
|
|
13
|
-
it("rondt af op hele fusten", () => {
|
|
14
|
-
expect(compareSnapshots([kar(1, [["a", 9.6]])], [kar(1, [["a", 10]])]).identical).toBe(true);
|
|
15
|
-
});
|
|
16
|
-
it("meldt een echt verschil met positie", () => {
|
|
17
|
-
const r = compareSnapshots([kar(1, [["a", 10]])], [kar(1, [["a", 12]])]);
|
|
18
|
-
expect(r.identical).toBe(false);
|
|
19
|
-
expect(r.differences[0]?.cartNumber).toBe(1);
|
|
20
|
-
});
|
|
21
|
-
it("meldt een extra kar", () => {
|
|
22
|
-
const r = compareSnapshots([kar(1, [["a", 10]])], [kar(1, [["a", 10]]), kar(2, [["b", 1]])]);
|
|
23
|
-
expect(r.identical).toBe(false);
|
|
24
|
-
expect(r.cartsAfter).toBe(2);
|
|
25
|
-
});
|
|
26
|
-
it("is fail-closed bij onleesbare invoer: leeg vs leeg is identiek, leeg vs iets niet", () => {
|
|
27
|
-
expect(compareSnapshots(null, undefined).identical).toBe(true);
|
|
28
|
-
expect(compareSnapshots(null, [kar(1, [["a", 1]])]).identical).toBe(false);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
import { summarizeDiffRuns } from "./plannerDiff";
|
|
32
|
-
describe("summarizeDiffRuns", () => {
|
|
33
|
-
it("overgeslagen telt niet als vergeleken of afwijkend", () => {
|
|
34
|
-
const s = summarizeDiffRuns([
|
|
35
|
-
{ buffer_id: "b1", order_ref: "A", status: "overgeslagen", identical: null },
|
|
36
|
-
{ buffer_id: "b2", order_ref: "B", status: "vergeleken", identical: true },
|
|
37
|
-
{ buffer_id: "b3", order_ref: "C", status: "wachtend", identical: null },
|
|
38
|
-
]);
|
|
39
|
-
expect(s).toMatchObject({ totaal: 1, identiek: 1, afwijkend: 0, mislukt: 0, overgeslagen: 1 });
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quarantineFilter.test.d.ts","sourceRoot":"","sources":["../../src/lib/quarantineFilter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
|
-
import { resolve } from "node:path";
|
|
4
|
-
// Bewaakt dat de karindeling bestelregels in quarantaine nooit inleest.
|
|
5
|
-
// Live bewezen op 01-10 (FO-2601354): regel in quarantaine verdween uit karren en pickwachtrij.
|
|
6
|
-
const bron = readFileSync(resolve(__dirname, "loadCarrierPlanning.server.ts"), "utf8");
|
|
7
|
-
describe("karindeling — quarantaine", () => {
|
|
8
|
-
it("elke lezing van order_items filtert op quarantined_at", () => {
|
|
9
|
-
const lezingen = bron.split('.from("order_items")').slice(1);
|
|
10
|
-
expect(lezingen.length).toBeGreaterThan(0);
|
|
11
|
-
for (const stuk of lezingen) {
|
|
12
|
-
expect(stuk.slice(0, 800)).toContain('.is("quarantined_at", null)');
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
it("orders op gedeelde karren negeren regels in quarantaine", () => {
|
|
16
|
-
expect(bron).toContain('.is("order_items.quarantined_at", null)');
|
|
17
|
-
});
|
|
18
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolveBuffer.test.d.ts","sourceRoot":"","sources":["../../src/lib/resolveBuffer.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { resolveBufferForOrderInternal } from "./loadCarrierPlanning.server";
|
|
3
|
-
function fakeClient(initial, afterRpc) {
|
|
4
|
-
const calls = { rpc: 0, writes: 0 };
|
|
5
|
-
let current = initial;
|
|
6
|
-
const client = {
|
|
7
|
-
from(table) {
|
|
8
|
-
return {
|
|
9
|
-
select: () => ({
|
|
10
|
-
eq: () => ({
|
|
11
|
-
maybeSingle: async () => ({ data: table === "orders" ? { id: "o1", buffer_id: current } : null }),
|
|
12
|
-
}),
|
|
13
|
-
}),
|
|
14
|
-
update: () => { calls.writes++; return { eq: async () => ({}) }; },
|
|
15
|
-
insert: () => { calls.writes++; return { select: () => ({ single: async () => ({}) }) }; },
|
|
16
|
-
};
|
|
17
|
-
},
|
|
18
|
-
async rpc() { calls.rpc++; current = afterRpc; return { error: null }; },
|
|
19
|
-
};
|
|
20
|
-
return { client: client, calls };
|
|
21
|
-
}
|
|
22
|
-
describe("resolveBufferForOrderInternal (alleen lezen)", () => {
|
|
23
|
-
it("gebruikt de bestaande buffer zonder iets te schrijven", async () => {
|
|
24
|
-
const { client, calls } = fakeClient("b1", "b2");
|
|
25
|
-
expect(await resolveBufferForOrderInternal(client, "o1")).toBe("b1");
|
|
26
|
-
expect(calls).toEqual({ rpc: 0, writes: 0 });
|
|
27
|
-
});
|
|
28
|
-
it("laat de database beslissen als er nog geen buffer is", async () => {
|
|
29
|
-
const { client, calls } = fakeClient(null, "b9");
|
|
30
|
-
expect(await resolveBufferForOrderInternal(client, "o1")).toBe("b9");
|
|
31
|
-
expect(calls).toEqual({ rpc: 1, writes: 0 });
|
|
32
|
-
});
|
|
33
|
-
it("maakt nooit zelf een buffer als de database er geen geeft", async () => {
|
|
34
|
-
const { client, calls } = fakeClient(null, null);
|
|
35
|
-
expect(await resolveBufferForOrderInternal(client, "o1")).toBeNull();
|
|
36
|
-
expect(calls.writes).toBe(0);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"taskCounts.test.d.ts","sourceRoot":"","sources":["../../src/lib/taskCounts.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { tellOpenTaken } from "./taskCounts";
|
|
3
|
-
describe("tellOpenTaken", () => {
|
|
4
|
-
it("telt per module", () => {
|
|
5
|
-
expect(tellOpenTaken([{ owner_module: "verkoop", open_count: "36" }, { owner_module: "afhandeling", open_count: 136 }]))
|
|
6
|
-
.toEqual({ verkoop: 36, afhandeling: 136 });
|
|
7
|
-
});
|
|
8
|
-
it("onleesbare invoer geeft lege telling", () => {
|
|
9
|
-
expect(tellOpenTaken(null)).toEqual({});
|
|
10
|
-
expect(tellOpenTaken([{ owner_module: "x", open_count: "abc" }, { open_count: 3 }])).toEqual({});
|
|
11
|
-
});
|
|
12
|
-
});
|