Skip to content

test(web): pin Stock write-off's clearKey-before-refresh ordering (#703 PR 3 residual) #708

Closed

Description

@mforce

Found while reviewing #706 (#703 PR 3). Test-only; the shipped code is correct.

Gap. StockPage.onWriteOff rotates the write-off's idempotency key immediately after the write (clearKey("write-off")), BEFORE the optimistic row patch and refreshAfterWriteOff — the #163 ordering, owner-locked verbatim in PR 3 (19-handoff-pr3.md §0 item 2). Nothing pins the ORDER: refreshAfterWriteOff is wrapped in try { … } catch { setPageError(loadStockFailed) } (StockPage.tsx:443-448), so a mutant that moves clearKey("write-off") to after that try/catch keeps the pre-existing test rotates the key once the write succeeds, even if the refresh after it fails (StockPage.test.tsx:454) green — the refresh failure is swallowed, the key still rotates, just later. The mutant is only observable when a SECOND write-off is submitted while the first's refresh is still pending (the reopened dialog's keyFor would return the spent key).

Inventory and Expenses carry the equivalent ordering test from PR 3 (still refreshes the list and rotates the key when an abandoned create succeeds; the Expenses ApiError-spends-the-key test); Stock does not.

Fix. One test in web/src/routes/StockPage.test.tsx: hold the post-write refresh (getStock deferred), submit a write-off, dismiss, reopen the same lot, submit a second write-off while the first refresh is still pending → the second call's key differs from the first. Then run the mutant (move clearKey("write-off") below the refreshAfterWriteOff try/catch) and confirm the new test goes RED; restore; green.

Scope. Test only. No product change. Not part of #703 PR 4 (Users) by owner decision 2026-09-07.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions