fix: per-content-type openapi w/ spec

This commit is contained in:
Joel Kaasinen 2023-03-03 11:47:01 +02:00
parent b149c8c5af
commit 2d60702769
2 changed files with 45 additions and 26 deletions

View file

@ -118,7 +118,9 @@
{::openapi/content {"application/json" (coercion/-compile-model this (:body parameters) nil)}})}) {::openapi/content {"application/json" (coercion/-compile-model this (:body parameters) nil)}})})
(when (:request parameters) (when (:request parameters)
{:requestBody (openapi/openapi-spec {:requestBody (openapi/openapi-spec
{::openapi/content (coercion/-compile-model this (:content (:request parameters)) nil)})}) {::openapi/content (into {}
(for [[format model] (:content (:request parameters))]
[format (coercion/-compile-model this model nil)]))})})
(when responses (when responses
{:responses {:responses
(into (into
@ -131,7 +133,9 @@
{::openapi/content {"application/json" (coercion/-compile-model this (:body response) nil)}})) {::openapi/content {"application/json" (coercion/-compile-model this (:body response) nil)}}))
(when (:content response) (when (:content response)
(openapi/openapi-spec (openapi/openapi-spec
{::openapi/content (coercion/-compile-model this (:content response) nil)})))]))}))) {::openapi/content (into {}
(for [[format model] (:content response)]
[format (coercion/-compile-model this model nil)]))})))]))})))
(throw (throw
(ex-info (ex-info
(str "Can't produce Spec apidocs for " specification) (str "Can't produce Spec apidocs for " specification)

View file

@ -385,15 +385,16 @@
(doseq [[coercion ->schema] (doseq [[coercion ->schema]
[[#'malli/coercion (fn [nom] [:map [nom :string]])] [[#'malli/coercion (fn [nom] [:map [nom :string]])]
[#'schema/coercion (fn [nom] {nom s/Str})] [#'schema/coercion (fn [nom] {nom s/Str})]
#_ ;; Doesn't work yet
[#'spec/coercion (fn [nom] {nom string?})]]] [#'spec/coercion (fn [nom] {nom string?})]]]
(testing coercion (testing coercion
(let [app (ring/ring-handler (let [app (ring/ring-handler
(ring/router (ring/router
[["/parameters" [["/parameters"
{:post {:coercion @coercion {:post {:coercion @coercion
:parameters {:request {:content {"application/json" (->schema :b)}}} :parameters {:request {:content {"application/json" (->schema :b)
:responses {200 {:content {"application/json" (->schema :ok)}}} "application/edn" (->schema :c)}}}
:responses {200 {:content {"application/json" (->schema :ok)
"application/edn" (->schema :edn)}}}
:handler (fn [req] :handler (fn [req]
{:status 200 {:status 200
:body (-> req :parameters :request)})}}] :body (-> req :parameters :request)})}}]
@ -407,38 +408,52 @@
app app
:body)] :body)]
(testing "body parameter" (testing "body parameter"
(is (= {:schema {:type "object" (is (match? {:schema {:type "object"
:properties {:b {:type "string"}} :properties {:b {:type "string"}}
:additionalProperties false #_#_:additionalProperties false ;; not present for spec
:required ["b"]}} :required ["b"]}}
(-> spec (-> spec
(get-in [:paths "/parameters" :post :requestBody :content "application/json"]) (get-in [:paths "/parameters" :post :requestBody :content "application/json"])
normalize)))) normalize)))
(is (match? {:schema {:type "object"
:properties {:c {:type "string"}}
#_#_:additionalProperties false ;; not present for spec
:required ["c"]}}
(-> spec
(get-in [:paths "/parameters" :post :requestBody :content "application/edn"])
normalize))))
(testing "body response" (testing "body response"
(is (= {:schema {:type "object" (is (match? {:schema {:type "object"
:properties {:ok {:type "string"}} :properties {:ok {:type "string"}}
:additionalProperties false #_#_:additionalProperties false ;; not present for spec
:required ["ok"]}} :required ["ok"]}}
(-> spec (-> spec
(get-in [:paths "/parameters" :post :responses 200 :content "application/json"]) (get-in [:paths "/parameters" :post :responses 200 :content "application/json"])
normalize)))) normalize)))
(is (match? {:schema {:type "object"
:properties {:edn {:type "string"}}
#_#_:additionalProperties false ;; not present for spec
:required ["edn"]}}
(-> spec
(get-in [:paths "/parameters" :post :responses 200 :content "application/edn"])
normalize))))
(testing "validation" (testing "validation"
(let [valid-query {:request-method :post (let [query {:request-method :post
:uri "/parameters" :uri "/parameters"
:muuntaja/request {:format "application/json"} :muuntaja/request {:format "application/json"}
:muuntaja/response {:format "application/json"} :muuntaja/response {:format "application/json"}
:body-params {:b "x"}}] :body-params {:b "x"}}]
(testing "of output" (testing "of output"
(is (= {:type :reitit.coercion/response-coercion (is (= {:type :reitit.coercion/response-coercion
:in [:response :body]} :in [:response :body]}
(try (try
(app (assoc valid-query :body-params {:b "x"})) (app query)
(catch clojure.lang.ExceptionInfo e (catch clojure.lang.ExceptionInfo e
(select-keys (ex-data e) [:type :in])))))) (select-keys (ex-data e) [:type :in]))))))
(testing "of input" (testing "of input"
(is (= {:type :reitit.coercion/request-coercion (is (= {:type :reitit.coercion/request-coercion
:in [:request :body-params]} :in [:request :body-params]}
(try (try
(app (assoc valid-query :body-params {:z 1})) (app (assoc query :body-params {:z 1}))
(catch clojure.lang.ExceptionInfo e (catch clojure.lang.ExceptionInfo e
(select-keys (ex-data e) [:type :in])))))))))))) (select-keys (ex-data e) [:type :in]))))))))))))