mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 08:21: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