Repository: oliyh/martian
Pull request #164 (2023-02-14 18:18:44)

add support for the deprecated field on the operation
When an operation is deprecated in the openapi spec this PR makes the `deprecated` field available when exploring the endpoint.


oliyh: Hi,

Thanks for the contribution! There are some failing tests in `martian.core-test` that need updating, and I've left a couple of comments too.

Cheers
wkok: Updated with your suggestions.
The tests that still fail seems to do with a host that's maybe not running?
wkok: Updated with your suggestions.

The tests that still fail seems to be related to some host?
`ERROR - GET https://pedestal-api.herokuapp.com/swagger.json's callback `

Patch:
diff --git a/core/src/martian/core.cljc b/core/src/martian/core.cljc
index f306c0c..b48f3e7 100644
--- a/core/src/martian/core.cljc
+++ b/core/src/martian/core.cljc
@@ -107,15 +107,16 @@
 (defn explore
   ([martian] (mapv (juxt :route-name :summary) (:handlers (resolve-instance martian))))
   ([martian route-name]
-   (when-let [{:keys [parameter-aliases summary] :as handler} (find-handler (:handlers (resolve-instance martian)) route-name)]
-     {:summary summary
-      :parameters (reduce (fn [params parameter-key]
-                            (merge params (alias-schema (get parameter-aliases parameter-key) (get handler parameter-key))))
-                          {}
-                          parameter-schemas)
-      :returns (->> (:response-schemas handler)
-                    (map (juxt (comp :v :status) :body))
-                    (into {}))})))
+   (when-let [{:keys [parameter-aliases summary deprecated?] :as handler} (find-handler (:handlers (resolve-instance martian)) route-name)]
+     (-> {:summary summary
+          :parameters (reduce (fn [params parameter-key]
+                                (merge params (alias-schema (get parameter-aliases parameter-key) (get handler parameter-key))))
+                              {}
+                              parameter-schemas)
+          :returns (->> (:response-schemas handler)
+                        (map (juxt (comp :v :status) :body))
+                        (into {}))}
+         (cond-> deprecated? (assoc :deprecated? true))))))
 
 (defn- build-instance [api-root handlers {:keys [interceptors] :as opts}]
   (->Martian api-root handlers (or interceptors default-interceptors) (dissoc opts :interceptors)))
diff --git a/core/src/martian/openapi.cljc b/core/src/martian/openapi.cljc
index 710daa4..6a991ca 100644
--- a/core/src/martian/openapi.cljc
+++ b/core/src/martian/openapi.cljc
@@ -177,17 +177,18 @@
                 responses  (process-responses (update-vals-future (:responses definition)
                                                                   (partial resolve-ref components))
                                               components (:decodes content-types))]]
-      {:path-parts         (vec (tokenise-path url))
-       :method             method
-       :path-schema        (process-parameters (:path parameters) components)
-       :query-schema       (process-parameters (:query parameters) components)
-       :body-schema        (:schema body)
-       :form-schema        (process-parameters (:form parameters) components)
-       :headers-schema     (process-parameters (:header parameters) components)
-       :response-schemas   (vec (keep #(dissoc % :content-type) responses))
-       :produces           (vec (keep :content-type responses))
-       :consumes           [(:content-type body)]
-       :summary            (:summary definition)
-       :description        (:description definition)
-       :openapi-definition definition
-       :route-name         (->kebab-case-keyword (:operationId definition))})))
+      (-> {:path-parts         (vec (tokenise-path url))
+           :method             method
+           :path-schema        (process-parameters (:path parameters) components)
+           :query-schema       (process-parameters (:query parameters) components)
+           :body-schema        (:schema body)
+           :form-schema        (process-parameters (:form parameters) components)
+           :headers-schema     (process-parameters (:header parameters) components)
+           :response-schemas   (vec (keep #(dissoc % :content-type) responses))
+           :produces           (vec (keep :content-type responses))
+           :consumes           [(:content-type body)]
+           :summary            (:summary definition)
+           :description        (:description definition)
+           :openapi-definition definition
+           :route-name         (->kebab-case-keyword (:operationId definition))}
+          (cond-> (:deprecated definition) (assoc :deprecated? true))))))


Test patch:
diff --git a/core/test/martian/yaml_test.clj b/core/test/martian/yaml_test.clj
index 1e57f69..4a46ed0 100644
--- a/core/test/martian/yaml_test.clj
+++ b/core/test/martian/yaml_test.clj
@@ -8,6 +8,20 @@
 (def openapi-yaml
   (yaml-resource "openapi.yaml"))
 
+(defn map-vals [f m]
+  (->> (map (fn [[k v]] [k (f v)]) m)
+       (into {})))
+
+(defn deprecate-all
+  "Adds the deprecated field to all paths"
+  [yml]
+  (update yml :paths
+          (fn [paths]
+            (map-vals (fn [path]
+                        (map-vals #(assoc % :deprecated true)
+                                  path))
+                      paths))))
+
 (deftest openapi-sanity-check
   (testing "parses each handler"
     (is (= {:summary        "Update an existing pet"
@@ -64,4 +78,14 @@
                                    :decodes ["application/json"]})
                (->> (filter #(= (:route-name %) :update-pet)))
                first
-               (select-keys [:consumes :produces]))))))
+               (select-keys [:consumes :produces])))))
+
+  (testing "deprecated? correctly set"
+    (is (= {:deprecated? true}
+           (-> openapi-yaml
+               (yaml/cleanup)
+               deprecate-all
+               (openapi->handlers {})
+               (->> (filter #(= (:route-name %) :update-pet)))
+               first
+               (select-keys [:deprecated?]))))))