summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-04-25 16:34:59 -0300
committerEuAndreh <eu@euandre.org>2026-04-25 16:34:59 -0300
commitc8e495f45e6b038d55d14c744151e10bfae03757 (patch)
tree05f31b1694e8635b0484c378719af6ea1f791edb /tests
parentSupport comma-separated PRIVMSG and NAMES targets (diff)
downloadpapod-c8e495f45e6b038d55d14c744151e10bfae03757.tar.gz
papod-c8e495f45e6b038d55d14c744151e10bfae03757.tar.xz
WHOWAS now returns history of recently-disconnected clients
QUIT and socket cleanup paths push a small (last 32) ring of {nick, username, realname, host, ts} entries into a new :whowas atom on the components map. WHOWAS reads that ring case- insensitively and answers with RPL_WHOWASUSER (314) + RPL_WHOISSERVER (312) for each match, terminated with RPL_ENDOFWHOWAS (369), or falls back to ERR_WASNOSUCHNICK (406) when nothing is found.
Diffstat (limited to 'tests')
-rw-r--r--tests/integration.clj3
-rw-r--r--tests/unit.clj39
2 files changed, 40 insertions, 2 deletions
diff --git a/tests/integration.clj b/tests/integration.clj
index 39993dc..84f8647 100644
--- a/tests/integration.clj
+++ b/tests/integration.clj
@@ -49,7 +49,8 @@
:chan-modes (atom {})
:chan-keys (atom {})
:chan-limits (atom {})
- :invites (atom {})}))
+ :invites (atom {})
+ :whowas (atom [])}))
(defn- make-client
"Creates a simulated client connection using piped streams.
diff --git a/tests/unit.clj b/tests/unit.clj
index 5439c71..b8fc57f 100644
--- a/tests/unit.clj
+++ b/tests/unit.clj
@@ -115,7 +115,8 @@
:chan-modes (atom {})
:chan-keys (atom {})
:chan-limits (atom {})
- :invites (atom {})})))
+ :invites (atom {})
+ :whowas (atom [])})))
(defn test-network!
[conn]
@@ -1870,6 +1871,42 @@
(swap! (:chan-limits comp) assoc "#small" 1)
(let [replies (handle-join ["#small"] bob comp)]
(is (string/includes? (first replies) "471")))))
+ (testing "WHOWAS returns history after QUIT"
+ (let [c (registered-client "alice"
+ (java.io.ByteArrayOutputStream.))
+ components (test-components)
+ comp (assoc components
+ :clients (atom {"bob" {:client-atom
+ (atom
+ {:nick "bob"
+ :registered? true
+ :user
+ {:username "bobu"
+ :realname "Bob"}})
+ :w
+ (java.io.ByteArrayOutputStream.)}}))]
+ ;; Bob quits
+ (let [bob (:client-atom (get @(:clients comp) "bob"))]
+ (replies-for! {:command "QUIT" :params [":bye"]}
+ bob comp))
+ ;; Alice WHOWAS bob — gets history
+ (let [replies (replies-for!
+ {:command "WHOWAS" :params ["" "bob"]}
+ c comp)]
+ (is (>= (count replies) 2))
+ (is (some #(re-find #" 314 " %) replies))
+ (is (some #(re-find #" 369 " %) replies))
+ (is (not (some #(re-find #" 406 " %) replies))))))
+ (testing "WHOWAS for unknown nick returns 406"
+ (let [c (registered-client "alice"
+ (java.io.ByteArrayOutputStream.))
+ components (test-components)]
+ (let [replies (replies-for!
+ {:command "WHOWAS"
+ :params ["" "neverexisted"]}
+ c components)]
+ (is (some #(re-find #" 406 " %) replies))
+ (is (some #(re-find #" 369 " %) replies)))))
(testing "+k key blocks JOIN with 475"
(let [{:keys [test-network-id] :as components}
(test-components-with-network)