forked from loafle/openapi-generator-original
Merge pull request #1659 from xhh/clojure-auth
Improvements on Clojure client: authentications, collectionFormat
This commit is contained in:
commit
e5cd37ee9b
@ -1,5 +1,5 @@
|
|||||||
{{=< >=}}(ns <package>.<classname>
|
{{=< >=}}(ns <package>.<classname>
|
||||||
(:require [<baseNamespace>.core :refer [call-api check-required-params]])
|
(:require [<baseNamespace>.core :refer [call-api check-required-params with-collection-format]])
|
||||||
(:import (java.io File)))
|
(:import (java.io File)))
|
||||||
<#operations><#operation>
|
<#operations><#operation>
|
||||||
(defn <operationId>
|
(defn <operationId>
|
||||||
@ -9,11 +9,12 @@
|
|||||||
<#hasOptionalParams>(</hasOptionalParams>[<#allParams><#required><#isFile>^File </isFile><paramName> </required></allParams><#hasOptionalParams>{:keys [<#allParams><^required><#isFile>^File </isFile><paramName> </required></allParams>]}</hasOptionalParams>]<#hasRequiredParams>
|
<#hasOptionalParams>(</hasOptionalParams>[<#allParams><#required><#isFile>^File </isFile><paramName> </required></allParams><#hasOptionalParams>{:keys [<#allParams><^required><#isFile>^File </isFile><paramName> </required></allParams>]}</hasOptionalParams>]<#hasRequiredParams>
|
||||||
<#hasOptionalParams> </hasOptionalParams>(check-required-params<#allParams><#required> <paramName></required></allParams>)</hasRequiredParams>
|
<#hasOptionalParams> </hasOptionalParams>(check-required-params<#allParams><#required> <paramName></required></allParams>)</hasRequiredParams>
|
||||||
<#hasOptionalParams> </hasOptionalParams>(call-api "<path>" :<httpMethod>
|
<#hasOptionalParams> </hasOptionalParams>(call-api "<path>" :<httpMethod>
|
||||||
<#hasOptionalParams> </hasOptionalParams> {:path-params {<#pathParams>"<baseName>" <paramName> </pathParams>}
|
<#hasOptionalParams> </hasOptionalParams> {:path-params {<#pathParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </pathParams>}
|
||||||
<#hasOptionalParams> </hasOptionalParams> :header-params {<#headerParams>"<baseName>" <paramName> </headerParams>}
|
<#hasOptionalParams> </hasOptionalParams> :header-params {<#headerParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </headerParams>}
|
||||||
<#hasOptionalParams> </hasOptionalParams> :query-params {<#queryParams>"<baseName>" <paramName> </queryParams>}
|
<#hasOptionalParams> </hasOptionalParams> :query-params {<#queryParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </queryParams>}
|
||||||
<#hasOptionalParams> </hasOptionalParams> :form-params {<#formParams>"<baseName>" <paramName> </formParams>}<#bodyParam>
|
<#hasOptionalParams> </hasOptionalParams> :form-params {<#formParams>"<baseName>" <#collectionFormat>(with-collection-format <paramName> :<collectionFormat>)</collectionFormat><^collectionFormat><paramName></collectionFormat> </formParams>}<#bodyParam>
|
||||||
<#hasOptionalParams> </hasOptionalParams> :body-param <paramName></bodyParam>
|
<#hasOptionalParams> </hasOptionalParams> :body-param <paramName></bodyParam>
|
||||||
<#hasOptionalParams> </hasOptionalParams> :content-types [<#consumes>"<mediaType>"<#hasMore> </hasMore></consumes>]
|
<#hasOptionalParams> </hasOptionalParams> :content-types [<#consumes>"<mediaType>"<#hasMore> </hasMore></consumes>]
|
||||||
<#hasOptionalParams> </hasOptionalParams> :accepts [<#produces>"<mediaType>"<#hasMore> </hasMore></produces>]}))<#hasOptionalParams>)</hasOptionalParams>
|
<#hasOptionalParams> </hasOptionalParams> :accepts [<#produces>"<mediaType>"<#hasMore> </hasMore></produces>]
|
||||||
|
<#hasOptionalParams> </hasOptionalParams> :auth-names [<#authMethods>"<&name>"<#hasMore> </hasMore></authMethods>]})<#hasOptionalParams>)</hasOptionalParams>)
|
||||||
</operation></operations>
|
</operation></operations>
|
@ -1,4 +1,4 @@
|
|||||||
(ns {{{baseNamespace}}}.core
|
{{=< >=}}(ns <&baseNamespace>.core
|
||||||
(:require [cheshire.core :refer [generate-string parse-string]]
|
(:require [cheshire.core :refer [generate-string parse-string]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clj-http.client :as client])
|
[clj-http.client :as client])
|
||||||
@ -7,12 +7,18 @@
|
|||||||
(java.util Date TimeZone)
|
(java.util Date TimeZone)
|
||||||
(java.text SimpleDateFormat)))
|
(java.text SimpleDateFormat)))
|
||||||
|
|
||||||
|
(def auth-definitions
|
||||||
|
{<#authMethods>"<&name>" <#isBasic>{:type :basic}</isBasic><#isApiKey>{:type :api-key<#isKeyInHeader> :in :header</isKeyInHeader><#isKeyInQuery> :in :query</isKeyInQuery> :param-name "<&keyParamName>"}</isApiKey><#isOAuth>{:type :oauth2}</isOAuth><#hasMore>
|
||||||
|
</hasMore></authMethods>})
|
||||||
|
|
||||||
(def default-api-context
|
(def default-api-context
|
||||||
"Default API context."
|
"Default API context."
|
||||||
{:base-url "http://petstore.swagger.io/v2"
|
{:base-url "<&basePath>"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||||
:debug false})
|
:debug false
|
||||||
|
:auths {<#authMethods>"<&name>" nil<#hasMore>
|
||||||
|
</hasMore></authMethods>}})
|
||||||
|
|
||||||
(def ^:dynamic *api-context*
|
(def ^:dynamic *api-context*
|
||||||
"Dynamic API context to be applied in API calls."
|
"Dynamic API context to be applied in API calls."
|
||||||
@ -20,12 +26,16 @@
|
|||||||
|
|
||||||
(defmacro with-api-context
|
(defmacro with-api-context
|
||||||
"A helper macro to wrap *api-context* with default values."
|
"A helper macro to wrap *api-context* with default values."
|
||||||
[context & body]
|
[api-context & body]
|
||||||
`(binding [*api-context* (merge *api-context* ~context)]
|
`(let [api-context# ~api-context
|
||||||
~@body))
|
api-context# (-> *api-context*
|
||||||
|
(merge api-context#)
|
||||||
|
(assoc :auths (merge (:auths *api-context*) (:auths api-context#))))]
|
||||||
|
(binding [*api-context* api-context#]
|
||||||
|
~@body)))
|
||||||
|
|
||||||
(defmacro check-required-params
|
(defmacro check-required-params
|
||||||
"Throw exception if the given parameter value is nil."
|
"Throw exception if any of the given parameters is nil."
|
||||||
[& params]
|
[& params]
|
||||||
(->> params
|
(->> params
|
||||||
(map (fn [p]
|
(map (fn [p]
|
||||||
@ -33,9 +43,14 @@
|
|||||||
(throw (IllegalArgumentException. ~(str "The parameter \"" p "\" is required"))))))
|
(throw (IllegalArgumentException. ~(str "The parameter \"" p "\" is required"))))))
|
||||||
(list* 'do)))
|
(list* 'do)))
|
||||||
|
|
||||||
(defn- make-date-format
|
(defn with-collection-format
|
||||||
([format-str] (make-date-format format-str nil))
|
"Attach collection-format to meta data of the given parameter."
|
||||||
([format-str time-zone]
|
[param collection-format]
|
||||||
|
(and param (with-meta param {:collection-format collection-format})))
|
||||||
|
|
||||||
|
(defn- ^SimpleDateFormat make-date-format
|
||||||
|
([^String format-str] (make-date-format format-str nil))
|
||||||
|
([^String format-str ^String time-zone]
|
||||||
(let [date-format (SimpleDateFormat. format-str)]
|
(let [date-format (SimpleDateFormat. format-str)]
|
||||||
(when time-zone
|
(when time-zone
|
||||||
(.setTimeZone date-format (TimeZone/getTimeZone time-zone)))
|
(.setTimeZone date-format (TimeZone/getTimeZone time-zone)))
|
||||||
@ -75,35 +90,79 @@
|
|||||||
(-> (make-date-format datetime-format time-zone)
|
(-> (make-date-format datetime-format time-zone)
|
||||||
(.parse s)))))
|
(.parse s)))))
|
||||||
|
|
||||||
(defn param-to-str [param]
|
(defn param->str
|
||||||
"Format the given parameter value to string."
|
"Format the given parameter value to string."
|
||||||
|
[param]
|
||||||
(cond
|
(cond
|
||||||
(instance? Date param) (format-datetime param)
|
(instance? Date param) (format-datetime param)
|
||||||
(sequential? param) (str/join "," param)
|
(sequential? param) (str/join "," param)
|
||||||
:else (str param)))
|
:else (str param)))
|
||||||
|
|
||||||
|
(defn auth->opts
|
||||||
|
"Process the given auth to an option map that might conatin request options and parameters."
|
||||||
|
[{:keys [type in param-name]} value]
|
||||||
|
(case type
|
||||||
|
:basic {:req-opts {:basic-auth value}}
|
||||||
|
:oauth2 {:req-opts {:oauth-token value}}
|
||||||
|
:api-key (case in
|
||||||
|
:header {:header-params {param-name value}}
|
||||||
|
:query {:query-params {param-name value}}
|
||||||
|
(throw (IllegalArgumentException. (str "Invalid `in` for api-key auth: " in))))
|
||||||
|
(throw (IllegalArgumentException. (str "Invalid auth `type`: " type)))))
|
||||||
|
|
||||||
|
(defn process-auth
|
||||||
|
"Process the given auth name into options, which is merged into the given opts."
|
||||||
|
[opts auth-name]
|
||||||
|
(if-let [value (get-in *api-context* [:auths auth-name])]
|
||||||
|
(merge-with merge
|
||||||
|
opts
|
||||||
|
(auth->opts (get auth-definitions auth-name) value))
|
||||||
|
opts))
|
||||||
|
|
||||||
|
(defn auths->opts
|
||||||
|
"Process the given auth names to an option map that might conatin request options and parameters."
|
||||||
|
[auth-names]
|
||||||
|
(reduce process-auth {} auth-names))
|
||||||
|
|
||||||
|
(declare normalize-param)
|
||||||
|
|
||||||
(defn make-url
|
(defn make-url
|
||||||
"Make full URL by adding base URL and filling path parameters."
|
"Make full URL by adding base URL and filling path parameters."
|
||||||
[path path-params]
|
[path path-params]
|
||||||
(let [path (reduce (fn [p [k v]]
|
(let [path (reduce (fn [p [k v]]
|
||||||
(str/replace p (re-pattern (str "\\{" k "\\}")) (param-to-str v)))
|
(str/replace p (re-pattern (str "\\{" k "\\}")) (normalize-param v)))
|
||||||
path
|
path
|
||||||
path-params)]
|
path-params)]
|
||||||
(str (:base-url *api-context*) path)))
|
(str (:base-url *api-context*) path)))
|
||||||
|
|
||||||
|
(defn normalize-array-param
|
||||||
|
"Normalize array paramater according to :collection-format specified in the parameter's meta data.
|
||||||
|
When the parameter contains File, a seq is returned so as to keep File parameters.
|
||||||
|
For :multi collection format, a seq is returned which will be handled properly by clj-http.
|
||||||
|
For other cases, a string is returned."
|
||||||
|
[xs]
|
||||||
|
(if (some (partial instance? File) xs)
|
||||||
|
(map normalize-param xs)
|
||||||
|
(case (-> (meta xs) :collection-format (or :csv))
|
||||||
|
:csv (str/join "," (map normalize-param xs))
|
||||||
|
:ssv (str/join " " (map normalize-param xs))
|
||||||
|
:tsv (str/join "\t" (map normalize-param xs))
|
||||||
|
:pipes (str/join "|" (map normalize-param xs))
|
||||||
|
:multi (map normalize-param xs))))
|
||||||
|
|
||||||
(defn normalize-param
|
(defn normalize-param
|
||||||
"Normalize parameter value, handling three cases:
|
"Normalize parameter value, handling three cases:
|
||||||
for sequential value, normalize each elements of it;
|
for sequential value, apply `normalize-array-param` which handles collection format;
|
||||||
for File value, do nothing with it;
|
for File value, use current value;
|
||||||
otherwise, call `param-to-string`."
|
otherwise, apply `param->str`."
|
||||||
[param]
|
[param]
|
||||||
(cond
|
(cond
|
||||||
(sequential? param) (map normalize-param param)
|
(sequential? param) (normalize-array-param param)
|
||||||
(instance? File param) param
|
(instance? File param) param
|
||||||
:else (param-to-str param)))
|
:else (param->str param)))
|
||||||
|
|
||||||
(defn normalize-params
|
(defn normalize-params
|
||||||
"Normalize parameters values: remove nils, format to string with `param-to-str`."
|
"Normalize parameters values: remove nils, format to string with `param->str`."
|
||||||
[params]
|
[params]
|
||||||
(->> params
|
(->> params
|
||||||
(remove (comp nil? second))
|
(remove (comp nil? second))
|
||||||
@ -144,7 +203,7 @@
|
|||||||
;; for non-JSON response, return the body string directly
|
;; for non-JSON response, return the body string directly
|
||||||
:else body))
|
:else body))
|
||||||
|
|
||||||
(defn form-params-to-multipart
|
(defn form-params->multipart
|
||||||
"Convert the given form parameters map into a vector as clj-http's :multipart option."
|
"Convert the given form parameters map into a vector as clj-http's :multipart option."
|
||||||
[form-params]
|
[form-params]
|
||||||
(->> form-params
|
(->> form-params
|
||||||
@ -153,25 +212,27 @@
|
|||||||
|
|
||||||
(defn call-api
|
(defn call-api
|
||||||
"Call an API by making HTTP request and return its response."
|
"Call an API by making HTTP request and return its response."
|
||||||
[path method {:keys [path-params query-params header-params form-params body-param content-types accepts]}]
|
[path method {:keys [path-params body-param content-types accepts auth-names] :as opts}]
|
||||||
(let [{:keys [debug]} *api-context*
|
(let [{:keys [debug]} *api-context*
|
||||||
|
{:keys [req-opts query-params header-params form-params]} (auths->opts auth-names)
|
||||||
|
query-params (merge query-params (:query-params opts))
|
||||||
|
header-params (merge header-params (:header-params opts))
|
||||||
|
form-params (merge form-params (:form-params opts))
|
||||||
url (make-url path path-params)
|
url (make-url path path-params)
|
||||||
content-type (or (json-preferred-mime content-types)
|
content-type (or (json-preferred-mime content-types) (and body-param :json))
|
||||||
(and body-param :json))
|
|
||||||
accept (or (json-preferred-mime accepts) :json)
|
accept (or (json-preferred-mime accepts) :json)
|
||||||
multipart? (= "multipart/form-data" content-type)
|
multipart? (= "multipart/form-data" content-type)
|
||||||
opts (cond-> {:url url :method method}
|
req-opts (cond-> req-opts
|
||||||
|
true (assoc :url url :method method)
|
||||||
accept (assoc :accept accept)
|
accept (assoc :accept accept)
|
||||||
(seq query-params) (assoc :query-params (normalize-params query-params))
|
(seq query-params) (assoc :query-params (normalize-params query-params))
|
||||||
(seq header-params) (assoc :header-params (normalize-params header-params))
|
(seq header-params) (assoc :headers (normalize-params header-params))
|
||||||
(and content-type (not multipart?)) (assoc :content-type content-type)
|
(and content-type (not multipart?)) (assoc :content-type content-type)
|
||||||
multipart? (assoc :multipart (-> form-params
|
multipart? (assoc :multipart (-> form-params normalize-params form-params->multipart))
|
||||||
normalize-params
|
|
||||||
form-params-to-multipart))
|
|
||||||
(and (not multipart?) (seq form-params)) (assoc :form-params (normalize-params form-params))
|
(and (not multipart?) (seq form-params)) (assoc :form-params (normalize-params form-params))
|
||||||
body-param (assoc :body (serialize body-param content-type))
|
body-param (assoc :body (serialize body-param content-type))
|
||||||
debug (assoc :debug true :debug-body true))
|
debug (assoc :debug true :debug-body true))
|
||||||
resp (client/request opts)]
|
resp (client/request req-opts)]
|
||||||
(when debug
|
(when debug
|
||||||
(println "Response:")
|
(println "Response:")
|
||||||
(println resp))
|
(println resp))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
(ns swagger-petstore.api.pet
|
(ns swagger-petstore.api.pet
|
||||||
(:require [swagger-petstore.core :refer [call-api check-required-params]])
|
(:require [swagger-petstore.core :refer [call-api check-required-params with-collection-format]])
|
||||||
(:import (java.io File)))
|
(:import (java.io File)))
|
||||||
|
|
||||||
(defn update-pet
|
(defn update-pet
|
||||||
@ -14,7 +14,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types ["application/json" "application/xml"]
|
:content-types ["application/json" "application/xml"]
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn add-pet
|
(defn add-pet
|
||||||
"Add a new pet to the store
|
"Add a new pet to the store
|
||||||
@ -28,7 +29,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types ["application/json" "application/xml"]
|
:content-types ["application/json" "application/xml"]
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn find-pets-by-status
|
(defn find-pets-by-status
|
||||||
"Finds Pets by status
|
"Finds Pets by status
|
||||||
@ -38,10 +40,11 @@
|
|||||||
(call-api "/pet/findByStatus" :get
|
(call-api "/pet/findByStatus" :get
|
||||||
{:path-params {}
|
{:path-params {}
|
||||||
:header-params {}
|
:header-params {}
|
||||||
:query-params {"status" status }
|
:query-params {"status" (with-collection-format status :multi) }
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn find-pets-by-tags
|
(defn find-pets-by-tags
|
||||||
"Finds Pets by tags
|
"Finds Pets by tags
|
||||||
@ -51,10 +54,11 @@
|
|||||||
(call-api "/pet/findByTags" :get
|
(call-api "/pet/findByTags" :get
|
||||||
{:path-params {}
|
{:path-params {}
|
||||||
:header-params {}
|
:header-params {}
|
||||||
:query-params {"tags" tags }
|
:query-params {"tags" (with-collection-format tags :multi) }
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn get-pet-by-id
|
(defn get-pet-by-id
|
||||||
"Find pet by ID
|
"Find pet by ID
|
||||||
@ -66,7 +70,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["api_key"]}))
|
||||||
|
|
||||||
(defn update-pet-with-form
|
(defn update-pet-with-form
|
||||||
"Updates a pet in the store with form data
|
"Updates a pet in the store with form data
|
||||||
@ -79,7 +84,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {"name" name "status" status }
|
:form-params {"name" name "status" status }
|
||||||
:content-types ["application/x-www-form-urlencoded"]
|
:content-types ["application/x-www-form-urlencoded"]
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn delete-pet
|
(defn delete-pet
|
||||||
"Deletes a pet
|
"Deletes a pet
|
||||||
@ -92,7 +98,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
|
||||||
(defn upload-file
|
(defn upload-file
|
||||||
"uploads an image
|
"uploads an image
|
||||||
@ -105,4 +112,5 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {"additionalMetadata" additional-metadata "file" file }
|
:form-params {"additionalMetadata" additional-metadata "file" file }
|
||||||
:content-types ["multipart/form-data"]
|
:content-types ["multipart/form-data"]
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["petstore_auth"]})))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
(ns swagger-petstore.api.store
|
(ns swagger-petstore.api.store
|
||||||
(:require [swagger-petstore.core :refer [call-api check-required-params]])
|
(:require [swagger-petstore.core :refer [call-api check-required-params with-collection-format]])
|
||||||
(:import (java.io File)))
|
(:import (java.io File)))
|
||||||
|
|
||||||
(defn get-inventory
|
(defn get-inventory
|
||||||
@ -12,7 +12,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names ["api_key"]}))
|
||||||
|
|
||||||
(defn place-order
|
(defn place-order
|
||||||
"Place an order for a pet
|
"Place an order for a pet
|
||||||
@ -26,7 +27,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn get-order-by-id
|
(defn get-order-by-id
|
||||||
"Find purchase order by ID
|
"Find purchase order by ID
|
||||||
@ -38,7 +40,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []}))
|
||||||
|
|
||||||
(defn delete-order
|
(defn delete-order
|
||||||
"Delete purchase order by ID
|
"Delete purchase order by ID
|
||||||
@ -50,4 +53,5 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []}))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
(ns swagger-petstore.api.user
|
(ns swagger-petstore.api.user
|
||||||
(:require [swagger-petstore.core :refer [call-api check-required-params]])
|
(:require [swagger-petstore.core :refer [call-api check-required-params with-collection-format]])
|
||||||
(:import (java.io File)))
|
(:import (java.io File)))
|
||||||
|
|
||||||
(defn create-user
|
(defn create-user
|
||||||
@ -14,7 +14,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn create-users-with-array-input
|
(defn create-users-with-array-input
|
||||||
"Creates list of users with given input array
|
"Creates list of users with given input array
|
||||||
@ -28,7 +29,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn create-users-with-list-input
|
(defn create-users-with-list-input
|
||||||
"Creates list of users with given input array
|
"Creates list of users with given input array
|
||||||
@ -42,7 +44,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn login-user
|
(defn login-user
|
||||||
"Logs user into the system
|
"Logs user into the system
|
||||||
@ -55,7 +58,8 @@
|
|||||||
:query-params {"username" username "password" password }
|
:query-params {"username" username "password" password }
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn logout-user
|
(defn logout-user
|
||||||
"Logs out current logged in user session
|
"Logs out current logged in user session
|
||||||
@ -67,7 +71,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []}))
|
||||||
|
|
||||||
(defn get-user-by-name
|
(defn get-user-by-name
|
||||||
"Get user by user name
|
"Get user by user name
|
||||||
@ -79,7 +84,8 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []}))
|
||||||
|
|
||||||
(defn update-user
|
(defn update-user
|
||||||
"Updated user
|
"Updated user
|
||||||
@ -93,7 +99,8 @@
|
|||||||
:form-params {}
|
:form-params {}
|
||||||
:body-param body
|
:body-param body
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]})))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []})))
|
||||||
|
|
||||||
(defn delete-user
|
(defn delete-user
|
||||||
"Delete user
|
"Delete user
|
||||||
@ -105,4 +112,5 @@
|
|||||||
:query-params {}
|
:query-params {}
|
||||||
:form-params {}
|
:form-params {}
|
||||||
:content-types []
|
:content-types []
|
||||||
:accepts ["application/json" "application/xml"]}))
|
:accepts ["application/json" "application/xml"]
|
||||||
|
:auth-names []}))
|
||||||
|
@ -7,12 +7,18 @@
|
|||||||
(java.util Date TimeZone)
|
(java.util Date TimeZone)
|
||||||
(java.text SimpleDateFormat)))
|
(java.text SimpleDateFormat)))
|
||||||
|
|
||||||
|
(def auth-definitions
|
||||||
|
{"petstore_auth" {:type :oauth2}
|
||||||
|
"api_key" {:type :api-key :in :header :param-name "api_key"}})
|
||||||
|
|
||||||
(def default-api-context
|
(def default-api-context
|
||||||
"Default API context."
|
"Default API context."
|
||||||
{:base-url "http://petstore.swagger.io/v2"
|
{:base-url "http://petstore.swagger.io/v2"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||||
:debug false})
|
:debug false
|
||||||
|
:auths {"petstore_auth" nil
|
||||||
|
"api_key" nil}})
|
||||||
|
|
||||||
(def ^:dynamic *api-context*
|
(def ^:dynamic *api-context*
|
||||||
"Dynamic API context to be applied in API calls."
|
"Dynamic API context to be applied in API calls."
|
||||||
@ -20,12 +26,16 @@
|
|||||||
|
|
||||||
(defmacro with-api-context
|
(defmacro with-api-context
|
||||||
"A helper macro to wrap *api-context* with default values."
|
"A helper macro to wrap *api-context* with default values."
|
||||||
[context & body]
|
[api-context & body]
|
||||||
`(binding [*api-context* (merge *api-context* ~context)]
|
`(let [api-context# ~api-context
|
||||||
~@body))
|
api-context# (-> *api-context*
|
||||||
|
(merge api-context#)
|
||||||
|
(assoc :auths (merge (:auths *api-context*) (:auths api-context#))))]
|
||||||
|
(binding [*api-context* api-context#]
|
||||||
|
~@body)))
|
||||||
|
|
||||||
(defmacro check-required-params
|
(defmacro check-required-params
|
||||||
"Throw exception if the given parameter value is nil."
|
"Throw exception if any of the given parameters is nil."
|
||||||
[& params]
|
[& params]
|
||||||
(->> params
|
(->> params
|
||||||
(map (fn [p]
|
(map (fn [p]
|
||||||
@ -33,9 +43,14 @@
|
|||||||
(throw (IllegalArgumentException. ~(str "The parameter \"" p "\" is required"))))))
|
(throw (IllegalArgumentException. ~(str "The parameter \"" p "\" is required"))))))
|
||||||
(list* 'do)))
|
(list* 'do)))
|
||||||
|
|
||||||
(defn- make-date-format
|
(defn with-collection-format
|
||||||
([format-str] (make-date-format format-str nil))
|
"Attach collection-format to meta data of the given parameter."
|
||||||
([format-str time-zone]
|
[param collection-format]
|
||||||
|
(and param (with-meta param {:collection-format collection-format})))
|
||||||
|
|
||||||
|
(defn- ^SimpleDateFormat make-date-format
|
||||||
|
([^String format-str] (make-date-format format-str nil))
|
||||||
|
([^String format-str ^String time-zone]
|
||||||
(let [date-format (SimpleDateFormat. format-str)]
|
(let [date-format (SimpleDateFormat. format-str)]
|
||||||
(when time-zone
|
(when time-zone
|
||||||
(.setTimeZone date-format (TimeZone/getTimeZone time-zone)))
|
(.setTimeZone date-format (TimeZone/getTimeZone time-zone)))
|
||||||
@ -75,35 +90,79 @@
|
|||||||
(-> (make-date-format datetime-format time-zone)
|
(-> (make-date-format datetime-format time-zone)
|
||||||
(.parse s)))))
|
(.parse s)))))
|
||||||
|
|
||||||
(defn param-to-str [param]
|
(defn param->str
|
||||||
"Format the given parameter value to string."
|
"Format the given parameter value to string."
|
||||||
|
[param]
|
||||||
(cond
|
(cond
|
||||||
(instance? Date param) (format-datetime param)
|
(instance? Date param) (format-datetime param)
|
||||||
(sequential? param) (str/join "," param)
|
(sequential? param) (str/join "," param)
|
||||||
:else (str param)))
|
:else (str param)))
|
||||||
|
|
||||||
|
(defn auth->opts
|
||||||
|
"Process the given auth to an option map that might conatin request options and parameters."
|
||||||
|
[{:keys [type in param-name]} value]
|
||||||
|
(case type
|
||||||
|
:basic {:req-opts {:basic-auth value}}
|
||||||
|
:oauth2 {:req-opts {:oauth-token value}}
|
||||||
|
:api-key (case in
|
||||||
|
:header {:header-params {param-name value}}
|
||||||
|
:query {:query-params {param-name value}}
|
||||||
|
(throw (IllegalArgumentException. (str "Invalid `in` for api-key auth: " in))))
|
||||||
|
(throw (IllegalArgumentException. (str "Invalid auth `type`: " type)))))
|
||||||
|
|
||||||
|
(defn process-auth
|
||||||
|
"Process the given auth name into options, which is merged into the given opts."
|
||||||
|
[opts auth-name]
|
||||||
|
(if-let [value (get-in *api-context* [:auths auth-name])]
|
||||||
|
(merge-with merge
|
||||||
|
opts
|
||||||
|
(auth->opts (get auth-definitions auth-name) value))
|
||||||
|
opts))
|
||||||
|
|
||||||
|
(defn auths->opts
|
||||||
|
"Process the given auth names to an option map that might conatin request options and parameters."
|
||||||
|
[auth-names]
|
||||||
|
(reduce process-auth {} auth-names))
|
||||||
|
|
||||||
|
(declare normalize-param)
|
||||||
|
|
||||||
(defn make-url
|
(defn make-url
|
||||||
"Make full URL by adding base URL and filling path parameters."
|
"Make full URL by adding base URL and filling path parameters."
|
||||||
[path path-params]
|
[path path-params]
|
||||||
(let [path (reduce (fn [p [k v]]
|
(let [path (reduce (fn [p [k v]]
|
||||||
(str/replace p (re-pattern (str "\\{" k "\\}")) (param-to-str v)))
|
(str/replace p (re-pattern (str "\\{" k "\\}")) (normalize-param v)))
|
||||||
path
|
path
|
||||||
path-params)]
|
path-params)]
|
||||||
(str (:base-url *api-context*) path)))
|
(str (:base-url *api-context*) path)))
|
||||||
|
|
||||||
|
(defn normalize-array-param
|
||||||
|
"Normalize array paramater according to :collection-format specified in the parameter's meta data.
|
||||||
|
When the parameter contains File, a seq is returned so as to keep File parameters.
|
||||||
|
For :multi collection format, a seq is returned which will be handled properly by clj-http.
|
||||||
|
For other cases, a string is returned."
|
||||||
|
[xs]
|
||||||
|
(if (some (partial instance? File) xs)
|
||||||
|
(map normalize-param xs)
|
||||||
|
(case (-> (meta xs) :collection-format (or :csv))
|
||||||
|
:csv (str/join "," (map normalize-param xs))
|
||||||
|
:ssv (str/join " " (map normalize-param xs))
|
||||||
|
:tsv (str/join "\t" (map normalize-param xs))
|
||||||
|
:pipes (str/join "|" (map normalize-param xs))
|
||||||
|
:multi (map normalize-param xs))))
|
||||||
|
|
||||||
(defn normalize-param
|
(defn normalize-param
|
||||||
"Normalize parameter value, handling three cases:
|
"Normalize parameter value, handling three cases:
|
||||||
for sequential value, normalize each elements of it;
|
for sequential value, apply `normalize-array-param` which handles collection format;
|
||||||
for File value, do nothing with it;
|
for File value, use current value;
|
||||||
otherwise, call `param-to-string`."
|
otherwise, apply `param->str`."
|
||||||
[param]
|
[param]
|
||||||
(cond
|
(cond
|
||||||
(sequential? param) (map normalize-param param)
|
(sequential? param) (normalize-array-param param)
|
||||||
(instance? File param) param
|
(instance? File param) param
|
||||||
:else (param-to-str param)))
|
:else (param->str param)))
|
||||||
|
|
||||||
(defn normalize-params
|
(defn normalize-params
|
||||||
"Normalize parameters values: remove nils, format to string with `param-to-str`."
|
"Normalize parameters values: remove nils, format to string with `param->str`."
|
||||||
[params]
|
[params]
|
||||||
(->> params
|
(->> params
|
||||||
(remove (comp nil? second))
|
(remove (comp nil? second))
|
||||||
@ -144,7 +203,7 @@
|
|||||||
;; for non-JSON response, return the body string directly
|
;; for non-JSON response, return the body string directly
|
||||||
:else body))
|
:else body))
|
||||||
|
|
||||||
(defn form-params-to-multipart
|
(defn form-params->multipart
|
||||||
"Convert the given form parameters map into a vector as clj-http's :multipart option."
|
"Convert the given form parameters map into a vector as clj-http's :multipart option."
|
||||||
[form-params]
|
[form-params]
|
||||||
(->> form-params
|
(->> form-params
|
||||||
@ -153,25 +212,27 @@
|
|||||||
|
|
||||||
(defn call-api
|
(defn call-api
|
||||||
"Call an API by making HTTP request and return its response."
|
"Call an API by making HTTP request and return its response."
|
||||||
[path method {:keys [path-params query-params header-params form-params body-param content-types accepts]}]
|
[path method {:keys [path-params body-param content-types accepts auth-names] :as opts}]
|
||||||
(let [{:keys [debug]} *api-context*
|
(let [{:keys [debug]} *api-context*
|
||||||
|
{:keys [req-opts query-params header-params form-params]} (auths->opts auth-names)
|
||||||
|
query-params (merge query-params (:query-params opts))
|
||||||
|
header-params (merge header-params (:header-params opts))
|
||||||
|
form-params (merge form-params (:form-params opts))
|
||||||
url (make-url path path-params)
|
url (make-url path path-params)
|
||||||
content-type (or (json-preferred-mime content-types)
|
content-type (or (json-preferred-mime content-types) (and body-param :json))
|
||||||
(and body-param :json))
|
|
||||||
accept (or (json-preferred-mime accepts) :json)
|
accept (or (json-preferred-mime accepts) :json)
|
||||||
multipart? (= "multipart/form-data" content-type)
|
multipart? (= "multipart/form-data" content-type)
|
||||||
opts (cond-> {:url url :method method}
|
req-opts (cond-> req-opts
|
||||||
|
true (assoc :url url :method method)
|
||||||
accept (assoc :accept accept)
|
accept (assoc :accept accept)
|
||||||
(seq query-params) (assoc :query-params (normalize-params query-params))
|
(seq query-params) (assoc :query-params (normalize-params query-params))
|
||||||
(seq header-params) (assoc :header-params (normalize-params header-params))
|
(seq header-params) (assoc :headers (normalize-params header-params))
|
||||||
(and content-type (not multipart?)) (assoc :content-type content-type)
|
(and content-type (not multipart?)) (assoc :content-type content-type)
|
||||||
multipart? (assoc :multipart (-> form-params
|
multipart? (assoc :multipart (-> form-params normalize-params form-params->multipart))
|
||||||
normalize-params
|
|
||||||
form-params-to-multipart))
|
|
||||||
(and (not multipart?) (seq form-params)) (assoc :form-params (normalize-params form-params))
|
(and (not multipart?) (seq form-params)) (assoc :form-params (normalize-params form-params))
|
||||||
body-param (assoc :body (serialize body-param content-type))
|
body-param (assoc :body (serialize body-param content-type))
|
||||||
debug (assoc :debug true :debug-body true))
|
debug (assoc :debug true :debug-body true))
|
||||||
resp (client/request opts)]
|
resp (client/request req-opts)]
|
||||||
(when debug
|
(when debug
|
||||||
(println "Response:")
|
(println "Response:")
|
||||||
(println resp))
|
(println resp))
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
(ns swagger-petstore.api.pet-test
|
(ns swagger-petstore.api.pet-test
|
||||||
(:require [clojure.test :refer :all]
|
(:require [clojure.test :refer :all]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
|
[swagger-petstore.core :refer [with-api-context]]
|
||||||
[swagger-petstore.api.pet :refer :all]))
|
[swagger-petstore.api.pet :refer :all]))
|
||||||
|
|
||||||
|
(defn credentials-fixture [f]
|
||||||
|
(with-api-context {:auths {"api_key" "special-key"}}
|
||||||
|
(f)))
|
||||||
|
|
||||||
|
(use-fixtures :once credentials-fixture)
|
||||||
|
|
||||||
(defn- make-random-pet
|
(defn- make-random-pet
|
||||||
([] (make-random-pet nil))
|
([] (make-random-pet nil))
|
||||||
([{:keys [id] :as attrs :or {id (System/currentTimeMillis)}}]
|
([{:keys [id] :as attrs :or {id (System/currentTimeMillis)}}]
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
(ns swagger-petstore.api.store-test
|
(ns swagger-petstore.api.store-test
|
||||||
(:require [clojure.test :refer :all]
|
(:require [clojure.test :refer :all]
|
||||||
|
[swagger-petstore.core :refer [with-api-context]]
|
||||||
[swagger-petstore.api.store :refer :all])
|
[swagger-petstore.api.store :refer :all])
|
||||||
(:import (java.util Date)))
|
(:import (java.util Date)))
|
||||||
|
|
||||||
|
(defn credentials-fixture [f]
|
||||||
|
(with-api-context {:auths {"api_key" "special-key"}}
|
||||||
|
(f)))
|
||||||
|
|
||||||
|
(use-fixtures :once credentials-fixture)
|
||||||
|
|
||||||
(defn- make-random-order []
|
(defn- make-random-order []
|
||||||
{:id (+ 90000 (rand-int 10000))
|
{:id (+ 90000 (rand-int 10000))
|
||||||
:petId 200
|
:petId 200
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
(ns swagger-petstore.api.user-test
|
(ns swagger-petstore.api.user-test
|
||||||
(:require [clojure.test :refer :all]
|
(:require [clojure.test :refer :all]
|
||||||
|
[swagger-petstore.core :refer [with-api-context]]
|
||||||
[swagger-petstore.api.user :refer :all]))
|
[swagger-petstore.api.user :refer :all]))
|
||||||
|
|
||||||
|
(defn credentials-fixture [f]
|
||||||
|
(with-api-context {:auths {"api_key" "special-key"}}
|
||||||
|
(f)))
|
||||||
|
|
||||||
|
(use-fixtures :once credentials-fixture)
|
||||||
|
|
||||||
(defn- make-random-user
|
(defn- make-random-user
|
||||||
([] (make-random-user nil))
|
([] (make-random-user nil))
|
||||||
([{:keys [id] :as attrs :or {id (System/currentTimeMillis)}}]
|
([{:keys [id] :as attrs :or {id (System/currentTimeMillis)}}]
|
||||||
|
@ -9,30 +9,43 @@
|
|||||||
(is (= {:base-url "http://petstore.swagger.io/v2"
|
(is (= {:base-url "http://petstore.swagger.io/v2"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||||
:debug false}
|
:debug false
|
||||||
|
:auths {"api_key" nil
|
||||||
|
"petstore_auth" nil}}
|
||||||
default-api-context
|
default-api-context
|
||||||
*api-context*
|
*api-context*
|
||||||
(with-api-context {}
|
(with-api-context {}
|
||||||
*api-context*))))
|
*api-context*))))
|
||||||
(testing "customize via with-api-context"
|
(testing "customize via with-api-context"
|
||||||
(with-api-context {:base-url "http://localhost" :debug true}
|
(with-api-context {:base-url "http://localhost"
|
||||||
|
:debug true
|
||||||
|
:auths {"api_key" "key1"
|
||||||
|
"petstore_auth" "token1"}}
|
||||||
(is (= {:base-url "http://localhost"
|
(is (= {:base-url "http://localhost"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||||
:debug true}
|
:debug true
|
||||||
|
:auths {"api_key" "key1"
|
||||||
|
"petstore_auth" "token1"}}
|
||||||
*api-context*))
|
*api-context*))
|
||||||
;; nested with-api-context inherits values from the outer api context
|
;; nested with-api-context inherits values from the outer api context
|
||||||
(with-api-context {:datetime-format "yyyy-MM-dd HH:mm:ss"}
|
(with-api-context {:datetime-format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
:auths {"api_key" "key2"}}
|
||||||
(is (= {:base-url "http://localhost"
|
(is (= {:base-url "http://localhost"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd HH:mm:ss"
|
:datetime-format "yyyy-MM-dd HH:mm:ss"
|
||||||
:debug true}
|
:debug true
|
||||||
|
:auths {"api_key" "key2"
|
||||||
|
"petstore_auth" "token1"}}
|
||||||
*api-context*))))
|
*api-context*))))
|
||||||
;; back to default api context
|
;; back to default api context
|
||||||
(is (= {:base-url "http://petstore.swagger.io/v2"
|
(is (= {:base-url "http://petstore.swagger.io/v2"
|
||||||
:date-format "yyyy-MM-dd"
|
:date-format "yyyy-MM-dd"
|
||||||
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
:datetime-format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
|
||||||
:debug false}
|
:debug false
|
||||||
|
:auths {"api_key" nil
|
||||||
|
"petstore_auth" nil}}
|
||||||
|
default-api-context
|
||||||
*api-context*))))
|
*api-context*))))
|
||||||
|
|
||||||
(deftest test-check-required-params
|
(deftest test-check-required-params
|
||||||
@ -69,10 +82,10 @@
|
|||||||
"2015-11-07T00:49:09-03:00")
|
"2015-11-07T00:49:09-03:00")
|
||||||
(is (thrown? ParseException (parse-datetime "2015-11-07T03:49:09.123Z"))))))
|
(is (thrown? ParseException (parse-datetime "2015-11-07T03:49:09.123Z"))))))
|
||||||
|
|
||||||
(deftest test-param-to-str
|
(deftest test-param->str
|
||||||
(let [date (parse-datetime "2015-11-07T03:49:09.123Z")]
|
(let [date (parse-datetime "2015-11-07T03:49:09.123Z")]
|
||||||
(are [param expected]
|
(are [param expected]
|
||||||
(is (= expected (param-to-str param)))
|
(is (= expected (param->str param)))
|
||||||
nil ""
|
nil ""
|
||||||
"abc" "abc"
|
"abc" "abc"
|
||||||
123 "123"
|
123 "123"
|
||||||
@ -80,6 +93,25 @@
|
|||||||
[12 "34"] "12,34"
|
[12 "34"] "12,34"
|
||||||
date (format-datetime date))))
|
date (format-datetime date))))
|
||||||
|
|
||||||
|
(deftest test-auths->opts
|
||||||
|
(testing "auth values not set by default"
|
||||||
|
(is (= {} (auths->opts ["api_key" "petstore_auth"])))
|
||||||
|
(is (= {} (auths->opts []))))
|
||||||
|
(testing "set api_key"
|
||||||
|
(with-api-context {:auths {"api_key" "my key"}}
|
||||||
|
(is (= {:header-params {"api_key" "my key"}} (auths->opts ["api_key" "petstore_auth"])))
|
||||||
|
(is (= {:header-params {"api_key" "my key"}} (auths->opts ["api_key"])))
|
||||||
|
(is (= {} (auths->opts ["petstore_auth"])))
|
||||||
|
(is (= {} (auths->opts [])))))
|
||||||
|
(testing "set both api_key and petstore_auth"
|
||||||
|
(with-api-context {:auths {"api_key" "my key" "petstore_auth" "my token"}}
|
||||||
|
(is (= {:req-opts {:oauth-token "my token"}
|
||||||
|
:header-params {"api_key" "my key"}}
|
||||||
|
(auths->opts ["api_key" "petstore_auth"])))
|
||||||
|
(is (= {:req-opts {:oauth-token "my token"}} (auths->opts ["petstore_auth"])))
|
||||||
|
(is (= {:header-params {"api_key" "my key"}} (auths->opts ["api_key"])))
|
||||||
|
(is (= {} (auths->opts []))))))
|
||||||
|
|
||||||
(deftest test-make-url
|
(deftest test-make-url
|
||||||
(are [path path-params url]
|
(are [path path-params url]
|
||||||
(is (= url (make-url path path-params)))
|
(is (= url (make-url path path-params)))
|
||||||
@ -92,14 +124,27 @@
|
|||||||
(let [file (-> "hello.txt" io/resource io/file)]
|
(let [file (-> "hello.txt" io/resource io/file)]
|
||||||
(are [param expected]
|
(are [param expected]
|
||||||
(is (= expected (normalize-param param)))
|
(is (= expected (normalize-param param)))
|
||||||
[12 "34"] ["12" "34"]
|
|
||||||
file file
|
file file
|
||||||
"abc" "abc"
|
"abc" "abc"
|
||||||
[[12 "34"] file "abc"] [["12" "34"] file "abc"])))
|
[12 "34"] "12,34"
|
||||||
|
^{:collection-format :csv} [12 "34"] "12,34"
|
||||||
|
^{:collection-format :ssv} [12 "34"] "12 34"
|
||||||
|
^{:collection-format :tsv} [12 "34"] "12\t34"
|
||||||
|
(with-collection-format [12 "34"] :pipes) "12|34"
|
||||||
|
(with-collection-format [12 "34"] :multi) ["12" "34"]
|
||||||
|
[[12 "34"] file "abc"] ["12,34" file "abc"])))
|
||||||
|
|
||||||
(deftest test-normalize-params
|
(deftest test-normalize-params
|
||||||
(is (= {:a "123" :b ["4" ["5" "6"]]}
|
(is (= {:a "123" :b "4,5,6"}
|
||||||
(normalize-params {:a 123 :b [4 [5 "6"]] :c nil}))))
|
(normalize-params {:a 123 :b [4 [5 "6"]] :c nil})))
|
||||||
|
(is (= {:a "123" :b ["4" "5,6"]}
|
||||||
|
(normalize-params {:a 123
|
||||||
|
:b ^{:collection-format :multi} [4 [5 "6"]]
|
||||||
|
:c nil})))
|
||||||
|
(is (= {:a "123" :b "4 5|6"}
|
||||||
|
(normalize-params {:a 123
|
||||||
|
:b (with-collection-format [4 (with-collection-format [5 "6"] :pipes)] :ssv)
|
||||||
|
:c nil}))))
|
||||||
|
|
||||||
(deftest test-json-mime?
|
(deftest test-json-mime?
|
||||||
(are [mime expected]
|
(are [mime expected]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user