|
1 | 1 | (ns clj-http.test.core |
2 | | - (:use [clojure.test] |
| 2 | + (:use [name.stadig.conjecture] |
3 | 3 | [clojure.java.io :only [file]]) |
4 | 4 | (:require [clojure.pprint :as pp] |
5 | 5 | [clj-http.client :as client] |
6 | 6 | [clj-http.core :as core] |
| 7 | + [clj-http.test.support :as support] |
7 | 8 | [clj-http.util :as util] |
8 | 9 | [cheshire.core :as json] |
9 | 10 | [ring.adapter.jetty :as ring]) |
|
14 | 15 | (org.apache.http.protocol HttpContext ExecutionContext) |
15 | 16 | (org.apache.http.impl.client DefaultHttpClient))) |
16 | 17 |
|
17 | | -(defn handler [req] |
18 | | - ;;(pp/pprint req) |
19 | | - ;;(println) (println) |
20 | | - (condp = [(:request-method req) (:uri req)] |
21 | | - [:get "/get"] |
22 | | - {:status 200 :body "get"} |
23 | | - [:get "/clojure"] |
24 | | - {:status 200 :body "{:foo \"bar\" :baz 7M :eggplant {:quux #{1 2 3}}}" |
25 | | - :headers {"content-type" "application/clojure"}} |
26 | | - [:get "/clojure-bad"] |
27 | | - {:status 200 :body "{:foo \"bar\" :baz #=(+ 1 1)}" |
28 | | - :headers {"content-type" "application/clojure"}} |
29 | | - [:get "/json"] |
30 | | - {:status 200 :body "{\"foo\":\"bar\"}"} |
31 | | - [:get "/json-bad"] |
32 | | - {:status 400 :body "{\"foo\":\"bar\"}"} |
33 | | - [:get "/redirect"] |
34 | | - {:status 302 :headers |
35 | | - {"location" "http://localhost:18080/redirect"}} |
36 | | - [:get "/redirect-to-get"] |
37 | | - {:status 302 :headers |
38 | | - {"location" "http://localhost:18080/get"}} |
39 | | - [:head "/head"] |
40 | | - {:status 200} |
41 | | - [:get "/content-type"] |
42 | | - {:status 200 :body (:content-type req)} |
43 | | - [:get "/header"] |
44 | | - {:status 200 :body (get-in req [:headers "x-my-header"])} |
45 | | - [:post "/post"] |
46 | | - {:status 200 :body (slurp (:body req))} |
47 | | - [:get "/error"] |
48 | | - {:status 500 :body "o noes"} |
49 | | - [:get "/timeout"] |
50 | | - (do |
51 | | - (Thread/sleep 10) |
52 | | - {:status 200 :body "timeout"}) |
53 | | - [:delete "/delete-with-body"] |
54 | | - {:status 200 :body "delete-with-body"} |
55 | | - [:post "/multipart"] |
56 | | - {:status 200 :body (:body req)} |
57 | | - [:get "/get-with-body"] |
58 | | - {:status 200 :body (:body req)} |
59 | | - [:options "/options"] |
60 | | - {:status 200 :body "options"} |
61 | | - [:copy "/copy"] |
62 | | - {:status 200 :body "copy"} |
63 | | - [:move "/move"] |
64 | | - {:status 200 :body "move"} |
65 | | - [:patch "/patch"] |
66 | | - {:status 200 :body "patch"} |
67 | | - [:get "/headers"] |
68 | | - {:status 200 :body (json/encode (:headers req))})) |
69 | | - |
70 | | -(defn run-server |
71 | | - [] |
72 | | - (defonce server |
73 | | - (ring/run-jetty handler {:port 18080 :join? false}))) |
| 18 | +(use-fixtures :once support/server-fixture) |
74 | 19 |
|
75 | 20 | (defn localhost [path] |
76 | 21 | (str "http://localhost:18080" path)) |
|
87 | 32 | (slurp (:body req))) |
88 | 33 |
|
89 | 34 | (deftest ^{:integration true} makes-get-request |
90 | | - (run-server) |
91 | 35 | (let [resp (request {:request-method :get :uri "/get"})] |
92 | 36 | (is (= 200 (:status resp))) |
93 | 37 | (is (= "get" (slurp-body resp))))) |
94 | 38 |
|
95 | 39 | (deftest ^{:integration true} makes-head-request |
96 | | - (run-server) |
97 | 40 | (let [resp (request {:request-method :head :uri "/head"})] |
98 | 41 | (is (= 200 (:status resp))) |
99 | 42 | (is (nil? (:body resp))))) |
100 | 43 |
|
101 | 44 | (deftest ^{:integration true} sets-content-type-with-charset |
102 | | - (run-server) |
103 | 45 | (let [resp (client/request {:scheme :http |
104 | 46 | :server-name "localhost" |
105 | 47 | :server-port 18080 |
|
109 | 51 | (is (= "text/plain; charset=UTF-8" (:body resp))))) |
110 | 52 |
|
111 | 53 | (deftest ^{:integration true} sets-content-type-without-charset |
112 | | - (run-server) |
113 | 54 | (let [resp (client/request {:scheme :http |
114 | 55 | :server-name "localhost" |
115 | 56 | :server-port 18080 |
|
118 | 59 | (is (= "text/plain" (:body resp))))) |
119 | 60 |
|
120 | 61 | (deftest ^{:integration true} sets-arbitrary-headers |
121 | | - (run-server) |
122 | 62 | (let [resp (request {:request-method :get :uri "/header" |
123 | 63 | :headers {"x-my-header" "header-val"}})] |
124 | 64 | (is (= "header-val" (slurp-body resp))))) |
125 | 65 |
|
126 | 66 | (deftest ^{:integration true} sends-and-returns-byte-array-body |
127 | | - (run-server) |
128 | 67 | (let [resp (request {:request-method :post :uri "/post" |
129 | 68 | :body (util/utf8-bytes "contents")})] |
130 | 69 | (is (= 200 (:status resp))) |
131 | 70 | (is (= "contents" (slurp-body resp))))) |
132 | 71 |
|
133 | 72 | (deftest ^{:integration true} returns-arbitrary-headers |
134 | | - (run-server) |
135 | 73 | (let [resp (request {:request-method :get :uri "/get"})] |
136 | 74 | (is (string? (get-in resp [:headers "date"]))))) |
137 | 75 |
|
138 | 76 | (deftest ^{:integration true} returns-status-on-exceptional-responses |
139 | | - (run-server) |
140 | 77 | (let [resp (request {:request-method :get :uri "/error"})] |
141 | 78 | (is (= 500 (:status resp))))) |
142 | 79 |
|
143 | 80 | (deftest ^{:integration true} sets-socket-timeout |
144 | | - (run-server) |
145 | 81 | (try |
146 | 82 | (is (thrown? java.net.SocketTimeoutException |
147 | 83 | (client/request {:scheme :http |
|
151 | 87 | :socket-timeout 1}))))) |
152 | 88 |
|
153 | 89 | (deftest ^{:integration true} delete-with-body |
154 | | - (run-server) |
155 | 90 | (let [resp (request {:request-method :delete :uri "/delete-with-body" |
156 | 91 | :body (.getBytes "foo bar")})] |
157 | 92 | (is (= 200 (:status resp))))) |
158 | 93 |
|
159 | 94 | (deftest ^{:integration true} self-signed-ssl-get |
160 | | - (let [t (doto (Thread. #(ring/run-jetty handler |
| 95 | + (let [t (doto (Thread. #(ring/run-jetty support/handler |
161 | 96 | {:port 8081 :ssl-port 18082 :ssl? true |
162 | 97 | :keystore "test-resources/keystore" |
163 | 98 | :key-password "keykey"})) .start)] |
|
177 | 112 | (.stop t))))) |
178 | 113 |
|
179 | 114 | (deftest ^{:integration true} multipart-form-uploads |
180 | | - (run-server) |
181 | 115 | (let [bytes (util/utf8-bytes "byte-test") |
182 | 116 | stream (ByteArrayInputStream. bytes) |
183 | 117 | resp (request {:request-method :post :uri "/multipart" |
|
209 | 143 | (is (re-find #"content" resp-body)))) |
210 | 144 |
|
211 | 145 | (deftest ^{:integration true} t-save-request-obj |
212 | | - (run-server) |
213 | 146 | (let [resp (request {:request-method :post :uri "/post" |
214 | 147 | :body "foo bar" |
215 | 148 | :save-request? true |
|
248 | 181 | {"set-cookie" ["one" "two"] "server" "some-server"})) |
249 | 182 |
|
250 | 183 | (deftest ^{:integration true} t-streaming-response |
251 | | - (run-server) |
252 | 184 | (let [stream (:body (request {:request-method :get :uri "/get" :as :stream})) |
253 | 185 | body (slurp stream)] |
254 | 186 | (is (= "get" body)))) |
|
258 | 190 | (client/request {:method :bad :url "http://example.org"})))) |
259 | 191 |
|
260 | 192 | (deftest ^{:integration true} throw-on-too-many-redirects |
261 | | - (run-server) |
262 | 193 | (let [resp (client/get (localhost "/redirect") |
263 | 194 | {:max-redirects 2 :throw-exceptions false})] |
264 | 195 | (is (= 302 (:status resp))) |
|
272 | 203 | {:throw-exceptions true})))) |
273 | 204 |
|
274 | 205 | (deftest ^{:integration true} get-with-body |
275 | | - (run-server) |
276 | 206 | (let [resp (request {:request-method :get :uri "/get-with-body" |
277 | 207 | :body (.getBytes "foo bar")})] |
278 | 208 | (is (= 200 (:status resp))) |
279 | 209 | (is (= "foo bar" (String. (:body resp)))))) |
280 | 210 |
|
281 | 211 | (deftest ^{:integration true} head-with-body |
282 | | - (run-server) |
283 | 212 | (let [resp (request {:request-method :head :uri "/head" :body "foo"})] |
284 | 213 | (is (= 200 (:status resp))))) |
285 | 214 |
|
286 | 215 | (deftest ^{:integration true} t-clojure-output-coercion |
287 | | - (run-server) |
288 | 216 | (let [resp (client/get (localhost "/clojure") {:as :clojure})] |
289 | 217 | (is (= 200 (:status resp))) |
290 | 218 | (is (= {:foo "bar" :baz 7M :eggplant {:quux #{1 2 3}}} (:body resp)))) |
|
293 | 221 | (is (= {:foo "bar" :baz 7M :eggplant {:quux #{1 2 3}}} (:body resp))))) |
294 | 222 |
|
295 | 223 | (deftest ^{:integration true} t-json-output-coercion |
296 | | - (run-server) |
297 | 224 | (let [resp (client/get (localhost "/json") {:as :json}) |
298 | 225 | resp-str (client/get (localhost "/json") |
299 | 226 | {:as :json :coerce :exceptional}) |
|
318 | 245 | (is (= "{\"foo\":\"bar\"}" (:body bad-resp-json2))))) |
319 | 246 |
|
320 | 247 | (deftest ^{:integration true} t-ipv6 |
321 | | - (run-server) |
322 | 248 | (let [resp (client/get "http://[::1]:18080/get")] |
323 | 249 | (is (= 200 (:status resp))) |
324 | 250 | (is (= "get" (:body resp))))) |
|
339 | 265 |
|
340 | 266 | ;; super-basic test for methods that aren't used that often |
341 | 267 | (deftest ^{:integration true} t-copy-options-move |
342 | | - (run-server) |
343 | 268 | (let [resp1 (client/options (localhost "/options")) |
344 | 269 | resp2 (client/move (localhost "/move")) |
345 | 270 | resp3 (client/copy (localhost "/copy")) |
|
351 | 276 | (is (= "patch" (:body resp4))))) |
352 | 277 |
|
353 | 278 | (deftest ^{:integration true} t-json-encoded-form-params |
354 | | - (run-server) |
355 | 279 | (let [params {:param1 "value1" :param2 {:foo "bar"}} |
356 | 280 | resp (client/post (localhost "/post") {:content-type :json |
357 | 281 | :form-params params})] |
358 | 282 | (is (= 200 (:status resp))) |
359 | 283 | (is (= (json/encode params) (:body resp))))) |
360 | 284 |
|
361 | 285 | (deftest ^{:integration true} t-response-interceptor |
362 | | - (run-server) |
363 | 286 | (let [saved-ctx (atom []) |
364 | 287 | {:keys [status trace-redirects] :as resp} |
365 | 288 | (client/get |
|
376 | 299 | (is (every? #(instance? HttpConnection (:http-conn %)) @saved-ctx)))) |
377 | 300 |
|
378 | 301 | (deftest ^{:integration true} t-send-input-stream-body |
379 | | - (run-server) |
380 | 302 | (let [b1 (:body (client/post "http://localhost:18080/post" |
381 | 303 | {:body (ByteArrayInputStream. (.getBytes "foo")) |
382 | 304 | :length 3})) |
|
406 | 328 | ;; This relies on connections to writequit.org being slower than 1ms, if this |
407 | 329 | ;; fails, you must have very nice internet. |
408 | 330 | (deftest ^{:integration true} sets-conn-timeout |
409 | | - (run-server) |
410 | 331 | (try |
411 | 332 | (is (thrown? org.apache.http.conn.ConnectTimeoutException |
412 | 333 | (client/request {:scheme :https |
|
417 | 338 | :conn-timeout 1}))))) |
418 | 339 |
|
419 | 340 | (deftest ^{:integration true} connection-pool-timeout |
420 | | - (run-server) |
421 | 341 | (client/with-connection-pool {:timeout 1 :threads 1 :default-per-route 1} |
422 | 342 | (let [async-request #(future (client/request {:scheme :http |
423 | 343 | :server-name "localhost" |
|
436 | 356 | (is (or timeout-error1 timeout-error2))))) |
437 | 357 |
|
438 | 358 | (deftest ^{:integration true} t-header-collections |
439 | | - (run-server) |
440 | 359 | (let [headers (-> (client/get "http://localhost:18080/headers" |
441 | 360 | {:headers {"foo" ["bar" "baz"] |
442 | 361 | "eggplant" "quux"}}) |
|
446 | 365 | (select-keys headers ["foo" "eggplant"]))))) |
447 | 366 |
|
448 | 367 | (deftest ^{:integration true} t-clojure-no-read-eval |
449 | | - (run-server) |
450 | 368 | (is (thrown-with-msg? |
451 | 369 | java.lang.RuntimeException |
452 | 370 | #".*(EvalReader|eval reading) not allowed when \*read-eval\* is false.*" |
|
0 commit comments