reitit/test/cljc/reitit/core_test.cljc

249 lines
9.7 KiB
Text
Raw Normal View History

2017-08-07 11:08:39 +00:00
(ns reitit.core-test
(:require [clojure.test :refer [deftest testing is are]]
2017-10-02 05:05:42 +00:00
[reitit.core :as r #?@(:cljs [:refer [Match Router]])])
2017-08-09 17:14:07 +00:00
#?(:clj
(:import (reitit.core Match Router)
(clojure.lang ExceptionInfo))))
2017-08-07 11:08:39 +00:00
(deftest reitit-test
2017-08-07 11:27:54 +00:00
(testing "routers handling wildcard paths"
(are [r name]
2017-11-24 07:01:05 +00:00
(testing "wild"
2017-08-09 17:14:07 +00:00
2017-11-24 07:01:05 +00:00
(testing "simple"
(let [router (r/router ["/api" ["/ipa" ["/:size" ::beer]]] {:router r})]
(is (= name (r/router-name router)))
(is (= [["/api/ipa/:size" {:name ::beer} nil]]
(r/routes router)))
2017-12-31 09:34:13 +00:00
(is (map? (r/options router)))
2017-11-24 07:01:05 +00:00
(is (= (r/map->Match
{:template "/api/ipa/:size"
:data {:name ::beer}
:path "/api/ipa/large"
2018-02-01 14:23:44 +00:00
:path-params {:size "large"}})
2017-11-24 07:01:05 +00:00
(r/match-by-path router "/api/ipa/large")))
(is (= (r/map->Match
{:template "/api/ipa/:size"
:data {:name ::beer}
:path "/api/ipa/large"
2018-02-01 14:23:44 +00:00
:path-params {:size "large"}})
2017-11-24 07:01:05 +00:00
(r/match-by-name router ::beer {:size "large"})))
2018-03-20 14:30:53 +00:00
(is (= (r/map->Match
{:template "/api/ipa/:size"
:data {:name ::beer}
:path "/api/ipa/large"
:path-params {:size "large"}})
(r/match-by-name router ::beer {:size :large})))
2017-11-24 07:01:05 +00:00
(is (= nil (r/match-by-name router "ILLEGAL")))
(is (= [::beer] (r/route-names router)))
(testing "name-based routing with missing parameters"
(is (= (r/map->PartialMatch
{:template "/api/ipa/:size"
:data {:name ::beer}
:required #{:size}
2018-02-01 14:23:44 +00:00
:path-params nil})
2017-11-24 07:01:05 +00:00
(r/match-by-name router ::beer)))
2017-12-31 09:34:13 +00:00
(is (r/partial-match? (r/match-by-name router ::beer)))
2017-11-24 07:01:05 +00:00
(is (thrown-with-msg?
ExceptionInfo
#"^missing path-params for route /api/ipa/:size -> \#\{:size\}$"
(r/match-by-name! router ::beer))))))
(testing "complex"
(let [router (r/router
[["/:abba" ::abba]
["/abba/1" ::abba2]
["/:jabba/2" ::jabba2]
["/:abba/:dabba/doo" ::doo]
["/abba/:dabba/boo" ::boo]
["/:jabba/:dabba/:doo/*foo" ::wild]]
{:router r})
2017-11-24 07:01:05 +00:00
matches #(-> router (r/match-by-path %) :data :name)]
(is (= ::abba (matches "/abba")))
(is (= ::abba2 (matches "/abba/1")))
(is (= ::jabba2 (matches "/abba/2")))
2017-11-24 07:01:05 +00:00
(is (= ::doo (matches "/abba/1/doo")))
(is (= ::boo (matches "/abba/1/boo")))
(is (= ::wild (matches "/olipa/kerran/avaruus/vaan/ei/toista/kertaa"))))))
2017-09-08 05:17:45 +00:00
r/linear-router :linear-router
2017-11-24 07:01:05 +00:00
r/segment-router :segment-router
r/mixed-router :mixed-router))
2017-08-09 17:14:07 +00:00
(testing "routers handling static paths"
(are [r name]
(let [router (r/router ["/api" ["/ipa" ["/large" ::beer]]] {:router r})]
(is (= name (r/router-name router)))
(is (= [["/api/ipa/large" {:name ::beer} nil]]
(r/routes router)))
2017-12-31 09:34:13 +00:00
(is (map? (r/options router)))
(is (= (r/map->Match
{:template "/api/ipa/large"
2017-11-18 10:47:16 +00:00
:data {:name ::beer}
:path "/api/ipa/large"
2018-02-01 14:23:44 +00:00
:path-params {}})
(r/match-by-path router "/api/ipa/large")))
(is (= (r/map->Match
{:template "/api/ipa/large"
2017-11-18 10:47:16 +00:00
:data {:name ::beer}
:path "/api/ipa/large"
2018-02-01 14:23:44 +00:00
:path-params {:size "large"}})
(r/match-by-name router ::beer {:size "large"})))
(is (= nil (r/match-by-name router "ILLEGAL")))
(is (= [::beer] (r/route-names router)))
(testing "can't be created with wildcard routes"
(is (thrown-with-msg?
ExceptionInfo
#"can't create :lookup-router with wildcard routes"
(r/lookup-router
(r/resolve-routes
["/api/:version/ping"] {}))))))
r/lookup-router :lookup-router
r/single-static-path-router :single-static-path-router
r/linear-router :linear-router
2017-11-24 07:01:05 +00:00
r/segment-router :segment-router
r/mixed-router :mixed-router))
2018-06-03 14:48:47 +00:00
(testing "nil routes are allowed ans stripped"
(is (= [] (r/routes (r/router nil))))
(is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]]))))
(is (= [["/ping" {} nil]] (r/routes (r/router [nil [nil] ["/ping"]]))))
(is (= [["/ping" {} nil]] (r/routes (r/router [[[nil [nil] ["/ping"]]]])))))
(testing "route coercion & compilation"
2017-09-08 05:17:45 +00:00
(testing "custom compile"
(let [compile-times (atom 0)
2017-11-18 10:47:16 +00:00
coerce (fn [[path data] _]
(if-not (:invalid? data)
[path (assoc data :path path)]))
compile (fn [[path data] _]
(swap! compile-times inc)
(constantly path))
2017-10-02 05:05:42 +00:00
router (r/router
["/api" {:roles #{:admin}}
["/ping" ::ping]
["/pong" ::pong]
["/hidden" {:invalid? true}
["/utter"]
["/crap"]]]
{:coerce coerce
:compile compile})]
2017-09-08 05:17:45 +00:00
(testing "routes are coerced"
(is (= [["/api/ping" {:name ::ping
:path "/api/ping",
:roles #{:admin}}]
["/api/pong" {:name ::pong
:path "/api/pong",
:roles #{:admin}}]]
2017-10-02 05:05:42 +00:00
(map butlast (r/routes router)))))
(testing "route match contains compiled handler"
(is (= 2 @compile-times))
2017-10-02 05:05:42 +00:00
(let [{:keys [result]} (r/match-by-path router "/api/pong")]
(is result)
(is (= "/api/pong" (result)))
(is (= 2 @compile-times))))))
2017-09-08 05:17:45 +00:00
(testing "default compile"
2017-10-02 05:05:42 +00:00
(let [router (r/router ["/ping" (constantly "ok")])]
(let [{:keys [result]} (r/match-by-path router "/ping")]
(is result)
(is (= "ok" (result)))))))
2017-08-11 13:02:08 +00:00
(testing "custom router"
2017-10-02 05:05:42 +00:00
(let [router (r/router ["/ping"] {:router (fn [_ _]
(reify Router
(r/router-name [_]
::custom)))})]
(is (= ::custom (r/router-name router)))))
2017-08-07 11:08:39 +00:00
(testing "bide sample"
(let [routes [["/auth/login" :auth/login]
["/auth/recovery/token/:token" :auth/recovery]
2017-08-07 11:27:54 +00:00
["/workspace/:project-uuid/:page-uuid" :workspace/page]]
expected [["/auth/login" {:name :auth/login}]
["/auth/recovery/token/:token" {:name :auth/recovery}]
["/workspace/:project-uuid/:page-uuid" {:name :workspace/page}]]]
2017-10-02 05:05:42 +00:00
(is (= expected (r/resolve-routes routes {})))))
2017-08-07 11:27:54 +00:00
2017-08-07 11:08:39 +00:00
(testing "ring sample"
(let [pong (constantly "ok")
routes ["/api" {:mw [:api]}
2017-08-07 11:27:54 +00:00
["/ping" :kikka]
["/user/:id" {:parameters {:id "String"}}
["/:sub-id" {:parameters {:sub-id "String"}}]]
["/pong" pong]
2017-08-07 11:27:54 +00:00
["/admin" {:mw [:admin] :roles #{:admin}}
2017-08-07 12:18:38 +00:00
["/user" {:roles ^:replace #{:user}}]
2017-08-07 11:27:54 +00:00
["/db" {:mw [:db]}]]]
expected [["/api/ping" {:mw [:api], :name :kikka}]
["/api/user/:id/:sub-id" {:mw [:api], :parameters {:id "String", :sub-id "String"}}]
["/api/pong" {:mw [:api], :handler pong}]
2017-08-07 11:27:54 +00:00
["/api/admin/user" {:mw [:api :admin], :roles #{:user}}]
["/api/admin/db" {:mw [:api :admin :db], :roles #{:admin}}]]
2017-10-02 05:05:42 +00:00
router (r/router routes)]
(is (= expected (r/resolve-routes routes {})))
(is (= (r/map->Match
{:template "/api/user/:id/:sub-id"
2017-11-18 10:47:16 +00:00
:data {:mw [:api], :parameters {:id "String", :sub-id "String"}}
:path "/api/user/1/2"
2018-02-01 14:23:44 +00:00
:path-params {:id "1", :sub-id "2"}})
2017-10-02 05:05:42 +00:00
(r/match-by-path router "/api/user/1/2"))))))
2017-08-21 17:44:16 +00:00
(deftest conflicting-routes-test
(are [conflicting? data]
2017-10-02 05:05:42 +00:00
(let [routes (r/resolve-routes data {})
conflicts (-> routes (r/resolve-routes {}) (r/conflicting-routes))]
2017-08-21 17:44:16 +00:00
(if conflicting? (seq conflicts) (nil? conflicts)))
true [["/a"]
["/a"]]
true [["/a"]
["/:b"]]
true [["/a"]
["/*b"]]
true [["/a/1/2"]
["/*b"]]
false [["/a"]
["/a/"]]
false [["/a"]
["/a/1"]]
false [["/a"]
["/a/:b"]]
false [["/a"]
["/a/*b"]]
true [["/v2/public/messages/dataset/bulk"]
2017-08-21 06:02:03 +00:00
["/v2/public/messages/dataset/:dataset-id"]])
2017-08-21 17:44:16 +00:00
(testing "all conflicts are returned"
(is (= {["/a" {}] #{["/*d" {}] ["/:b" {}]},
["/:b" {}] #{["/c" {}] ["/*d" {}]},
["/c" {}] #{["/*d" {}]}}
(-> [["/a"] ["/:b"] ["/c"] ["/*d"]]
2017-10-02 05:05:42 +00:00
(r/resolve-routes {})
(r/conflicting-routes)))))
2017-08-21 17:44:16 +00:00
2017-08-21 06:02:03 +00:00
(testing "router with conflicting routes"
(testing "throws by default"
(is (thrown-with-msg?
ExceptionInfo
2017-09-18 05:29:52 +00:00
#"Router contains conflicting routes"
2017-10-02 05:05:42 +00:00
(r/router
2017-08-21 06:02:03 +00:00
[["/a"] ["/a"]]))))
(testing "can be configured to ignore"
2017-10-02 05:05:42 +00:00
(is (not (nil? (r/router [["/a"] ["/a"]] {:conflicts (constantly nil)})))))))