;; lib/dream/tests/error.sx — status phrases + dream-catch.

(define dream-er-pass 0)
(define dream-er-fail 0)
(define dream-er-fails (list))

(define
  dream-er-test
  (fn
    (name actual expected)
    (if
      (= actual expected)
      (set! dream-er-pass (+ dream-er-pass 1))
      (begin
        (set! dream-er-fail (+ dream-er-fail 1))
        (append! dream-er-fails {:name name :actual actual :expected expected})))))

;; ── status phrases ─────────────────────────────────────────────────
(dream-er-test "200 OK" (dream-status-text 200) "OK")
(dream-er-test "404 Not Found" (dream-status-text 404) "Not Found")
(dream-er-test
  "405 phrase"
  (dream-status-text 405)
  "Method Not Allowed")
(dream-er-test
  "500 phrase"
  (dream-status-text 500)
  "Internal Server Error")
(dream-er-test "unknown phrase" (dream-status-text 599) "Unknown")
(dream-er-test "status line" (dream-status-line 404) "404 Not Found")
(dream-er-test
  "status page status"
  (dream-status (dream-status-page 403))
  403)
(dream-er-test
  "status page body"
  (dream-resp-body (dream-status-page 403))
  "<h1>403 Forbidden</h1>")

;; ── dream-catch ────────────────────────────────────────────────────
(define dream-er-boom (fn (req) (error "kaboom")))
(define dream-er-ok (fn (req) (dream-text "fine")))

(dream-er-test
  "catch normal passes through"
  (dream-resp-body
    ((dream-catch dream-er-ok) (dream-request "GET" "/" {} "")))
  "fine")
(dream-er-test
  "catch error -> 500"
  (dream-status
    ((dream-catch dream-er-boom) (dream-request "GET" "/" {} "")))
  500)
(dream-er-test
  "catch 500 body"
  (dream-resp-body
    ((dream-catch dream-er-boom) (dream-request "GET" "/" {} "")))
  "<h1>500 Internal Server Error</h1>")

;; custom error page receives the error
(define
  dream-er-custom
  (dream-catch-with (fn (req e) (dream-text (str "ERR:" e)))))
(dream-er-test
  "custom error page"
  (dream-resp-body
    ((dream-er-custom dream-er-boom) (dream-request "GET" "/" {} "")))
  "ERR:kaboom")
(dream-er-test
  "custom passes normal through"
  (dream-resp-body
    ((dream-er-custom dream-er-ok) (dream-request "GET" "/" {} "")))
  "fine")

;; catch composes around a router
(define
  dream-er-app
  (dream-catch
    (dream-router
      (list (dream-get "/boom" dream-er-boom) (dream-get "/ok" dream-er-ok)))))
(dream-er-test
  "router error caught"
  (dream-status (dream-er-app (dream-request "GET" "/boom" {} "")))
  500)
(dream-er-test
  "router ok intact"
  (dream-resp-body (dream-er-app (dream-request "GET" "/ok" {} "")))
  "fine")

(define dream-er-tests-run! (fn () {:total (+ dream-er-pass dream-er-fail) :passed dream-er-pass :failed dream-er-fail :fails dream-er-fails}))
