mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 00:11:11 +00:00
Support ring-route-data validation
This commit is contained in:
parent
0dbb75ad44
commit
1a9583b31b
2 changed files with 85 additions and 0 deletions
33
modules/reitit-ring/src/reitit/ring/spec.cljc
Normal file
33
modules/reitit-ring/src/reitit/ring/spec.cljc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
(ns reitit.ring.spec
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[reitit.middleware #?@(:cljs [:refer [Middleware]])]
|
||||
[reitit.spec :as rs])
|
||||
#?(:clj
|
||||
(:import (reitit.middleware Middleware))))
|
||||
|
||||
;;
|
||||
;; Specs
|
||||
;;
|
||||
|
||||
(s/def ::middleware (s/coll-of (partial instance? Middleware)))
|
||||
|
||||
(s/def ::data
|
||||
(s/keys :req-un [::rs/handler]
|
||||
:opt-un [::rs/name ::middleware]))
|
||||
|
||||
;;
|
||||
;; Validator
|
||||
;;
|
||||
|
||||
(defn- validate-ring-route-data [routes spec]
|
||||
(->> (for [[p _ c] routes
|
||||
[method {:keys [data] :as endpoint}] c
|
||||
:when endpoint]
|
||||
(when-let [problems (and spec (s/explain-data spec data))]
|
||||
(rs/->Problem p method data spec problems)))
|
||||
(keep identity) (seq)))
|
||||
|
||||
(defn validate-spec!
|
||||
[routes {:keys [spec ::rs/explain] :or {explain s/explain-str, spec ::data}}]
|
||||
(when-let [problems (validate-ring-route-data routes spec)]
|
||||
(rs/throw-on-problems! problems explain)))
|
||||
52
test/cljc/reitit/ring_spec_test.cljc
Normal file
52
test/cljc/reitit/ring_spec_test.cljc
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
(ns reitit.ring-spec-test
|
||||
(:require [clojure.test :refer [deftest testing is]]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.ring.spec :as rrs]
|
||||
[reitit.core :as r]
|
||||
[reitit.spec :as rs])
|
||||
#?(:clj
|
||||
(:import (clojure.lang ExceptionInfo))))
|
||||
|
||||
|
||||
(deftest route-data-validation-test
|
||||
(testing "validation is turned off by default"
|
||||
(is (true? (r/router?
|
||||
(r/router
|
||||
["/api" {:handler "identity"}])))))
|
||||
|
||||
(testing "with default spec validates :name, :handler and :middleware"
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Invalid route data"
|
||||
(ring/router
|
||||
["/api" {:handler "identity"}]
|
||||
{:validate rrs/validate-spec!})))
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Invalid route data"
|
||||
(ring/router
|
||||
["/api" {:handler identity
|
||||
:name "kikka"}]
|
||||
{:validate rrs/validate-spec!})))
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Invalid route data"
|
||||
(ring/router
|
||||
["/api" {:handler identity
|
||||
:middleware [{}]}]
|
||||
{:validate rrs/validate-spec!}))))
|
||||
|
||||
(testing "all endpoints are validated"
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Invalid route data"
|
||||
(ring/router
|
||||
["/api" {:patch {:handler "identity"}}]
|
||||
{:validate rrs/validate-spec!}))))
|
||||
|
||||
(testing "spec can be overridden"
|
||||
(is (true? (r/router?
|
||||
(ring/router
|
||||
["/api" {:handler "identity"}]
|
||||
{:spec any?
|
||||
:validate rrs/validate-spec!}))))))
|
||||
Loading…
Reference in a new issue