Skip to content

Commit

Permalink
invoice item api + price api
Browse files Browse the repository at this point in the history
invoice item api

cljfmt

protocol name

fix response path and refactor url-fn

price api and tests for price and invoice items

require namespaces
  • Loading branch information
jramosg authored and bgalartza committed Mar 21, 2024
1 parent 8e69b7b commit f143a74
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/dev/gethop/payments/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
(get-upcoming-invoice [this customer-id opt-args])
(update-invoice [this invoice-id invoice]))

(defprotocol InvoiceItems
(create-invoice-item [this invoice-item])
(update-invoice-item [this invoice-item-id invoice-item])
(get-invoice-item [this invoice-item-id])
(get-all-invoice-items [this opt-args])
(delete-invoice-item [this invoice-item-id]))

(defprotocol Price
(create-price [this price])
(update-price [this price-id price])
(get-price [this price-id])
(get-all-prices [this opt-args]))

(defprotocol Product
(create-product [this product])
(get-product [this product-id])
Expand Down
2 changes: 2 additions & 0 deletions src/dev/gethop/payments/stripe.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
[dev.gethop.payments.stripe.ephemeral-key]
[dev.gethop.payments.stripe.event]
[dev.gethop.payments.stripe.invoice]
[dev.gethop.payments.stripe.invoice-items]
[dev.gethop.payments.stripe.payment-intent]
[dev.gethop.payments.stripe.payment-method]
[dev.gethop.payments.stripe.plan]
[dev.gethop.payments.stripe.price]
[dev.gethop.payments.stripe.product]
[dev.gethop.payments.stripe.subscription]
[dev.gethop.payments.stripe.usage-record]
Expand Down
40 changes: 40 additions & 0 deletions src/dev/gethop/payments/stripe/invoice_items.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(ns dev.gethop.payments.stripe.invoice-items
(:require [dev.gethop.payments.core :as core]
[dev.gethop.payments.stripe.core :refer [execute]])
(:import [dev.gethop.payments.stripe.core Stripe]))

(def ^:const ^:private url-path "/invoiceitems")
(def ^:const ^:private response-path [:invoiceitems :body])

(defn- url-fn [id] (str url-path "/" id))

(def ^:const api-definition
{:create {:method :post
:url url-path
:response response-path}
:get {:method :get
:url url-fn
:response response-path}
:get-all {:method :get
:url url-path
:response response-path}
:update {:method :post
:url url-fn
:response response-path}
:delete {:method :delete
:url url-fn
:response response-path}})

(extend-protocol core/InvoiceItems
Stripe
(create-invoice-item [this invoice-item]
(execute this (:create api-definition) {:entity invoice-item}))
(update-invoice-item [this invoice-item-id invoice-item]
(execute this (:update api-definition) {:entity invoice-item
:path-params [invoice-item-id]}))
(get-invoice-item [this invoice-item-id]
(execute this (:get api-definition) {:path-params [invoice-item-id]}))
(get-all-invoice-items [this opt-args]
(execute this (:get-all api-definition) {:opt-req-args opt-args}))
(delete-invoice-item [this invoice-item-id]
(execute this (:delete api-definition) {:path-params [invoice-item-id]})))
35 changes: 35 additions & 0 deletions src/dev/gethop/payments/stripe/price.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns dev.gethop.payments.stripe.price
(:require [dev.gethop.payments.core :as core]
[dev.gethop.payments.stripe.core :refer [execute]])
(:import [dev.gethop.payments.stripe.core Stripe]))

(def ^:const ^:private url-path "/prices")
(def ^:const ^:private response-path [:price :body])

(defn- url-fn [id] (str url-path "/" id))

(def ^:const api-definition
{:create {:method :post
:url url-path
:response response-path}
:update {:method :post
:url url-fn
:response response-path}
:get {:method :get
:url url-fn
:response response-path}
:get-all {:method :get
:url url-path
:response response-path}})

(extend-protocol core/Price
Stripe
(create-price [this price]
(execute this (:create api-definition) {:entity price}))
(update-price [this price-id price]
(execute this (:update api-definition) {:entity price
:path-params [price-id]}))
(get-price [this price-id]
(execute this (:get api-definition) {:path-params [price-id]}))
(get-all-prices [this opt-args]
(execute this (:get-all api-definition) {:opt-req-args opt-args})))
73 changes: 73 additions & 0 deletions test/dev/gethop/payments/stripe/invoice_items_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
(ns dev.gethop.payments.stripe.invoice-items-test
(:require [clojure.string :as str]
[clojure.test :refer :all]
[dev.gethop.payments.core :as core]
[dev.gethop.payments.stripe]
[dev.gethop.payments.stripe.test-utils :as test-utils]))

(defn- get-new-invoice-item-id [payment-adapter]
(let [customer-id (test-utils/create-test-customer+get-id payment-adapter)
price-id (test-utils/create-price+get-id payment-adapter)]
(-> (core/create-invoice-item payment-adapter {:customer customer-id
:price price-id})
:invoiceitems
:id)))

