diff --git a/modules/reitit-interceptors/src/reitit/http/interceptors/multipart.clj b/modules/reitit-interceptors/src/reitit/http/interceptors/multipart.clj index d616c689..4a2d4ba1 100644 --- a/modules/reitit-interceptors/src/reitit/http/interceptors/multipart.clj +++ b/modules/reitit-interceptors/src/reitit/http/interceptors/multipart.clj @@ -19,13 +19,17 @@ "Spec for file param created by ring.middleware.multipart-params.temp-file store." (st/spec {:spec (s/keys :req-un [::filename ::content-type ::tempfile ::size]) - :swagger/type "file"})) + :swagger/type "file" + :openapi {:type "string" + :format "binary"}})) (def bytes-part "Spec for file param created by ring.middleware.multipart-params.byte-array store." (st/spec {:spec (s/keys :req-un [::filename ::content-type ::bytes]) - :swagger/type "file"})) + :swagger/type "file" + :openapi {:type "string" + :format "binary"}})) (defn- coerced-request [request coercers] (if-let [coerced (if coercers (coercion/coerce-request coercers request))] diff --git a/modules/reitit-spec/src/reitit/coercion/spec.cljc b/modules/reitit-spec/src/reitit/coercion/spec.cljc index d453dd61..d5edd78b 100644 --- a/modules/reitit-spec/src/reitit/coercion/spec.cljc +++ b/modules/reitit-spec/src/reitit/coercion/spec.cljc @@ -108,7 +108,7 @@ (update $ :schema #(coercion/-compile-model this % nil)) $))]))}))) :openapi (merge - (when (seq (dissoc parameters :body :request)) + (when (seq (dissoc parameters :body :request :multipart)) (openapi/openapi-spec {::openapi/parameters (into (empty parameters) (for [[k v] (dissoc parameters :body :request)] @@ -124,6 +124,12 @@ (into {} (for [[format model] (:content (:request parameters))] [format (coercion/-compile-model this model nil)])))})}) + (when (:multipart parameters) + {:requestBody + (openapi/openapi-spec + {::openapi/content + {"multipart/form-data" + (coercion/-compile-model this (:multipart parameters) nil)}})}) (when responses {:responses (into diff --git a/test/cljc/reitit/openapi_test.clj b/test/cljc/reitit/openapi_test.clj index 3db5533f..0216ac8e 100644 --- a/test/cljc/reitit/openapi_test.clj +++ b/test/cljc/reitit/openapi_test.clj @@ -8,6 +8,7 @@ [reitit.coercion.malli :as malli] [reitit.coercion.schema :as schema] [reitit.coercion.spec :as spec] + [reitit.http.interceptors.multipart] [reitit.openapi :as openapi] [reitit.ring :as ring] [reitit.ring.spec] @@ -429,6 +430,39 @@ (testing "spec is valid" (is (nil? (validate spec)))))))) +(deftest multipart-test + (doseq [[coercion file-schema] + [#_[#'malli/coercion (fn [nom] [:map [nom :string]])] + #_[#'schema/coercion (fn [nom] {nom s/Str})] + [#'spec/coercion reitit.http.interceptors.multipart/bytes-part]]] + (testing coercion + (let [app (ring/ring-handler + (ring/router + [["/upload" + {:post {:decription "upload" + :coercion @coercion + :parameters {:multipart {:file file-schema}} + :handler identity}}] + ["/openapi.json" + {:get {:handler (openapi/create-openapi-handler) + :openapi {:info {:title "" :version "0.0.1"}} + :no-doc true}}]] + {:data {:middleware [openapi/openapi-feature]}})) + spec (-> {:request-method :get + :uri "/openapi.json"} + app + :body)] + (testing "multipart body" + (is (= {:requestBody {:content {"multipart/form-data" {:schema {:type "object" + :properties {"file" {:type "string" + :format "binary"}} + :required ["file"]}}}}} + (-> spec + (get-in [:paths "/upload" :post]) + #_normalize)))) + (testing "spec is valid" + (is (nil? (validate spec)))))))) + (deftest per-content-type-test (doseq [[coercion ->schema] [[#'malli/coercion (fn [nom] [:map [nom :string]])]