Files
rose-ash/lib/dream/tests/flash.sx
giles edff7735e7
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m14s
dream: flash messages — single-request cookie store + 14 tests
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 14:38:26 +00:00

130 lines
4.4 KiB
Plaintext

;; lib/dream/tests/flash.sx — codec + read-after-write across requests.
(define dream-fl-pass 0)
(define dream-fl-fail 0)
(define dream-fl-fails (list))
(define
dream-fl-test
(fn
(name actual expected)
(if
(= actual expected)
(set! dream-fl-pass (+ dream-fl-pass 1))
(begin
(set! dream-fl-fail (+ dream-fl-fail 1))
(append! dream-fl-fails {:name name :actual actual :expected expected})))))
;; ── codec ──────────────────────────────────────────────────────────
(dream-fl-test "encode one" (dr/flash-encode (list {:message "saved" :category "info"})) "info|saved")
(dream-fl-test
"encode two"
(dr/flash-encode (list {:message "a" :category "info"} {:message "b" :category "error"}))
"info|a~error|b")
(dream-fl-test "decode one" (dr/flash-decode "info|saved") (list {:message "saved" :category "info"}))
(dream-fl-test "decode empty" (dr/flash-decode "") (list))
(dream-fl-test
"roundtrip special chars"
(dr/flash-decode (dr/flash-encode (list {:message "a~b%c" :category "x|y"})))
(list {:message "a~b%c" :category "x|y"}))
(dream-fl-test "escape pipe" (dr/flash-encode (list {:message "a|b" :category "c"})) "c|a%7Cb")
;; extract a cookie value from a Set-Cookie string
(define
dream-fl-cookie-val
(fn
(setc)
(let
((after (substr setc (+ (index-of setc "=") 1))))
(substr after 0 (index-of after ";")))))
;; ── read-after-write across requests ───────────────────────────────
(define
dream-fl-set-h
(fn
(req)
(begin (dream-add-flash-message req "info" "Saved!") (dream-text "done"))))
(define dream-fl-set-app (dream-flash dream-fl-set-h))
;; request 1: add a flash, no incoming -> sets the flash cookie
(define
dream-fl-r1
(dream-fl-set-app (dream-request "POST" "/save" {} "")))
(dream-fl-test "writer body" (dream-resp-body dream-fl-r1) "done")
(dream-fl-test
"writer sets flash cookie"
(len (dream-resp-cookies dream-fl-r1))
1)
(dream-fl-test
"writer has no incoming"
(dream-flash-messages
(assoc (dream-request "GET" "/" {} "") :dream-flash {:box (dr/flash-box) :incoming (list)}))
(list))
;; request 2: carries the flash cookie -> handler reads it, cookie cleared
(define
dream-fl-cval
(dream-fl-cookie-val (first (dream-resp-cookies dream-fl-r1))))
(define
dream-fl-read-h
(fn
(req)
(let
((msgs (dream-flash-messages req)))
(dream-text
(if (empty? msgs) "none" (dream-flash-message (first msgs)))))))
(define dream-fl-read-app (dream-flash dream-fl-read-h))
(define
dream-fl-r2
(dream-fl-read-app (dream-request "GET" "/" {:Cookie (str "dream.flash=" dream-fl-cval)} "")))
(dream-fl-test "reader sees message" (dream-resp-body dream-fl-r2) "Saved!")
(dream-fl-test
"reader clears cookie (Max-Age=0)"
(contains? (first (dream-resp-cookies dream-fl-r2)) "Max-Age=0")
true)
;; request 3: no flash cookie -> nothing to read, no cookie set
(define
dream-fl-r3
(dream-fl-read-app (dream-request "GET" "/" {} "")))
(dream-fl-test "no flash -> none" (dream-resp-body dream-fl-r3) "none")
(dream-fl-test
"no flash -> no cookie"
(len (dream-resp-cookies dream-fl-r3))
0)
;; ── multiple categories ────────────────────────────────────────────
(define
dream-fl-multi-h
(fn
(req)
(begin
(dream-add-flash-message req "info" "i1")
(dream-add-flash-message req "error" "e1")
(dream-add-flash-message req "info" "i2")
(dream-text "ok"))))
(define
dream-fl-multi-r1
((dream-flash dream-fl-multi-h) (dream-request "GET" "/" {} "")))
(define
dream-fl-multi-val
(dream-fl-cookie-val (first (dream-resp-cookies dream-fl-multi-r1))))
(define
dream-fl-count-h
(fn
(req)
(dream-text
(str
(len (dream-flash-messages req))
"/"
(len (dream-flash-of req "info"))))))
(define
dream-fl-multi-r2
((dream-flash dream-fl-count-h) (dream-request "GET" "/" {:Cookie (str "dream.flash=" dream-fl-multi-val)} "")))
(dream-fl-test
"multi: all + filtered counts"
(dream-resp-body dream-fl-multi-r2)
"3/2")
(define dream-fl-tests-run! (fn () {:total (+ dream-fl-pass dream-fl-fail) :passed dream-fl-pass :failed dream-fl-fail :fails dream-fl-fails}))