Last active
February 1, 2019 14:08
-
-
Save grierson/4bcdf11cf93d556671f13826dd355308 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns dorsia.core | |
(:require [ring.adapter.jetty :as jetty] | |
[ring.util.response :as resp] | |
[integrant.core :as ig] | |
[reitit.ring :as ring])) | |
;; Start Persistence | |
(defprotocol ReservationRepository | |
(create [this reservation] "Add reservation") | |
(read-reservations [this datetime] "Get all reservations")) | |
(def reservations (atom [{:quantity 3 :name "Alice"} | |
{:quantity 4 :name "Bob"}])) | |
(defrecord MemoryRepo [] | |
ReservationRepository | |
(create [this reservation] | |
(swap! reservations conj reservation)) | |
(read-reservations [this datetime] | |
@reservations)) | |
;; End Persistence | |
;; Start Usecase | |
(defn try-accept [capacity reservedSeats reservation] | |
(let [reservedSeats (reduce + (map :quantity reservedSeats)) | |
total (+ reservedSeats (:quantity reservation))] | |
(when (<= total capacity) | |
reservation))) | |
(defn try-accept-comp [reservationRepository capacity reservation] | |
(let [reservations (read-reservations reservationRepository (:datetime reservation)) | |
result (try-accept capacity reservations reservation)] | |
(when result | |
(create reservationRepository reservation)))) | |
;; End Usecase | |
;; Start Handlers | |
(defn try-accept-handler [reservationRepository capacity {:keys [query-params]}] | |
(if-let [response (try-accept-comp reservationRepository capacity query-params)] | |
(resp/response response) | |
(resp/bad-request "Could not handle"))) | |
(defn get-requests-handler [reservationRepository {:keys [query-params]}] | |
(if-let [response (read-reservations reservationRepository (:datetime query-params))] | |
(resp/response response) | |
(resp/bad-request "Could not handle"))) | |
;; End Handlers | |
;; Integrant / Dependency Injectioni | |
(defmethod ig/init-key :dorsia/reservations.repository/memory [_ _] | |
(MemoryRepo.)) | |
(defmethod ig/init-key :dorsia/routes [_ routes] | |
(-> routes | |
ring/router | |
ring/ring-handler)) | |
(defmethod ig/init-key :ring.adapter/jetty [_ {:keys [handler port]}] | |
(jetty/run-jetty handler {:port port | |
:join? false})) | |
(defmethod ig/halt-key! :ring.adapter/jetty [_ server] | |
(.stop server)) | |
(defmethod ig/init-key :handler.reservations/get [_ {:keys [reservationRepository]}] | |
(fn [request] | |
(get-requests-handler reservationRepository request))) | |
(defmethod ig/init-key :handler.reservations/post [_ {:keys [reservationRepository capacity]}] | |
(fn [request] | |
(try-accept-handler reservationRepository capacity request))) | |
;; Integrant / Dependency Injection | |
(derive :ring.adapter/jetty :ring/adapter) | |
(derive :dorsia.reservations/repository :dorsia.reservations.repository/memory) | |
(def config | |
{:ring.adapter/jetty {:port 8080, :handler (ig/ref :dorsia/routes)} | |
:dorsia/reservations.repository/memory {} | |
:dorsia/routes ["/api" | |
["/reservations" {:get (ig/ref :handler.reservations/get) | |
:post (ig/ref :handler.reservations/post)}]] | |
:handler.reservations/get {:reservationRepository (ig/ref :dorsia.reservations/repository} | |
:handler.reservations/post {:reservationRepository (ig/ref :dorsia.reservations/repository) | |
:capacity 10}}) | |
(comment | |
(def system (ig/init config [:dorsia/routes])) | |
((:dorsia/routes system) {:request-method :get | |
:uri "/api/reservations"}) | |
((:dorsia/routes system) {:request-method :post | |
:uri "/api/reservations" | |
:query-params {:name "Charlie" | |
:quantity 1}}) | |
(ig/halt! system)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Query/Business logic/Command Sandwich Tests | |
(def database-stub | |
(reify reservationRepository | |
{:read-reservations [{:quantity 3 | |
:datetime (t/date-time 1986 10 14 4 3 27 456)}] | |
:create (throws RuntimeException "Insert not supported"}) | |
(def email-stub | |
(reify emailService | |
{:send (throws RuntimeException "Insert not supported"}) | |
(deftest comp-test | |
(let [capacity 10 | |
request {:quantity 4 :datetime (t/date-time 1986 10 14 4 3 27 456)} | |
result (try-accept-comp email-stub database-stub capacity request)] | |
(is (some? result)))) | |
;; Pure business logic Tests | |
(deftest try-accept | |
(let [capacity 10 | |
reservedSeats [{:quantity 6 (t/date-time 1986 10 14 4 3 27 456)}] | |
reservation {:quantity 3 (t/date-time 1986 10 14 4 3 27 456)} | |
result (try-accept capacity reservedSeats reservation] | |
(is (some? result)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment