Files
rose-ash/lib/commerce/tests/refund.sx
giles e66fbfc540
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
commerce: refund lifecycle as a flow-on-sx flow (20 tests) — Phase 5 backlog complete
refund.sx — refund as a second flow-on-sx flow (request -> approve -> settle)
with two suspension points (approval = human/policy decision, settle =
provider). refund-begin! records :refund-requested and suspends at approval;
refund-approve! advances to settle; refund-settle! records :refunded
(idempotent) and completes; refund-reject! records :refund-rejected and cancels.
Only :refunded moves the books. Reuses order.sx flow helpers. Completes the
Phase 5 backlog. Total 278/278 across 17 suites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:01:16 +00:00

79 lines
2.7 KiB
Plaintext

;; lib/commerce/tests/refund.sx — refund lifecycle as a flow-on-sx flow.
;; Uses (commerce-test name got expected) provided by conformance.sh.
;; Builds the (expensive) flow env once; all assertions share it.
(define env (refund-make-env))
(define b (persist/mem-backend))
(define q1 {:codes (list) :subtotal 1000 :discount 0 :total 1200 :tax 200})
;; a paid, fulfilled order to refund (set up directly via the ledger)
(define _c (order-create b "O1" 1 q1))
(define _p (order-pay b "O1" "pay-1" 2 1200))
(commerce-test "setup-recon-ok" (order-recon b "O1") :ok)
;; --- happy path: request -> approve -> settle ---
(define rid (refund-begin! env b "O1" "rf-1" 10 500))
(commerce-test "begin-waiting-approve" (order-flow-waiting env rid) "approve")
(commerce-test
"begin-not-yet-refunded"
(order-refunded-amount-of (order-events b "O1"))
0)
(commerce-test "begin-recon-unchanged" (order-recon b "O1") :ok)
(define a1 (refund-approve! env rid))
(commerce-test "approve-result" a1 :approved)
(commerce-test "approve-waiting-settle" (order-flow-waiting env rid) "settle")
(define s1 (refund-settle! env b rid "O1" "rf-1" 11 500))
(commerce-test "settle-result" s1 :settled)
(commerce-test "settle-flow-done" (order-flow-status env rid) "done")
(commerce-test
"settle-refunded-amount"
(order-refunded-amount-of (order-events b "O1"))
500)
;; net 1200 - 500 = 700 < total 1200 -> underpaid (partial refund)
(commerce-test "settle-recon-underpaid" (order-recon b "O1") :underpaid)
;; --- idempotent settle: replayed provider callback is a no-op ---
(define s1b (refund-settle! env b rid "O1" "rf-1" 11 500))
(commerce-test "replay-already-settled" s1b :already-settled)
(commerce-test
"replay-refunded-once"
(order-refunded-amount-of (order-events b "O1"))
500)
;; --- reject path: approval denied, books untouched ---
(define _c2 (order-create b "O2" 1 q1))
(define _p2 (order-pay b "O2" "pay-2" 2 1200))
(define rid2 (refund-begin! env b "O2" "rf-2" 20 1200))
(commerce-test
"reject-waiting-approve"
(order-flow-waiting env rid2)
"approve")
(define j2 (refund-reject! env b "O2" rid2 21 "policy"))
(commerce-test "reject-result" j2 :rejected)
(commerce-test "reject-flow-not-waiting" (order-flow-waiting env rid2) nil)
(commerce-test
"reject-no-refund"
(order-refunded-amount-of (order-events b "O2"))
0)
(commerce-test "reject-recon-ok" (order-recon b "O2") :ok)
;; settling a rejected/cancelled refund does nothing
(define s2 (refund-settle! env b rid2 "O2" "rf-2" 22 1200))
(commerce-test "reject-then-settle-noop" s2 :already-settled)
(commerce-test
"reject-still-no-refund"
(order-refunded-amount-of (order-events b "O2"))
0)
;; --- distinct flow ids ---
(commerce-test "distinct-refund-ids" (not (= rid rid2)) true)