diff options
| author | EuAndreh <eu@euandre.org> | 2026-04-25 16:05:59 -0300 |
|---|---|---|
| committer | EuAndreh <eu@euandre.org> | 2026-04-25 16:05:59 -0300 |
| commit | 5f7d58c81eda3c8de4725a4a0561a10723786d7a (patch) | |
| tree | 154ff4f0c59e96a728fa05ad9f4c2907d4ceb989 /tests | |
| parent | Implement channel modes, labeled-response, chathistory BATCH (diff) | |
| download | papod-5f7d58c81eda3c8de4725a4a0561a10723786d7a.tar.gz papod-5f7d58c81eda3c8de4725a4a0561a10723786d7a.tar.xz | |
Add NICK validation, voice tracking, multi-prefix, OPER/TIME
NICK now rejects invalid characters with 432, does
case-insensitive collision detection, and broadcasts NICK
changes to all clients sharing a channel after registration.
Voice (+v) is tracked in a new :voiced atom alongside ops, with
cleanup on PART/KICK/QUIT/disconnect. NAMES and the on-join
NAMES reply honor multi-prefix when the client negotiated the
capability.
Per-recipient PRIVMSG delivery now sends tagged variants only to
clients that negotiated message-tags or server-time, while still
echoing tagged messages back to senders with echo-message.
TOPIC enforces +t against non-ops with 482. WHO marks opers with
*, MODE <nick> reports +o, and WHOIS adds the 313 oper line.
OPER and TIME commands are now implemented (381/464 and 391).
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/integration.clj | 9 | ||||
| -rw-r--r-- | tests/unit.clj | 54 |
2 files changed, 41 insertions, 22 deletions
diff --git a/tests/integration.clj b/tests/integration.clj index b92f85d..3e12833 100644 --- a/tests/integration.clj +++ b/tests/integration.clj @@ -45,6 +45,7 @@ :clients (atom {}) :channels (atom {}) :ops (atom {}) + :voiced (atom {}) :chan-modes (atom {})})) (defn- make-client @@ -168,13 +169,12 @@ ;; Alice should see bob's join (let [alice-out (wait-for alice "JOIN" 2000)] (is (string/includes? alice-out "bob"))) - ;; Alice sends — bob receives with msgid + time + ;; Alice sends — bob receives (.reset (:client-out bob)) (send! alice "PRIVMSG #test :Hello from Alice!") (let [bob-out (wait-for bob "Hello from Alice" 2000)] (is (string/includes? bob-out "PRIVMSG #test")) - (is (string/includes? bob-out "@msgid=")) - (is (string/includes? bob-out "time="))) + (is (string/includes? bob-out "Hello from Alice"))) (finally ((:close! alice)) ((:close! bob)))))) @@ -264,8 +264,7 @@ (.reset (:client-out bob)) (send! alice "PRIVMSG bob :hey bob") (let [bob-out (wait-for bob "hey bob" 2000)] - (is (string/includes? bob-out "PRIVMSG bob :hey bob")) - (is (string/includes? bob-out "@msgid="))) + (is (string/includes? bob-out "PRIVMSG bob :hey bob"))) (finally ((:close! alice)) ((:close! bob)))))) diff --git a/tests/unit.clj b/tests/unit.clj index d172e2a..c5cabaa 100644 --- a/tests/unit.clj +++ b/tests/unit.clj @@ -111,7 +111,8 @@ :papod.process/started-at (java.util.Date.)}]) {:conn conn :cracha cracha-state :process-id proc-id :clients (atom {}) :channels (atom {}) - :ops (atom {}) :chan-modes (atom {})}))) + :ops (atom {}) :voiced (atom {}) + :chan-modes (atom {})}))) (defn test-network! [conn] @@ -1441,13 +1442,18 @@ (testing "messages include msgid tags" (let [alice-out (java.io.ByteArrayOutputStream.) bob-out (java.io.ByteArrayOutputStream.) + bob (registered-client "bob" bob-out) + _ (swap! bob assoc + :caps #{"message-tags" "server-time"}) {:keys [test-network-id] :as components} (assoc (test-components-with-network) :clients (atom {"alice" {:w alice-out} - "bob" {:w bob-out}}) + "bob" {:w bob-out + :client-atom bob}}) :channels (atom {"#test" #{"alice" "bob"}})) conn (:conn components) - alice (registered-client "alice" alice-out test-network-id)] + alice (registered-client "alice" alice-out + test-network-id)] ;; Create channel in DB @(d/transact conn [{:papod.channel/id (java.util.UUID/randomUUID) @@ -1587,13 +1593,18 @@ (testing "+reply tag on PRIVMSG creates thread" (let [alice-out (java.io.ByteArrayOutputStream.) bob-out (java.io.ByteArrayOutputStream.) + bob (registered-client "bob" bob-out) + _ (swap! bob assoc + :caps #{"message-tags" "server-time"}) {:keys [test-network-id] :as components} (assoc (test-components-with-network) :clients (atom {"alice" {:w alice-out} - "bob" {:w bob-out}}) + "bob" {:w bob-out + :client-atom bob}}) :channels (atom {})) conn (:conn components) - alice (registered-client "alice" alice-out test-network-id)] + alice (registered-client "alice" alice-out + test-network-id)] (handle-join ["#test"] alice components) (swap! (:channels components) update "#test" conj "bob") (replies-for! {:command "PRIVMSG" :params ["" "#test" ":parent message"]} @@ -1626,13 +1637,19 @@ (deftest test_ircv3-capabilities (testing "server-time tag on outgoing messages" (let [bob-out (java.io.ByteArrayOutputStream.) + bob (registered-client "bob" bob-out) + _ (swap! bob assoc + :caps #{"message-tags" "server-time"}) {:keys [test-network-id] :as components} (assoc (test-components-with-network) - :clients (atom {"alice" {:w (java.io.ByteArrayOutputStream.)} - "bob" {:w bob-out}}) + :clients (atom {"alice" + {:w (java.io.ByteArrayOutputStream.)} + "bob" + {:w bob-out :client-atom bob}}) :channels (atom {"#test" #{"alice" "bob"}})) conn (:conn components) - alice (registered-client "alice" (java.io.ByteArrayOutputStream.) + alice (registered-client "alice" + (java.io.ByteArrayOutputStream.) test-network-id)] @(d/transact conn [{:papod.channel/id (java.util.UUID/randomUUID) @@ -1644,7 +1661,8 @@ (handle-privmsg ["#test" ":hello"] alice components) (let [delivered (.toString bob-out "UTF-8")] (is (string/includes? delivered "time=")) - (is (re-find #"time=\d{4}-\d{2}-\d{2}T" delivered))))) + (is (re-find #"time=\d{4}-\d{2}-\d{2}T" + delivered))))) (testing "echo-message echoes back to sender" (let [alice-out (java.io.ByteArrayOutputStream.) bob-out (java.io.ByteArrayOutputStream.) @@ -1662,15 +1680,17 @@ :papod.channel/type :papod.channel.type/public :papod.channel/description "" :papod.channel/created-at (java.util.Date.)}]) - ;; Without echo-message: sender doesn't receive - (handle-privmsg ["#test" ":no-echo"] alice components) - (is (= "" (.toString alice-out "UTF-8"))) - ;; With echo-message: sender receives their own message + ;; Without echo-message: no reply + (let [replies (handle-privmsg ["#test" ":no-echo"] + alice components)] + (is (empty? replies))) + ;; With echo-message: reply includes the message (swap! alice assoc :caps #{"echo-message"}) - (handle-privmsg ["#test" ":with-echo"] alice components) - (let [echoed (.toString alice-out "UTF-8")] - (is (string/includes? echoed "with-echo")) - (is (string/includes? echoed "@msgid="))))) + (let [replies (handle-privmsg ["#test" ":with-echo"] + alice components)] + (is (= 1 (count replies))) + (is (string/includes? (first replies) "with-echo")) + (is (string/includes? (first replies) "@msgid="))))) (testing "CAP LS advertises all capabilities" (let [c (client) replies (handle-cap ["LS" "302"] c no-conn)] |
