;; lib/events/tests/ticket.sx — paid-ticket contract + settlement orchestration. (define ev-tk-pass 0) (define ev-tk-fail 0) (define ev-tk-failures (list)) (define ev-tk-check! (fn (name got expected) (if (= got expected) (set! ev-tk-pass (+ ev-tk-pass 1)) (do (set! ev-tk-fail (+ ev-tk-fail 1)) (append! ev-tk-failures (str name "\n expected: " expected "\n got: " got)))))) (define ev-tk-run-all! (fn () (do (let ((req (ev/checkout-request "occ1" (quote nia) 1500 "GBP" "ref-1"))) (do (ev-tk-check! "checkout-request is tagged" (ev/checkout-request? req) true) (ev-tk-check! "payment-result is not a checkout-request" (ev/checkout-request? (ev/payment-paid "o" (quote a) "r")) false) (ev-tk-check! "request occ-key accessor" (ev/req-occ-key req) "occ1") (ev-tk-check! "request actor accessor" (ev/req-actor req) (quote nia)) (ev-tk-check! "request amount accessor" (ev/req-amount req) 1500) (ev-tk-check! "request currency accessor" (ev/req-currency req) "GBP") (ev-tk-check! "request ref accessor" (ev/req-ref req) "ref-1"))) (let ((res (ev/payment-paid "occ1" (quote nia) "ref-1"))) (do (ev-tk-check! "payment-result is tagged" (ev/payment-result? res) true) (ev-tk-check! "result status accessor" (ev/result-status res) :paid) (ev-tk-check! "failed constructor carries status" (ev/result-status (ev/payment-failed "o" (quote a) "r")) :failed) (ev-tk-check! "expired constructor carries status" (ev/result-status (ev/payment-expired "o" (quote a) "r")) :expired))) (let ((b (persist/open))) (do (let ((r (ev/request-ticket! b "show" 1 (quote a) 2000 "GBP" "ref-a"))) (do (ev-tk-check! "request-ticket awaiting-payment" (get r :status) :awaiting-payment) (ev-tk-check! "request-ticket returns a checkout-request" (ev/checkout-request? (get r :request)) true) (ev-tk-check! "checkout-request carries the amount" (ev/req-amount (get r :request)) 2000))) (ev-tk-check! "held seat reserves capacity" (ev/seats-left b "show" 1) 0) (ev-tk-check! "second buyer is full while payment pends" (get (ev/request-ticket! b "show" 1 (quote c) 2000 "GBP" "ref-c") :status) :full) (ev-tk-check! "held seat state pending" (ev/seat-state b "show" (quote a)) :held))) (let ((b (persist/open))) (do (ev/request-ticket! b "gig" 2 (quote a) 2000 "GBP" "ref-a") (let ((s (ev/settle-payment! b (ev/payment-paid "gig" (quote a) "ref-a")))) (ev-tk-check! "settle paid confirms" (get s :status) :confirmed)) (ev-tk-check! "confirmed seat state" (ev/seat-state b "gig" (quote a)) :confirmed) (ev-tk-check! "redelivered paid is still confirmed (idempotent)" (get (ev/settle-payment! b (ev/payment-paid "gig" (quote a) "ref-a")) :status) :confirmed) (ev-tk-check! "still exactly one seat taken" (ev-booking-count b "gig") 1))) (let ((b (persist/open))) (do (ev/request-ticket! b "fail" 1 (quote a) 2000 "GBP" "ref-a") (ev-tk-check! "seat held before failure" (ev/seats-left b "fail" 1) 0) (let ((s (ev/settle-payment! b (ev/payment-failed "fail" (quote a) "ref-a")))) (ev-tk-check! "settle failed releases" (get s :status) :released)) (ev-tk-check! "released seat frees capacity" (ev/seats-left b "fail" 1) 1) (ev-tk-check! "redelivered failure is a noop" (get (ev/settle-payment! b (ev/payment-failed "fail" (quote a) "ref-a")) :status) :noop) (ev-tk-check! "freed seat available to next buyer" (get (ev/request-ticket! b "fail" 1 (quote c) 2000 "GBP" "ref-c") :status) :awaiting-payment) (ev/request-ticket! b "exp" 1 (quote a) 2000 "GBP" "ref-a") (ev-tk-check! "settle expired releases" (get (ev/settle-payment! b (ev/payment-expired "exp" (quote a) "ref-a")) :status) :released))) (let ((b (persist/open))) (do (ev/request-ticket! b "race" 1 (quote a) 2000 "GBP" "ref-a") (ev/settle-payment! b (ev/payment-expired "race" (quote a) "ref-a")) (ev-tk-check! "late paid for a vanished hold needs a refund" (get (ev/settle-payment! b (ev/payment-paid "race" (quote a) "ref-a")) :status) :paid-but-no-hold) (ev-tk-check! "no phantom seat created" (ev-booking-count b "race") 0))) (let ((b (persist/open))) (do (let ((start (ev/request-ticket! b "e2e" 3 (quote nia) 2500 "GBP" "ref-nia"))) (ev/settle-payment! b (ev/payment-paid (ev/req-occ-key (get start :request)) (ev/req-actor (get start :request)) (ev/req-ref (get start :request))))) (ev-tk-check! "e2e roster holds the buyer" (ev/roster b "e2e") (list (quote nia))) (ev-tk-check! "e2e seat confirmed" (ev/seat-state b "e2e" (quote nia)) :confirmed)))))) (define ev-ticket-tests-run! (fn () (do (set! ev-tk-pass 0) (set! ev-tk-fail 0) (set! ev-tk-failures (list)) (ev-tk-run-all!) {:failures ev-tk-failures :total (+ ev-tk-pass ev-tk-fail) :passed ev-tk-pass :failed ev-tk-fail})))