(ns rxhttp.test-jvm
  (:require [clojure.test :as t]
            [beicon.core :as rx]
            [rxhttp.jvm :as http]
            [cheshire.core :as json])
  (:import java.util.concurrent.CountDownLatch))

;; --- helpers

(defn drain!
  [ob]
  (let [result (volatile! nil)
        latch (CountDownLatch. 1)]
    (rx/subscribe ob
                   #(vreset! result %)
                   #(do
                      (vreset! result %)
                      (.countDown latch))
                   #(.countDown latch))
    (.await latch)
    @result))

  --- jvm tests

(t/deftest send-plain-get
  (let [url ""
        req {:method :get
             :query-params {:foo "bar"}
             :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (t/is (= (get-in rsp [:headers "content-type"]) "application/json"))))

(t/deftest send-plain-get-with-client-error
  (let [url ""
        req {:method :get :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 400))))

(t/deftest send-plain-get-with-server-error
  (let [url ""
        req {:method :get :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 500))))

(t/deftest send-plain-get-with-timeout
  (let [url ""
        req {:method :get :url url}
        opts {:timeout 1000}
        rsp (drain! (http/send! req opts))]
    (t/is (instance? java.net.SocketTimeoutException rsp))))

(t/deftest send-plain-post
  (let [url ""
        req {:method :post
             :headers {:content-type "application/json"}
             :body (json/encode {:foo "bar"})
             :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (let [body (json/decode (:body rsp) true)]
      (t/is (= (:body req) (:data body))))))

(t/deftest send-sync-plain
  (let [url ""
        req {:method :get
             :query-params {:foo "bar"}
             :url url}
        rsp (http/send!! req)]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (t/is (= (get-in rsp [:headers "content-type"]) "application/json"))))

 --- helpers
(ns rxhttp.test-jvm
  (:require [clojure.test :as t]
            [beicon.core :as rx]
            [rxhttp.jvm :as http]
            [cheshire.core :as json])
  (:import java.util.concurrent.CountDownLatch))


(defn drain!
  [ob]
  (let [result (volatile! nil)
        latch (CountDownLatch. 1)]
    (rx/subscribe ob
                   #(vreset! result %)
                   #(do
                      (vreset! result %)
                      (.countDown latch))
                   #(.countDown latch))
    (.await latch)
    @result))

  --- jvm tests

(t/deftest send-plain-get
  (let [url ""
        req {:method :get
             :query-params {:foo "bar"}
             :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (t/is (= (get-in rsp [:headers "content-type"]) "application/json"))))

(t/deftest send-plain-get-with-client-error
  (let [url ""
        req {:method :get :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 400))))

(t/deftest send-plain-get-with-server-error
  (let [url ""
        req {:method :get :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 500))))

(t/deftest send-plain-get-with-timeout
  (let [url ""
        req {:method :get :url url}
        opts {:timeout 1000}
        rsp (drain! (http/send! req opts))]
    (t/is (instance? java.net.SocketTimeoutException rsp))))

(t/deftest send-plain-post
  (let [url ""
        req {:method :post
             :headers {:content-type "application/json"}
             :body (json/encode {:foo "bar"})
             :url url}
        rsp (drain! (http/send! req))]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (let [body (json/decode (:body rsp) true)]
      (t/is (= (:body req) (:data body))))))

(t/deftest send-sync-plain
  (let [url ""
        req {:method :get
             :query-params {:foo "bar"}
             :url url}
        rsp (http/send!! req)]
    (t/is (string? (:body rsp)))
    (t/is (= (:status rsp) 200))
    (t/is (= (get-in rsp [:headers "content-type"]) "application/json"))))
