mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
Middleware can also contribute to router specs
This commit is contained in:
parent
70209aabce
commit
9273f99806
3 changed files with 55 additions and 18 deletions
|
|
@ -6,7 +6,7 @@
|
|||
(defprotocol IntoMiddleware
|
||||
(into-middleware [this data opts]))
|
||||
|
||||
(defrecord Middleware [name wrap])
|
||||
(defrecord Middleware [name wrap spec])
|
||||
(defrecord Endpoint [data handler middleware])
|
||||
|
||||
(def ^:dynamic *max-compile-depth* 10)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
(ns reitit.ring.spec
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[reitit.middleware #?@(:cljs [:refer [Middleware]])]
|
||||
[reitit.spec :as rs])
|
||||
#?(:clj
|
||||
(:import (reitit.middleware Middleware))))
|
||||
[reitit.middleware :as middleware]
|
||||
[reitit.spec :as rs]))
|
||||
|
||||
;;
|
||||
;; Specs
|
||||
;;
|
||||
|
||||
(s/def ::middleware (s/coll-of (partial instance? Middleware)))
|
||||
(s/def ::middleware (s/coll-of (partial satisfies? middleware/IntoMiddleware)))
|
||||
|
||||
(s/def ::data
|
||||
(s/keys :req-un [::rs/handler]
|
||||
|
|
@ -19,10 +17,22 @@
|
|||
;; Validator
|
||||
;;
|
||||
|
||||
(defn merge-specs [specs]
|
||||
(when-let [non-specs (seq (remove #(or (s/spec? %) (s/get-spec %)) specs))]
|
||||
(throw
|
||||
(ex-info
|
||||
(str "Not all specs satisfy the Spec protocol: " non-specs)
|
||||
{:specs specs
|
||||
:non-specs non-specs})))
|
||||
(s/merge-spec-impl (vec specs) (vec specs) nil))
|
||||
|
||||
(defn- validate-ring-route-data [routes spec]
|
||||
(->> (for [[p _ c] routes
|
||||
[method {:keys [data] :as endpoint}] c
|
||||
:when endpoint]
|
||||
[method {:keys [data middleware] :as endpoint}] c
|
||||
:when endpoint
|
||||
:let [mw-specs (seq (keep :spec middleware))
|
||||
specs (keep identity (into [spec] mw-specs))
|
||||
spec (merge-specs specs)]]
|
||||
(when-let [problems (and spec (s/explain-data spec data))]
|
||||
(rs/->Problem p method data spec problems)))
|
||||
(keep identity) (seq)))
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
(:require [clojure.test :refer [deftest testing is]]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.ring.spec :as rrs]
|
||||
[clojure.spec.alpha :as s]
|
||||
[reitit.core :as r]
|
||||
[reitit.spec :as rs])
|
||||
[expound.alpha :as e])
|
||||
#?(:clj
|
||||
(:import (clojure.lang ExceptionInfo))))
|
||||
|
||||
(s/def ::role #{:admin :user})
|
||||
(s/def ::roles (s/and (s/coll-of ::role :into #{}) set?))
|
||||
|
||||
(deftest route-data-validation-test
|
||||
(testing "validation is turned off by default"
|
||||
|
|
@ -27,13 +30,6 @@
|
|||
(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"
|
||||
|
|
@ -46,7 +42,38 @@
|
|||
|
||||
(testing "spec can be overridden"
|
||||
(is (true? (r/router?
|
||||
(ring/router
|
||||
["/api" {:handler "identity"}]
|
||||
{:spec (s/spec any?)
|
||||
:validate rrs/validate-spec!}))))
|
||||
|
||||
(testing "predicates are not allowed"
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Not all specs satisfy the Spec protocol"
|
||||
(ring/router
|
||||
["/api" {:handler "identity"}]
|
||||
{:spec any?
|
||||
:validate rrs/validate-spec!}))))))
|
||||
:validate rrs/validate-spec!})))))
|
||||
|
||||
(testing "middleware can contribute to specs"
|
||||
(is (true? (r/router?
|
||||
(ring/router
|
||||
["/api" {:get {:handler identity
|
||||
:roles #{:admin}}}]
|
||||
{:validate rrs/validate-spec!
|
||||
:data {:middleware [{:spec (s/keys :opt-un [::roles])
|
||||
:wrap (fn [handler]
|
||||
(fn [request]
|
||||
(handler request)))}]}}))))
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Invalid route data"
|
||||
(ring/router
|
||||
["/api" {:get {:handler identity
|
||||
:roles #{:adminz}}}]
|
||||
{:validate rrs/validate-spec!
|
||||
:data {:middleware [{:spec (s/keys :opt-un [::roles])
|
||||
:wrap (fn [handler]
|
||||
(fn [request]
|
||||
(handler request)))}]}})))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue