diff --git a/src/io/pedestal/ions/test.clj b/src/io/pedestal/ions/test.clj index af145d8..da9710e 100644 --- a/src/io/pedestal/ions/test.clj +++ b/src/io/pedestal/ions/test.clj @@ -10,7 +10,21 @@ ;; You must not remove this notice, or any other, from this software. (ns io.pedestal.ions.test - (:require [clojure.test :as t])) + (:require [clojure.test :as t]) + (:import (java.io ByteArrayInputStream InputStream))) + + +(defprotocol IonTestRequestBody + (streaming-body [body] + "Returns a request body compatible with pedestal.ion's `response-for`.")) + +(extend-protocol IonTestRequestBody + String + (streaming-body [body] + (ByteArrayInputStream. (.getBytes body))) + + InputStream + (streaming-body [body] body)) (defn response-for "Like pedestal.service's `response-for` but expects `service` to be a handler @@ -20,16 +34,20 @@ server-name remote-addr scheme - headers] + headers + body] :or {server-port 0 server-name "localhost" remote-addr "127.0.0.1" scheme :http - headers {}}} options] - (service {:server-port server-port - :server-name server-name - :remote-addr remote-addr - :uri url - :scheme scheme - :request-method verb - :headers headers}))) + headers {}}} options + request {:server-port server-port + :server-name server-name + :remote-addr remote-addr + :uri url + :scheme scheme + :request-method verb + :headers headers}] + (service (cond-> request + body + (assoc :body (streaming-body body)))))) diff --git a/test/io/pedestal/ions_test.clj b/test/io/pedestal/ions_test.clj index 3f65eef..0b6fc24 100644 --- a/test/io/pedestal/ions_test.clj +++ b/test/io/pedestal/ions_test.clj @@ -18,23 +18,30 @@ [io.pedestal.ions :as ions] [io.pedestal.ions.test :as ions.test] [datomic.ion] - [clojure.edn :as edn])) + [cheshire.core :as json]) + (:import (java.io ByteArrayInputStream))) ;; Test app (defn about - [request] + [_] {:status 200 :body (format "Clojure %s" (clojure-version))}) (defn home - [request] + [_] {:status 200 :body "Hello World!"}) +(defn echo + [request] + {:status 200 + :body (:json-params request)}) + (def common-interceptors [(body-params/body-params) http/json-body]) (def routes #{["/" :get (conj common-interceptors `home)] - ["/about" :get (conj common-interceptors `about)]}) + ["/about" :get (conj common-interceptors `about)] + ["/echo" :post (conj common-interceptors `echo)]}) (defn service [] @@ -62,14 +69,45 @@ (:body (ions.test/response-for (service) :get "/about"))) (is (= (:headers (ions.test/response-for (service) :get "/about")) - {"Content-Type" "text/plain" - "Strict-Transport-Security" "max-age=31536000; includeSubdomains" - "X-Frame-Options" "DENY" - "X-Content-Type-Options" "nosniff" - "X-XSS-Protection" "1; mode=block" - "X-Download-Options" "noopen" + {"Content-Type" "text/plain" + "Strict-Transport-Security" "max-age=31536000; includeSubdomains" + "X-Frame-Options" "DENY" + "X-Content-Type-Options" "nosniff" + "X-XSS-Protection" "1; mode=block" + "X-Download-Options" "noopen" "X-Permitted-Cross-Domain-Policies" "none" - "Content-Security-Policy" "object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;"}))) + "Content-Security-Policy" "object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;"}))) + +(defn- post-echo + [body] + (ions.test/response-for (service) + :post "/echo" + :headers {"content-type" "application/json"} + :body body)) + +(deftest post-test + (let [expected {:foo "bar"} + json-payload (json/encode expected)] + ;; user are here instead + (testing "string body" + (let [result (post-echo json-payload)] + (is (= 200 (:status result))) + (is (= expected + (-> result + :body + slurp + (json/parse-string keyword)))))) + + (testing "stream body" + (let [result (post-echo (ByteArrayInputStream. (.getBytes json-payload)))] + (is (= 200 (:status result))) + (is (= expected + (-> result + :body + slurp + (json/parse-string keyword)))))))) + + (deftest params-test (let [param-key "a-param"