Closes the two IMPORTANT test-coverage gaps from the final implementation review. Pure additions; no production code changes. - Spec test #3: submitQuote({partial:true}) accepts zero-priced items when is_no_quote=true (status flips to partial_approval_pending) - Spec test #5: strengthen the no-supplier + no-quote assertion to check the missing array directly, not just the failure.code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
87eacdc307
commit
e0d214c94f
1 changed files with 47 additions and 0 deletions
|
|
@ -1255,6 +1255,18 @@ describe("diagnosePdfReadiness with is_no_quote", () => {
|
|||
expect(result.failure?.details?.issues?.[0]?.missing).toContain(
|
||||
"no supplier"
|
||||
);
|
||||
// Stronger assertion (spec test case #5): confirm the `details.issues`
|
||||
// array directly contains an object whose `missing` list includes
|
||||
// "no supplier". Guards against future refactors that drop the
|
||||
// missing-array shape (e.g. moving the supplier check out of the
|
||||
// per-issue structure).
|
||||
expect(result.failure?.details?.issues).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
missing: expect.arrayContaining(["no supplier"]),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
// And the pricing/processed checks must NOT appear in the missing list
|
||||
// (since the operator marked this as a decline).
|
||||
const missing = result.failure?.details?.issues?.[0]?.missing ?? [];
|
||||
|
|
@ -1909,6 +1921,41 @@ describe("submitQuote with is_no_quote", () => {
|
|||
expect(stored.status).toBe("approval_pending");
|
||||
});
|
||||
|
||||
it("flips a new no-quote quote to partial_approval_pending when partial:true even with zero-priced items", async () => {
|
||||
// Spec test case #3: `submitQuote` accepts zero-priced items when
|
||||
// `is_no_quote` true AND `partial: true`. Mirrors the previous test
|
||||
// (spec #1) but flips on the partial flag and asserts the
|
||||
// `partial_approval_pending` target status — not the full-approval
|
||||
// path.
|
||||
await pbMock.collection("quotes").create({
|
||||
id: "q-test",
|
||||
quote_number: "Q-2026-08-004",
|
||||
status: "new",
|
||||
is_no_quote: true,
|
||||
});
|
||||
await pbMock.collection("quote_items").create({
|
||||
id: "qi-zero",
|
||||
quote: "q-test",
|
||||
description: "M16 bolt",
|
||||
selling_price: 0,
|
||||
});
|
||||
await pbMock.collection("quote_items").create({
|
||||
id: "qi-priced",
|
||||
quote: "q-test",
|
||||
description: "Hex nut",
|
||||
selling_price: 100,
|
||||
});
|
||||
|
||||
const result = await submitQuote("q-test", undefined, { partial: true });
|
||||
expect(result.statusChanged).toBe(true);
|
||||
expect(result.quote.status).toBe("partial_approval_pending");
|
||||
expect(result.targetStatus).toBe("partial_approval_pending");
|
||||
|
||||
// PB row updated in place.
|
||||
const stored = await pbMock.collection("quotes").getOne("q-test");
|
||||
expect(stored.status).toBe("partial_approval_pending");
|
||||
});
|
||||
|
||||
it("still throws unpriced_items for a regular (non-no-quote) quote with zero-priced items", async () => {
|
||||
await pbMock.collection("quotes").create({
|
||||
id: "q-test",
|
||||
|
|
|
|||
Loading…
Reference in a new issue