 (defn parse-json [body]
   (cond
     (nil? body) body
-    (string? body) body
+    (string? body) (json/parse-string body)
     :else (json/parse-string (slurp (io/reader body)))))
 
 (defn read-body [response]
-  (update response :body parse-json))
+  (let [content-type (get-in response [:headers "Content-Type"])]
+    (if (str/starts-with? content-type "application/json")
+      (update response :body parse-json)
+      response)))
 
 (defn app [request]
   (-> request router/app read-body))

                         app)]
        (is (unauthorized? response))))))

(defn- get-user-id [session]
  (let [response (-> (request :get "/api/settings")
                     (merge session)
                     app)]
    (assert (ok? response) {:response response})
    (UUID/fromString (get-in (json/parse-string (:body response)) [:user :id]))))

(defn- create-congregation! [name]
  (db/with-db [conn {}]
    (let [cong-id (UUID/randomUUID)]
      (dispatcher/command! conn (projections/cached-state)
                           {:command/type :congregation.command/create-congregation
                            :command/time (Instant/now)
                            :command/system "test"
                            :congregation/id cong-id
                            :congregation/name name})
      cong-id)))

(deftest super-user-test
  (let [cong-id (create-congregation! "sudo test")
        session (login! app)
        user-id (get-user-id session)]



(deftest add-user-test
  (let [session (login! app)
        cong-id (create-congregation! session "Congregation")
        new-user-id (db/with-db [conn {}]
                      (user/save-user! conn "user1" {:name "User 1"}))]

    (testing "add user"
      (let [response (try-add-user! session cong-id new-user-id)]
        (is (ok? response))
        ;; TODO: check the result through the API
        (let [users (congregation/get-users (projections/cached-state) cong-id)]
          (is (contains? (set users) new-user-id)))))

    (testing "invalid user"
      (let [response (try-add-user! session cong-id (UUID. 0 1))]
        (is (bad-request? response))
        (is (= {:errors [["no-such-user" "00000000-0000-0000-0000-000000000001"]]}
               (:body response)))))

    (testing "no access"
      (revoke-access-from-all! cong-id)
      (let [response (try-add-user! session cong-id new-user-id)]
        (is (forbidden? response))))))

(deftest set-user-permissions-test
  (let [session (login! app)
        cong-id (create-congregation! session "Congregation")
        user-id (db/with-db [conn {}]
                  (user/save-user! conn "user1" {:name "User 1"}))]
    (is (ok? (try-add-user! session cong-id user-id)))

    ;; TODO: test changing permissions (after new users no more get full admin access)?

