Skip to content

Commit

Permalink
fix: parsing body parameters from examples (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenlaater committed Jul 15, 2019
1 parent be38b2e commit 61de0b6
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/code_examples_generator/resource_parser.clj
Expand Up @@ -33,7 +33,7 @@
:scheme scheme
:uri uri
:query-string (form-encode (coerce-examples->values queryParameters))
:body (coerce-examples->values body)
:body (:example body)
:headers (coerce-examples->values headers)}]
(into {} (remove (fn [[_ v]] (when-not (keyword? v) (empty? v))) r))))

Expand Down
63 changes: 63 additions & 0 deletions test-resources/broker-api.edn
@@ -0,0 +1,63 @@
{:raml-version "1.0",
:title "Platform Of Trust Data Broker",
:version "v1",
:baseUri
{:uri "https://api-sandbox.oftrust.net",
:raml-clj-parser.reader/uri-parameters []},
:mediaType "application/json",
:description
"The Broker API provides means to connect a service to a translator that will\nreturn desired data from different sources. The data broker does not mangle\nthe data in any way, it only functions as a proxy between services and\ntranslators.\n",
:types
{:data-product-request
{:type "object",
:properties
{:timestamp
{:description "A timestamp in RFC3339 format",
:type "string",
:example #inst "2018-11-01T12:00:00.000-00:00"},
:productCode
{:description "The data product's product code",
:type "string",
:example "product-1"},
:parameters
{:description "Additional parameters to be sent to the translator",
:type "object",
:example
"{\n \"param-1\": \"param-1 value\",\n \"param-2\": \"param-2 value\"\n}\n"}}}},
"/broker/{version}/fetch-data-product"
{:uri "/broker/{version}/fetch-data-product",
:raml-clj-parser.reader/uri-parameters ["version"],
:description
"Use a data product. E.g. request data from the external data source\nconnected to the data product.\n",
:post
{:description
"Request data from an external service defined by the data product, and\n product code. The data broker will validate the signature of the\n payload and when verified, relay the request to the translator\n connected to the data product. The translator will translate the\n information fetched from an external source into a standardized format\n that will be returned to the requester.\n",
:headers
{:X-Pot-Signature
{:description
"A HMAC-SHA256 signature in base64 encoded format.\nThe signature is created by taking the request payload, e.g. a\nPython dict, and converting it to a string. <br/><br/>\n\nPython example: <br/><br/>\n<code>\n body_string = json.dumps( <br/>\n body, <br/>\n sort_keys=True, <br/>\n indent=None, <br/>\n separators=(',', ': ') <br/>\n).strip() <br/><br/>\n</code>\nThe keys MUST be sorted, without indentation and separators comma\n(,) and colon (:) specified. <br/><br/>\n\nGet the digest by passing the app access token (generated when\ncreating a new app) and the body string to `hmac`:<br/><br/>\n<code>\ndigest = <br/>\nhmac.new(app_access_token.encode('utf-8'), <br/>\nbody_string.encode('utf-8'),<br/>\nhashlib.sha256).digest()<br/><br/>\n</code><br/>\nReturn the digest in base64 encoded format:<br/>\n<code>\nX-Pot-Signature = base64.b64encode(digest).decode()<br/>\n</code>\n",
:type "string",
:example "Ioma1gqOVFUBrXiziWS....CLqBG4vFozG3YgzPzillNip0="},
:X-Pot-App
{:description "The requesting application's client ID.",
:type "string",
:example "379780e4-b511-4fa9-aef8-bda9bd58ab89"},
:X-Pot-Token?
{:description
"The currently logged in user's OAuth access token.\n",
:type "string",
:example
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzY29w...DVs5aaf"}},
:body
{:type "data-product-request",
:example
"{\n \"timestamp\": \"2018-11-01T12:00:00+00:00\",\n \"productCode\": \"product-1\",\n \"parameters\": {\n \"param-1\": \"Value\",\n \"param-2\": \"Value\"\n }\n}\n"},
:responses
{"200"
{:body
{:example
"{\n \"@context\": \"<context url>\",\n \"data\": {\n <response from translator>\n },\n \"signature\": {\n \"type\": \"<signature type>\",\n \"created\": \"<RFC3339>\",\n \"creator\": \"<public key URL>\",\n \"signatureValue\": \"...\"\n }\n}\n"}},
"422"
{:body
{:example
"{\n \"error\": {\n \"status\": 422,\n \"message\": {\n \"mandatoryParameter\": [\n \"Missing data for required field.\"\n ]\n }\n }\n}\n"}}}}}}
48 changes: 32 additions & 16 deletions test/code_examples_generator/resource_parser_test.clj
Expand Up @@ -34,16 +34,22 @@
"pot" false})))))

(deftest test-get-ring-request
(testing "ring-request keys"
(with-redefs [coerce-examples->values (constantly "stub")]
(is (= '(:request-method
:server-name
:scheme
:uri
:query-string
:body
:headers)
(keys (get-ring-request {} :get "pot.org" "https" "/"))))))
(testing "requried ring-request keys are always when proper data has been provided "
(is (= '(:request-method
:server-name
:scheme
:uri
:query-string
:body
:headers)
(keys (get-ring-request
{:body {:example "test"}
:queryParameters {:t1 {:example 1}}
:headers {:h1 {:example 2}}}
:get
"pot.org"
"https"
"/")))))
(testing "no empty or nil values"
(is (= '(:request-method :uri :query-string)
(keys (get-ring-request {:queryParameters {:test {:example "ok"}}
Expand All @@ -55,14 +61,14 @@
(is (= h (:headers (get-ring-request {:headers h} "" "" "" "")))))))
(testing "body parameters exist"
(with-redefs [coerce-examples->values (fn [m] m)]
(let [b {:test "body"}]
(is (= b (:body (get-ring-request {:body b} "" "" "" "")))))))
(let [b {:type "test" :example "this should get displayed"}]
(is (= (:example b)
(:body (get-ring-request {:body b} "" "" "" "")))))))
(testing "query parameters should get url encoded"
(with-redefs [coerce-examples->values (fn [m] m)]
(let [q {:test "query"}
r (get-ring-request {:queryParameters q} "" "" "" "")]
(is (= (form-encode q) (:query-string r)))))))
;; TODO also test body and headers!

(deftest test-get-methods
(testing "always return a map"
Expand All @@ -87,13 +93,12 @@
(are [f s] (= clojure.lang.LazySeq (type (get-requests f {} s)))
{} ""
nil "pot.org"))
(testing "message-api"
(testing "requests of message-api"
(let [requests (->> (get-requests
(edn/read-string
(slurp "test-resources/message-api.edn"))
{:host "" :scheme ""})
(map #(:ring-request %)))]

(is (= 6 (count requests)))
(is (= '(:post :get :put :delete :post :get)
(map #(:request-method %) requests)))
Expand All @@ -103,4 +108,15 @@
"/messages/{version}/{id}"
"/messages/{version}/{id}/read"
"/messages/{version}/{toIdentity}/list")
(map #(:uri %) requests))))))
(map #(:uri %) requests)))))
(testing "body parameters of broker-api"
(let [raml (edn/read-string (slurp "test-resources/broker-api.edn"))
requests (->> (get-requests raml {:host "" :scheme ""})
(map #(:ring-request %)))]

(is (= (-> requests first :body)
(-> raml
(get "/broker/{version}/fetch-data-product")
:post
:body
:example))))))

0 comments on commit 61de0b6

Please sign in to comment.