From 26dcbef5d1074430434f09cafd11e90a27ed89bb Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 14:06:45 +0300 Subject: [PATCH 1/8] Add tests for missing sieppari asyncs --- test/clj/reitit/http_test.clj | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/test/clj/reitit/http_test.clj b/test/clj/reitit/http_test.clj index 8c2c5ba4..cf6a807e 100644 --- a/test/clj/reitit/http_test.clj +++ b/test/clj/reitit/http_test.clj @@ -6,7 +6,8 @@ [reitit.interceptor.sieppari :as sieppari] [reitit.http :as http] [reitit.ring :as ring] - [reitit.core :as r]) + [reitit.core :as r] + [clojure.core.async :as a]) (:import (clojure.lang ExceptionInfo))) (defn interceptor [name] @@ -281,6 +282,37 @@ (is (= 406 (:status (respond)))) (is (= ::nil (raise)))))))))) +(deftest core-async-test + (testing "works if registered" + (require '[sieppari.async.core-async]) + (let [response {:status 200, :body "ok"} + app (http/ring-handler + (http/router + ["/ping" {:get {:interceptors [{:enter #(a/go %)}] + :handler (fn [_] (a/go response))}}]) + (ring/create-default-handler) + {:executor sieppari/executor})] + (let [respond (promise)] + (app {:request-method :get, :uri "/ping"} respond ::irrelevant) + (is (= response @respond)))))) + +(defrecord MyAsyncContext []) + +(deftest unknown-async-test + (testing "works if registered" + (require '[sieppari.async.core-async]) + (let [response {:status 200, :body "ok"} + app (http/ring-handler + (http/router + ["/ping" {:get {:interceptors [{:enter map->MyAsyncContext}] + :handler (fn [_] response)}}]) + (ring/create-default-handler) + {:executor sieppari/executor})] + (let [raise (promise)] + (app {:request-method :get, :uri "/ping"} ::irrelevant raise) + (let [response' @raise] + (is (instance? ExceptionInfo response'))))))) + (deftest interceptor-transform-test (let [interceptor (fn [name] {:name name :enter (fn [ctx] From 5cd1cfa5e2be6095bb3de52a1df066a30e836f20 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 14:07:03 +0300 Subject: [PATCH 2/8] Update to latest swagger-ui --- CHANGELOG.md | 2 +- project.clj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03150b9c..336721c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Sat, 16 May 2020 14:08:08 +0300 Subject: [PATCH 3/8] Update swagger test --- test/cljc/reitit/swagger_test.clj | 270 +++++++++++++++++------------- 1 file changed, 151 insertions(+), 119 deletions(-) diff --git a/test/cljc/reitit/swagger_test.clj b/test/cljc/reitit/swagger_test.clj index 1e5b24f8..ba3c4566 100644 --- a/test/cljc/reitit/swagger_test.clj +++ b/test/cljc/reitit/swagger_test.clj @@ -9,7 +9,8 @@ [reitit.coercion.schema :as schema] [schema.core :refer [Int]] [muuntaja.core :as m] - [spec-tools.data-spec :as ds])) + [spec-tools.data-spec :as ds] + [schema.core :as s])) (def app (ring/ring-handler @@ -79,40 +80,147 @@ 500 {:description "fail"}} :handler (fn [{{{:keys [x y]} :query {:keys [z]} :path} :parameters}] - {:status 200, :body {:total (+ x y z)}})}}]]] + {:status 200, :body {:total (+ x y z)}})} + :post {:summary "plus with body" + :parameters {:body (s/maybe [s/Int]) + :path {:z s/Int}} + :swagger {:responses {400 {:schema {:type "string"} + :description "kosh"}}} + :responses {200 {:body {:total s/Int}} + 500 {:description "fail"}} + :handler (fn [{{{:keys [z]} :path + xs :body} :parameters}] + {:status 200, :body {:total (+ (reduce + xs) z)}})}}]]] {:data {:middleware [swagger/swagger-feature rrc/coerce-exceptions-middleware rrc/coerce-request-middleware rrc/coerce-response-middleware]}}))) +(require '[fipp.edn]) (deftest swagger-test (testing "endpoints work" (testing "spec" (is (= {:body {:total 6}, :status 200} - (app - {:request-method :get - :uri "/api/spec/plus/3" - :query-params {:x "2", :y "1"}}))) + (app {:request-method :get + :uri "/api/spec/plus/3" + :query-params {:x "2", :y "1"}}))) (is (= {:body {:total 7}, :status 200} - (app - {:request-method :post - :uri "/api/spec/plus/3" - :body-params [1 3]})))) + (app {:request-method :post + :uri "/api/spec/plus/3" + :body-params [1 3]})))) (testing "schema" (is (= {:body {:total 6}, :status 200} - (app - {:request-method :get - :uri "/api/schema/plus/3" - :query-params {:x "2", :y "1"}}))))) + (app {:request-method :get + :uri "/api/schema/plus/3" + :query-params {:x "2", :y "1"}}))))) (testing "swagger-spec" - (let [spec (:body (app - {:request-method :get - :uri "/api/swagger.json"})) + (let [spec (:body (app {:request-method :get + :uri "/api/swagger.json"})) expected {:x-id #{::math} :swagger "2.0" :info {:title "my-api"} - :paths {"/api/schema/plus/{z}" {:get {:parameters [{:description "" + :paths {"/api/spec/plus/{z}" {:get {:parameters [{:in "query" + :name "x" + :description "" + :required true + :type "integer" + :format "int64"} + {:in "query" + :name "y" + :description "" + :required true + :type "integer" + :format "int64"} + {:in "path" + :name "z" + :description "" + :required true + :type "integer" + :format "int64"}] + :responses {200 {:description "" + :schema {:type "object" + :properties {"total" {:format "int64" + :type "integer"}} + :required ["total"]}} + 400 {:schema {:type "string"} + :description "kosh"} + 500 {:description "fail"}} + :summary "plus"} + :post {:parameters [{:in "body", + :name "", + :description "", + :required false, + :schema {:type "array", + :items {:type "integer", + :format "int64"} + :x-nullable true}} + {:in "path" + :name "z" + :description "" + :type "integer" + :required true + :format "int64"}] + :responses {200 {:schema {:properties {"total" {:format "int64" + :type "integer"}} + :required ["total"] + :type "object"} + :description ""} + 400 {:schema {:type "string"} + :description "kosh"} + 500 {:description "fail"}} + :summary "plus with body"}} + "/api/malli/plus/{z}" {:get {:parameters [{:in "query" + :name :x + :description "" + :required true + :type "integer" + :format "int64"} + {:in "query" + :name :y + :description "" + :required true + :type "integer" + :format "int64"} + {:in "path" + :name :z + :description "" + :required true + :type "integer" + :format "int64"}] + :responses {200 {:schema {:type "object" + :properties {:total {:format "int64" + :type "integer"}} + :required [:total]} + :description ""} + 400 {:schema {:type "string"} + :description "kosh"} + 500 {:description "fail"}} + :summary "plus"} + :post {:parameters [{:in "body", + :name "body", + :description "", + :required false, + :schema {:type "array", + :items {:type "integer", + :format "int64"} + :x-nullable true}} + {:in "path" + :name :z + :description "" + :type "integer" + :required true + :format "int64"}] + :responses {200 {:description "" + :schema {:properties {:total {:format "int64" + :type "integer"}} + :required [:total] + :type "object"}} + 400 {:schema {:type "string"} + :description "kosh"} + 500 {:description "fail"}} + :summary "plus with body"}} + "/api/schema/plus/{z}" {:get {:parameters [{:description "" :format "int32" :in "query" :name "x" @@ -139,107 +247,31 @@ 400 {:schema {:type "string"} :description "kosh"} 500 {:description "fail"}} - :summary "plus"}} - "/api/malli/plus/{z}" {:get {:parameters [{:description "" - :format "int64" - :in "query" - :name :x - :required true - :type "integer"} - {:description "" - :format "int64" - :in "query" - :name :y - :required true - :type "integer"} - {:in "path" - :name :z - :description "" - :type "integer" - :required true - :format "int64"}] - :responses {200 {:description "" - :schema {:properties {:total {:format "int64" - :type "integer"}} - :required [:total] - :type "object"}} - 400 {:schema {:type "string"} - :description "kosh"} - 500 {:description "fail"}} - :summary "plus"} - :post {:parameters [{:in "body", - :name "", - :description "", - :required false, - :schema {:type "array", - :items {:type "integer", - :format "int64"} - :x-nullable true}} - {:in "path" - :name :z - :description "" - :type "integer" - :required true - :format "int64"}] - :responses {200 {:description "" - :schema {:properties {:total {:format "int64" - :type "integer"}} - :required [:total] - :type "object"}} - 400 {:schema {:type "string"} - :description "kosh"} - 500 {:description "fail"}} - :summary "plus with body"}} - "/api/spec/plus/{z}" {:get {:parameters [{:description "" - :format "int64" - :in "query" - :name "x" - :required true - :type "integer"} - {:description "" - :format "int64" - :in "query" - :name "y" - :required true - :type "integer"} - {:in "path" - :name "z" - :description "" - :type "integer" - :required true - :format "int64"}] - :responses {200 {:description "" - :schema {:properties {"total" {:format "int64" - :type "integer"}} - :required ["total"] - :type "object"}} - 400 {:schema {:type "string"} - :description "kosh"} - 500 {:description "fail"}} - :summary "plus"} - :post {:parameters [{:in "body", - :name "", - :description "", - :required false, - :schema {:type "array", - :items {:type "integer", - :format "int64"} - :x-nullable true}} - {:in "path" - :name "z" - :description "" - :type "integer" - :required true - :format "int64"}] - :responses {200 {:description "" - :schema {:properties {"total" {:format "int64" - :type "integer"}} - :required ["total"] - :type "object"}} - 400 {:schema {:type "string"} - :description "kosh"} - 500 {:description "fail"}} - :summary "plus with body"}}}}] + :summary "plus"} + :post {:parameters [{:in "body", + :name "body", + :description "", + :required false, + :schema {:type "array", + :items {:type "integer", + :format "int32"} + :x-nullable true}} + {:in "path" + :name "z" + :description "" + :type "integer" + :required true + :format "int32"}] + :responses {200 {:description "" + :schema {:properties {"total" {:format "int32" + :type "integer"}} + :additionalProperties false + :required ["total"] + :type "object"}} + 400 {:schema {:type "string"} + :description "kosh"} + 500 {:description "fail"}} + :summary "plus with body"}}}}] (is (= expected spec)) (testing "ring-async swagger-spec" From 39aafc902986c8ab394b85f60e2e30297430e469 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 14:08:16 +0300 Subject: [PATCH 4/8] Fix malli + swagger --- CHANGELOG.md | 4 ++++ modules/reitit-malli/src/reitit/coercion/malli.cljc | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 336721c0..e21f2d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,10 @@ is called the first time, so that `rfe/push-state` and such can be called * lots of bug fixes, see [spec-tools changelog](https://github.com/metosin/spec-tools/blob/master/CHANGELOG.md#0102-2020-05-05) +### `reitit-malli` + +* Swagger body-parameters don't use empty default, fixes [#399](https://github.com/metosin/reitit/issues/399) + ### `reitit-sieppari` * changes from Sieppari: diff --git a/modules/reitit-malli/src/reitit/coercion/malli.cljc b/modules/reitit-malli/src/reitit/coercion/malli.cljc index 45124991..3e57ef28 100644 --- a/modules/reitit-malli/src/reitit/coercion/malli.cljc +++ b/modules/reitit-malli/src/reitit/coercion/malli.cljc @@ -80,7 +80,7 @@ (defmethod extract-parameter :body [_ schema options] (let [swagger-schema (swagger/transform schema (merge options {:in :body, :type :parameter}))] [{:in "body" - :name (:title swagger-schema "") + :name (:title swagger-schema "body") :description (:description swagger-schema "") :required (not= :maybe (m/name schema)) :schema swagger-schema}])) From 6777cb8620aa66aeb80da4534fcbf5d5dfb77d49 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 14:25:28 +0300 Subject: [PATCH 5/8] spec-tools 0.10.3 --- CHANGELOG.md | 2 +- project.clj | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e21f2d60..b5a79584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Sat, 16 May 2020 17:34:55 +0300 Subject: [PATCH 6/8] Update sieppari, fix tests --- project.clj | 2 +- test/clj/reitit/http_test.clj | 14 +++++++------- test/cljc/reitit/swagger_test.clj | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/project.clj b/project.clj index 2ab60aa2..85325b45 100644 --- a/project.clj +++ b/project.clj @@ -32,7 +32,7 @@ [metosin/schema-tools "0.12.2"] [metosin/muuntaja "0.6.7"] [metosin/jsonista "0.2.6"] - [metosin/sieppari "0.0.0-alpha9"] + [metosin/sieppari "0.0.0-alpha10"] [metosin/malli "0.0.1-20200404.091302-14"] ;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111 diff --git a/test/clj/reitit/http_test.clj b/test/clj/reitit/http_test.clj index cf6a807e..766d8dc7 100644 --- a/test/clj/reitit/http_test.clj +++ b/test/clj/reitit/http_test.clj @@ -294,24 +294,24 @@ {:executor sieppari/executor})] (let [respond (promise)] (app {:request-method :get, :uri "/ping"} respond ::irrelevant) - (is (= response @respond)))))) + (is (= response (deref respond 100 ::timeout))))))) (defrecord MyAsyncContext []) (deftest unknown-async-test (testing "works if registered" - (require '[sieppari.async.core-async]) (let [response {:status 200, :body "ok"} app (http/ring-handler (http/router ["/ping" {:get {:interceptors [{:enter map->MyAsyncContext}] :handler (fn [_] response)}}]) (ring/create-default-handler) - {:executor sieppari/executor})] - (let [raise (promise)] - (app {:request-method :get, :uri "/ping"} ::irrelevant raise) - (let [response' @raise] - (is (instance? ExceptionInfo response'))))))) + {:executor sieppari/executor}) + respond (promise) + raise (promise)] + (app {:request-method :get, :uri "/ping"} respond raise) + (let [raised (deref raise 100 ::timeout)] + (is (instance? ExceptionInfo raised)))))) (deftest interceptor-transform-test (let [interceptor (fn [name] {:name name diff --git a/test/cljc/reitit/swagger_test.clj b/test/cljc/reitit/swagger_test.clj index ba3c4566..5ef99a63 100644 --- a/test/cljc/reitit/swagger_test.clj +++ b/test/cljc/reitit/swagger_test.clj @@ -148,7 +148,7 @@ 500 {:description "fail"}} :summary "plus"} :post {:parameters [{:in "body", - :name "", + :name "body", :description "", :required false, :schema {:type "array", From 95fe8c36352f6c8d8a6a4b72539c0640730d940d Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 17:48:19 +0300 Subject: [PATCH 7/8] Add return values to enable file return in swagger-ui --- examples/http-swagger/src/example/server.clj | 1 + examples/pedestal-swagger/src/example/server.clj | 1 + examples/ring-malli-swagger/src/example/server.clj | 1 + examples/ring-spec-swagger/src/example/server.clj | 1 + examples/ring-swagger/src/example/server.clj | 1 + 5 files changed, 5 insertions(+) diff --git a/examples/http-swagger/src/example/server.clj b/examples/http-swagger/src/example/server.clj index d652cdb4..7b0b381f 100644 --- a/examples/http-swagger/src/example/server.clj +++ b/examples/http-swagger/src/example/server.clj @@ -59,6 +59,7 @@ ["/download" {:get {:summary "downloads a file" :swagger {:produces ["image/png"]} + :responses {200 {:description "image"}} :handler (fn [_] {:status 200 :headers {"Content-Type" "image/png"} diff --git a/examples/pedestal-swagger/src/example/server.clj b/examples/pedestal-swagger/src/example/server.clj index 69b2f865..4d8191b5 100644 --- a/examples/pedestal-swagger/src/example/server.clj +++ b/examples/pedestal-swagger/src/example/server.clj @@ -58,6 +58,7 @@ ["/download" {:get {:summary "downloads a file" :swagger {:produces ["image/png"]} + :responses {200 {:description "image"}} :handler (fn [_] {:status 200 :headers {"Content-Type" "image/png"} diff --git a/examples/ring-malli-swagger/src/example/server.clj b/examples/ring-malli-swagger/src/example/server.clj index 1a5d7d89..e05d847e 100644 --- a/examples/ring-malli-swagger/src/example/server.clj +++ b/examples/ring-malli-swagger/src/example/server.clj @@ -44,6 +44,7 @@ ["/download" {:get {:summary "downloads a file" :swagger {:produces ["image/png"]} + :responses {200 {:description "image"}} :handler (fn [_] {:status 200 :headers {"Content-Type" "image/png"} diff --git a/examples/ring-spec-swagger/src/example/server.clj b/examples/ring-spec-swagger/src/example/server.clj index 69615800..7b8c6cb9 100644 --- a/examples/ring-spec-swagger/src/example/server.clj +++ b/examples/ring-spec-swagger/src/example/server.clj @@ -54,6 +54,7 @@ ["/download" {:get {:summary "downloads a file" :swagger {:produces ["image/png"]} + :responses {200 {:description "image"}} :handler (fn [_] {:status 200 :headers {"Content-Type" "image/png"} diff --git a/examples/ring-swagger/src/example/server.clj b/examples/ring-swagger/src/example/server.clj index 8416c2b4..bf010440 100644 --- a/examples/ring-swagger/src/example/server.clj +++ b/examples/ring-swagger/src/example/server.clj @@ -41,6 +41,7 @@ ["/download" {:get {:summary "downloads a file" :swagger {:produces ["image/png"]} + :responses {200 {:description "image"}} :handler (fn [_] {:status 200 :headers {"Content-Type" "image/png"} From bdfae526bb7184dcb20d40800c81403d3430641d Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Sat, 16 May 2020 17:53:43 +0300 Subject: [PATCH 8/8] Fix async examples --- examples/http-swagger/src/example/server.clj | 1 + examples/http/src/example/server.clj | 2 ++ 2 files changed, 3 insertions(+) diff --git a/examples/http-swagger/src/example/server.clj b/examples/http-swagger/src/example/server.clj index 7b0b381f..b23f7bf8 100644 --- a/examples/http-swagger/src/example/server.clj +++ b/examples/http-swagger/src/example/server.clj @@ -21,6 +21,7 @@ [clojure.java.io :as io] [clojure.spec.alpha :as s] [spec-tools.core :as st] + [sieppari.async.manifold] [manifold.deferred :as d])) (s/def ::x int?) diff --git a/examples/http/src/example/server.clj b/examples/http/src/example/server.clj index adc6a90d..021e11ff 100644 --- a/examples/http/src/example/server.clj +++ b/examples/http/src/example/server.clj @@ -2,6 +2,8 @@ (:require [reitit.http :as http] [reitit.ring :as ring] [reitit.interceptor.sieppari] + [sieppari.async.core-async] ;; needed for core.async + [sieppari.async.manifold] ;; needed for manifold [ring.adapter.jetty :as jetty] [muuntaja.interceptor] [clojure.core.async :as a]