logger.debug("%s: self-ping timed out; assuming still joined", room)
def muc_message(self, msg: Message):
- if msg['mucnick'] == self.nick or 'groupchat' != msg['type']:
+ if 'groupchat' != msg['type']:
+ return False
+ if msg['mucnick'] == self.nick or msg['mucnick'] in (conf_get('other_bots') or []):
+ # Ignoring only our own nick isn't enough: two sibling bot
+ # instances in the same room each correctly ignore themselves
+ # but will happily react to each other's replies, which can
+ # produce an infinite cross-bot reply loop (e.g. one bot's
+ # catch-all posts a URL, the other's URL-resolver replies with
+ # a title that re-triggers the first bot's catch-all, forever).
return False
return self.message(msg)
--- /dev/null
+# -*- coding: utf-8 -*-
+from unittest.mock import Mock
+
+import distbot.bot.bot as bot_module
+from distbot.bot.bot import Bot
+
+
+def _fake_bot(nick="urlbug"):
+ fake = Mock()
+ fake.nick = nick
+ return fake
+
+
+def test_ignores_own_messages():
+ fake = _fake_bot(nick="urlbug")
+ msg = {"mucnick": "urlbug", "type": "groupchat"}
+ assert Bot.muc_message(fake, msg) is False
+ fake.message.assert_not_called()
+
+
+def test_ignores_other_configured_bots(monkeypatch):
+ monkeypatch.setattr(bot_module, "conf_get", lambda key: ["pibug", "urlbrot"] if key == "other_bots" else None)
+ fake = _fake_bot(nick="urlbug")
+ msg = {"mucnick": "pibug", "type": "groupchat"}
+ assert Bot.muc_message(fake, msg) is False
+ fake.message.assert_not_called()
+
+
+def test_reacts_to_real_users(monkeypatch):
+ monkeypatch.setattr(bot_module, "conf_get", lambda key: ["pibug", "urlbrot"] if key == "other_bots" else None)
+ fake = _fake_bot(nick="urlbug")
+ fake.message.return_value = "handled"
+ msg = {"mucnick": "someRealUser", "type": "groupchat"}
+ assert Bot.muc_message(fake, msg) == "handled"
+ fake.message.assert_called_once_with(msg)
+
+
+def test_other_bots_unset_defaults_gracefully(monkeypatch):
+ monkeypatch.setattr(bot_module, "conf_get", lambda key: None)
+ fake = _fake_bot(nick="urlbug")
+ fake.message.return_value = "handled"
+ msg = {"mucnick": "someRealUser", "type": "groupchat"}
+ assert Bot.muc_message(fake, msg) == "handled"
+
+
+def test_ignores_non_groupchat():
+ fake = _fake_bot(nick="urlbug")
+ msg = {"mucnick": "someRealUser", "type": "chat"}
+ assert Bot.muc_message(fake, msg) is False
+ fake.message.assert_not_called()