|
| 1 | +(ns eca.features.hooks-test |
| 2 | + (:require |
| 3 | + [babashka.process :as p] |
| 4 | + [clojure.test :refer [deftest is testing]] |
| 5 | + [eca.features.hooks :as f.hooks] |
| 6 | + [eca.test-helper :as h] |
| 7 | + [matcher-combinators.test :refer [match?]])) |
| 8 | + |
| 9 | +(h/reset-components-before-test) |
| 10 | + |
| 11 | +(defn set-action-payload [a*] |
| 12 | + (fn [p] |
| 13 | + (reset! a* p))) |
| 14 | + |
| 15 | +(deftest trigger-if-matches!-test |
| 16 | + (testing "prePrompt" |
| 17 | + (h/reset-components!) |
| 18 | + (h/config! {:hooks {"my-hook" {:type "prePrompt" |
| 19 | + :actions [{:type "shell" |
| 20 | + :shell "echo hey"}]}}}) |
| 21 | + (let [on-before-action* (atom nil) |
| 22 | + on-after-action* (atom nil)] |
| 23 | + (with-redefs [p/sh (constantly {:exit 0 :out "hey" :err nil})] |
| 24 | + (f.hooks/trigger-if-matches! |
| 25 | + :prePrompt |
| 26 | + {:foo "1"} |
| 27 | + {:on-before-action (set-action-payload on-before-action*) |
| 28 | + :on-after-action (set-action-payload on-after-action*)} |
| 29 | + (h/db) |
| 30 | + (h/config))) |
| 31 | + (is (match? |
| 32 | + {:id string? |
| 33 | + :name "my-hook"} |
| 34 | + @on-before-action*)) |
| 35 | + (is (match? |
| 36 | + {:id string? |
| 37 | + :name "my-hook" |
| 38 | + :status 0 |
| 39 | + :output "hey" |
| 40 | + :error nil} |
| 41 | + @on-after-action*)))) |
| 42 | + (testing "preToolCall does not matches" |
| 43 | + (h/reset-components!) |
| 44 | + (h/config! {:hooks {"my-hook" {:type "preToolCall" |
| 45 | + :matcher "my-mcp__my.*" |
| 46 | + :actions [{:type "shell" |
| 47 | + :shell "echo hey"}]}}}) |
| 48 | + (let [on-before-action* (atom nil) |
| 49 | + on-after-action* (atom nil)] |
| 50 | + (with-redefs [p/sh (constantly {:exit 2 :out nil :err "stop!"})] |
| 51 | + (f.hooks/trigger-if-matches! |
| 52 | + :preToolCall |
| 53 | + {:server "my-other-mcp" |
| 54 | + :tool-name "my-tool"} |
| 55 | + {:on-before-action (set-action-payload on-before-action*) |
| 56 | + :on-after-action (set-action-payload on-after-action*)} |
| 57 | + (h/db) |
| 58 | + (h/config))) |
| 59 | + (is (match? |
| 60 | + nil |
| 61 | + @on-before-action*)) |
| 62 | + (is (match? |
| 63 | + nil |
| 64 | + @on-after-action*)))) |
| 65 | + (testing "preToolCall matches" |
| 66 | + (h/reset-components!) |
| 67 | + (h/config! {:hooks {"my-hook" {:type "preToolCall" |
| 68 | + :matcher "my-mcp__my.*" |
| 69 | + :actions [{:type "shell" |
| 70 | + :shell "echo hey"}]}}}) |
| 71 | + (let [on-before-action* (atom nil) |
| 72 | + on-after-action* (atom nil)] |
| 73 | + (with-redefs [p/sh (constantly {:exit 2 :out nil :err "stop!"})] |
| 74 | + (f.hooks/trigger-if-matches! |
| 75 | + :preToolCall |
| 76 | + {:server "my-mcp" |
| 77 | + :tool-name "my-tool"} |
| 78 | + {:on-before-action (set-action-payload on-before-action*) |
| 79 | + :on-after-action (set-action-payload on-after-action*)} |
| 80 | + (h/db) |
| 81 | + (h/config))) |
| 82 | + (is (match? |
| 83 | + {:id string? |
| 84 | + :name "my-hook"} |
| 85 | + @on-before-action*)) |
| 86 | + (is (match? |
| 87 | + {:id string? |
| 88 | + :name "my-hook" |
| 89 | + :status 2 |
| 90 | + :output nil |
| 91 | + :error "stop!"} |
| 92 | + @on-after-action*))))) |
0 commit comments