From 70a31155487f4a860592ade8ea1e7ecc77eedfab Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Sat, 25 Apr 2026 13:49:34 -0300 Subject: Track channel operators; improve WHO, WHOIS, CAP, NAMES, TOPIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Channel operators: - Auto-op channel creator on JOIN (first user to join gets @) - Track ops in :ops atom, clean up on PART/QUIT/KICK - KICK now requires channel operator status (482) - NAMES shows @ prefix for operators - WHO shows @ in flags for operators - Add is-op? and names-for helpers WHO improvements: - Include realname (not nick) in trailing field of 352 - Support WHO * (list all visible users) - Case-insensitive nick lookup for WHO - Show G (gone/away) or H (here) + @ for ops in flags WHOIS improvements: - Add RPL_WHOISSERVER (312) - Support WHOIS two-param form - Case-insensitive nick lookup CAP improvements: - NAK preserves exact requested string (no reordering) - Add multi-prefix to supported capabilities NAMES improvements: - NAMES without args lists all channels with members - Use names-for helper for consistent @ prefix rendering TOPIC: return 403 for nonexistent channel (was 442) irctest: 220 passed, 426 failed, 218 skipped (up from 214). Unit: 260 assertions, Integration: 38 assertions — all pass. --- tests/integration.clj | 3 ++- tests/unit.clj | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/integration.clj b/tests/integration.clj index 769af90..ed70e4e 100644 --- a/tests/integration.clj +++ b/tests/integration.clj @@ -43,7 +43,8 @@ :process-id process-id :net-id net-id :clients (atom {}) - :channels (atom {})})) + :channels (atom {}) + :ops (atom {})})) (defn- make-client "Creates a simulated client connection using piped streams. diff --git a/tests/unit.clj b/tests/unit.clj index f2718eb..f6a74de 100644 --- a/tests/unit.clj +++ b/tests/unit.clj @@ -110,7 +110,8 @@ :papod.process/hostname "test" :papod.process/started-at (java.util.Date.)}]) {:conn conn :cracha cracha-state :process-id proc-id - :clients (atom {}) :channels (atom {})}))) + :clients (atom {}) :channels (atom {}) + :ops (atom {})}))) (defn test-network! [conn] @@ -587,7 +588,7 @@ (testing "CAP REQ unsupported capability" (let [c (atom {:nick "x" :cap-negotiating? true})] (is (string/includes? - (first (handle-cap ["REQ" ":multi-prefix"] c no-conn)) + (first (handle-cap ["REQ" ":unknown-cap"] c no-conn)) "NAK")))) (testing "already authenticated" (let [c (atom {:nick "x" :caps #{"sasl"} :authenticated? true})] @@ -1258,7 +1259,8 @@ :clients (atom {"alice" {:w alice-out} "bob" {:w bob-out} "baz" {:w baz-out}}) - :channels (atom {"#test" #{"alice" "bob" "baz"}})) + :channels (atom {"#test" #{"alice" "bob" "baz"}}) + :ops (atom {"#test" #{"alice"}})) alice (registered-client "alice" alice-out)] (handle-kick ["#test" "bob" ":bye!"] alice components) ;; bob removed from channel @@ -1278,7 +1280,8 @@ (assoc (test-components) :clients (atom {"alice" {:w alice-out} "bob" {:w bob-out}}) - :channels (atom {"#test" #{"alice" "bob"}})) + :channels (atom {"#test" #{"alice" "bob"}}) + :ops (atom {"#test" #{"alice"}})) alice (registered-client "alice" alice-out)] (handle-kick ["#test" "bob"] alice components) (is (string/includes? (.toString bob-out "UTF-8") -- cgit v1.3