From f55b9febe8974f861e2179baddaf9d48fa73552c Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Thu, 22 Feb 2018 00:38:26 -0300 Subject: A better swagger documentation and a better routing test --- src/clj/queue_api/db/core.clj | 11 ++- src/clj/queue_api/routes/services.clj | 139 +++++++++++++++++++++---------- test/clj/queue_api/test/db/core_test.clj | 20 +++-- test/clj/queue_api/test/handler.clj | 64 +++++++++----- 4 files changed, 158 insertions(+), 76 deletions(-) diff --git a/src/clj/queue_api/db/core.clj b/src/clj/queue_api/db/core.clj index 0482feb..adbda25 100644 --- a/src/clj/queue_api/db/core.clj +++ b/src/clj/queue_api/db/core.clj @@ -16,12 +16,12 @@ (defn add-agent "Add an agent into the database" - [{:keys [id name primary-skillset secondary-skillset]}] + [{:keys [id name primary_skillset secondary_skillset]}] (d/transact! conn [{:agent/id id :agent/name name - :agent/primary-skillset primary-skillset - :agent/secondary-skillset secondary-skillset}])) + :agent/primary-skillset primary_skillset + :agent/secondary-skillset secondary_skillset}])) (defn add-job "Add a job into the database" @@ -107,6 +107,11 @@ [id] (d/entity @conn [:agent/id id])) +(defn job + "Get a job by id" + [id] + (d/entity @conn [:job/id id])) + (defn fittest-job "Get the fittest job for a agent `id`." [^String id] diff --git a/src/clj/queue_api/routes/services.clj b/src/clj/queue_api/routes/services.clj index 766f831..c3c83e9 100644 --- a/src/clj/queue_api/routes/services.clj +++ b/src/clj/queue_api/routes/services.clj @@ -2,7 +2,39 @@ (:require [ring.util.http-response :refer :all] [compojure.api.sweet :refer :all] [schema.core :as s] - [queue-api.db.core :as db])) + [queue-api.db.core :as db] + [ring.util.http-status :as http-status])) + + + +(s/defschema new-agent + {:id s/Str + :name s/Str + :primary_skillset [s/Str] + (s/optional-key :secondary_skillset) [s/Str]}) + +(s/defschema new-job + {:id s/Str + :type s/Str + :urgent s/Bool}) + +(s/defschema agent-id + {:agent_id s/Str}) + +(s/defschema agent-sum + [{:type s/Str + :jobs s/Int}]) + +(s/defschema error-message + {:message s/Str}) + +(s/defschema job-sum + {:completed [s/Str] + :processing [s/Str] + :unassigned [s/Str]}) + +(s/defschema job-request + {:job_request {:job_id s/Str :agent_id s/Str}}) (defapi service-routes {:swagger {:ui "/swagger-ui" @@ -12,52 +44,67 @@ :description "Manages agent resources"}}}} (context "/agent" [] - :tags ["agent"] - (PUT "/" [] - :body-params [id :- String, name :- String, primary_skillset :- [String], secondary_skillset :- [String]] - :summary "Add a new agent" - (db/add-agent - {:id id - :name name - :primary-skillset primary_skillset - :secondary-skillset secondary_skillset}) - (ok)) - (POST "/" [] - :return [{:type String :jobs s/Int}] - :body-params [agent_id :- String] - :summary "Get summary of an agent" - (let [jobs (db/sum-agent agent_id)] - (map (fn [x] - {:type (first x) - :jobs (last x)}) jobs)))) + (resource + {:tags ["agent"] + :put {:summary "Add a new agent" + :responses {http-status/created {:description "Agent Created"} + http-status/bad-request {:description "Agent id already exists" + :schema error-message}} + :parameters {:body-params new-agent} + :handler (fn [{body :body-params}] + (if (nil? (db/agent (:id body))) + (do (db/add-agent body) + {:status 201}) + (bad-request {:message "Agent id already exists"})))} + :post {:summary "Get summary of an agent" + :parameters {:body-params agent-id} + :responses {http-status/ok {:schema agent-sum + :description "Fetched correctly"} + http-status/not-found {:schema error-message + :description "Agent not found"}} + :handler (fn [{body :body-params}] + (let [a (:agent_id body)] + (if-not (nil? (db/agent a)) + (let [jobs (db/sum-agent a)] + (ok (map (fn [x] + {:type (first x) + :jobs (last x)}) jobs))) + (not-found {:message "Agent does not exist"}))))}})) + (context "/job" [] - :tags ["job"] - (PUT "/" [] - :body-params [id :- String, type :- String, urgent :- Boolean] - :summary "Add a new job" - (db/add-job {:id id - :type type - :urgent urgent}) - (ok)) - (POST "/" [] - :return {:job_request {:job_id s/Any :agent_id String}} - :body-params [agent_id :- String] - :summary "Request a job to a given agent" - - (let [a (agent agent_id)] - (if (nil? a) - (not-found {:message "Agent does not exist"})) - (let [j (db/dequeue-job agent_id)] - (if (nil? j) - (not-found {:message "There is no job available for given agent"}) - (ok {:job_request {:job_id j :agent_id agent_id}}))))) - - (GET "/" [] - :return {:completed [String] - :processing [String] - :unassigned [String]} - :summary "Get a summary of the queue" - (ok (db/sum-queue))))) + (resource + {:tags ["job"] + :put {:summary "Add a new job" + :responses {http-status/created {:description "Job Created"} + http-status/bad-request {:description "Job id already exists" + :schema error-message}} + :parameters {:body-params new-job} + :handler (fn [{body :body-params}] + (if (nil? (db/job (:id body))) + (do + (db/add-job body) + {:status 201}) + (bad-request {:message "job id already exist"})))} + :post {:summary "Request a job to a given agent" + :responses {http-status/ok {:description "Job assigned successfully" + :schema job-request} + http-status/not-found {:description "Agent not found or there is no job avaliable" + :schema error-message}} + :parameters {:body-params agent-id} + :handler (fn [{body :body-params}] + (let [id (:agent_id body) + a (db/agent id)] + (if (nil? a) + (not-found {:message "Agent does not exist"})) + (let [j (db/dequeue-job id)] + (if (nil? j) + (not-found {:message "There is no job available for given agent"}) + (ok {:job_request {:job_id j :agent_id id}})))))} + :get {:summary "Get queue summary" + :responses {http-status/ok {:description "Jobs summary fetched correctly" + :schema job-sum}} + :handler (fn [_] + (ok (db/sum-queue)))}}))) diff --git a/test/clj/queue_api/test/db/core_test.clj b/test/clj/queue_api/test/db/core_test.clj index 117cc26..4afa99d 100644 --- a/test/clj/queue_api/test/db/core_test.clj +++ b/test/clj/queue_api/test/db/core_test.clj @@ -105,17 +105,12 @@ (d/transact! conn base-schema) (f))) - - -(defn job [id] - (d/entity @conn [:job/id id])) - (deftest add-agent-test (testing "Test adding agent" (let [tx (add-agent {:id "1d7158f8-f7a0-4ff9-9758-25efcc5aae65" :name "Derpinson" - :primary-skillset ["rewards-question" "bills-question"] - :secondary-skillset []}) + :primary_skillset ["rewards-question" "bills-question"] + :secondary_skillset []}) tx-data (:tx-data tx)] (is (not (empty? tx-data)))))) @@ -244,9 +239,18 @@ (testing "Test agent" (are [left right] (= left right) - (d/entity @conn [:agent/id "644be0ce-035d-48cb-867e-8e6de2714a8d"]) (agent "644be0ce-035d-48cb-867e-8e6de2714a8d") + (d/entity @conn [:agent/id "644be0ce-035d-48cb-867e-8e6de2714a8d"]) + (agent "644be0ce-035d-48cb-867e-8e6de2714a8d") nil (agent "7b8e17fc-7953-44cf-9249-294c4eb73087")))) +(deftest job-test + (testing "Test agent" + (are [left right] + (= left right) + (d/entity @conn [:job/id "dfa7744f-8d61-4d37-885f-dbef2d4df13b"]) + (job "dfa7744f-8d61-4d37-885f-dbef2d4df13b") + nil (job "7b8e17fc-7953-44cf-9249-294c4eb73087")))) + (deftest dequeue-job-test (testing "Test Dummy Derp dequeuing process" (are [left right] diff --git a/test/clj/queue_api/test/handler.clj b/test/clj/queue_api/test/handler.clj index eeb860a..9dd13eb 100644 --- a/test/clj/queue_api/test/handler.clj +++ b/test/clj/queue_api/test/handler.clj @@ -2,50 +2,76 @@ (:require [clojure.test :refer :all] [ring.mock.request :refer :all] [queue-api.handler :refer :all] - [mount.core :as mount])) + [queue-api.db.core :refer :all] + [mount.core :as mount] + [queue-api.test.db.core-test :refer [base-schema]] + [datascript.core :as d])) (use-fixtures :once (fn [f] (mount/start #'queue-api.config/env - #'queue-api.handler/app - #'queue-api.db.core/conn)git + #'queue-api.handler/app) + (f))) +(use-fixtures + :each + (fn [f] + (mount/stop #'queue-api.db.core/conn) + (mount/start #'queue-api.db.core/conn) + (d/transact! conn base-schema) (f))) (deftest agent-test - (testing "Agent route" + (testing "Agent route PUT" (let [response (-> (request :put "/agent") (json-body {:id "8ab86c18-3fae-4804-bfd9-c3d6e8f66260" :name "Dummy" :primary_skillset ["reward_request"] :secondary_skillset []}) app)] - (is (= 200 (:status response)))) + (is (= 201 (:status response)))) + (let [response (-> (request :put "/agent") + (json-body {:id "644be0ce-035d-48cb-867e-8e6de2714a8d" + :name "Dummy" + :primary_skillset ["reward_request"] + :secondary_skillset []}) + app)] + (is (= 400 (:status response))))) + (testing "Agent route POST" (let [response (-> (request :post "/agent") - (json-body {:agent_id "8ab86c18-3fae-4804-bfd9-c3d6e8f66260"}) + (json-body {:agent_id "51c6324b-a176-4663-8b5f-03fc2544dbe2"}) + app)] + (is (= 404 (:status response)))) + (let [response (-> (request :post "/agent") + (json-body {:agent_id "644be0ce-035d-48cb-867e-8e6de2714a8d"}) app)] (is (= 200 (:status response)))))) (deftest job-test - (testing "Job route" + (testing "Job route PUT" (let [response (-> (request :put "/job") - (json-body {:id "895e9b31-5690-486e-b8dd-5c2345e056f6" - :type "bills_request" + (json-body {:id "650d3df1-9eed-4070-9751-2f8504bcf909" + :type "bills_question" :urgent false}) app)] + (is (= 201 (:status response)))) + (let [response (-> (request :put "/agent") + (json-body {:id "1e0d939d-494b-48d2-9247-b5ae207a519a" + :type "bills_question" + :urgent false}) + app)] + (is (= 400 (:status response))))) + + (testing "Job route POST" + (let [response (-> (request :post "/job") + (json-body {:agent_id "644be0ce-035d-48cb-867e-8e6de2714a8d"}) + app)] (is (= 200 (:status response)))) (let [response (-> (request :post "/job") - (json-body {:agent_id "8ab86c18-3fae-4804-bfd9-c3d6e8f66260"}) + (json-body {:agent_id "933e0f19-08f8-4976-ad9f-f5fc4bf9047e"}) app)] - (is (= 400 (:status response)))))) - -(deftest queue-test - (testing "Queue route" + (is (= 404 (:status response))))) + (testing "Job route GET" (let [response (app (request :get "/job"))] (is (= 200 (:status response)))))) - -(deftest invalid-test - (testing "not-found route" - (let [response (app (request :get "/invalid"))] - (is (= 404 (:status response)))))) -- cgit v1.2.3