@7365admin1/module-hygiene 4.28.2-staging.10 → 4.29.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@7365admin1/module-hygiene",
3
3
  "license": "MIT",
4
- "version": "4.28.2-staging.10",
4
+ "version": "4.29.0",
5
5
  "author": "7365admin1",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -4,6 +4,7 @@ import test from "node:test";
4
4
  import {
5
5
  CHECKOUT_DECIDABLE_STATUS,
6
6
  CHECKOUT_DECISIONS,
7
+ applyCheckOutDecision,
7
8
  buildCheckOutDecision,
8
9
  isCheckOutDecision,
9
10
  } from "./.build/hygiene-checkout-decision.util.mjs";
@@ -62,3 +63,106 @@ test("the decision vocabulary is exactly the two the client calls", () => {
62
63
  assert.equal(isCheckOutDecision("reject"), false);
63
64
  assert.equal(isCheckOutDecision(""), false);
64
65
  });
66
+
67
+ /*
68
+ Returning the drawn-down quantity to stock on a disapproval.
69
+
70
+ A fake stands in for the repository update. It behaves the way the real one
71
+ does: the row is decided once, and every later attempt matches nothing —
72
+ which the repository turns into a 404. These tests exist so that a refused
73
+ decision can never reach the stock call, because a second credit or a second
74
+ deduction is money the client cannot see going wrong.
75
+ */
76
+
77
+ function fakeRow() {
78
+ let pending = true;
79
+ const credits = [];
80
+
81
+ return {
82
+ credits,
83
+ // Mirrors `{ _id, status: "pending" }`: decides once, then matches nothing.
84
+ decide: async () => {
85
+ if (!pending) {
86
+ throw new Error(
87
+ "Check out item not found or is no longer pending approval.",
88
+ );
89
+ }
90
+ pending = false;
91
+ return 1;
92
+ },
93
+ returnStock: async () => {
94
+ credits.push(1);
95
+ },
96
+ };
97
+ }
98
+
99
+ test("a disapproval returns the quantity to stock exactly once", async () => {
100
+ const row = fakeRow();
101
+
102
+ assert.equal(
103
+ await applyCheckOutDecision("disapprove", row.decide, row.returnStock),
104
+ 1,
105
+ );
106
+ assert.deepEqual(row.credits, [1]);
107
+ });
108
+
109
+ test("an approval moves no stock", async () => {
110
+ const row = fakeRow();
111
+
112
+ await applyCheckOutDecision("approve", row.decide, row.returnStock);
113
+
114
+ assert.deepEqual(row.credits, []);
115
+ });
116
+
117
+ test("disapproving twice does not credit stock twice", async () => {
118
+ const row = fakeRow();
119
+
120
+ await applyCheckOutDecision("disapprove", row.decide, row.returnStock);
121
+
122
+ await assert.rejects(
123
+ () => applyCheckOutDecision("disapprove", row.decide, row.returnStock),
124
+ /no longer pending/,
125
+ );
126
+
127
+ assert.deepEqual(row.credits, [1]);
128
+ });
129
+
130
+ test("approving after a disapproval is refused, so nothing is deducted again", async () => {
131
+ const row = fakeRow();
132
+
133
+ await applyCheckOutDecision("disapprove", row.decide, row.returnStock);
134
+
135
+ await assert.rejects(
136
+ () => applyCheckOutDecision("approve", row.decide, row.returnStock),
137
+ /no longer pending/,
138
+ );
139
+
140
+ assert.deepEqual(row.credits, [1]);
141
+ });
142
+
143
+ test("a decision that matched no row never reaches the stock call", async () => {
144
+ const credits = [];
145
+
146
+ const decided = await applyCheckOutDecision(
147
+ "disapprove",
148
+ async () => 0,
149
+ async () => credits.push(1),
150
+ );
151
+
152
+ assert.equal(decided, 0);
153
+ assert.deepEqual(credits, []);
154
+ });
155
+
156
+ test("a failed stock return propagates, so the caller can abort the transaction", async () => {
157
+ await assert.rejects(
158
+ () =>
159
+ applyCheckOutDecision(
160
+ "disapprove",
161
+ async () => 1,
162
+ async () => {
163
+ throw new Error("Supply not found.");
164
+ },
165
+ ),
166
+ /Supply not found/,
167
+ );
168
+ });
@@ -1,5 +0,0 @@
1
- ---
2
- "@7365admin1/module-hygiene": minor
3
- ---
4
-
5
- Add approve / disapprove to hygiene check out items (repository, controller and decision util).