From 4027aa1e4489c24852d2d0e964a019792082394e Mon Sep 17 00:00:00 2001 From: PJ Date: Sat, 15 Aug 2026 23:02:37 +0530 Subject: [PATCH] test(folio): pin that a commit stays in the window until Home reads it The interaction that keeps a stale Home card list from ever banking counts the budget has already forgotten: a submit lands on the ledger, so the reading that resets the window is a whole action later and the submit is still in it. Characterization, not a regression: no code changed and it cannot go red first. --- .../test/folio-home-card-readings.test.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pkg/spec/test/folio-home-card-readings.test.ts b/pkg/spec/test/folio-home-card-readings.test.ts index c76babe..876ab67 100644 --- a/pkg/spec/test/folio-home-card-readings.test.ts +++ b/pkg/spec/test/folio-home-card-readings.test.ts @@ -107,6 +107,7 @@ function run(steps: { route: string | null; cards: CardReading[]; lastAction: un const idle = { kind: "Tap", on: "testTag:AccountCard" }; const doubleSubmit = { kind: "DoubleTap", on: "testTag:AddTransactionScreen > testTag:TxnSubmit" }; +const submit = { kind: "Tap", on: "testTag:AddTransactionScreen > testTag:TxnSubmit" }; test("an un-laid-out Home no longer kills the counting invariant", () => { const trace = run([ @@ -157,3 +158,45 @@ test("an un-laid-out Home does not close the counting window", () => { true, ); }); + +// What keeps a healthy submit from ever arriving as a rise nobody paid for. The +// reading banked here also resets the submit window, so a Home card list drawn +// before the store caught up with a commit would bank stale counts, start the +// next window empty, and leave the rise turning up with no budget to cover it. +// The app cannot put that frame in front of the spec: submit() pops one entry, +// so a commit lands back on the ledger it came from and the first Home reading +// is a whole action later, with the submit still in the window when the rise +// does show up. +test("a submit landing on the ledger is still in the window when Home reads it", () => { + const trace = run([ + { route: "home", cards: [card("Checking", 0, "3")], lastAction: idle }, + { route: "ledger", cards: [], lastAction: submit }, + { route: "home", cards: [card("Checking", 5000, "4")], lastAction: idle }, + ]); + assert.equal(trace[2]?.submits, 1); + assert.equal( + committedTransactionsExceedSubmits({ + countsBefore: trace[1]?.counts ?? null, + countsAfter: trace[2]?.counts ?? null, + submitsInWindow: trace[2]?.submits ?? 0, + }), + false, + ); +}); + +test("and a double submit down that same path still convicts", () => { + const trace = run([ + { route: "home", cards: [card("Checking", 0, "3")], lastAction: idle }, + { route: "ledger", cards: [], lastAction: doubleSubmit }, + { route: "home", cards: [card("Checking", 10000, "5")], lastAction: idle }, + ]); + assert.equal(trace[2]?.submits, 1); + assert.equal( + committedTransactionsExceedSubmits({ + countsBefore: trace[1]?.counts ?? null, + countsAfter: trace[2]?.counts ?? null, + submitsInWindow: trace[2]?.submits ?? 0, + }), + true, + ); +});