From f4d05664232889a2f6c0353f88116a8f4ba24c3f Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Fri, 9 Jul 2021 10:26:14 +0200 Subject: [PATCH 1/3] Append the path to the github url with slash when necessary --- src/clj_github/httpkit_client.clj | 12 +++++++++--- test/clj_github/httpkit_client_test.clj | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/clj_github/httpkit_client.clj b/src/clj_github/httpkit_client.clj index 64de116..f2b096c 100644 --- a/src/clj_github/httpkit_client.clj +++ b/src/clj_github/httpkit_client.clj @@ -11,12 +11,17 @@ (defn get-installation-token [{:keys [token-fn]}] (token-fn)) +(defn- append-url-path [baseurl path] + (str baseurl (when-not (or (.endsWith baseurl "/") + (.startsWith path "/")) + "/") path)) + (defn- prepare - [{:keys [token-fn]} {:keys [path method body] :or {method :get} :as request}] + [{:keys [token-fn]} {:keys [path method body] :or {method :get path ""} :as request}] (-> request (assoc :method method) (assoc-some :body (and body (cheshire/generate-string body))) - (assoc :url (str github-url path)) + (assoc :url (append-url-path github-url path)) (assoc-in [:headers "Content-Type"] "application/json") (assoc-in [:headers "Authorization"] (str "Bearer " (token-fn))))) @@ -30,7 +35,8 @@ (get-in response [:headers "Content-Type"]))) (defn request [client req-map] - (let [response @(httpkit/request (prepare client req-map))] + (let [request (prepare client req-map) + response @(httpkit/request request)] (if (success-codes (:status response)) (update response :body (partial parse-body (content-type response))) (throw (ex-info "Request to GitHub failed" diff --git a/test/clj_github/httpkit_client_test.clj b/test/clj_github/httpkit_client_test.clj index 7733f17..cb67483 100644 --- a/test/clj_github/httpkit_client_test.clj +++ b/test/clj_github/httpkit_client_test.clj @@ -24,6 +24,10 @@ (with-fake-http [{:url "https://api.github.com/path"} {:status 200}] (is (match? {:status 200} (sut/request client {:path "/path"}))))) + (testing "path is appended to url with optional slash" + (with-fake-http [{:url "https://api.github.com/path"} + {:status 200}] + (is (match? {:status 200} (sut/request client {:path "path"}))))) (testing "github token is added to authorization header" (with-fake-http [{:headers {"Authorization" "Bearer token" "Content-Type" "application/json"}} From 34219544bc577cf85a52d060210cca435cee96af Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Fri, 9 Jul 2021 15:13:29 +0200 Subject: [PATCH 2/3] Allow to override Authorization and Content-Type request headers --- src/clj_github/httpkit_client.clj | 8 +++++--- test/clj_github/httpkit_client_test.clj | 26 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/clj_github/httpkit_client.clj b/src/clj_github/httpkit_client.clj index f2b096c..10c0e22 100644 --- a/src/clj_github/httpkit_client.clj +++ b/src/clj_github/httpkit_client.clj @@ -22,8 +22,9 @@ (assoc :method method) (assoc-some :body (and body (cheshire/generate-string body))) (assoc :url (append-url-path github-url path)) - (assoc-in [:headers "Content-Type"] "application/json") - (assoc-in [:headers "Authorization"] (str "Bearer " (token-fn))))) + ;; TODO http headers are case insensitive, also this could be keywords + (update-in [:headers "Content-Type"] #(or % "application/json")) + (update-in [:headers "Authorization"] #(or % (str "Bearer " (token-fn)))))) (defn- parse-body [content-type body] (if (and content-type (re-find #"application/json" content-type)) @@ -43,7 +44,8 @@ {:response (select-keys response [:status :body])} (:error response)))))) -(defn new-client [{:keys [app-id private-key token org] :as opts}] +(defn new-client [{:keys [app-id private-key token org token-fn] :as opts}] + {:pre [(or token app-id token-fn)]} (cond token {:token-fn (constantly token)} diff --git a/test/clj_github/httpkit_client_test.clj b/test/clj_github/httpkit_client_test.clj index cb67483..6ccbb1f 100644 --- a/test/clj_github/httpkit_client_test.clj +++ b/test/clj_github/httpkit_client_test.clj @@ -47,4 +47,28 @@ (with-fake-http [{} {:error cause :status nil}] (let [e (try (sut/request client {}) (catch Exception e e))] (is (re-matches #"(?i)Request to GitHub failed" (.getMessage e))) - (is (= cause (.getCause e))))))))) + (is (= cause (.getCause e))))))) + (testing "request headers" + (testing "Can use custom headers" + (with-fake-http [(fn [req] + (is (= "test" (get-in req [:headers "Test-Header"])))) + {:status 200}] + ;; assertion is in fake http callback + (sut/request client {:headers {"Test-Header" "test"}}))) + (testing "Can override authentication" + ;; clj-github sets authorization header unless specified. Beware that the + ;; implementation here is case sensitive whereas HTTP headers are not. + (with-fake-http [(fn [req] + (is (= "Test SomeValue" (get-in req [:headers "Authorization"])))) + {:status 200}] + ;; assertion is in fake http callback + (sut/request client {:headers {"Authorization" "Test SomeValue"}}))) + (testing "Can override content-type" + ;; clj-github sets the content-type header unless specified. Beware that the + ;; implementation here is case sensitive whereas HTTP headers are not. + (with-fake-http [(fn [req] + (is (= "test/test" (get-in req [:headers "Content-Type"])))) + {:status 200}] + ;; assertion is in fake http callback + (sut/request client {:headers {"Content-Type" "test/test"}})))))) + From 9e280a3a3b011e36bc95b31436ff1211276b1283 Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Fri, 9 Jul 2021 15:20:26 +0200 Subject: [PATCH 3/3] Bump version to 0.4.2 and update changelog --- CHANGELOG.md | 5 +++++ project.clj | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 727abb8..147bca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.4.2 + +- Join path with baseurl using a `/` where necessary +- Allow to specify the Content-Type and Authorization request headers manually + ## 0.4.1 - Include httpkit error in exception when available diff --git a/project.clj b/project.clj index ede7ed1..c24c9a5 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject dev.nubank/clj-github "0.4.1" +(defproject dev.nubank/clj-github "0.4.2" :description "A Clojure library for interacting with the github developer API" :url "https://github.com/nubank/clj-github" :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"