dream: chat (ws rooms) + todo (forms+CSRF) demos + 17 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m2s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m2s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
(define dream-dm-cbackend (dream-memory-sessions))
|
||||
(define dream-dm-capp (dream-counter-app-with dream-dm-cbackend))
|
||||
|
||||
;; first visit: no cookie -> count 1, session cookie set
|
||||
(define dream-dm-c1 (dream-dm-capp (dream-dm-req "GET" "/" {})))
|
||||
(dream-dm-test
|
||||
"counter first visit"
|
||||
@@ -50,8 +49,6 @@
|
||||
"counter sets cookie"
|
||||
(len (dream-resp-cookies dream-dm-c1))
|
||||
1)
|
||||
|
||||
;; subsequent visits with the cookie increment
|
||||
(dream-dm-test
|
||||
"counter second visit"
|
||||
(dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"})))
|
||||
@@ -60,8 +57,6 @@
|
||||
"counter third visit"
|
||||
(dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"})))
|
||||
"<p>You have visited this page 3 time(s).</p>")
|
||||
|
||||
;; reset zeroes the counter then redirects
|
||||
(define
|
||||
dream-dm-reset
|
||||
(dream-dm-capp (dream-dm-req "POST" "/reset" {:Cookie "dream.session=s1"})))
|
||||
@@ -73,11 +68,131 @@
|
||||
"counter after reset"
|
||||
(dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"})))
|
||||
"<p>You have visited this page 1 time(s).</p>")
|
||||
|
||||
;; a different session is independent
|
||||
(dream-dm-test
|
||||
"counter distinct session"
|
||||
(dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {})))
|
||||
"<p>You have visited this page 1 time(s).</p>")
|
||||
|
||||
;; ── chat (websocket rooms) ─────────────────────────────────────────
|
||||
(define dream-dm-rooms (dream-chat-rooms))
|
||||
(define dream-dm-wsB (dream-mock-ws (list)))
|
||||
(define dream-dm-wsC (dream-mock-ws (list)))
|
||||
((get dream-dm-rooms :join) "general" dream-dm-wsB)
|
||||
((get dream-dm-rooms :join) "general" dream-dm-wsC)
|
||||
(dream-dm-test
|
||||
"room has two members"
|
||||
(len ((get dream-dm-rooms :members) "general"))
|
||||
2)
|
||||
|
||||
;; client A joins, sends two messages, then disconnects
|
||||
(define dream-dm-wsA (dream-mock-ws (list "hi" "again")))
|
||||
((dream-chat-session dream-dm-rooms "general") dream-dm-wsA)
|
||||
(dream-dm-test
|
||||
"B got broadcasts"
|
||||
(dream-ws-sent dream-dm-wsB)
|
||||
(list "hi" "again"))
|
||||
(dream-dm-test
|
||||
"C got broadcasts"
|
||||
(dream-ws-sent dream-dm-wsC)
|
||||
(list "hi" "again"))
|
||||
(dream-dm-test
|
||||
"A echoed own messages"
|
||||
(dream-ws-sent dream-dm-wsA)
|
||||
(list "hi" "again"))
|
||||
(dream-dm-test
|
||||
"A left on disconnect"
|
||||
(len ((get dream-dm-rooms :members) "general"))
|
||||
2)
|
||||
(dream-dm-test "A closed" (dream-ws-closed? dream-dm-wsA) true)
|
||||
|
||||
;; route produces an upgrade response
|
||||
(define dream-dm-chat-app (dream-chat-app-with (dream-chat-rooms)))
|
||||
(dream-dm-test
|
||||
"chat route upgrades"
|
||||
(dream-websocket?
|
||||
(dream-dm-chat-app (dream-dm-req "GET" "/chat/lobby" {})))
|
||||
true)
|
||||
(dream-dm-test
|
||||
"chat index html"
|
||||
(dream-resp-body (dream-dm-chat-app (dream-dm-req "GET" "/" {})))
|
||||
"<h1>Rooms</h1>")
|
||||
|
||||
;; ── todo (forms + CSRF) ────────────────────────────────────────────
|
||||
(define dream-dm-todo-store (dream-todo-store))
|
||||
(define dream-dm-todo-backend (dream-memory-sessions))
|
||||
(define
|
||||
dream-dm-todo-app
|
||||
(dream-todo-app-with dream-dm-todo-store dream-dm-todo-backend "topsecret"))
|
||||
(define
|
||||
dream-dm-todo-tok
|
||||
(dr/csrf-make-token dream-csrf-sign-default "topsecret" "s1"))
|
||||
|
||||
;; establish session s1
|
||||
(dream-dm-todo-app (dream-request "GET" "/" {} ""))
|
||||
(define
|
||||
dream-dm-add1
|
||||
(dream-dm-todo-app
|
||||
(dream-request
|
||||
"POST"
|
||||
"/add"
|
||||
{:Cookie "dream.session=s1"}
|
||||
(str "text=Buy+milk&dream.csrf=" dream-dm-todo-tok))))
|
||||
(dream-dm-test "todo add redirects" (dream-status dream-dm-add1) 303)
|
||||
(dream-dm-test
|
||||
"todo store has item"
|
||||
(len ((get dream-dm-todo-store :all)))
|
||||
1)
|
||||
|
||||
(define
|
||||
dream-dm-todo-page
|
||||
(dream-resp-body
|
||||
(dream-dm-todo-app (dream-request "GET" "/" {:Cookie "dream.session=s1"} ""))))
|
||||
(dream-dm-test
|
||||
"todo lists item"
|
||||
(contains? dream-dm-todo-page "Buy milk")
|
||||
true)
|
||||
(dream-dm-test
|
||||
"todo has csrf tag"
|
||||
(contains? dream-dm-todo-page "dream.csrf")
|
||||
true)
|
||||
(dream-dm-test
|
||||
"todo item not done"
|
||||
(contains? dream-dm-todo-page "[ ] Buy milk")
|
||||
true)
|
||||
|
||||
(dream-dm-todo-app
|
||||
(dream-request
|
||||
"POST"
|
||||
"/toggle/1"
|
||||
{:Cookie "dream.session=s1"}
|
||||
(str "dream.csrf=" dream-dm-todo-tok)))
|
||||
(dream-dm-test
|
||||
"todo toggled done"
|
||||
(contains?
|
||||
(dream-resp-body
|
||||
(dream-dm-todo-app (dream-request "GET" "/" {:Cookie "dream.session=s1"} "")))
|
||||
"[x] Buy milk")
|
||||
true)
|
||||
|
||||
(dream-dm-test
|
||||
"todo add without token 403"
|
||||
(dream-status
|
||||
(dream-dm-todo-app (dream-request "POST" "/add" {:Cookie "dream.session=s1"} "text=Sneaky")))
|
||||
403)
|
||||
(dream-dm-test
|
||||
"todo unchanged after reject"
|
||||
(len ((get dream-dm-todo-store :all)))
|
||||
1)
|
||||
|
||||
(dream-dm-todo-app
|
||||
(dream-request
|
||||
"POST"
|
||||
"/delete/1"
|
||||
{:Cookie "dream.session=s1"}
|
||||
(str "dream.csrf=" dream-dm-todo-tok)))
|
||||
(dream-dm-test
|
||||
"todo deleted"
|
||||
(len ((get dream-dm-todo-store :all)))
|
||||
0)
|
||||
|
||||
(define dream-dm-tests-run! (fn () {:total (+ dream-dm-pass dream-dm-fail) :passed dream-dm-pass :failed dream-dm-fail :fails dream-dm-fails}))
|
||||
|
||||
Reference in New Issue
Block a user