Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
126 lines
4.6 KiB
Plaintext
126 lines
4.6 KiB
Plaintext
;; lib/dream/tests/static.sx — content types, etags, 304, ranges, traversal.
|
|
|
|
(define dream-st-pass 0)
|
|
(define dream-st-fail 0)
|
|
(define dream-st-fails (list))
|
|
|
|
(define
|
|
dream-st-test
|
|
(fn
|
|
(name actual expected)
|
|
(if
|
|
(= actual expected)
|
|
(set! dream-st-pass (+ dream-st-pass 1))
|
|
(begin
|
|
(set! dream-st-fail (+ dream-st-fail 1))
|
|
(append! dream-st-fails {:name name :actual actual :expected expected})))))
|
|
|
|
;; ── content type + ext ─────────────────────────────────────────────
|
|
(dream-st-test "ext css" (dr/ext-of "a/b/style.css") "css")
|
|
(dream-st-test "ext multi-dot" (dr/ext-of "a.min.js") "js")
|
|
(dream-st-test "ext none" (dr/ext-of "README") "")
|
|
(dream-st-test
|
|
"ctype css"
|
|
(dream-content-type-for "x.css")
|
|
"text/css; charset=utf-8")
|
|
(dream-st-test
|
|
"ctype html"
|
|
(dream-content-type-for "x.html")
|
|
"text/html; charset=utf-8")
|
|
(dream-st-test "ctype png" (dream-content-type-for "x.png") "image/png")
|
|
(dream-st-test
|
|
"ctype unknown"
|
|
(dream-content-type-for "x.bin")
|
|
"application/octet-stream")
|
|
|
|
;; ── etag ───────────────────────────────────────────────────────────
|
|
(dream-st-test
|
|
"etag deterministic"
|
|
(= (dr/etag-of "abc") (dr/etag-of "abc"))
|
|
true)
|
|
(dream-st-test
|
|
"etag content-sensitive"
|
|
(= (dr/etag-of "abc") (dr/etag-of "abd"))
|
|
false)
|
|
(dream-st-test
|
|
"etag length-sensitive"
|
|
(= (dr/etag-of "ab") (dr/etag-of "abc"))
|
|
false)
|
|
|
|
;; ── serving via router mount ───────────────────────────────────────
|
|
(define dream-st-files {:/srv/app.css "body{color:red}" :/srv/index.html "<h1>Hi</h1>"})
|
|
(define dream-st-fs (dream-memory-fs dream-st-files))
|
|
(define
|
|
dream-st-app
|
|
(dream-router
|
|
(list (dream-get "/static/**" (dream-static-with "/srv" dream-st-fs)))))
|
|
(define
|
|
dream-st-get
|
|
(fn
|
|
(target headers)
|
|
(dream-st-app (dream-request "GET" target headers ""))))
|
|
|
|
(define dream-st-css (dream-st-get "/static/app.css" {}))
|
|
(dream-st-test "serve status 200" (dream-status dream-st-css) 200)
|
|
(dream-st-test "serve body" (dream-resp-body dream-st-css) "body{color:red}")
|
|
(dream-st-test
|
|
"serve content-type"
|
|
(dream-resp-header dream-st-css "content-type")
|
|
"text/css; charset=utf-8")
|
|
(dream-st-test
|
|
"serve accept-ranges"
|
|
(dream-resp-header dream-st-css "accept-ranges")
|
|
"bytes")
|
|
(dream-st-test
|
|
"serve has etag"
|
|
(not (nil? (dream-resp-header dream-st-css "etag")))
|
|
true)
|
|
(dream-st-test
|
|
"missing file 404"
|
|
(dream-status (dream-st-get "/static/nope.txt" {}))
|
|
404)
|
|
(dream-st-test
|
|
"traversal blocked 403"
|
|
(dream-status (dream-st-get "/static/../secret" {}))
|
|
403)
|
|
|
|
;; ── conditional: If-None-Match -> 304 ──────────────────────────────
|
|
(define dream-st-etag (dream-resp-header dream-st-css "etag"))
|
|
(define dream-st-304 (dream-st-get "/static/app.css" {:If-None-Match dream-st-etag}))
|
|
(dream-st-test "matching etag 304" (dream-status dream-st-304) 304)
|
|
(dream-st-test "304 empty body" (dream-resp-body dream-st-304) "")
|
|
(dream-st-test
|
|
"stale etag 200"
|
|
(dream-status (dream-st-get "/static/app.css" {:If-None-Match "\"stale\""}))
|
|
200)
|
|
(dream-st-test
|
|
"star etag 304"
|
|
(dream-status (dream-st-get "/static/app.css" {:If-None-Match "*"}))
|
|
304)
|
|
|
|
;; ── range requests ─────────────────────────────────────────────────
|
|
(define dream-st-range (dream-st-get "/static/app.css" {:Range "bytes=0-3"}))
|
|
(dream-st-test "range status 206" (dream-status dream-st-range) 206)
|
|
(dream-st-test "range body slice" (dream-resp-body dream-st-range) "body")
|
|
(dream-st-test
|
|
"range content-range"
|
|
(dream-resp-header dream-st-range "content-range")
|
|
"bytes 0-3/15")
|
|
(define dream-st-open (dream-st-get "/static/app.css" {:Range "bytes=5-"}))
|
|
(dream-st-test "open range body" (dream-resp-body dream-st-open) "color:red}")
|
|
(dream-st-test
|
|
"open range header"
|
|
(dream-resp-header dream-st-open "content-range")
|
|
"bytes 5-14/15")
|
|
(define dream-st-bad (dream-st-get "/static/app.css" {:Range "bytes=20-30"}))
|
|
(dream-st-test
|
|
"unsatisfiable range 416"
|
|
(dream-status dream-st-bad)
|
|
416)
|
|
(dream-st-test
|
|
"416 content-range"
|
|
(dream-resp-header dream-st-bad "content-range")
|
|
"bytes */15")
|
|
|
|
(define dream-st-tests-run! (fn () {:total (+ dream-st-pass dream-st-fail) :passed dream-st-pass :failed dream-st-fail :fails dream-st-fails}))
|