Codebase list comidi-clojure / a32e6ff test / puppetlabs / comidi_test.clj
a32e6ff

Tree @a32e6ff (Download .tar.gz)

comidi_test.clj @a32e6ffraw · history · blame

(ns puppetlabs.comidi-test
  (require [clojure.test :refer :all]
           [puppetlabs.comidi :as comidi]
           [schema.test :as schema-test]
           [puppetlabs.comidi :refer :all]
           [schema.core :as schema]
           [clojure.zip :as zip]))

(use-fixtures :once schema-test/validate-schemas)

(defn replace-regexes-for-equality-check
  [xs]
  (loop [loc (zip/vector-zip xs)]
    (if (zip/end? loc)
      (zip/root loc)
      (recur
        (let [node (zip/node loc)]
          (if (pattern? node)
            (zip/edit loc #(str "REGEX: " (.pattern %)))
            (zip/next loc)))))))

(deftest handler-schema-test
  (testing "handler schema"
    (is (nil? (schema/check Handler :foo)))
    (is (nil? (schema/check Handler (fn [] :foo))))
    (is (nil? (schema/check Handler {:get (fn [] :foo)})))
    (is (nil? (schema/check Handler {:post :foo})))))

(deftest pattern-schema-test
  (testing "pattern schema"
    (is (nil? (schema/check BidiPattern "/foo")))
    (is (nil? (schema/check BidiPattern :foo)))
    (is (nil? (schema/check BidiPattern ["/foo/" :foo "/foo"])))
    (is (nil? (schema/check BidiPattern ["/foo/" [#".*" :rest]])))))

(deftest destination-schema-test
  (testing "route destination schema"
    (is (nil? (schema/check BidiRouteDestination :foo)))
    (is (nil? (schema/check BidiRouteDestination (fn [] nil))))
    (is (nil? (schema/check BidiRouteDestination {:get (fn [] nil)})))
    (is (nil? (schema/check BidiRouteDestination {:get :my-handler})))
    (is (nil? (schema/check BidiRouteDestination [[["/foo/" :foo "/foo"] :foo]])))
    (is (not (nil? (schema/check BidiRouteDestination [["/foo/" :foo "/foo"] :foo]))))
    (is (nil? (schema/check BidiRouteDestination [[["/foo/" :foo]
                                                   :foo-handler]
                                                  [["/bar/" :bar]
                                                   {:get :bar-handler}]])))))

(deftest route-schema-test
  (testing "route schema"
    (is (nil? (schema/check BidiRoute [:foo :foo])))
    (is (nil? (schema/check BidiRoute ["/foo" [[:foo :foo]]])))
    (is (not (nil? (schema/check BidiRoute ["/foo" [:foo :foo]]))))
    (is (nil? (schema/check BidiRoute ["" [[["/foo/" :foo]
                                            :foo-handler]
                                           [["/bar/" :bar]
                                            {:get :bar-handler}]]])))))

(deftest update-route-info-test
  (let [orig-route-info {:path           []
                         :request-method :any}]
    (testing "HTTP verb keyword causes request-method to be updated"
      (doseq [verb [:get :post :put :delete :head]]
        (is (= {:path           []
                :request-method verb}
               (update-route-info* orig-route-info verb)))))
    (testing "string path elements get added to the path"
      (is (= {:path           ["/foo"]
              :request-method :any}
             (update-route-info* orig-route-info "/foo"))))
    (testing "keyword path elements get added to the path"
      (is (= {:path           [:foo]
              :request-method :any}
             (update-route-info* orig-route-info :foo))))
    (testing "vector path elements get flattened and added to the path"
      (is (= {:path           ["/foo/" :foo]
              :request-method :any}
             (update-route-info* orig-route-info ["/foo/" :foo]))))
    (testing "regex path element gets added to the path"
      (is (= {:path ["/foo/" ["REGEX: .*" :foo]]
              :request-method :any}
             (-> (update-route-info* orig-route-info ["/foo/" [#".*" :foo]])
                 (update-in [:path] replace-regexes-for-equality-check)))))))

(deftest route-metadata-test
  (testing "route metadata includes ordered list of routes and lookup by handler"
    (let [routes ["" [[["/foo/" :foo]
                       :foo-handler]
                      [["/bar/" :bar]
                       [["/baz" {:get :baz-handler}]
                        ["/bam" {:put :bam-handler}]
                        ["/bap" {:any :bap-handler}]]]
                      ["/buzz" {:post :buzz-handler}]]]
          expected-foo-meta {:path '("" "/foo/" :foo)
                             :request-method :any}
          expected-baz-meta {:path '("" "/bar/" :bar "/baz")
                             :request-method :get}
          expected-bam-meta {:path '("" "/bar/" :bar "/bam")
                             :request-method :put}
          expected-bap-meta {:path '("" "/bar/" :bar "/bap")
                             :request-method :any}
          expected-buzz-meta {:path '("" "/buzz")
                              :request-method :post}]
      (is (= (comidi/route-metadata routes)
             {:routes [expected-foo-meta
                       expected-baz-meta
                       expected-bam-meta
                       expected-bap-meta
                       expected-buzz-meta]
              :handlers {:foo-handler expected-foo-meta
                         :baz-handler expected-baz-meta
                         :bam-handler expected-bam-meta
                         :bap-handler expected-bap-meta
                         :buzz-handler expected-buzz-meta}})))))

(deftest routes-test
  (is (= ["" [["/foo" :foo-handler]
              [["/bar/" :bar] :bar-handler]]]
         (routes ["/foo" :foo-handler]
                 [["/bar/" :bar] :bar-handler]))))

(deftest context-test
  (testing "simple context"
    (is (= ["/foo" [["/bar" :bar-handler]
                    [["/baz" :baz] :baz-handler]]]
           (context "/foo"
                    ["/bar" :bar-handler]
                    [["/baz" :baz] :baz-handler]))))
  (testing "context with variable"
    (is (= [["/foo" :foo] [["/bar" :bar-handler]
                           [["/baz" :baz] :baz-handler]]]
           (context ["/foo" :foo]
                    ["/bar" :bar-handler]
                    [["/baz" :baz] :baz-handler])))))

(deftest routes->handler-test
  (testing "routes are matched against a request properly, with route params"
    (let [handler (routes->handler ["/foo"
                                    [[""
                                      [["/bar"
                                        (fn [req] :bar)]
                                       [["/baz/" :baz]
                                        (fn [req]
                                          {:endpoint :baz
                                           :route-params (:route-params req)})]]]]])]
      (is (= :bar (handler {:uri "/foo/bar"})))
      (is (= {:endpoint :baz
              :route-params {:baz "howdy"}}
             (handler {:uri "/foo/baz/howdy"})))))
  (testing "request-methods are honored"
    (let [handler (routes->handler ["/foo" {:get (fn [req] :foo)}])]
      (is (nil? (handler {:uri "/foo"})))
      (is (= :foo (handler {:uri "/foo" :request-method :get})))))
  (testing "contexts can bind route variables"
    (let [handler (routes->handler
                    (context ["/foo/" :foo]
                             [["/bar/" :bar]
                              (fn [req] (:route-params req))]))]
      (is (= {:foo "hi"
              :bar "there"}
             (handler {:uri "/foo/hi/bar/there"})))))
  (testing "route metadata is added to fn metadata"
    (let [foo-handler (fn [req] :foo)
          handler (routes->handler ["/foo" {:get foo-handler}])]
      (let [route-meta (:route-metadata (meta handler))]
        (is (= {:routes [{:path           ["/foo"]
                          :request-method :get}]
                :handlers {foo-handler {:path           ["/foo"]
                                        :request-method :get}}}
               route-meta))))))

(deftest routes->handler-middleware-test
  (let [handler (routes->handler
                  (context ["/foo/" :foo]
                           [["/bar/" :bar]
                            (fn [req] (:route-params req))])
                  (fn [f]
                    (fn [req]
                      {:result (f req)
                       :route-info (:route-info req)})))]
    (is (= {:result {:foo "hi"
                     :bar "there"}
            :route-info {:path ["/foo/" :foo "/bar/" :bar]
                         :request-method :any}}
           (handler {:uri "/foo/hi/bar/there"})))))

(deftest context-handler-test
  (let [handler (context-handler ["/foo/" :foo]
                                 [["/bar/" :bar]
                                  (fn [req] (:route-params req))])]
    (is (= {:foo "hi"
            :bar "there"}
           (handler {:uri "/foo/hi/bar/there"})))))


(deftest compojure-macros-test
  (let [routes (context ["/foo/" :foo]
                        (ANY ["/any/" :any] [foo any]
                             (str "foo: " foo " any: " any))
                        (GET ["/get/" :get] [foo get]
                             (fn [req] {:foo foo
                                        :get get}))
                        (HEAD ["/head/" :head] [foo head]
                              {:foo foo
                               :head head})
                        (PUT "/put" [foo]
                             {:status 500
                              :body foo})
                        (POST ["/post/" :post] [post]
                              post)
                        (DELETE ["/delete/" :delete] [foo delete]
                                (atom {:foo foo
                                       :delete delete})))
        handler (routes->handler routes)]
    (is (nil? (handler {:uri "/foo/hi/get/there" :request-method :post})))
    (is (nil? (handler {:uri "/foo/hi/head/there" :request-method :get})))
    (is (nil? (handler {:uri "/foo/hi/put" :request-method :get})))
    (is (nil? (handler {:uri "/foo/hi/post/there" :request-method :get})))
    (is (nil? (handler {:uri "/foo/hi/delete/there" :request-method :get})))

    (is (= "foo: hi any: there" (:body (handler {:uri "/foo/hi/any/there"}))))
    (is (= {:foo "hi"
            :get "there"}
           (select-keys
             (handler {:uri "/foo/hi/get/there" :request-method :get})
             [:foo :get])))
    (is (= {:foo "hi"
            :head "there"}
           (select-keys
             (handler {:uri "/foo/hi/head/there" :request-method :head})
             [:foo :head])))
    (is (= {:status 500
            :body "hi"}
           (select-keys
             (handler {:uri "/foo/hi/put" :request-method :put})
             [:status :body])))
    (is (= {:status 200
            :body "there"}
           (select-keys
             (handler {:uri "/foo/hi/post/there" :request-method :post})
             [:status :body])))
    (is (= {:status 200
            :foo "hi"
            :delete "there"}
           (select-keys
             (handler {:uri "/foo/hi/delete/there" :request-method :delete})
             [:status :foo :delete])))))

(deftest not-found-test
  (testing "root not-found handler"
    (let [handler (routes->handler (not-found "nobody's home, yo"))]
      (is (= {:status 404
              :body   "nobody's home, yo"}
             (select-keys
               (handler {:uri "/hi/there"})
               [:body :status])))))
  (testing "nested not-found handler"
    (let [handler (routes->handler
                    (routes
                      ["/bar" [["" (fn [req] :bar)]
                               (not-found "nothing else under bar!")]]
                      (not-found "nothing else under root!")))]
      (is (= :bar (handler {:uri "/bar"})))
      (is (= {:status 404
              :body "nothing else under bar!"}
             (select-keys
               (handler {:uri "/bar/baz"})
               [:status :body])))
      (is (= {:status 404
              :body "nothing else under root!"}
             (select-keys
               (handler {:uri "/yo/mang"})
               [:status :body]))))))

(deftest regex-test
  (let [handler (routes->handler
                  ["/foo" [[["/boo/" [#".*" :rest]]
                             (fn [req] (:rest (:route-params req)))]]])]
    (is (= "hi/there"
           (handler {:uri "/foo/boo/hi/there"})))))