aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Johannes Christ <[email protected]>2019-10-12 14:43:10 +0200
committerGravatar Sebastiaan Zeeff <[email protected]>2019-10-14 22:20:19 +0200
commit0ccb798f03ecb92b73111ffc05ee0f446034142b (patch)
tree806ca8431e3681017e8e7dae6a150a16fa14d20f
parentMerge branch 'unittest-migration' of github.com:python-discord/bot into unitt... (diff)
Move the `token_remover` cog tests to `unittest`.
-rw-r--r--tests/cogs/__init__.py0
-rw-r--r--tests/cogs/test_token_remover.py139
2 files changed, 139 insertions, 0 deletions
diff --git a/tests/cogs/__init__.py b/tests/cogs/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/cogs/__init__.py
diff --git a/tests/cogs/test_token_remover.py b/tests/cogs/test_token_remover.py
new file mode 100644
index 000000000..e5d3648de
--- /dev/null
+++ b/tests/cogs/test_token_remover.py
@@ -0,0 +1,139 @@
+import asyncio
+import logging
+import unittest
+from unittest.mock import MagicMock
+
+from discord import Colour
+
+from bot.cogs.token_remover import (
+ DELETION_MESSAGE_TEMPLATE,
+ TokenRemover,
+ setup as setup_cog,
+)
+from bot.constants import Channels, Colours, Event, Icons
+from tests.helpers import AsyncMock
+
+
+class TokenRemoverTests(unittest.TestCase):
+ """Tests the `TokenRemover` cog."""
+
+ def setUp(self):
+ """Adds the cog, a bot, and a message to the instance for usage in tests."""
+ self.bot = MagicMock()
+ self.bot.get_cog.return_value = MagicMock()
+ self.bot.get_cog.return_value.send_log_message = AsyncMock()
+ self.cog = TokenRemover(bot=self.bot)
+
+ self.msg = MagicMock()
+ self.msg.author = MagicMock()
+ self.msg.author.__str__.return_value = 'lemon'
+ self.msg.author.bot = False
+ self.msg.author.avatar_url_as.return_value = 'picture-lemon.png'
+ self.msg.author.id = 42
+ self.msg.author.mention = '@lemon'
+ self.msg.channel.send = AsyncMock()
+ self.msg.channel.mention = '#lemonade-stand'
+ self.msg.content = ''
+ self.msg.delete = AsyncMock()
+ self.msg.id = 555
+
+ def test_is_valid_user_id_is_true_for_numeric_content(self):
+ """A string decoding to numeric characters is a valid user ID."""
+ # MTIz = base64(123)
+ self.assertTrue(TokenRemover.is_valid_user_id('MTIz'))
+
+ def test_is_valid_user_id_is_false_for_alphabetic_content(self):
+ """A string decoding to alphabetic characters is not a valid user ID."""
+ # YWJj = base64(abc)
+ self.assertFalse(TokenRemover.is_valid_user_id('YWJj'))
+
+ def test_is_valid_timestamp_is_true_for_valid_timestamps(self):
+ """A string decoding to a valid timestamp should be recognized as such."""
+ self.assertTrue(TokenRemover.is_valid_timestamp('DN9r_A'))
+
+ def test_is_valid_timestamp_is_false_for_invalid_values(self):
+ """A string not decoding to a valid timestamp should not be recognized as such."""
+ # MTIz = base64(123)
+ self.assertFalse(TokenRemover.is_valid_timestamp('MTIz'))
+
+ def test_mod_log_property(self):
+ """The `mod_log` property should ask the bot to return the `ModLog` cog."""
+ self.bot.get_cog.return_value = 'lemon'
+ self.assertEqual(self.cog.mod_log, self.bot.get_cog.return_value)
+ self.bot.get_cog.assert_called_once_with('ModLog')
+
+ def test_ignores_bot_messages(self):
+ """When the message event handler is called with a bot message, nothing is done."""
+ self.msg.author.bot = True
+ coroutine = self.cog.on_message(self.msg)
+ self.assertIsNone(asyncio.run(coroutine))
+
+ def test_ignores_messages_without_tokens(self):
+ """Messages without anything looking like a token are ignored."""
+ for content in ('', 'lemon wins'):
+ with self.subTest(content=content):
+ self.msg.content = content
+ coroutine = self.cog.on_message(self.msg)
+ self.assertIsNone(asyncio.run(coroutine))
+
+ def test_ignores_messages_with_invalid_tokens(self):
+ """Messages with values that are invalid tokens are ignored."""
+ for content in ('foo.bar.baz', 'x.y.'):
+ with self.subTest(content=content):
+ self.msg.content = content
+ coroutine = self.cog.on_message(self.msg)
+ self.assertIsNone(asyncio.run(coroutine))
+
+ def test_censors_valid_tokens(self):
+ """Valid tokens are censored."""
+ cases = (
+ # (content, censored_token)
+ ('MTIz.DN9R_A.xyz', 'MTIz.DN9R_A.xxx'),
+ )
+
+ for content, censored_token in cases:
+ with self.subTest(content=content, censored_token=censored_token):
+ self.msg.content = content
+ coroutine = self.cog.on_message(self.msg)
+ with self.assertLogs(logger='bot.cogs.token_remover', level=logging.DEBUG) as cm:
+ self.assertIsNone(asyncio.run(coroutine)) # no return value
+
+ [line] = cm.output
+ log_message = (
+ "Censored a seemingly valid token sent by "
+ "lemon (`42`) in #lemonade-stand, "
+ f"token was `{censored_token}`"
+ )
+ self.assertIn(log_message, line)
+
+ self.msg.delete.assert_called_once_with()
+ self.msg.channel.send.assert_called_once_with(
+ DELETION_MESSAGE_TEMPLATE.format(mention='@lemon')
+ )
+ self.bot.get_cog.assert_called_with('ModLog')
+ self.msg.author.avatar_url_as.assert_called_once_with(static_format='png')
+
+ mod_log = self.bot.get_cog.return_value
+ mod_log.ignore.assert_called_once_with(Event.message_delete, self.msg.id)
+ mod_log.send_log_message.assert_called_once_with(
+ icon_url=Icons.token_removed,
+ colour=Colour(Colours.soft_red),
+ title="Token removed!",
+ text=log_message,
+ thumbnail='picture-lemon.png',
+ channel_id=Channels.mod_alerts
+ )
+
+
+class TokenRemoverSetupTests(unittest.TestCase):
+ """Tests setup of the `TokenRemover` cog."""
+
+ def test_setup(self):
+ """Setup of the cog should log a message at `INFO` level."""
+ bot = MagicMock()
+ with self.assertLogs(logger='bot.cogs.token_remover', level=logging.INFO) as cm:
+ setup_cog(bot)
+
+ [line] = cm.output
+ bot.add_cog.assert_called_once()
+ self.assertIn("Cog loaded: TokenRemover", line)