mirror of
https://github.com/penpot/penpot.git
synced 2025-05-11 06:36:37 +02:00
🎉 Add tests for webhooks rpc and logger
This commit is contained in:
parent
21abd98b95
commit
f2b60261f8
5 changed files with 183 additions and 11 deletions
|
@ -22,11 +22,11 @@
|
||||||
|
|
||||||
;; --- PROC
|
;; --- PROC
|
||||||
|
|
||||||
(defn lookup-webhooks-by-team
|
(defn- lookup-webhooks-by-team
|
||||||
[pool team-id]
|
[pool team-id]
|
||||||
(db/exec! pool ["select * from webhook where team_id=? and is_active=true" team-id]))
|
(db/exec! pool ["select * from webhook where team_id=? and is_active=true" team-id]))
|
||||||
|
|
||||||
(defn lookup-webhooks-by-project
|
(defn- lookup-webhooks-by-project
|
||||||
[pool project-id]
|
[pool project-id]
|
||||||
(let [sql [(str "select * from webhook as w"
|
(let [sql [(str "select * from webhook as w"
|
||||||
" join project as p on (p.team_id = w.team_id)"
|
" join project as p on (p.team_id = w.team_id)"
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
project-id]]
|
project-id]]
|
||||||
(db/exec! pool sql)))
|
(db/exec! pool sql)))
|
||||||
|
|
||||||
(defn lookup-webhooks-by-file
|
(defn- lookup-webhooks-by-file
|
||||||
[pool file-id]
|
[pool file-id]
|
||||||
(let [sql [(str "select * from webhook as w"
|
(let [sql [(str "select * from webhook as w"
|
||||||
" join project as p on (p.team_id = w.team_id)"
|
" join project as p on (p.team_id = w.team_id)"
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
file-id]]
|
file-id]]
|
||||||
(db/exec! pool sql)))
|
(db/exec! pool sql)))
|
||||||
|
|
||||||
(defn lookup-webhooks
|
(defn- lookup-webhooks
|
||||||
[{:keys [::db/pool]} {:keys [props] :as event}]
|
[{:keys [::db/pool]} {:keys [props] :as event}]
|
||||||
(or (some->> (:team-id props) (lookup-webhooks-by-team pool))
|
(or (some->> (:team-id props) (lookup-webhooks-by-team pool))
|
||||||
(some->> (:project-id props) (lookup-webhooks-by-project pool))
|
(some->> (:project-id props) (lookup-webhooks-by-project pool))
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
(declare interpret-exception)
|
(declare interpret-exception)
|
||||||
(declare interpret-response)
|
(declare interpret-response)
|
||||||
|
|
||||||
(def ^:private mapper
|
(def ^:private json-mapper
|
||||||
(json/mapper
|
(json/mapper
|
||||||
{:encode-key-fn str/camel
|
{:encode-key-fn str/camel
|
||||||
:decode-key-fn (comp keyword str/kebab)
|
:decode-key-fn (comp keyword str/kebab)
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
whook (::config props)
|
whook (::config props)
|
||||||
|
|
||||||
body (case (:mtype whook)
|
body (case (:mtype whook)
|
||||||
"application/json" (json/encode-str event mapper)
|
"application/json" (json/encode-str event json-mapper)
|
||||||
"application/transit+json" (t/encode-str event)
|
"application/transit+json" (t/encode-str event)
|
||||||
"application/x-www-form-urlencoded" (uri/map->query-string event))]
|
"application/x-www-form-urlencoded" (uri/map->query-string event))]
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@
|
||||||
{::doc/added "1.17"}
|
{::doc/added "1.17"}
|
||||||
[{:keys [::db/pool ::wrk/executor] :as cfg} {:keys [profile-id team-id] :as params}]
|
[{:keys [::db/pool ::wrk/executor] :as cfg} {:keys [profile-id team-id] :as params}]
|
||||||
(check-edition-permissions! pool profile-id team-id)
|
(check-edition-permissions! pool profile-id team-id)
|
||||||
(->> (validate-webhook! cfg nil params)
|
(->> (validate-quotes! cfg params)
|
||||||
(p/fmap executor (fn [_] (validate-quotes! cfg params)))
|
(p/fmap executor (fn [_] (validate-webhook! cfg nil params)))
|
||||||
(p/fmap executor (fn [_] (insert-webhook! cfg params)))))
|
(p/fmap executor (fn [_] (insert-webhook! cfg params)))))
|
||||||
|
|
||||||
(s/def ::update-webhook
|
(s/def ::update-webhook
|
||||||
|
|
|
@ -284,6 +284,19 @@
|
||||||
:session-id session-id
|
:session-id session-id
|
||||||
:profile-id profile-id})))))
|
:profile-id profile-id})))))
|
||||||
|
|
||||||
|
(defn create-webhook*
|
||||||
|
([params] (create-webhook* *pool* params))
|
||||||
|
([pool {:keys [team-id id uri mtype is-active]
|
||||||
|
:or {is-active true
|
||||||
|
mtype "application/json"
|
||||||
|
uri "http://example.com/webhook"}}]
|
||||||
|
(db/insert! pool :webhook
|
||||||
|
{:id (or id (uuid/next))
|
||||||
|
:team-id team-id
|
||||||
|
:uri uri
|
||||||
|
:is-active is-active
|
||||||
|
:mtype mtype})))
|
||||||
|
|
||||||
;; --- RPC HELPERS
|
;; --- RPC HELPERS
|
||||||
|
|
||||||
(defn handle-error
|
(defn handle-error
|
||||||
|
@ -417,6 +430,10 @@
|
||||||
[& params]
|
[& params]
|
||||||
(apply db/query *pool* params))
|
(apply db/query *pool* params))
|
||||||
|
|
||||||
|
(defn db-get
|
||||||
|
[& params]
|
||||||
|
(apply db/get* *pool* params))
|
||||||
|
|
||||||
(defn sleep
|
(defn sleep
|
||||||
[ms-or-duration]
|
[ms-or-duration]
|
||||||
(Thread/sleep (inst-ms (dt/duration ms-or-duration))))
|
(Thread/sleep (inst-ms (dt/duration ms-or-duration))))
|
||||||
|
|
120
backend/test/backend_tests/loggers_webhooks_test.clj
Normal file
120
backend/test/backend_tests/loggers_webhooks_test.clj
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns backend-tests.loggers-webhooks-test
|
||||||
|
(:require
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[app.db :as db]
|
||||||
|
[app.http :as http]
|
||||||
|
[app.storage :as sto]
|
||||||
|
[backend-tests.helpers :as th]
|
||||||
|
[clojure.test :as t]
|
||||||
|
[mockery.core :refer [with-mocks]]))
|
||||||
|
|
||||||
|
(t/use-fixtures :once th/state-init)
|
||||||
|
(t/use-fixtures :each th/database-reset)
|
||||||
|
|
||||||
|
(t/deftest process-event-handler-with-no-webhooks
|
||||||
|
(with-mocks [submit-mock {:target 'app.worker/submit! :return nil}]
|
||||||
|
(let [prof (th/create-profile* 1 {:is-active true})
|
||||||
|
res (th/run-task! :process-webhook-event
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event
|
||||||
|
{:type "mutation"
|
||||||
|
:name "create-project"
|
||||||
|
:props {:team-id (:default-team-id prof)}}}})]
|
||||||
|
|
||||||
|
(t/is (= 0 (:call-count @submit-mock)))
|
||||||
|
(t/is (nil? res)))))
|
||||||
|
|
||||||
|
(t/deftest process-event-handler
|
||||||
|
(with-mocks [submit-mock {:target 'app.worker/submit! :return nil}]
|
||||||
|
(let [prof (th/create-profile* 1 {:is-active true})
|
||||||
|
whk (th/create-webhook* {:team-id (:default-team-id prof)})
|
||||||
|
res (th/run-task! :process-webhook-event
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event
|
||||||
|
{:type "mutation"
|
||||||
|
:name "create-project"
|
||||||
|
:props {:team-id (:default-team-id prof)}}}})]
|
||||||
|
|
||||||
|
(t/is (= 1 (:call-count @submit-mock)))
|
||||||
|
(t/is (nil? res)))))
|
||||||
|
|
||||||
|
(t/deftest run-webhook-handler-1
|
||||||
|
(with-mocks [http-mock {:target 'app.http.client/req! :return {:status 200}}]
|
||||||
|
(let [prof (th/create-profile* 1 {:is-active true})
|
||||||
|
whk (th/create-webhook* {:team-id (:default-team-id prof)})
|
||||||
|
evt {:type "mutation"
|
||||||
|
:name "create-project"
|
||||||
|
:props {:team-id (:default-team-id prof)}}
|
||||||
|
res (th/run-task! :run-webhook
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event evt
|
||||||
|
:app.loggers.webhooks/config whk}})]
|
||||||
|
|
||||||
|
(t/is (= 1 (:call-count @http-mock)))
|
||||||
|
|
||||||
|
(let [rows (th/db-exec! ["select * from webhook_delivery where webhook_id=?"
|
||||||
|
(:id whk)])]
|
||||||
|
(t/is (= 1 (count rows)))
|
||||||
|
(t/is (nil? (-> rows first :error-code))))
|
||||||
|
|
||||||
|
;; Refresh webhook
|
||||||
|
(let [whk' (th/db-get :webhook {:id (:id whk)})]
|
||||||
|
(t/is (nil? (:error-code whk')))
|
||||||
|
(prn whk'))
|
||||||
|
|
||||||
|
)))
|
||||||
|
|
||||||
|
(t/deftest run-webhook-handler-2
|
||||||
|
(with-mocks [http-mock {:target 'app.http.client/req! :return {:status 400}}]
|
||||||
|
(let [prof (th/create-profile* 1 {:is-active true})
|
||||||
|
whk (th/create-webhook* {:team-id (:default-team-id prof)})
|
||||||
|
evt {:type "mutation"
|
||||||
|
:name "create-project"
|
||||||
|
:props {:team-id (:default-team-id prof)}}
|
||||||
|
res (th/run-task! :run-webhook
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event evt
|
||||||
|
:app.loggers.webhooks/config whk}})]
|
||||||
|
|
||||||
|
(t/is (= 1 (:call-count @http-mock)))
|
||||||
|
|
||||||
|
(let [rows (th/db-query :webhook-delivery {:webhook-id (:id whk)})]
|
||||||
|
(t/is (= 1 (count rows)))
|
||||||
|
(t/is (= "unexpected-status:400" (-> rows first :error-code))))
|
||||||
|
|
||||||
|
;; Refresh webhook
|
||||||
|
(let [whk' (th/db-get :webhook {:id (:id whk)})]
|
||||||
|
(t/is (= "unexpected-status:400" (:error-code whk')))
|
||||||
|
(t/is (= 1 (:error-count whk'))))
|
||||||
|
|
||||||
|
|
||||||
|
;; RUN 2 times more
|
||||||
|
|
||||||
|
(th/run-task! :run-webhook
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event evt
|
||||||
|
:app.loggers.webhooks/config whk}})
|
||||||
|
|
||||||
|
(th/run-task! :run-webhook
|
||||||
|
{:props
|
||||||
|
{:app.loggers.webhooks/event evt
|
||||||
|
:app.loggers.webhooks/config whk}})
|
||||||
|
|
||||||
|
|
||||||
|
(let [rows (th/db-query :webhook-delivery {:webhook-id (:id whk)})]
|
||||||
|
(t/is (= 3 (count rows)))
|
||||||
|
(t/is (= "unexpected-status:400" (-> rows first :error-code))))
|
||||||
|
|
||||||
|
;; Refresh webhook
|
||||||
|
(let [whk' (th/db-get :webhook {:id (:id whk)})]
|
||||||
|
(t/is (= "unexpected-status:400" (:error-code whk')))
|
||||||
|
(t/is (= 3 (:error-count whk')))
|
||||||
|
(t/is (false? (:is-active whk'))))
|
||||||
|
|
||||||
|
)))
|
|
@ -12,8 +12,6 @@
|
||||||
[app.storage :as sto]
|
[app.storage :as sto]
|
||||||
[backend-tests.helpers :as th]
|
[backend-tests.helpers :as th]
|
||||||
[clojure.test :as t]
|
[clojure.test :as t]
|
||||||
[datoteka.fs :as fs]
|
|
||||||
[datoteka.io :as io]
|
|
||||||
[mockery.core :refer [with-mocks]]))
|
[mockery.core :refer [with-mocks]]))
|
||||||
|
|
||||||
(t/use-fixtures :once th/state-init)
|
(t/use-fixtures :once th/state-init)
|
||||||
|
@ -52,7 +50,6 @@
|
||||||
(t/is (= (:mtype params) (:mtype result)))
|
(t/is (= (:mtype params) (:mtype result)))
|
||||||
(vreset! whook result))))
|
(vreset! whook result))))
|
||||||
|
|
||||||
|
|
||||||
(th/reset-mock! http-mock)
|
(th/reset-mock! http-mock)
|
||||||
|
|
||||||
(t/testing "update webhook 1 (success)"
|
(t/testing "update webhook 1 (success)"
|
||||||
|
@ -144,3 +141,41 @@
|
||||||
(t/is (= (:code error-data) :object-not-found)))))
|
(t/is (= (:code error-data) :object-not-found)))))
|
||||||
|
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
(t/deftest webhooks-quotes
|
||||||
|
(with-mocks [http-mock {:target 'app.http.client/req!
|
||||||
|
:return {:status 200}}]
|
||||||
|
|
||||||
|
(let [prof (th/create-profile* 1 {:is-active true})
|
||||||
|
team-id (:default-team-id prof)
|
||||||
|
params {::th/type :create-webhook
|
||||||
|
:profile-id (:id prof)
|
||||||
|
:team-id team-id
|
||||||
|
:uri "http://example.com"
|
||||||
|
:mtype "application/json"}
|
||||||
|
out1 (th/command! params)
|
||||||
|
out2 (th/command! params)
|
||||||
|
out3 (th/command! params)
|
||||||
|
out4 (th/command! params)
|
||||||
|
out5 (th/command! params)
|
||||||
|
out6 (th/command! params)
|
||||||
|
out7 (th/command! params)
|
||||||
|
out8 (th/command! params)
|
||||||
|
out9 (th/command! params)]
|
||||||
|
|
||||||
|
(t/is (= 8 (:call-count @http-mock)))
|
||||||
|
|
||||||
|
(t/is (nil? (:error out1)))
|
||||||
|
(t/is (nil? (:error out2)))
|
||||||
|
(t/is (nil? (:error out3)))
|
||||||
|
(t/is (nil? (:error out4)))
|
||||||
|
(t/is (nil? (:error out5)))
|
||||||
|
(t/is (nil? (:error out6)))
|
||||||
|
(t/is (nil? (:error out7)))
|
||||||
|
(t/is (nil? (:error out8)))
|
||||||
|
|
||||||
|
(let [error (:error out9)
|
||||||
|
error-data (ex-data error)]
|
||||||
|
(t/is (th/ex-info? error))
|
||||||
|
(t/is (= (:type error-data) :restriction))
|
||||||
|
(t/is (= (:code error-data) :webhooks-quote-reached))))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue