host: view + edit the SX source of each blog post (blog 47/47, 213 total)
Posts ARE SX source, so expose it: a public raw-source view and a guarded in-browser source editor. - GET /<slug>/source — raw sx_content as text/plain (public; a published post's source isn't secret). - GET /<slug>/edit — edit form pre-filled with the post's title, raw source (in a textarea, render-to-html-escaped so it shows verbatim), and status (current value pre-selected). Guarded (editor only). Slug is preserved. - POST /<slug>/edit — save the edited source; same write-time validation as create (unparseable body -> 400, post left intact); 303 back to the post. - post page gains "view source · edit · all posts" footer links. Routing: /:slug/source + /:slug/edit are two-segment patterns; the router consumes :param as exactly one segment and requires a full match, so /:slug does not shadow them (asserted). 14 new blog tests cover view (200/text-plain/ raw body/404/no-shadow) and edit (401 unauth GET+POST, 200 form, source shown, 303 save, persisted, slug preserved, 400 malformed, 404 missing). Verified live on blog.rose-ash.com: view source, guarded edit form, save round-trip (rendered post + source both reflect the edit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -149,6 +149,51 @@
|
||||
(contains? (dream-resp-body (host-bl-wapp (host-bl-req "/my-first-post/"))) "<h1>My First Post</h1>")
|
||||
true)
|
||||
|
||||
;; -- view source (public) --
|
||||
(host-bl-test "view source -> 200"
|
||||
(dream-status (host-bl-wapp (host-bl-req "/my-first-post/source"))) 200)
|
||||
(host-bl-test "view source is text/plain"
|
||||
(dream-resp-header (host-bl-wapp (host-bl-req "/my-first-post/source")) "content-type")
|
||||
"text/plain; charset=utf-8")
|
||||
(host-bl-test "view source returns raw sx_content"
|
||||
(contains? (dream-resp-body (host-bl-wapp (host-bl-req "/my-first-post/source"))) "(article")
|
||||
true)
|
||||
(host-bl-test "view source missing -> 404"
|
||||
(dream-status (host-bl-wapp (host-bl-req "/ghost/source"))) 404)
|
||||
(host-bl-test "/:slug not shadowed by /:slug/source"
|
||||
(dream-status (host-bl-wapp (host-bl-req "/my-first-post/"))) 200)
|
||||
|
||||
;; -- edit source (guarded GET form + guarded POST save) --
|
||||
(host-bl-test "edit form no auth -> 401"
|
||||
(dream-status (host-bl-wapp (host-bl-send "GET" "/my-first-post/edit" nil "" ""))) 401)
|
||||
(host-bl-test "edit form authed -> 200"
|
||||
(dream-status (host-bl-wapp (host-bl-send "GET" "/my-first-post/edit" "Bearer good" "" ""))) 200)
|
||||
(host-bl-test "edit form shows current source"
|
||||
(contains? (dream-resp-body (host-bl-wapp (host-bl-send "GET" "/my-first-post/edit" "Bearer good" "" "")))
|
||||
"(article")
|
||||
true)
|
||||
(host-bl-test "edit submit no auth -> 401"
|
||||
(dream-status (host-bl-wapp (host-bl-send "POST" "/my-first-post/edit" nil
|
||||
"application/x-www-form-urlencoded" "sx_content=(p+%22x%22)"))) 401)
|
||||
(host-bl-test "edit submit authed -> 303"
|
||||
(dream-status (host-bl-wapp (host-bl-send "POST" "/my-first-post/edit" "Bearer good"
|
||||
"application/x-www-form-urlencoded"
|
||||
"title=My+First+Post&sx_content=(p+%22edited+via+editor%22)&status=published"))) 303)
|
||||
(host-bl-test "edit persisted the new content"
|
||||
(contains? (dream-resp-body (host-bl-wapp (host-bl-req "/my-first-post/"))) "edited via editor")
|
||||
true)
|
||||
(host-bl-test "edit preserves the slug"
|
||||
(dream-resp-header
|
||||
(host-bl-wapp (host-bl-send "POST" "/my-first-post/edit" "Bearer good"
|
||||
"application/x-www-form-urlencoded" "title=Renamed&sx_content=(p+%22y%22)&status=draft"))
|
||||
"location")
|
||||
"/my-first-post/")
|
||||
(host-bl-test "edit malformed body -> 400"
|
||||
(dream-status (host-bl-wapp (host-bl-send "POST" "/my-first-post/edit" "Bearer good"
|
||||
"application/x-www-form-urlencoded" "sx_content=%3Ch1+broken%29"))) 400)
|
||||
(host-bl-test "edit missing post -> 404"
|
||||
(dream-status (host-bl-wapp (host-bl-send "GET" "/ghost/edit" "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))
|
||||
|
||||
Reference in New Issue
Block a user