summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/papod.clj22
-rw-r--r--tests/unit.clj58
2 files changed, 74 insertions, 6 deletions
diff --git a/src/papod.clj b/src/papod.clj
index bf41507..ffcf1c2 100644
--- a/src/papod.clj
+++ b/src/papod.clj
@@ -953,7 +953,20 @@
" nt" ;; channel modes
))
(numeric-reply client "005"
- "NETWORK=papod :are supported by this server")
+ (str "AWAYLEN=200 CASEMAPPING=ascii"
+ " CHANLIMIT=#:100 CHANMODES=,,l,nt"
+ " CHANNELLEN=64 CHANTYPES=#"
+ " ELIST= HOSTLEN=64"
+ " KICKLEN=300 MAXLIST=b:50"
+ " MAXTARGETS=4 MODES=4"
+ " NETWORK=papod NICKLEN=30"
+ " PREFIX=(ov)@+ STATUSMSG=@+"
+ " :are supported by this server"))
+ (numeric-reply client "005"
+ (str "TARGMAX=KICK:1,LIST:1,WHOIS:1"
+ " TOPICLEN=390 USERLEN=18"
+ " UTF8ONLY"
+ " :are supported by this server"))
(numeric-reply client "422"
":MOTD File is missing")]
memos (pending-memos (:conn components) nick)]
@@ -3050,12 +3063,15 @@
"OPER :Not enough parameters")]
:else
(let [oper-name (first params)
- oper-pass (second params)]
+ oper-pass (second params)
+ nick (client-target client)]
(if (and (= oper-name "operuser")
(= oper-pass "operpassword"))
(do (swap! client assoc :oper? true)
[(numeric-reply client "381"
- ":You are now an IRC operator")])
+ ":You are now an IRC operator")
+ (str ":" +server-name+ " MODE "
+ nick " :+o")])
[(numeric-reply client "464"
":Password incorrect")])))
diff --git a/tests/unit.clj b/tests/unit.clj
index c5cabaa..6b9e36b 100644
--- a/tests/unit.clj
+++ b/tests/unit.clj
@@ -179,7 +179,7 @@
{:command "USER"
:params ["" "joe" "0" "x" ":Joe"]}
c no-conn)]
- (is (= 6 (count replies)))
+ (is (= 7 (count replies)))
(is (string/includes? (first replies) "001"))
(is (:registered? @c)))))
(testing "USER before NICK does not register"
@@ -552,7 +552,7 @@
(is (:authenticated? @c2)))
;; CAP END completes registration
(let [replies (handle-cap ["END"] c2 components)]
- (is (= 6 (count replies)))
+ (is (= 7 (count replies)))
(is (string/includes? (first replies) "001"))
(is (:registered? @c2))))))
(testing "SASL with wrong password"
@@ -715,7 +715,7 @@
(let [replies (@#'papod/replies-for!
{:command "USER" :params ["" "bob" "0" "x" ":B"]}
c components)]
- (is (= 7 (count replies)))
+ (is (= 8 (count replies)))
(is (string/includes? (first replies) "001"))
(is (string/includes? (last replies) "MemoServ")))))))
@@ -1736,6 +1736,58 @@
(let [replies (handle-markread ["#test"] alice components)]
(is (string/includes? (first replies) "2026-04-22T10:00:00.000Z"))))))
+(deftest test_isupport-and-oper
+ (testing "RPL_ISUPPORT advertises required tokens"
+ (let [c (client)]
+ (replies-for! {:command "NICK" :params ["" "joe"]}
+ c no-conn)
+ (let [replies (replies-for!
+ {:command "USER"
+ :params ["" "joe" "0" "x" ":Joe"]}
+ c no-conn)
+ isupport (filter #(re-find #" 005 " %) replies)
+ joined (string/join " " isupport)]
+ (is (seq isupport))
+ (is (string/includes? joined "PREFIX=(ov)@+"))
+ (is (string/includes? joined "CHANTYPES=#"))
+ (is (string/includes? joined "CASEMAPPING=ascii"))
+ (is (string/includes? joined "NETWORK=papod"))
+ (is (string/includes? joined "NICKLEN="))
+ (is (string/includes? joined "CHANNELLEN="))
+ (is (string/includes? joined "TARGMAX=")))))
+ (testing "OPER with correct credentials sends 381 + MODE +o"
+ (let [c (registered-client "baz" (java.io.ByteArrayOutputStream.))]
+ (let [replies (replies-for!
+ {:command "OPER"
+ :params ["" "operuser" "operpassword"]}
+ c no-conn)]
+ (is (= 2 (count replies)))
+ (is (string/includes? (first replies) "381"))
+ (is (re-find #"MODE baz :?\+o" (second replies)))
+ (is (:oper? @c)))))
+ (testing "OPER with wrong password returns 464"
+ (let [c (registered-client "baz" (java.io.ByteArrayOutputStream.))]
+ (let [replies (replies-for!
+ {:command "OPER"
+ :params ["" "operuser" "wrong"]}
+ c no-conn)]
+ (is (= 1 (count replies)))
+ (is (string/includes? (first replies) "464"))
+ (is (not (:oper? @c))))))
+ (testing "OPER missing args returns 461"
+ (let [c (registered-client "baz" (java.io.ByteArrayOutputStream.))]
+ (let [replies (replies-for!
+ {:command "OPER" :params ["" "only"]}
+ c no-conn)]
+ (is (string/includes? (first replies) "461")))))
+ (testing "TIME returns 391"
+ (let [c (registered-client "baz" (java.io.ByteArrayOutputStream.))]
+ (let [replies (replies-for!
+ {:command "TIME" :params []}
+ c no-conn)]
+ (is (= 1 (count replies)))
+ (is (string/includes? (first replies) "391"))))))
+
(defn -main
[& _args]
(binding [*out* *err*]