Created
January 5, 2016 19:06
-
-
Save Deraen/ff5e0d376c03de046faa to your computer and use it in GitHub Desktop.
Silk Schema query params
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defprotocol ToUrlParam | |
(-to-url-param [this])) | |
(defn to-url-param [x] | |
(if (satisfies? ToUrlParam x) | |
(-to-url-param x) | |
x)) | |
(extend-protocol ToUrlParam | |
PersistentHashSet | |
(-to-url-param [this] | |
; FIXME: Values must not contains commas | |
(string/join "," (map to-url-param this))) | |
ISequential | |
(-to-url-param [this] | |
; FIXME: Values must not contains commas | |
(string/join "," (map to-url-param this))) | |
Keyword | |
(-to-url-param [this] (name this))) | |
(defrecord SchemaQueryParams [schema coercer] | |
silk/Pattern | |
(-match [this that] | |
(coercer (util/map-keys keyword that))) | |
(-unmatch [this that] | |
(persistent! | |
(reduce-kv (fn [acc k v] | |
(assoc! acc (name k) (to-url-param v))) | |
(transient {}) (st/select-schema that schema)))) | |
(-match-validator [_] | |
some?) | |
(-unmatch-validators [_] | |
{})) | |
(defn collection-matcher [schema] | |
(if (or (sequential? schema) (set? schema)) | |
(fn [value] | |
(if (string? value) | |
(into (empty schema) (string/split value #",")) | |
value)))) | |
(defn query-string-coercion-matcher [schema] | |
(or (collection-matcher schema) | |
(sc/string-coercion-matcher schema))) | |
(defn schema-query [schema] | |
(map->SchemaQueryParams {:schema schema | |
:coercer (sc/coercer schema query-string-coercion-matcher)})) | |
;; | |
;; All routes | |
;; | |
(def routes | |
(silk/routes | |
[[:tickets [["dashboard"] (schema-query {(s/optional-key :limit) s/Int | |
(s/optional-key :sort) s/Keyword | |
(s/optional-key :q) s/Str | |
(s/optional-key :states) #{s/Keyword} | |
(s/optional-key :baskets) #{s/Int} | |
(s/optional-key :technicians) #{s/Int} | |
(s/optional-key :unsorted) s/Bool})]] | |
[:ticket [["tickets" :id] (data {:routing/nav :tickets})]] | |
])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(deftest schema-query-test | |
(testing "single required option" | |
(let [routes (silk/routes [[:tickets [["tickets"] (schema-query {:q s/Str})]]])] | |
(is (= "/tickets?q=a" | |
(silk/depart routes :tickets {:q "a"}))) | |
(is (thrown? js/Error (silk/depart routes :tickets))) | |
(is (= {:domkm.silk/name :tickets :q "a"} | |
(select-keys (silk/arrive routes "/tickets?q=a") [:domkm.silk/name :q]))) | |
(is (thrown? js/Error (silk/arrive routes "/tickets"))) )) | |
(testing "single optional option" | |
(let [routes (silk/routes [[:tickets [["tickets"] (schema-query {(s/optional-key :q) s/Str})]]])] | |
(is (= "/tickets?q=a" | |
(silk/depart routes :tickets {:q "a"}))) | |
(is (= "/tickets" | |
(silk/depart routes :tickets))) | |
(is (= {:domkm.silk/name :tickets :q "a"} | |
(select-keys (silk/arrive routes "/tickets?q=a") [:domkm.silk/name :q]))) | |
(is (= {:domkm.silk/name :tickets} | |
(select-keys (silk/arrive routes "/tickets") [:domkm.silk/name :q]))))) | |
(testing "optional set option" | |
(let [routes (silk/routes [[:tickets [["tickets"] (schema-query {(s/optional-key :baskets) #{s/Str}})]]])] | |
(is (= (str "/tickets?baskets=" (js/encodeURIComponent "a,b")) | |
(silk/depart routes :tickets {:baskets #{"a" "b"}}))) | |
(is (= {:domkm.silk/name :tickets :baskets #{"a" "b"}} | |
(select-keys (silk/arrive routes (str "/tickets?baskets=" (js/encodeURIComponent "a,b"))) [:domkm.silk/name :baskets]))))) | |
) | |
(test/run-tests) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment