|
6 | 6 | [ring.util.http-response :refer :all] |
7 | 7 | [clojure.core.async :as a] |
8 | 8 | [schema.core :as s] |
| 9 | + [compojure.api.middleware :as mw] |
9 | 10 | [compojure.api.coercion.schema :as cs])) |
10 | 11 |
|
11 | 12 | (defn is-has-body [expected value] |
12 | 13 | (is (= (second value) expected))) |
13 | 14 |
|
14 | 15 | (defn is-fails-with [expected-status [status body]] |
15 | | - (is (= status expected-status)) |
16 | | - (is (every? (partial contains? body) [:type :coercion :in :value :schema :errors]))) |
| 16 | + (is (= status expected-status) |
| 17 | + (pr-str body)) |
| 18 | + (is (every? (partial contains? body) [:type :coercion :in :value :schema :errors]) |
| 19 | + (pr-str body))) |
17 | 20 |
|
18 | 21 | (deftest schema-coercion-test |
19 | 22 | (testing "response schemas" |
|
74 | 77 | ping-route)] |
75 | 78 | (let [[status body] (get* app "/ping")] |
76 | 79 | (is (= 200 status)) |
77 | | - (is (= {:pong 123} body))))) |
| 80 | + (is (= {:pong 123} body)))) |
| 81 | + (testing "legacy" |
| 82 | + (let [app (api |
| 83 | + {:formatter :muuntaja |
| 84 | + :coercion mw/no-response-coercion} |
| 85 | + ping-route)] |
| 86 | + (let [[status body] (get* app "/ping")] |
| 87 | + (is (= 200 status)) |
| 88 | + (is (= {:pong 123} body)))))) |
78 | 89 | (testing "all coercion" |
79 | 90 | (let [app (api |
80 | 91 | {:formatter :muuntaja |
|
101 | 112 | (a/go (ok "foo"))))] |
102 | 113 | (is-fails-with 500 (get* app "/async")))))))) |
103 | 114 |
|
104 | | - (testing "body coersion" |
| 115 | + (testing "body coercion" |
105 | 116 | (let [beer-route (POST "/beer" [] |
106 | 117 | :body [body {:beers #{(s/enum "ipa" "apa")}}] |
107 | 118 | (ok body))] |
|
131 | 142 | (is (= 200 status)) |
132 | 143 | (is (= {:beers ["ipa" "apa" "ipa"]} body))))) |
133 | 144 |
|
| 145 | + (testing "legacy body-coercion can be disabled" |
| 146 | + (let [no-body-coercion (constantly (dissoc mw/default-coercion-matchers :body)) |
| 147 | + app (api |
| 148 | + {:formatter :muuntaja |
| 149 | + :coercion no-body-coercion} |
| 150 | + beer-route)] |
| 151 | + (let [[status body] (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))] |
| 152 | + (is (= 200 status)) |
| 153 | + (is (= {:beers ["ipa" "apa" "ipa"]} body)))) |
| 154 | + (let [app (api |
| 155 | + {:formatter :muuntaja |
| 156 | + :coercion nil} |
| 157 | + beer-route)] |
| 158 | + (let [[status body] (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))] |
| 159 | + (is (= 200 status)) |
| 160 | + (is (= {:beers ["ipa" "apa" "ipa"]} body))))) |
| 161 | + |
134 | 162 | (testing "body-coercion can be changed" |
135 | 163 | (let [nop-body-coercion (cs/create-coercion (assoc cs/default-options :body {:default (constantly nil)})) |
136 | 164 | app (api |
137 | 165 | {:formatter :muuntaja |
138 | 166 | :coercion nop-body-coercion} |
139 | 167 | beer-route)] |
| 168 | + (is-fails-with 400 (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))))) |
| 169 | + (testing "legacy body-coercion can be changed" |
| 170 | + (let [nop-body-coercion (constantly (assoc mw/default-coercion-matchers :body (constantly nil))) |
| 171 | + app (api |
| 172 | + {:formatter :muuntaja |
| 173 | + :coercion nop-body-coercion} |
| 174 | + beer-route)] |
140 | 175 | (is-fails-with 400 (post* app "/beer" (json-string {:beers ["ipa" "apa" "ipa"]}))))))) |
141 | 176 |
|
142 | 177 | (testing "query coercion" |
|
162 | 197 | (is (= 200 status)) |
163 | 198 | (is (= {:i "10"} body))))) |
164 | 199 |
|
| 200 | + (testing "legacy query-coercion can be disabled" |
| 201 | + (let [no-query-coercion (constantly (dissoc mw/default-coercion-matchers :string)) |
| 202 | + app (api |
| 203 | + {:formatter :muuntaja |
| 204 | + :coercion no-query-coercion} |
| 205 | + query-route)] |
| 206 | + (let [[status body] (get* app "/query" {:i 10})] |
| 207 | + (is (= 200 status)) |
| 208 | + (is (= {:i "10"} body))))) |
| 209 | + |
165 | 210 | (testing "query-coercion can be changed" |
166 | 211 | (let [nop-query-coercion (cs/create-coercion (assoc cs/default-options :string {:default (constantly nil)})) |
167 | 212 | app (api |
168 | 213 | {:formatter :muuntaja |
169 | 214 | :coercion nop-query-coercion} |
170 | 215 | query-route)] |
| 216 | + (is-fails-with 400 (get* app "/query" {:i 10})))) |
| 217 | + |
| 218 | + (testing "legacy query-coercion can be changed" |
| 219 | + (let [nop-query-coercion (constantly (assoc mw/default-coercion-matchers :string (constantly nil))) |
| 220 | + app (api |
| 221 | + {:formatter :muuntaja |
| 222 | + :coercion nop-query-coercion} |
| 223 | + query-route)] |
171 | 224 | (is-fails-with 400 (get* app "/query" {:i 10})))))) |
172 | 225 |
|
173 | 226 | (testing "route-specific coercion" |
|
207 | 260 |
|
208 | 261 | (testing "no coercion" |
209 | 262 | (let [[status body] (get* app "/no-coercion" {:i 10})] |
| 263 | + (is (= 200 status)) |
| 264 | + (is (= {:i "10"} body)))))) |
| 265 | + (testing "legacy route-specific coercion" |
| 266 | + (let [app (api |
| 267 | + {:formatter :muuntaja} |
| 268 | + (GET "/default" [] |
| 269 | + :query-params [i :- s/Int] |
| 270 | + (ok {:i i})) |
| 271 | + (GET "/disabled-coercion" [] |
| 272 | + :coercion (constantly (assoc mw/default-coercion-matchers :string (constantly nil))) |
| 273 | + :query-params [i :- s/Int] |
| 274 | + (ok {:i i})) |
| 275 | + (GET "/no-coercion" [] |
| 276 | + :coercion (constantly nil) |
| 277 | + :query-params [i :- s/Int] |
| 278 | + (ok {:i i})) |
| 279 | + (GET "/nil-coercion" [] |
| 280 | + :coercion nil |
| 281 | + :query-params [i :- s/Int] |
| 282 | + (ok {:i i})))] |
| 283 | + |
| 284 | + (testing "default coercion" |
| 285 | + (let [[status body] (get* app "/default" {:i 10})] |
| 286 | + (is (= 200 status)) |
| 287 | + (is (= {:i 10} body)))) |
| 288 | + |
| 289 | + (testing "disabled coercion" |
| 290 | + (is-fails-with 400 (get* app "/disabled-coercion" {:i 10}))) |
| 291 | + |
| 292 | + (testing "exception data" |
| 293 | + (let [ex (get* app "/disabled-coercion" {:i 10})] |
| 294 | + (is (= 400 (first ex))) |
| 295 | + (is (= {:type "compojure.api.exception/request-validation" |
| 296 | + :coercion "schema", |
| 297 | + :in ["request" "query-params"], |
| 298 | + :value {:i "10"} |
| 299 | + :schema "{Keyword Any, :i Int}", |
| 300 | + :errors {:i "(not (integer? \"10\"))"}} |
| 301 | + (select-keys (second ex) |
| 302 | + [:type :coercion :in :value :schema :errors]))))) |
| 303 | + |
| 304 | + (testing "no coercion" |
| 305 | + (let [[status body] (get* app "/no-coercion" {:i 10})] |
| 306 | + (is (= 200 status)) |
| 307 | + (is (= {:i "10"} body))) |
| 308 | + (let [[status body] (get* app "/nil-coercion" {:i 10})] |
210 | 309 | (is (= 200 status)) |
211 | 310 | (is (= {:i "10"} body))))))) |
212 | 311 |
|
|
237 | 336 | (is (= ["1" 2] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}})))) |
238 | 337 | (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}}))))) |
239 | 338 |
|
| 339 | + (testing "legacy coercion can be overridden" |
| 340 | + (let [app (context "/api" [] |
| 341 | + :query-params [{y :- Long 0}] |
| 342 | + (GET "/ping" [] |
| 343 | + :coercion (constantly nil) |
| 344 | + :query-params [x :- Long] |
| 345 | + (ok [x y])))] |
| 346 | + (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {}}))) |
| 347 | + (is (= ["abba" 0] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "abba"}})))) |
| 348 | + (is (= ["1" 0] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1"}})))) |
| 349 | + (is (= ["1" 2] (:body (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y 2}})))) |
| 350 | + (is (thrown? Exception (app {:request-method :get :uri "/api/ping" :query-params {:x "1", :y "abba"}}))))) |
| 351 | + |
240 | 352 | (testing "context coercion is used for subroutes" |
241 | 353 | (let [app (context "/api" [] |
242 | 354 | :coercion nil |
|
0 commit comments