;; lib/host/tests/blog.sx — blog on the editor's content model. Posts are ;; {slug,title,sx_content,status} records in the durable KV; a post page is ;; render-to-html(parse sx_content). Covers read/render, home index, JSON list, ;; slugify, the form-urlencoded editor ingest, and JSON CRUD (auth+ACL guarded). (define host-bl-pass 0) (define host-bl-fail 0) (define host-bl-fails (list)) (define host-bl-test (fn (name actual expected) (if (= actual expected) (set! host-bl-pass (+ host-bl-pass 1)) (begin (set! host-bl-fail (+ host-bl-fail 1)) (append! host-bl-fails {:name name :actual actual :expected expected}))))) (define host-bl-req (fn (target) (dream-request "GET" target {} ""))) (define host-bl-app (host/make-app (list host/feed-routes host/blog-routes))) ;; ── slugify ───────────────────────────────────────────────────────── (host-bl-test "slugify" (host/blog-slugify "Hello World") "hello-world") (host-bl-test "slugify trims spaces" (host/blog-slugify " A B ") "a-b") ;; ── render a stored post ──────────────────────────────────────────── (host/blog-use-store! (persist/open)) (host/blog-put! "hello" "Hello World" "(article (h1 \"Hello World\") (p \"A \" (strong \"bold\") \" word.\"))" "published") (host-bl-test "post 200" (dream-status (host-bl-app (host-bl-req "/hello/"))) 200) (host-bl-test "post content-type html" (contains? (dream-resp-header (host-bl-app (host-bl-req "/hello/")) "content-type") "text/html") true) (host-bl-test "post renders sx_content markup" (contains? (dream-resp-body (host-bl-app (host-bl-req "/hello/"))) "bold") true) (host-bl-test "post title in page" (contains? (dream-resp-body (host-bl-app (host-bl-req "/hello/"))) "Hello World") true) ;; ── home + list ───────────────────────────────────────────────────── (host-bl-test "home lists post" (contains? (dream-resp-body (host-bl-app (host-bl-req "/"))) "href=\"/hello/\"") true) (host-bl-test "json list shows post" (contains? (dream-resp-body (host-bl-app (host-bl-req "/posts"))) "\"slug\":\"hello\"") true) (host-bl-test "GET /new shows form" (contains? (dream-resp-body (host-bl-app (host-bl-req "/new"))) " 401" (dream-status (host-bl-wapp (host-bl-send "POST" "/new" nil "application/x-www-form-urlencoded" "title=X"))) 401) (host-bl-test "form ingest authed -> 303 redirect" (dream-status (host-bl-wapp (host-bl-send "POST" "/new" "Bearer good" "application/x-www-form-urlencoded" "title=My+First+Post&sx_content=(article+(h1+%22My+First+Post%22)+(p+%22Hi%22))&status=published"))) 303) (host-bl-test "form ingest set Location to the new slug" (dream-resp-header (host-bl-wapp (host-bl-send "POST" "/new" "Bearer good" "application/x-www-form-urlencoded" "title=Another+One&sx_content=(p+%22x%22)&status=published")) "location") "/another-one/") (host-bl-test "ingested post renders" (contains? (dream-resp-body (host-bl-wapp (host-bl-req "/my-first-post/"))) "

My First Post

") true) ;; -- JSON CRUD -- (host-bl-test "json create -> 201" (dream-status (host-bl-wapp (host-bl-send "POST" "/posts" "Bearer good" "application/json" "{\"title\":\"Json Post\",\"sx_content\":\"(p \\\"jp\\\")\",\"status\":\"draft\"}"))) 201) (host-bl-test "json create unpermitted -> 403" (dream-status (host-bl-wapp (host-bl-send "POST" "/posts" "Bearer weak" "application/json" "{\"title\":\"Nope\"}"))) 403) (host-bl-test "json create duplicate -> 409" (dream-status (host-bl-wapp (host-bl-send "POST" "/posts" "Bearer good" "application/json" "{\"slug\":\"json-post\",\"title\":\"Json Post\"}"))) 409) (host-bl-test "json create no title -> 400" (dream-status (host-bl-wapp (host-bl-send "POST" "/posts" "Bearer good" "application/json" "{}"))) 400) (host-bl-test "update -> 200" (dream-status (host-bl-wapp (host-bl-send "PUT" "/posts/json-post" "Bearer good" "application/json" "{\"sx_content\":\"(p \\\"edited\\\")\"}"))) 200) (host-bl-test "update changed content" (contains? (dream-resp-body (host-bl-wapp (host-bl-req "/json-post/"))) "edited") true) (host-bl-test "update missing -> 404" (dream-status (host-bl-wapp (host-bl-send "PUT" "/posts/ghost" "Bearer good" "application/json" "{}"))) 404) (host-bl-test "delete -> 200" (dream-status (host-bl-wapp (host-bl-send "DELETE" "/posts/json-post" "Bearer good" "" ""))) 200) (host-bl-test "deleted -> 404" (dream-status (host-bl-wapp (host-bl-req "/json-post/"))) 404) (host-bl-test "delete missing -> 404" (dream-status (host-bl-wapp (host-bl-send "DELETE" "/posts/ghost" "Bearer good" "" ""))) 404) ;; -- experimental unguarded create-only route (POST /new, no auth) -- (define host-bl-oapp (host/make-app (list host/blog-open-create-routes host/blog-routes))) (host/blog-use-store! (persist/open)) (host-bl-test "open create no auth -> 303" (dream-status (host-bl-oapp (host-bl-send "POST" "/new" nil "application/x-www-form-urlencoded" "title=Open+Post&sx_content=(p+%22o%22)&status=published"))) 303) (host-bl-test "open-created post renders" (contains? (dream-resp-body (host-bl-oapp (host-bl-req "/open-post/"))) "

o

") true) (define host-bl-tests-run! (fn () {:total (+ host-bl-pass host-bl-fail) :passed host-bl-pass :failed host-bl-fail :fails host-bl-fails}))