;; lib/dream/tests/demos.sx — end-to-end demo apps exercising the full stack. (define dream-dm-pass 0) (define dream-dm-fail 0) (define dream-dm-fails (list)) (define dream-dm-test (fn (name actual expected) (if (= actual expected) (set! dream-dm-pass (+ dream-dm-pass 1)) (begin (set! dream-dm-fail (+ dream-dm-fail 1)) (append! dream-dm-fails {:name name :actual actual :expected expected}))))) (define dream-dm-req (fn (method target headers) (dream-request method target headers ""))) ;; ── hello ────────────────────────────────────────────────────────── (dream-dm-test "hello root" (dream-resp-body (dream-hello-app (dream-dm-req "GET" "/" {}))) "

Hello, World!

") (dream-dm-test "hello name" (dream-resp-body (dream-hello-app (dream-dm-req "GET" "/hello/Ada" {}))) "

Hello, Ada!

") (dream-dm-test "hello content-type" (dream-resp-header (dream-hello-app (dream-dm-req "GET" "/" {})) "content-type") "text/html; charset=utf-8") ;; ── counter (sessions) ───────────────────────────────────────────── (define dream-dm-cbackend (dream-memory-sessions)) (define dream-dm-capp (dream-counter-app-with dream-dm-cbackend)) (define dream-dm-c1 (dream-dm-capp (dream-dm-req "GET" "/" {}))) (dream-dm-test "counter first visit" (dream-resp-body dream-dm-c1) "

You have visited this page 1 time(s).

") (dream-dm-test "counter sets cookie" (len (dream-resp-cookies dream-dm-c1)) 1) (dream-dm-test "counter second visit" (dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"}))) "

You have visited this page 2 time(s).

") (dream-dm-test "counter third visit" (dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"}))) "

You have visited this page 3 time(s).

") (define dream-dm-reset (dream-dm-capp (dream-dm-req "POST" "/reset" {:Cookie "dream.session=s1"}))) (dream-dm-test "counter reset redirects" (dream-status dream-dm-reset) 303) (dream-dm-test "counter after reset" (dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {:Cookie "dream.session=s1"}))) "

You have visited this page 1 time(s).

") (dream-dm-test "counter distinct session" (dream-resp-body (dream-dm-capp (dream-dm-req "GET" "/" {}))) "

You have visited this page 1 time(s).

") ;; ── 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" "/" {}))) "

Rooms

") ;; ── 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}))