From 26a0245a6a46a2444ae45547d4a98b26d1f8a8a4 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Thu, 1 Jul 2021 15:34:26 +0200 Subject: [PATCH] Add tests for the draft bot mode. --- Makefile | 2 + irctest/controllers/inspircd.py | 1 + irctest/server_tests/test_bot_mode.py | 138 ++++++++++++++++++++++++++ irctest/specifications.py | 1 + pytest.ini | 1 + 5 files changed, 143 insertions(+) create mode 100644 irctest/server_tests/test_bot_mode.py diff --git a/Makefile b/Makefile index 20b3fea..98d011b 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ ERGO_SELECTORS := \ # testNoticeNonexistentChannel fails because of https://github.com/inspircd/inspircd/issues/1849 # testDirectMessageEcho fails because of https://github.com/inspircd/inspircd/issues/1851 # testKeyValidation fails because of https://github.com/inspircd/inspircd/issues/1850 +# testBotPrivateMessage and testBotChannelMessage fail because https://github.com/inspircd/inspircd/pull/1910 is not released yet INSPIRCD_SELECTORS := \ not Ergo \ and not deprecated \ @@ -32,6 +33,7 @@ INSPIRCD_SELECTORS := \ and not testNoticeNonexistentChannel \ and not testDirectMessageEcho \ and not testKeyValidation \ + and not testBotPrivateMessage and not testBotChannelMessage \ $(EXTRA_SELECTORS) MAMMON_SELECTORS := \ diff --git a/irctest/controllers/inspircd.py b/irctest/controllers/inspircd.py index 5652634..d28f13f 100644 --- a/irctest/controllers/inspircd.py +++ b/irctest/controllers/inspircd.py @@ -36,6 +36,7 @@ TEMPLATE_CONFIG = """ target="services.example.org"> # Protocol: + diff --git a/irctest/server_tests/test_bot_mode.py b/irctest/server_tests/test_bot_mode.py new file mode 100644 index 0000000..23cdd5c --- /dev/null +++ b/irctest/server_tests/test_bot_mode.py @@ -0,0 +1,138 @@ +""" +Draft bot mode specification, as defined in + +""" + +from irctest import cases, runner +from irctest.numerics import RPL_WHOISBOT +from irctest.patma import ANYDICT, ANYSTR, StrRe + + +@cases.mark_specifications("IRCv3") +@cases.mark_isupport("BOT") +class BotModeTestCase(cases.BaseServerTestCase): + def setUp(self): + super().setUp() + self.connectClient("modegetter") + if "BOT" not in self.server_support: + raise runner.IsupportTokenNotSupported("BOT") + self._mode_char = self.server_support["BOT"] + + def _initBot(self): + self.assertEqual( + len(self._mode_char), + 1, + fail_msg=( + f"BOT ISUPPORT token should be exactly one character, " + f"but is: {self._mode_char!r}" + ), + ) + + self.connectClient("botnick", "bot") + + self.sendLine("bot", f"MODE botnick +{self._mode_char}") + + # Check echoed mode + self.assertMessageMatch( + self.getMessage("bot"), + command="MODE", + params=["botnick", StrRe(r"\+?" + self._mode_char)], + ) + + def testBotMode(self): + self._initBot() + + def testBotWhois(self): + self._initBot() + + self.connectClient("usernick", "user") + self.sendLine("user", "WHOIS botnick") + messages = self.getMessages("user") + messages = [msg for msg in messages if msg.command == RPL_WHOISBOT] + self.assertEqual( + len(messages), + 1, + msg=( + f"Expected exactly one RPL_WHOISBOT ({RPL_WHOISBOT}), " + f"got: {messages}" + ), + ) + + (message,) = messages + self.assertMessageMatch( + message, command=RPL_WHOISBOT, params=["usernick", "botnick", ANYSTR] + ) + + def testBotPrivateMessage(self): + self._initBot() + + self.connectClient("usernick", "user", capabilities=["message-tags"]) + + self.sendLine("bot", "PRIVMSG usernick :beep boop") + self.assertMessageMatch( + self.getMessage("user"), + command="PRIVMSG", + params=["usernick", "beep boop"], + tags={"draft/bot": None, **ANYDICT}, + ) + + def testBotChannelMessage(self): + self._initBot() + + self.connectClient("usernick", "user", capabilities=["message-tags"]) + + self.sendLine("bot", "JOIN #chan") + self.sendLine("user", "JOIN #chan") + self.getMessages("bot") + self.getMessages("user") + + self.sendLine("bot", "PRIVMSG #chan :beep boop") + self.assertMessageMatch( + self.getMessage("user"), + command="PRIVMSG", + params=["#chan", "beep boop"], + tags={"draft/bot": None, **ANYDICT}, + ) + + def testBotWhox(self): + self._initBot() + + self.connectClient("usernick", "user", capabilities=["message-tags"]) + + self.sendLine("bot", "JOIN #chan") + self.sendLine("user", "JOIN #chan") + self.getMessages("bot") + self.getMessages("user") + + self.sendLine("user", "WHO #chan") + msg1 = self.getMessage("user") + self.assertMessageMatch( + msg1, command="352", fail_msg="Expected WHO response (352), got: {msg}" + ) + msg2 = self.getMessage("user") + self.assertMessageMatch( + msg2, command="352", fail_msg="Expected WHO response (352), got: {msg}" + ) + + if msg1.params[5] == "botnick": + msg = msg1 + elif msg2.params[5] == "botnick": + msg = msg2 + else: + assert False, "No WHO response contained botnick" + + self.assertMessageMatch( + msg, + command="352", + params=[ + "usernick", + "#chan", + ANYSTR, # ident + ANYSTR, # hostname + ANYSTR, # server + "botnick", + StrRe(f".*{self._mode_char}.*"), + ANYSTR, # realname + ], + fail_msg="Expected WHO response with bot flag, got: {msg}", + ) diff --git a/irctest/specifications.py b/irctest/specifications.py index 4680744..6ea2d87 100644 --- a/irctest/specifications.py +++ b/irctest/specifications.py @@ -49,6 +49,7 @@ class Capabilities(enum.Enum): @enum.unique class IsupportTokens(enum.Enum): + BOT = "BOT" MONITOR = "MONITOR" STATUSMSG = "STATUSMSG" diff --git a/pytest.ini b/pytest.ini index 2b41119..35b2457 100644 --- a/pytest.ini +++ b/pytest.ini @@ -26,5 +26,6 @@ markers = sts # isupport tokens + BOT MONITOR STATUSMSG