Academy v4: 3 research-backed lessons (30 slides + audio); new bean logo; custom plan/lot names
Test and deploy / test-and-deploy (push) Successful in 59s

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Shane Maynard
2026-08-09 14:30:42 -04:00
co-authored by Claude Fable 5
parent ec078116b4
commit 8b80c3fa6f
65 changed files with 1315 additions and 78 deletions
+55
View File
@@ -134,6 +134,61 @@ test("inventory: consume decrements remaining, allows negative, is idempotent pe
assert.equal(withLog.body.log[1].planTitle, "Test coffee");
});
test("inventory: custom name is created, updated, listed, and falls back cleanly when unset", async () => {
const { app } = await setup();
const agent = request.agent(app);
const { csrf } = await signup(agent, "[email protected]");
// No name given: defaults to "" so the client's `lot.name || lot.origin` fallback applies.
const unnamed = await agent
.post("/api/inventory")
.set("x-csrf-token", csrf)
.send({ origin: "Huila, Colombia", initialWeightG: 500 });
assert.equal(unnamed.status, 201);
assert.equal(unnamed.body.lot.name, "");
assert.equal(unnamed.body.lot.origin, "Huila, Colombia");
// Named on create.
const named = await agent
.post("/api/inventory")
.set("x-csrf-token", csrf)
.send({ origin: "Yirgacheffe", name: " Spring Ethiopia ", initialWeightG: 300 });
assert.equal(named.status, 201);
assert.equal(named.body.lot.name, "Spring Ethiopia", "name is trimmed");
// Name is returned in both the list and the detail endpoints.
const list = await agent.get("/api/inventory");
const listedNamed = list.body.lots.find((l) => l.id === named.body.lot.id);
assert.equal(listedNamed.name, "Spring Ethiopia");
const listedUnnamed = list.body.lots.find((l) => l.id === unnamed.body.lot.id);
assert.equal(listedUnnamed.name, "");
const detail = await agent.get(`/api/inventory/${named.body.lot.id}`);
assert.equal(detail.body.lot.name, "Spring Ethiopia");
// Rename via PUT; other fields are left untouched (partial-update pattern).
const renamed = await agent
.put(`/api/inventory/${unnamed.body.lot.id}`)
.set("x-csrf-token", csrf)
.send({ name: "Reserve lot" });
assert.equal(renamed.status, 200);
assert.equal(renamed.body.lot.name, "Reserve lot");
assert.equal(renamed.body.lot.origin, "Huila, Colombia");
// A PUT that omits `name` leaves the existing name unchanged.
const untouched = await agent
.put(`/api/inventory/${unnamed.body.lot.id}`)
.set("x-csrf-token", csrf)
.send({ notes: "recheck moisture" });
assert.equal(untouched.body.lot.name, "Reserve lot");
// Clearing the name back out is honored explicitly.
const cleared = await agent
.put(`/api/inventory/${unnamed.body.lot.id}`)
.set("x-csrf-token", csrf)
.send({ name: "" });
assert.equal(cleared.body.lot.name, "");
});
test("inventory: consuming against another user's plan is refused", async () => {
const { app } = await setup();
const owner = request.agent(app);