add mock http request unit tests for the test channel

This commit is contained in:
Gered 2016-05-12 12:14:54 -04:00
parent 89ad55b9c8
commit 605d6c5d51
4 changed files with 152 additions and 1 deletions

View file

@ -9,6 +9,7 @@
[org.clojure/clojurescript "1.8.51"]]}
:dev
{:dependencies [[pjstadig/humane-test-output "0.8.0"]]
{:dependencies [[pjstadig/humane-test-output "0.8.0"]
[ring/ring-mock "0.3.0"]]
:injections [(require 'pjstadig.humane-test-output)
(pjstadig.humane-test-output/activate!)]}})

View file

@ -3,3 +3,18 @@
(defn ->queue
[& x]
(apply conj clojure.lang.PersistentQueue/EMPTY x))
(defn random-string
[& [n]]
(let [n (or n 12)
chars (map char (concat (range 48 58) (range 66 91) (range 97 123)))
password (take n (repeatedly #(rand-nth chars)))]
(reduce str password)))
(defn contains-all-of?
[m other-m]
(->> other-m
(map (fn [[k v]]
(= (get m k) v)))
(remove true?)
(empty?)))

View file

@ -0,0 +1,88 @@
(ns net.thegeez.browserchannel.server.http-request-tests
(:use
clojure.test
net.thegeez.browserchannel.common
net.thegeez.browserchannel.server
net.thegeez.browserchannel.test-async-adapter)
(:require
[cheshire.core :as json]
[ring.util.response :as response]
[ring.mock.request :as mock]))
(use-fixtures :each async-output-fixture)
(defn app
[request & [options]]
((-> (fn [{:keys [uri] :as request}]
(if (or (= "" uri)
(= "/" uri))
(response/response "Hello, world!")
(response/not-found "not found")))
(wrap-browserchannel (or options default-options))
(wrap-test-async-adapter (or options default-options)))
request))
;; http://web.archive.org/web/20121226064550/http://code.google.com/p/libevent-browserchannel-server/wiki/BrowserChannelProtocol#Get_Host_Prefixes
(deftest get-host-prefixes-test-incorrect-version
(let [resp (app (mock/request
:get "/channel/test"
{"VER" 7
"MODE" "init"
"zx" (random-string)
"t" 1}))]
(is (= 400 (:status resp)))))
(deftest get-host-prefixes-test-incorrect-request
(let [resp (app (mock/request
:get "/channel/test"))]
(is (= 400 (:status resp)))))
(deftest get-host-prefixes-test-no-prefixes
(let [resp (app (mock/request
:get "/channel/test"
{"VER" 8
"MODE" "init"
"zx" (random-string)
"t" 1}))]
(is (= 200 (:status resp)))
(is (contains-all-of? (:headers resp) (:headers default-options)))
(is (= (json/parse-string (:body resp))
[nil nil]))))
(deftest get-host-prefixes-test-with-prefixes
(let [options (merge default-options
{:host-prefixes ["a", "b", "c"]})
resp (app (mock/request
:get "/channel/test"
{"VER" 8
"MODE" "init"
"zx" (random-string)
"t" 1})
options)
body (json/parse-string (:body resp))]
(is (= 200 (:status resp)))
(is (contains-all-of? (:headers resp) (:headers default-options)))
(is (not (nil? (some #{(first body)} (:host-prefixes options)))))
(is (nil? (second body)))))
(deftest buffering-proxy-test
(let [resp (app (mock/request
:get "/channel/test"
{"VER" 8
"zx" (random-string)
"t" 1}))
async-resp @async-output]
(is (= 200 (:status resp)))
(is (= 200 (:status async-resp)))
(is (contains-all-of? (:headers async-resp) (:headers default-options)))
(is (not (:closed? async-resp)))
(is (= "11111" (:body async-resp)))
; browserchannel's buffering proxy test is supposed to work by initially sending
; "11111", then waits for 2 seconds (without closing the response), then sends
; "2" and finally closes the response.
; wait for 3 secs just to be safe
(Thread/sleep 3000)
(let [async-resp @async-output]
(is (:closed? async-resp))
(is (= "111112" (:body async-resp))))))

View file

@ -0,0 +1,47 @@
(ns net.thegeez.browserchannel.test-async-adapter
(:require
[net.thegeez.browserchannel.async-adapter :as bc-async-adapter]))
(def async-output (atom {}))
(defn write-async-output!
[data]
(if (map? data)
(swap! async-output merge data)
(swap! async-output (fn [{:keys [body] :as output}]
(assoc output :body (str body data))))))
(defn closed-async-output?
[]
(:closed? @async-output))
(defn async-output-fixture [f]
(reset! async-output {})
(f))
(deftype TestResponse
[write-fn closed?-fn]
bc-async-adapter/IAsyncAdapter
(head [this status headers]
(let [headers (assoc headers "Transfer-Encoding" "chunked")]
(write-fn {:status status :headers headers})))
(write-chunk [this data]
(if-not (closed?-fn)
(write-fn data)
(throw bc-async-adapter/ConnectionClosedException)))
(close [this]
(write-fn {:closed? true})))
(defn wrap-test-async-adapter
[handler & [options]]
(fn [request]
(let [resp (handler request)]
(if (= :http (:async resp))
(let [reactor (:reactor resp)
emit (TestResponse. write-async-output! closed-async-output?)]
(reactor emit)
{:status 200})
resp))))