(deftest ^:integration crete-invoice-item
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Create invoice item"
(let [customer-id (test-utils/create-test-customer+get-id payment-adapter)
price-id (test-utils/create-price+get-id payment-adapter)
{:keys [success? invoiceitems]}
(core/create-invoice-item payment-adapter {:customer customer-id
:price price-id})]
(is success?)
(is (map? invoiceitems))
(is (str/starts-with? (:id invoiceitems) "ii"))))))

(deftest ^:integration update-invoice-item
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Update invoice item"
(let [id (get-new-invoice-item-id payment-adapter)
new-desc "updating ii"
{:keys [success? invoiceitems]}
(core/update-invoice-item payment-adapter id {:description new-desc})]
(is success?)
(is (map? invoiceitems))
(is (= new-desc (:description invoiceitems)))))))

(deftest ^:integration get-invoice-item
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Get invoice item"
(let [id (get-new-invoice-item-id payment-adapter)
{:keys [success? invoiceitems]} (core/get-invoice-item payment-adapter id)]
(is success?)
(is (map? invoiceitems))
(is (= id (:id invoiceitems)))))
(testing "Get not existing invoice item"
(-> (core/get-invoice-item payment-adapter "not-existing-id")
:success?
false?
is))))

(deftest ^:integration get-invoice-items
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Get invoice items"
(let [now (test-utils/now-unix-timestamp)
id (get-new-invoice-item-id payment-adapter)
{success? :success? {:keys [data] :as invoiceitems} :invoiceitems}
(core/get-all-invoice-items payment-adapter {:created {:gte now}})]
(is success?)
(is (map? invoiceitems))
(is (vector? data))
(is (= id (get-in data [0 :id])))))))

(deftest ^:integration delete-invoice-item
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Successful delete invoice item"
(let [id (get-new-invoice-item-id payment-adapter)
{:keys [success?]} (core/delete-invoice-item payment-adapter id)]
(is success?)))
(testing "Not successful delete invoice item"
(let [{:keys [success?]} (core/delete-invoice-item payment-adapter "not-existing-id")]
(is (false? success?))))))
70 changes: 70 additions & 0 deletions test/dev/gethop/payments/stripe/price_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(ns dev.gethop.payments.stripe.price-test
(:require [clojure.string :as str]
[clojure.test :refer :all]
[dev.gethop.payments.core :as core]
[dev.gethop.payments.stripe.test-utils :as test-utils]))

(defn- get-new-price-id [payment-adapter]
(-> (core/create-price payment-adapter {:currency "eur"
:unit_amount 1000
:product_data {:name "Test product"}})
:price
:id))

(deftest ^:integration create-price
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Create valid price"
(let [{:keys [success? price]}
(core/create-price payment-adapter {:currency "eur"
:unit_amount 1000
:product_data {:name "Test product"}})]
(is success?)
(is (map? price))
(is (= (:object price) "price"))
(is (str/starts-with? (:id price) "price"))))
(testing "Create invalid price"
(-> (core/create-price payment-adapter {:currency "eur"
:unit_amount 1000})
:success?
false?
is))))

(deftest ^:integration update-price
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Update price"
(let [id (get-new-price-id payment-adapter)
{:keys [success? price] :as r} (core/update-price payment-adapter id {:active false})]
(is success?)
(is (map? price))
(is (false? (:active price)))))
(testing "Update not existing price"
(-> (core/update-price payment-adapter "not-existing-id" {:active false})
:success?
false?
is))))

(deftest ^:integration get-price
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Update price"
(let [id (get-new-price-id payment-adapter)
{:keys [success? price]} (core/get-price payment-adapter id)]
(is success?)
(is (map? price))
(is (= (:id price) id))))
(testing "Get not existing price"
(-> (core/get-price payment-adapter "not-existing-id")
:success?
false?
is))))

(deftest ^:integration get-all-prices
(let [payment-adapter (test-utils/init-payment-adapter)]
(testing "Get all prices"
(let [now (test-utils/now-unix-timestamp)
id (get-new-price-id payment-adapter)
{success? :success? {:keys [data] :as price} :price :as r}
(core/get-all-prices payment-adapter {:created {:gte now}})]
(is success?)
(is (map? price))
(is (vector? data))
(is (= id (get-in data [0 :id])))))))
26 changes: 26 additions & 0 deletions test/dev/gethop/payments/stripe/test_utils.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(ns dev.gethop.payments.stripe.test-utils
(:require [clojure.test :refer :all]
[dev.gethop.payments.core :as core]
[integrant.core :as ig]))

(def ^:const test-config {:api-key (System/getenv "STRIPE_TEST_API_KEY")})

(def ^:const test-customer-data {:description "customer for [email protected]"})

(defn init-payment-adapter []
(ig/init-key :dev.gethop.payments/stripe test-config))

(defn create-test-customer+get-id [payment-adapter]
(-> (core/create-customer payment-adapter test-customer-data)
:customer
:id))

(defn create-price+get-id [payment-adapter]
(-> (core/create-price payment-adapter {:currency "eur"
:unit_amount 1000
:product_data {:name "Test product"}})
:price
:id))

(defn now-unix-timestamp []
(int (/ (System/currentTimeMillis) 1000)))

0 comments on commit f143a74

Please sign in to comment.