Skip to content

Commit

Permalink
Add functions for a request validation #13
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasRychtecky committed Jun 8, 2018
1 parent 8962aad commit e6eb591
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
6 changes: 4 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@

:profiles {:dev {:plugins [[lein-cloverage "1.0.10"]
[lein-kibit "0.1.6"]
[jonase/eastwood "0.2.5"]]
:dependencies [[org.clojure/clojure "1.9.0"]]}})
[jonase/eastwood "0.2.5"]
[lein-eftest "0.5.2"]]
:dependencies [[org.clojure/clojure "1.9.0"]
[funcool/struct "1.3.0"]]}})
27 changes: 27 additions & 0 deletions src/rop/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,30 @@
:status (get-in extracted-result [:response :status] 200)
:headers (get-in extracted-result [:response :headers] {})}
extracted-result)))


(defn =validate-request=
"A railway function that validates a request by a given scheme.
If data are valid it updates them in the request (with coerced data), otherwise returns Bad Requests within errors.
Parameters:
- `validate` a function that takes an input and a validation scheme, it should return a tuple of errors
and validated input
- `scheme` a validation scheme
- `default` default values as a `hash-map`, it will be merged into a validated input
- `request-key a key in a `request` that holds the input data`
- `input` a ROP input"
[validate scheme defaults request-key {:keys [request] :as input}]
(let [[errors validated-input] (validate (select-keys (get request request-key) (keys scheme)) scheme)]
(if (nil? errors)
(succeed (assoc-in input [:request request-key] (merge (zipmap (keys scheme) (repeat nil))
defaults
validated-input)))
(fail {:status 400, :body {:errors errors}}))))


(defn =merge-params=
"A railway function that merges a given `source` key into a `target` key in a request.
It's useful when route params and body params are validated together."
[source target {:keys [request] :as input}]
(succeed (update-in input [:request target] merge (get request source))))
27 changes: 27 additions & 0 deletions test/rop/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
(:require
[clojure.string :refer [blank? lower-case]]
[clojure.test :refer [deftest is testing]]
[cats.core :as m]
[struct.core :as st]
[rop.core :as rop]))


Expand Down Expand Up @@ -83,3 +85,28 @@
validate-email
(rop/switch #(assoc % :new-user {:email (:email %), :id 1}))
(rop/dead send-email!))))))


(deftest validate-request-test
(testing "should assoc a validated input"
(is (= {:request {:params {:id 1}}}
(m/extract (rop/=validate-request= st/validate
{:id [st/number-str]}
{}
:params
{:request {:params {:id "1"}}})))))

(testing "should assoc errors"
(is (= {:status 400, :body {:errors {:id "must be a number"}}}
(m/extract (rop/=validate-request= st/validate
{:id [st/number-str]}
{}
:params
{:request {:params {:id ""}}}))))))


(deftest merge-params-test
(is (= {:request {:params {:id 1, :foo :bar}, :body-params {:foo :bar}}}
(m/extract (rop/=merge-params= :body-params
:params
{:request {:params {:id 1}, :body-params {:foo :bar}}})))))

0 comments on commit e6eb591

Please sign in to comment.