From 0eade4697bd76b9cc99e74777531ba00df558ff5 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 10:45:24 +0100 Subject: Add unit test for mentions antispam rule --- tests/bot/rules/test_mentions.py | 98 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/bot/rules/test_mentions.py (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py new file mode 100644 index 000000000..520184c2f --- /dev/null +++ b/tests/bot/rules/test_mentions.py @@ -0,0 +1,98 @@ +import unittest +from typing import List, NamedTuple, Tuple + +from bot.rules import mentions +from tests.helpers import async_test + + +class FakeMessage(NamedTuple): + author: str + mentions: List[None] + + +class Case(NamedTuple): + recent_messages: List[FakeMessage] + relevant_messages: Tuple[FakeMessage] + culprit: str + total_mentions: int + + +def msg(author: str, total_mentions: int) -> FakeMessage: + return FakeMessage(author=author, mentions=[None] * total_mentions) + + +class TestMentions(unittest.TestCase): + """Tests applying the `mentions` antispam rule.""" + + def setUp(self): + self.config = { + "max": 2, + "interval": 10 + } + + @async_test + async def test_mentions_within_limit(self): + """Messages with an allowed amount of mentions.""" + cases = ( + [msg("bob", 0)], + [msg("bob", 2)], + [msg("bob", 1), msg("bob", 1)], + [msg("bob", 1), msg("alice", 2)] + ) + + for recent_messages in cases: + last_message = recent_messages[0] + + with self.subTest( + last_message=last_message, + recent_messages=recent_messages, + config=self.config + ): + self.assertIsNone( + await mentions.apply(last_message, recent_messages, self.config) + ) + + @async_test + async def test_mentions_exceeding_limit(self): + """Messages with a higher than allowed amount of mentions.""" + cases = ( + Case( + [msg("bob", 3)], + (msg("bob", 3),), + ("bob",), + 3 + ), + Case( + [msg("alice", 2), msg("alice", 0), msg("alice", 1)], + (msg("alice", 2), msg("alice", 0), msg("alice", 1)), + ("alice",), + 3 + ), + Case( + [msg("bob", 2), msg("alice", 3), msg("bob", 2)], + (msg("bob", 2), msg("bob", 2)), + ("bob",), + 4 + ) + ) + + for recent_messages, relevant_messages, culprit, total_mentions in cases: + last_message = recent_messages[0] + + with self.subTest( + last_message=last_message, + recent_messages=recent_messages, + relevant_messages=relevant_messages, + culprit=culprit, + total_mentions=total_mentions, + cofig=self.config + ): + desired_output = ( + f"sent {total_mentions} mentions in {self.config['interval']}s", + culprit, + relevant_messages + ) + self.assertTupleEqual( + await mentions.apply(last_message, recent_messages, self.config), + desired_output + ) -- cgit v1.2.3 From 187d419810759992e19a792fd746f26960f3831a Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 10:46:34 +0100 Subject: Add missing docstring --- tests/bot/rules/test_mentions.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py index 520184c2f..987a42c0a 100644 --- a/tests/bot/rules/test_mentions.py +++ b/tests/bot/rules/test_mentions.py @@ -18,6 +18,7 @@ class Case(NamedTuple): def msg(author: str, total_mentions: int) -> FakeMessage: + """Makes a message with `total_mentions` mentions.""" return FakeMessage(author=author, mentions=[None] * total_mentions) -- cgit v1.2.3 From 32caead77e4bad04689892a29005faa3ffde2e83 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 10:50:54 +0100 Subject: Adjust docstring asterisk to backtick for consistency --- tests/bot/rules/test_links.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/rules/test_links.py b/tests/bot/rules/test_links.py index be832843b..40336beb0 100644 --- a/tests/bot/rules/test_links.py +++ b/tests/bot/rules/test_links.py @@ -18,7 +18,7 @@ class Case(NamedTuple): def msg(author: str, total_links: int) -> FakeMessage: - """Makes a message with *total_links* links.""" + """Makes a message with `total_links` links.""" content = " ".join(["https://pydis.com"] * total_links) return FakeMessage(author=author, content=content) -- cgit v1.2.3 From b87a98c7749edfeb9fbc368f2bf9a7ecb9434662 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 10:54:26 +0100 Subject: Use range to build mock mentions list --- tests/bot/rules/test_mentions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py index 987a42c0a..e1a971dbb 100644 --- a/tests/bot/rules/test_mentions.py +++ b/tests/bot/rules/test_mentions.py @@ -19,7 +19,7 @@ class Case(NamedTuple): def msg(author: str, total_mentions: int) -> FakeMessage: """Makes a message with `total_mentions` mentions.""" - return FakeMessage(author=author, mentions=[None] * total_mentions) + return FakeMessage(author=author, mentions=list(range(total_mentions))) class TestMentions(unittest.TestCase): -- cgit v1.2.3 From b1c6b4e20578395a5766ac116fd4def1df777de7 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 13:49:55 +0100 Subject: Adjust type hint to correctly represent internal type --- tests/bot/rules/test_mentions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py index e1a971dbb..08dd1d6d5 100644 --- a/tests/bot/rules/test_mentions.py +++ b/tests/bot/rules/test_mentions.py @@ -7,7 +7,7 @@ from tests.helpers import async_test class FakeMessage(NamedTuple): author: str - mentions: List[None] + mentions: List[int] class Case(NamedTuple): -- cgit v1.2.3 From f915782192fd7b631b23fa31e524cacdc8e72614 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 16:25:23 +0100 Subject: Use MockMessage instead of custom FakeMessage --- tests/bot/rules/test_mentions.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py index 08dd1d6d5..e377f2164 100644 --- a/tests/bot/rules/test_mentions.py +++ b/tests/bot/rules/test_mentions.py @@ -2,24 +2,18 @@ import unittest from typing import List, NamedTuple, Tuple from bot.rules import mentions -from tests.helpers import async_test - - -class FakeMessage(NamedTuple): - author: str - mentions: List[int] +from tests.helpers import MockMessage, async_test class Case(NamedTuple): - recent_messages: List[FakeMessage] - relevant_messages: Tuple[FakeMessage] - culprit: str + recent_messages: List[MockMessage, ...] + culprit: Tuple[str] total_mentions: int -def msg(author: str, total_mentions: int) -> FakeMessage: +def msg(author: str, total_mentions: int) -> MockMessage: """Makes a message with `total_mentions` mentions.""" - return FakeMessage(author=author, mentions=list(range(total_mentions))) + return MockMessage(author=author, mentions=list(range(total_mentions))) class TestMentions(unittest.TestCase): @@ -59,26 +53,28 @@ class TestMentions(unittest.TestCase): cases = ( Case( [msg("bob", 3)], - (msg("bob", 3),), ("bob",), 3 ), Case( [msg("alice", 2), msg("alice", 0), msg("alice", 1)], - (msg("alice", 2), msg("alice", 0), msg("alice", 1)), ("alice",), 3 ), Case( [msg("bob", 2), msg("alice", 3), msg("bob", 2)], - (msg("bob", 2), msg("bob", 2)), ("bob",), 4 ) ) - for recent_messages, relevant_messages, culprit, total_mentions in cases: + for recent_messages, culprit, total_mentions in cases: last_message = recent_messages[0] + relevant_messages = tuple( + msg + for msg in recent_messages + if msg.author == last_message.author + ) with self.subTest( last_message=last_message, -- cgit v1.2.3 From 16e6c36c6b370300ef7507d2e01421ad0d83f407 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Sat, 9 Nov 2019 16:27:02 +0100 Subject: Adjust incorrect type hint --- tests/bot/rules/test_mentions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/rules/test_mentions.py b/tests/bot/rules/test_mentions.py index e377f2164..ad49ead32 100644 --- a/tests/bot/rules/test_mentions.py +++ b/tests/bot/rules/test_mentions.py @@ -6,7 +6,7 @@ from tests.helpers import MockMessage, async_test class Case(NamedTuple): - recent_messages: List[MockMessage, ...] + recent_messages: List[MockMessage] culprit: Tuple[str] total_mentions: int -- cgit v1.2.3 From 2a9b1fc24ffe9679a565c0f9f4678357e9c80e44 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Wed, 13 Nov 2019 22:17:18 +0100 Subject: Adjust links rule to use proper MockMessage --- tests/bot/rules/test_links.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_links.py b/tests/bot/rules/test_links.py index 40336beb0..02a5d5501 100644 --- a/tests/bot/rules/test_links.py +++ b/tests/bot/rules/test_links.py @@ -2,25 +2,19 @@ import unittest from typing import List, NamedTuple, Tuple from bot.rules import links -from tests.helpers import async_test - - -class FakeMessage(NamedTuple): - author: str - content: str +from tests.helpers import MockMessage, async_test class Case(NamedTuple): - recent_messages: List[FakeMessage] - relevant_messages: Tuple[FakeMessage] + recent_messages: List[MockMessage] culprit: Tuple[str] total_links: int -def msg(author: str, total_links: int) -> FakeMessage: +def msg(author: str, total_links: int) -> MockMessage: """Makes a message with `total_links` links.""" content = " ".join(["https://pydis.com"] * total_links) - return FakeMessage(author=author, content=content) + return MockMessage(author=author, content=content) class LinksTests(unittest.TestCase): @@ -61,26 +55,28 @@ class LinksTests(unittest.TestCase): cases = ( Case( [msg("bob", 1), msg("bob", 2)], - (msg("bob", 1), msg("bob", 2)), ("bob",), 3 ), Case( [msg("alice", 1), msg("alice", 1), msg("alice", 1)], - (msg("alice", 1), msg("alice", 1), msg("alice", 1)), ("alice",), 3 ), Case( [msg("alice", 2), msg("bob", 3), msg("alice", 1)], - (msg("alice", 2), msg("alice", 1)), ("alice",), 3 ) ) - for recent_messages, relevant_messages, culprit, total_links in cases: + for recent_messages, culprit, total_links in cases: last_message = recent_messages[0] + relevant_messages = tuple( + msg + for msg in recent_messages + if msg.author == last_message.author + ) with self.subTest( last_message=last_message, -- cgit v1.2.3 From a2617d197f4863123caa33076d89b7612a902d60 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Wed, 13 Nov 2019 22:42:25 +0100 Subject: Adjust attachments rule to use MockMessage, restructure test cases --- tests/bot/rules/test_attachments.py | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index 4bb0acf7c..2f8294922 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -1,26 +1,17 @@ import asyncio import unittest -from dataclasses import dataclass -from typing import Any, List from bot.rules import attachments +from tests.helpers import MockMessage -# Using `MagicMock` sadly doesn't work for this usecase -# since it's __eq__ compares the MagicMock's ID. We just -# want to compare the actual attributes we set. -@dataclass -class FakeMessage: - author: str - attachments: List[Any] - - -def msg(total_attachments: int) -> FakeMessage: - return FakeMessage(author='lemon', attachments=list(range(total_attachments))) +def msg(total_attachments: int) -> MockMessage: + """Builds a message with `total_attachments` attachments.""" + return MockMessage(author='lemon', attachments=list(range(total_attachments))) class AttachmentRuleTests(unittest.TestCase): - """Tests applying the `attachment` antispam rule.""" + """Tests applying the `attachments` antispam rule.""" def test_allows_messages_without_too_many_attachments(self): """Messages without too many attachments are allowed as-is.""" @@ -38,13 +29,25 @@ class AttachmentRuleTests(unittest.TestCase): def test_disallows_messages_with_too_many_attachments(self): """Messages with too many attachments trigger the rule.""" cases = ( - ((msg(4), msg(0), msg(6)), [msg(4), msg(6)], 10), - ((msg(6),), [msg(6)], 6), - ((msg(1),) * 6, [msg(1)] * 6, 6), + ([msg(4), msg(0), msg(6)], 10), + ([msg(6)], 6), + ([msg(1)] * 6, 6), ) - for messages, relevant_messages, total in cases: - with self.subTest(messages=messages, relevant_messages=relevant_messages, total=total): - last_message, *recent_messages = messages + for messages, total in cases: + last_message, *recent_messages = messages + relevant_messages = [last_message] + [ + msg + for msg in recent_messages + if msg.author == last_message.author + and len(msg.attachments) > 0 + ] + + with self.subTest( + last_message=last_message, + recent_messages=recent_messages, + relevant_messages=relevant_messages, + total=total + ): coro = attachments.apply(last_message, recent_messages, {'max': 5}) self.assertEqual( asyncio.run(coro), -- cgit v1.2.3 From dd098d91e35c2e333af14919d7405fe47f298ac2 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Wed, 13 Nov 2019 22:48:59 +0100 Subject: Use async_test helper to simplify coro testing --- tests/bot/rules/test_attachments.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index 2f8294922..770dd3201 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -1,8 +1,7 @@ -import asyncio import unittest from bot.rules import attachments -from tests.helpers import MockMessage +from tests.helpers import MockMessage, async_test def msg(total_attachments: int) -> MockMessage: @@ -13,7 +12,8 @@ def msg(total_attachments: int) -> MockMessage: class AttachmentRuleTests(unittest.TestCase): """Tests applying the `attachments` antispam rule.""" - def test_allows_messages_without_too_many_attachments(self): + @async_test + async def test_allows_messages_without_too_many_attachments(self): """Messages without too many attachments are allowed as-is.""" cases = ( (msg(0), msg(0), msg(0)), @@ -22,17 +22,23 @@ class AttachmentRuleTests(unittest.TestCase): ) for last_message, *recent_messages in cases: - with self.subTest(last_message=last_message, recent_messages=recent_messages): - coro = attachments.apply(last_message, recent_messages, {'max': 5}) - self.assertIsNone(asyncio.run(coro)) + with self.subTest( + last_message=last_message, + recent_messages=recent_messages + ): + self.assertIsNone( + await attachments.apply(last_message, recent_messages, {'max': 5}) + ) - def test_disallows_messages_with_too_many_attachments(self): + @async_test + async def test_disallows_messages_with_too_many_attachments(self): """Messages with too many attachments trigger the rule.""" cases = ( ([msg(4), msg(0), msg(6)], 10), ([msg(6)], 6), ([msg(1)] * 6, 6), ) + for messages, total in cases: last_message, *recent_messages = messages relevant_messages = [last_message] + [ @@ -48,8 +54,7 @@ class AttachmentRuleTests(unittest.TestCase): relevant_messages=relevant_messages, total=total ): - coro = attachments.apply(last_message, recent_messages, {'max': 5}) self.assertEqual( - asyncio.run(coro), + await attachments.apply(last_message, recent_messages, {'max': 5}), (f"sent {total} attachments in 5s", ('lemon',), relevant_messages) ) -- cgit v1.2.3 From eef447a2c4e237a56b8f3cb72ee3e4bc54e7961c Mon Sep 17 00:00:00 2001 From: kwzrd Date: Thu, 14 Nov 2019 20:16:23 +0100 Subject: Adjust attachments rule unit test to correcty build the arguments for the tested rule --- tests/bot/rules/test_attachments.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index 770dd3201..a43741fcc 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -21,7 +21,9 @@ class AttachmentRuleTests(unittest.TestCase): (msg(0),), ) - for last_message, *recent_messages in cases: + for recent_messages in cases: + last_message = recent_messages[0] + with self.subTest( last_message=last_message, recent_messages=recent_messages @@ -39,14 +41,16 @@ class AttachmentRuleTests(unittest.TestCase): ([msg(1)] * 6, 6), ) - for messages, total in cases: - last_message, *recent_messages = messages - relevant_messages = [last_message] + [ + for recent_messages, total in cases: + last_message = recent_messages[0] + relevant_messages = tuple( msg for msg in recent_messages - if msg.author == last_message.author - and len(msg.attachments) > 0 - ] + if ( + msg.author == last_message.author + and len(msg.attachments) > 0 + ) + ) with self.subTest( last_message=last_message, -- cgit v1.2.3 From 37b526f372ebc981f5691c5aca1ca8c721da77f6 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Thu, 14 Nov 2019 20:18:57 +0100 Subject: Hold recent_messages in a list to respect type hint, set config in setUp --- tests/bot/rules/test_attachments.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index a43741fcc..fa6b63654 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -12,13 +12,16 @@ def msg(total_attachments: int) -> MockMessage: class AttachmentRuleTests(unittest.TestCase): """Tests applying the `attachments` antispam rule.""" + def setUp(self): + self.config = {"max": 5} + @async_test async def test_allows_messages_without_too_many_attachments(self): """Messages without too many attachments are allowed as-is.""" cases = ( - (msg(0), msg(0), msg(0)), - (msg(2), msg(2)), - (msg(0),), + [msg(0), msg(0), msg(0)], + [msg(2), msg(2)], + [msg(0)], ) for recent_messages in cases: @@ -29,7 +32,7 @@ class AttachmentRuleTests(unittest.TestCase): recent_messages=recent_messages ): self.assertIsNone( - await attachments.apply(last_message, recent_messages, {'max': 5}) + await attachments.apply(last_message, recent_messages, self.config) ) @async_test @@ -59,6 +62,6 @@ class AttachmentRuleTests(unittest.TestCase): total=total ): self.assertEqual( - await attachments.apply(last_message, recent_messages, {'max': 5}), + await attachments.apply(last_message, recent_messages, self.config), (f"sent {total} attachments in 5s", ('lemon',), relevant_messages) ) -- cgit v1.2.3 From 01731a8873f13cc8a85d08147941ffba7284cf20 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Thu, 14 Nov 2019 20:33:12 +0100 Subject: Make complex test cases namedtuples, recognize between various authors, pass config to subTest --- tests/bot/rules/test_attachments.py | 55 +++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index fa6b63654..d8d1b341f 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -1,12 +1,19 @@ import unittest +from typing import List, NamedTuple, Tuple from bot.rules import attachments from tests.helpers import MockMessage, async_test -def msg(total_attachments: int) -> MockMessage: +class Case(NamedTuple): + recent_messages: List[MockMessage] + culprit: Tuple[str] + total_attachments: int + + +def msg(author: str, total_attachments: int) -> MockMessage: """Builds a message with `total_attachments` attachments.""" - return MockMessage(author='lemon', attachments=list(range(total_attachments))) + return MockMessage(author=author, attachments=list(range(total_attachments))) class AttachmentRuleTests(unittest.TestCase): @@ -19,9 +26,9 @@ class AttachmentRuleTests(unittest.TestCase): async def test_allows_messages_without_too_many_attachments(self): """Messages without too many attachments are allowed as-is.""" cases = ( - [msg(0), msg(0), msg(0)], - [msg(2), msg(2)], - [msg(0)], + [msg("bob", 0), msg("bob", 0), msg("bob", 0)], + [msg("bob", 2), msg("bob", 2)], + [msg("bob", 2), msg("alice", 2), msg("bob", 2)], ) for recent_messages in cases: @@ -29,7 +36,8 @@ class AttachmentRuleTests(unittest.TestCase): with self.subTest( last_message=last_message, - recent_messages=recent_messages + recent_messages=recent_messages, + config=self.config ): self.assertIsNone( await attachments.apply(last_message, recent_messages, self.config) @@ -39,12 +47,29 @@ class AttachmentRuleTests(unittest.TestCase): async def test_disallows_messages_with_too_many_attachments(self): """Messages with too many attachments trigger the rule.""" cases = ( - ([msg(4), msg(0), msg(6)], 10), - ([msg(6)], 6), - ([msg(1)] * 6, 6), + Case( + [msg("bob", 4), msg("bob", 0), msg("bob", 6)], + ("bob",), + 10 + ), + Case( + [msg("bob", 4), msg("alice", 6), msg("bob", 2)], + ("bob",), + 6 + ), + Case( + [msg("alice", 6)], + ("alice",), + 6 + ), + ( + [msg("alice", 1) for _ in range(6)], + ("alice",), + 6 + ), ) - for recent_messages, total in cases: + for recent_messages, culprit, total_attachments in cases: last_message = recent_messages[0] relevant_messages = tuple( msg @@ -59,9 +84,15 @@ class AttachmentRuleTests(unittest.TestCase): last_message=last_message, recent_messages=recent_messages, relevant_messages=relevant_messages, - total=total + total_attachments=total_attachments, + config=self.config ): + desired_output = ( + f"sent {total_attachments} attachments in {self.config['max']}s", + culprit, + relevant_messages + ) self.assertEqual( await attachments.apply(last_message, recent_messages, self.config), - (f"sent {total} attachments in 5s", ('lemon',), relevant_messages) + desired_output ) -- cgit v1.2.3 From c74a6c4fb16052c00041b94c3a3e2ef10efe9827 Mon Sep 17 00:00:00 2001 From: kwzrd Date: Thu, 14 Nov 2019 20:34:00 +0100 Subject: Specify assertion to be a tuple comparison --- tests/bot/rules/test_attachments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/rules/test_attachments.py b/tests/bot/rules/test_attachments.py index d8d1b341f..d7187f315 100644 --- a/tests/bot/rules/test_attachments.py +++ b/tests/bot/rules/test_attachments.py @@ -92,7 +92,7 @@ class AttachmentRuleTests(unittest.TestCase): culprit, relevant_messages ) - self.assertEqual( + self.assertTupleEqual( await attachments.apply(last_message, recent_messages, self.config), desired_output ) -- cgit v1.2.3 From e07cf7342184b769d8c0655bc9b84be02809319a Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Wed, 4 Dec 2019 23:38:46 +0700 Subject: Added `unittest` for `bot.utils.time` --- tests/bot/utils/test_time.py | 87 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/bot/utils/test_time.py (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py new file mode 100644 index 000000000..0ef59292e --- /dev/null +++ b/tests/bot/utils/test_time.py @@ -0,0 +1,87 @@ +import asyncio +import unittest +from datetime import datetime, timezone +from unittest.mock import patch + +from dateutil.relativedelta import relativedelta + +from bot.utils import time +from tests.helpers import AsyncMock + + +class TimeTests(unittest.TestCase): + """Test helper functions in bot.utils.time.""" + + def setUp(self): + pass + + def test_humanize_delta(self): + """Testing humanize delta.""" + test_cases = ( + (relativedelta(days=2), 'seconds', 1, '2 days'), + (relativedelta(days=2, hours=2), 'seconds', 2, '2 days and 2 hours'), + (relativedelta(days=2, hours=2), 'seconds', 1, '2 days'), + (relativedelta(days=2, hours=2), 'days', 2, '2 days'), + + # Does not abort for unknown units, as the unit name is checked + # against the attribute of the relativedelta instance. + (relativedelta(days=2, hours=2), 'elephants', 2, '2 days and 2 hours'), + + # Very high maximum units, but it only ever iterates over + # each value the relativedelta might have. + (relativedelta(days=2, hours=2), 'hours', 20, '2 days and 2 hours'), + ) + + for delta, precision, max_units, expected in test_cases: + self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + + def test_humanize_delta_raises_for_invalid_max_units(self): + test_cases = (-1, 0) + + for max_units in test_cases: + with self.assertRaises(ValueError) as error: + time.humanize_delta(relativedelta(days=2, hours=2), 'hours', max_units) + self.assertEqual(str(error), 'max_units must be positive') + + def test_parse_rfc1123(self): + """Testing parse_rfc1123.""" + test_cases = ( + ('Sun, 15 Sep 2019 12:00:00 GMT', datetime(2019, 9, 15, 12, 0, 0, tzinfo=timezone.utc)), + ) + + for stamp, expected in test_cases: + self.assertEqual(time.parse_rfc1123(stamp), expected) + + @patch('asyncio.sleep', new_callable=AsyncMock) + def test_wait_until(self, mock): + """Testing wait_until.""" + start = datetime(2019, 1, 1, 0, 0) + then = datetime(2019, 1, 1, 0, 10) + + # No return value + assert asyncio.run(time.wait_until(then, start)) is None + + mock.assert_called_once_with(10 * 60) + + def test_format_infraction_with_duration(self): + """Testing format_infraction_with_duration.""" + test_cases = ( + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 2, '2019-12-12 00:01 (12 hours and 55 seconds)'), + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 1, '2019-12-12 00:01 (12 hours)'), + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6, + '2019-12-12 00:01 (11 hours, 55 minutes and 55 seconds)'), + ('2019-12-12T00:00:00Z', datetime(2019, 12, 11, 23, 59), 2, '2019-12-12 00:00 (1 minute)'), + ('2019-11-23T20:09:00Z', datetime(2019, 11, 15, 20, 15), 2, '2019-11-23 20:09 (7 days and 23 hours)'), + ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 2, '2019-11-23 20:09 (6 months and 28 days)'), + ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 6, + '2019-11-23 20:09 (6 months, 28 days, 23 hours and 54 minutes)'), + ('2019-11-23T20:58:00Z', datetime(2019, 11, 23, 20, 53), 2, '2019-11-23 20:58 (5 minutes)'), + ('2019-11-24T00:00:00Z', datetime(2019, 11, 23, 23, 59, 0), 2, '2019-11-24 00:00 (1 minute)'), + ('2019-11-23T23:59:00Z', datetime(2017, 7, 21, 23, 0), 2, '2019-11-23 23:59 (2 years and 4 months)'), + ('2019-11-23T23:59:00Z', datetime(2019, 11, 23, 23, 49, 5), 2, + '2019-11-23 23:59 (9 minutes and 55 seconds)'), + (None, datetime(2019, 11, 23, 23, 49, 5), 2, None), + ) + + for expiry, date_from, max_units, expected in test_cases: + self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) -- cgit v1.2.3 From b17dbe5e3e0dfa6ae44d660924455f709abefd0d Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 00:34:58 +0700 Subject: Splitting test cases for `humanize_delta` into proper, independent tests. --- tests/bot/utils/test_time.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 0ef59292e..5e5f2bf2f 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -15,18 +15,20 @@ class TimeTests(unittest.TestCase): def setUp(self): pass - def test_humanize_delta(self): - """Testing humanize delta.""" + def test_humanize_delta_handle_unknown_units(self): + """humanize_delta should be able to handle unknown units, and will not abort.""" test_cases = ( - (relativedelta(days=2), 'seconds', 1, '2 days'), - (relativedelta(days=2, hours=2), 'seconds', 2, '2 days and 2 hours'), - (relativedelta(days=2, hours=2), 'seconds', 1, '2 days'), - (relativedelta(days=2, hours=2), 'days', 2, '2 days'), - # Does not abort for unknown units, as the unit name is checked # against the attribute of the relativedelta instance. (relativedelta(days=2, hours=2), 'elephants', 2, '2 days and 2 hours'), + ) + for delta, precision, max_units, expected in test_cases: + self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + + def test_humanize_delta_handle_high_units(self): + """humanize_delta should be able to handle very high units.""" + test_cases = ( # Very high maximum units, but it only ever iterates over # each value the relativedelta might have. (relativedelta(days=2, hours=2), 'hours', 20, '2 days and 2 hours'), @@ -35,6 +37,18 @@ class TimeTests(unittest.TestCase): for delta, precision, max_units, expected in test_cases: self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + def test_humanize_delta_should_work_normally(self): + """Testing humanize delta.""" + test_cases = ( + (relativedelta(days=2), 'seconds', 1, '2 days'), + (relativedelta(days=2, hours=2), 'seconds', 2, '2 days and 2 hours'), + (relativedelta(days=2, hours=2), 'seconds', 1, '2 days'), + (relativedelta(days=2, hours=2), 'days', 2, '2 days'), + ) + + for delta, precision, max_units, expected in test_cases: + self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + def test_humanize_delta_raises_for_invalid_max_units(self): test_cases = (-1, 0) -- cgit v1.2.3 From 0aee728d6d23ef24f51834f39016f938f3f1b8a9 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 00:36:29 +0700 Subject: Added missing docstring for `test_humanize_delta_raises_for_invalid_max_units` --- tests/bot/utils/test_time.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 5e5f2bf2f..a929bee89 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -50,6 +50,7 @@ class TimeTests(unittest.TestCase): self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) def test_humanize_delta_raises_for_invalid_max_units(self): + """humanize_delta should raises ValueError('max_units must be positive') for invalid max units.""" test_cases = (-1, 0) for max_units in test_cases: -- cgit v1.2.3 From beed21355e7f0e25b69637768843c53d510b8969 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 00:40:38 +0700 Subject: Changed `assert` to `self.assertIs` for `test_wait_until` --- tests/bot/utils/test_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index a929bee89..0afabe400 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -74,7 +74,7 @@ class TimeTests(unittest.TestCase): then = datetime(2019, 1, 1, 0, 10) # No return value - assert asyncio.run(time.wait_until(then, start)) is None + self.assertIs(asyncio.run(time.wait_until(then, start)), None) mock.assert_called_once_with(10 * 60) -- cgit v1.2.3 From ccdd8363d75846f0841791ba54763dae28243c62 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 00:45:36 +0700 Subject: Splitting test cases for `format_infraction_with_duration` into proper, independent tests. --- tests/bot/utils/test_time.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 0afabe400..2a2a707d8 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -37,7 +37,7 @@ class TimeTests(unittest.TestCase): for delta, precision, max_units, expected in test_cases: self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) - def test_humanize_delta_should_work_normally(self): + def test_humanize_delta_should_normal_usage(self): """Testing humanize delta.""" test_cases = ( (relativedelta(days=2), 'seconds', 1, '2 days'), @@ -78,18 +78,38 @@ class TimeTests(unittest.TestCase): mock.assert_called_once_with(10 * 60) - def test_format_infraction_with_duration(self): - """Testing format_infraction_with_duration.""" + def test_format_infraction_with_duration_none_expiry(self): + """format_infraction_with_duration should work for None expiry.""" + self.assertEqual(time.format_infraction_with_duration(None), None) + + # To make sure that date_from and max_units are not touched + self.assertEqual(time.format_infraction_with_duration(None, date_from='Why hello there!'), None) + self.assertEqual(time.format_infraction_with_duration(None, max_units=float('inf')), None) + self.assertEqual( + time.format_infraction_with_duration(None, date_from='Why hello there!', max_units=float('inf')), + None + ) + + def test_format_infraction_with_duration_custom_units(self): + """format_infraction_with_duration should work for custom max_units.""" + self.assertEqual( + time.format_infraction_with_duration('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6), + '2019-12-12 00:01 (11 hours, 55 minutes and 55 seconds)' + ) + + self.assertEqual( + time.format_infraction_with_duration('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 20), + '2019-11-23 20:09 (6 months, 28 days, 23 hours and 54 minutes)' + ) + + def test_format_infraction_with_duration_normal_usage(self): + """format_infraction_with_duration should work for normal usage, across various durations.""" test_cases = ( ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 2, '2019-12-12 00:01 (12 hours and 55 seconds)'), ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 1, '2019-12-12 00:01 (12 hours)'), - ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6, - '2019-12-12 00:01 (11 hours, 55 minutes and 55 seconds)'), ('2019-12-12T00:00:00Z', datetime(2019, 12, 11, 23, 59), 2, '2019-12-12 00:00 (1 minute)'), ('2019-11-23T20:09:00Z', datetime(2019, 11, 15, 20, 15), 2, '2019-11-23 20:09 (7 days and 23 hours)'), ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 2, '2019-11-23 20:09 (6 months and 28 days)'), - ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 6, - '2019-11-23 20:09 (6 months, 28 days, 23 hours and 54 minutes)'), ('2019-11-23T20:58:00Z', datetime(2019, 11, 23, 20, 53), 2, '2019-11-23 20:58 (5 minutes)'), ('2019-11-24T00:00:00Z', datetime(2019, 11, 23, 23, 59, 0), 2, '2019-11-24 00:00 (1 minute)'), ('2019-11-23T23:59:00Z', datetime(2017, 7, 21, 23, 0), 2, '2019-11-23 23:59 (2 years and 4 months)'), -- cgit v1.2.3 From fa66195dbb6f79bb7174084835499a61e8cb03a3 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 00:52:15 +0700 Subject: Introduced test for `test_format_infraction`, refactored `test_parse_rfc1123`, fixed typo. --- tests/bot/utils/test_time.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 2a2a707d8..09fb824e4 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -50,7 +50,7 @@ class TimeTests(unittest.TestCase): self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) def test_humanize_delta_raises_for_invalid_max_units(self): - """humanize_delta should raises ValueError('max_units must be positive') for invalid max units.""" + """humanize_delta should raises ValueError('max_units must be positive') for invalid max_units.""" test_cases = (-1, 0) for max_units in test_cases: @@ -60,12 +60,14 @@ class TimeTests(unittest.TestCase): def test_parse_rfc1123(self): """Testing parse_rfc1123.""" - test_cases = ( - ('Sun, 15 Sep 2019 12:00:00 GMT', datetime(2019, 9, 15, 12, 0, 0, tzinfo=timezone.utc)), + self.assertEqual( + time.parse_rfc1123('Sun, 15 Sep 2019 12:00:00 GMT'), + datetime(2019, 9, 15, 12, 0, 0, tzinfo=timezone.utc) ) - for stamp, expected in test_cases: - self.assertEqual(time.parse_rfc1123(stamp), expected) + def test_format_infraction(self): + """Testing format_infraction.""" + self.assertEqual(time.format_infraction('2019-12-12T00:01:00Z'), '2019-12-12 00:01') @patch('asyncio.sleep', new_callable=AsyncMock) def test_wait_until(self, mock): -- cgit v1.2.3 From 5e0b19ae841f3f355931ad331f7aa861fbafc4d9 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 01:05:41 +0700 Subject: Added `self.subTest` for tests with multiple test cases & simplified single test case tests. --- tests/bot/utils/test_time.py | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 09fb824e4..c47a306f0 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -17,25 +17,15 @@ class TimeTests(unittest.TestCase): def test_humanize_delta_handle_unknown_units(self): """humanize_delta should be able to handle unknown units, and will not abort.""" - test_cases = ( - # Does not abort for unknown units, as the unit name is checked - # against the attribute of the relativedelta instance. - (relativedelta(days=2, hours=2), 'elephants', 2, '2 days and 2 hours'), - ) - - for delta, precision, max_units, expected in test_cases: - self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + # Does not abort for unknown units, as the unit name is checked + # against the attribute of the relativedelta instance. + self.assertEqual(time.humanize_delta(relativedelta(days=2, hours=2), 'elephants', 2), '2 days and 2 hours') def test_humanize_delta_handle_high_units(self): """humanize_delta should be able to handle very high units.""" - test_cases = ( - # Very high maximum units, but it only ever iterates over - # each value the relativedelta might have. - (relativedelta(days=2, hours=2), 'hours', 20, '2 days and 2 hours'), - ) - - for delta, precision, max_units, expected in test_cases: - self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + # Very high maximum units, but it only ever iterates over + # each value the relativedelta might have. + self.assertEqual(time.humanize_delta(relativedelta(days=2, hours=2), 'hours', 20), '2 days and 2 hours') def test_humanize_delta_should_normal_usage(self): """Testing humanize delta.""" @@ -47,14 +37,15 @@ class TimeTests(unittest.TestCase): ) for delta, precision, max_units, expected in test_cases: - self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) + with self.subTest(delta=delta, precision=precision, max_units=max_units, expected=expected): + self.assertEqual(time.humanize_delta(delta, precision, max_units), expected) def test_humanize_delta_raises_for_invalid_max_units(self): """humanize_delta should raises ValueError('max_units must be positive') for invalid max_units.""" test_cases = (-1, 0) for max_units in test_cases: - with self.assertRaises(ValueError) as error: + with self.subTest(max_units=max_units), self.assertRaises(ValueError) as error: time.humanize_delta(relativedelta(days=2, hours=2), 'hours', max_units) self.assertEqual(str(error), 'max_units must be positive') @@ -121,4 +112,5 @@ class TimeTests(unittest.TestCase): ) for expiry, date_from, max_units, expected in test_cases: - self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) + with self.subTest(expiry=expiry, date_from=date_from, max_units=max_units, expected=expected): + self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) -- cgit v1.2.3 From db341d927aab42c2e874cb499ab1c2e6c0e7647b Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 01:17:56 +0700 Subject: Moved all individual test cases into iterables and test with `self.subTest` context manager. --- tests/bot/utils/test_time.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index c47a306f0..25cd3f69f 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -73,27 +73,31 @@ class TimeTests(unittest.TestCase): def test_format_infraction_with_duration_none_expiry(self): """format_infraction_with_duration should work for None expiry.""" - self.assertEqual(time.format_infraction_with_duration(None), None) + test_cases = ( + (None, None, None, None), - # To make sure that date_from and max_units are not touched - self.assertEqual(time.format_infraction_with_duration(None, date_from='Why hello there!'), None) - self.assertEqual(time.format_infraction_with_duration(None, max_units=float('inf')), None) - self.assertEqual( - time.format_infraction_with_duration(None, date_from='Why hello there!', max_units=float('inf')), - None + # To make sure that date_from and max_units are not touched + (None, 'Why hello there!', None, None), + (None, None, float('inf'), None), + (None, 'Why hello there!', float('inf'), None), ) + for expiry, date_from, max_units, expected in test_cases: + with self.subTest(expiry=expiry, date_from=date_from, max_units=max_units, expected=expected): + self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) + def test_format_infraction_with_duration_custom_units(self): """format_infraction_with_duration should work for custom max_units.""" - self.assertEqual( - time.format_infraction_with_duration('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6), - '2019-12-12 00:01 (11 hours, 55 minutes and 55 seconds)' + test_cases = ( + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6, + '2019-12-12 00:01 (11 hours, 55 minutes and 55 seconds)'), + ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 20, + '2019-11-23 20:09 (6 months, 28 days, 23 hours and 54 minutes)') ) - self.assertEqual( - time.format_infraction_with_duration('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 20), - '2019-11-23 20:09 (6 months, 28 days, 23 hours and 54 minutes)' - ) + for expiry, date_from, max_units, expected in test_cases: + with self.subTest(expiry=expiry, date_from=date_from, max_units=max_units, expected=expected): + self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) def test_format_infraction_with_duration_normal_usage(self): """format_infraction_with_duration should work for normal usage, across various durations.""" -- cgit v1.2.3 From 323306776b0312e2a32ada213a35159311a93a7f Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Thu, 5 Dec 2019 01:42:23 +0700 Subject: Removed `setUp()` from `TimeTests` since it is not being used for anything. --- tests/bot/utils/test_time.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 25cd3f69f..7f55dc3ec 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -12,9 +12,6 @@ from tests.helpers import AsyncMock class TimeTests(unittest.TestCase): """Test helper functions in bot.utils.time.""" - def setUp(self): - pass - def test_humanize_delta_handle_unknown_units(self): """humanize_delta should be able to handle unknown units, and will not abort.""" # Does not abort for unknown units, as the unit name is checked -- cgit v1.2.3 From 6fe61e5919cb541a1651312a01ddf7e7f10d0f86 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 7 Dec 2019 20:11:50 -0800 Subject: Change all Bot imports to use the subclass --- bot/cogs/alias.py | 3 ++- bot/cogs/antimalware.py | 3 ++- bot/cogs/antispam.py | 3 ++- bot/cogs/bot.py | 3 ++- bot/cogs/clean.py | 3 ++- bot/cogs/defcon.py | 3 ++- bot/cogs/doc.py | 5 +++-- bot/cogs/duck_pond.py | 3 ++- bot/cogs/error_handler.py | 3 ++- bot/cogs/eval.py | 3 ++- bot/cogs/extensions.py | 3 ++- bot/cogs/filtering.py | 3 ++- bot/cogs/free.py | 3 ++- bot/cogs/help.py | 3 ++- bot/cogs/information.py | 3 ++- bot/cogs/jams.py | 5 +++-- bot/cogs/logging.py | 3 ++- bot/cogs/moderation/__init__.py | 3 +-- bot/cogs/moderation/infractions.py | 3 ++- bot/cogs/moderation/management.py | 3 ++- bot/cogs/moderation/modlog.py | 3 ++- bot/cogs/moderation/scheduler.py | 3 ++- bot/cogs/moderation/superstarify.py | 3 ++- bot/cogs/off_topic_names.py | 3 ++- bot/cogs/reddit.py | 3 ++- bot/cogs/reminders.py | 3 ++- bot/cogs/security.py | 4 +++- bot/cogs/site.py | 3 ++- bot/cogs/snekbox.py | 3 ++- bot/cogs/sync/__init__.py | 3 +-- bot/cogs/sync/cog.py | 3 ++- bot/cogs/sync/syncers.py | 7 ++++--- bot/cogs/tags.py | 3 ++- bot/cogs/token_remover.py | 3 ++- bot/cogs/utils.py | 3 ++- bot/cogs/verification.py | 3 ++- bot/cogs/watchchannels/__init__.py | 3 +-- bot/cogs/watchchannels/bigbrother.py | 3 ++- bot/cogs/watchchannels/talentpool.py | 3 ++- bot/cogs/watchchannels/watchchannel.py | 3 ++- bot/cogs/wolfram.py | 7 ++++--- bot/interpreter.py | 4 +++- tests/helpers.py | 4 +++- 43 files changed, 92 insertions(+), 52 deletions(-) (limited to 'tests') diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py index 5190c559b..4ee5a2aed 100644 --- a/bot/cogs/alias.py +++ b/bot/cogs/alias.py @@ -3,8 +3,9 @@ import logging from typing import Union from discord import Colour, Embed, Member, User -from discord.ext.commands import Bot, Cog, Command, Context, clean_content, command, group +from discord.ext.commands import Cog, Command, Context, clean_content, command, group +from bot.bot import Bot from bot.cogs.extensions import Extension from bot.cogs.watchchannels.watchchannel import proxy_user from bot.converters import TagNameConverter diff --git a/bot/cogs/antimalware.py b/bot/cogs/antimalware.py index 602819191..03c1e28a1 100644 --- a/bot/cogs/antimalware.py +++ b/bot/cogs/antimalware.py @@ -1,8 +1,9 @@ import logging from discord import Embed, Message, NotFound -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog +from bot.bot import Bot from bot.constants import AntiMalware as AntiMalwareConfig, Channels, URLs log = logging.getLogger(__name__) diff --git a/bot/cogs/antispam.py b/bot/cogs/antispam.py index 1340eb608..88912038a 100644 --- a/bot/cogs/antispam.py +++ b/bot/cogs/antispam.py @@ -7,9 +7,10 @@ from operator import itemgetter from typing import Dict, Iterable, List, Set from discord import Colour, Member, Message, NotFound, Object, TextChannel -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog from bot import rules +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import ( AntiSpam as AntiSpamConfig, Channels, diff --git a/bot/cogs/bot.py b/bot/cogs/bot.py index ee0a463de..a2edb7576 100644 --- a/bot/cogs/bot.py +++ b/bot/cogs/bot.py @@ -5,8 +5,9 @@ import time from typing import Optional, Tuple from discord import Embed, Message, RawMessageUpdateEvent, TextChannel -from discord.ext.commands import Bot, Cog, Context, command, group +from discord.ext.commands import Cog, Context, command, group +from bot.bot import Bot from bot.constants import Channels, DEBUG_MODE, Guild, MODERATION_ROLES, Roles, URLs from bot.decorators import with_role from bot.utils.messages import wait_for_deletion diff --git a/bot/cogs/clean.py b/bot/cogs/clean.py index dca411d01..3365d0934 100644 --- a/bot/cogs/clean.py +++ b/bot/cogs/clean.py @@ -4,8 +4,9 @@ import re from typing import Optional from discord import Colour, Embed, Message, User -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import ( Channels, CleanMessages, Colours, Event, diff --git a/bot/cogs/defcon.py b/bot/cogs/defcon.py index bedd70c86..f062a7546 100644 --- a/bot/cogs/defcon.py +++ b/bot/cogs/defcon.py @@ -6,8 +6,9 @@ from datetime import datetime, timedelta from enum import Enum from discord import Colour, Embed, Member -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import Channels, Colours, Emojis, Event, Icons, Roles from bot.decorators import with_role diff --git a/bot/cogs/doc.py b/bot/cogs/doc.py index e5b3a4062..7df159fd9 100644 --- a/bot/cogs/doc.py +++ b/bot/cogs/doc.py @@ -17,6 +17,7 @@ from requests import ConnectTimeout, ConnectionError, HTTPError from sphinx.ext import intersphinx from urllib3.exceptions import ProtocolError +from bot.bot import Bot from bot.constants import MODERATION_ROLES, RedirectOutput from bot.converters import ValidPythonIdentifier, ValidURL from bot.decorators import with_role @@ -147,7 +148,7 @@ class InventoryURL(commands.Converter): class Doc(commands.Cog): """A set of commands for querying & displaying documentation.""" - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot): self.base_urls = {} self.bot = bot self.inventories = {} @@ -506,7 +507,7 @@ class Doc(commands.Cog): return tag.name == "table" -def setup(bot: commands.Bot) -> None: +def setup(bot: Bot) -> None: """Doc cog load.""" bot.add_cog(Doc(bot)) log.info("Cog loaded: Doc") diff --git a/bot/cogs/duck_pond.py b/bot/cogs/duck_pond.py index 2d25cd17e..879071d1b 100644 --- a/bot/cogs/duck_pond.py +++ b/bot/cogs/duck_pond.py @@ -3,9 +3,10 @@ from typing import Optional, Union import discord from discord import Color, Embed, Member, Message, RawReactionActionEvent, User, errors -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog from bot import constants +from bot.bot import Bot from bot.utils.messages import send_attachments log = logging.getLogger(__name__) diff --git a/bot/cogs/error_handler.py b/bot/cogs/error_handler.py index 49411814c..cf90e9f48 100644 --- a/bot/cogs/error_handler.py +++ b/bot/cogs/error_handler.py @@ -14,9 +14,10 @@ from discord.ext.commands import ( NoPrivateMessage, UserInputError, ) -from discord.ext.commands import Bot, Cog, Context +from discord.ext.commands import Cog, Context from bot.api import ResponseCodeError +from bot.bot import Bot from bot.constants import Channels from bot.decorators import InChannelCheckFailure diff --git a/bot/cogs/eval.py b/bot/cogs/eval.py index 00b988dde..5daec3e39 100644 --- a/bot/cogs/eval.py +++ b/bot/cogs/eval.py @@ -9,8 +9,9 @@ from io import StringIO from typing import Any, Optional, Tuple import discord -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.constants import Roles from bot.decorators import with_role from bot.interpreter import Interpreter diff --git a/bot/cogs/extensions.py b/bot/cogs/extensions.py index bb66e0b8e..4d77d8205 100644 --- a/bot/cogs/extensions.py +++ b/bot/cogs/extensions.py @@ -6,8 +6,9 @@ from pkgutil import iter_modules from discord import Colour, Embed from discord.ext import commands -from discord.ext.commands import Bot, Context, group +from discord.ext.commands import Context, group +from bot.bot import Bot from bot.constants import Emojis, MODERATION_ROLES, Roles, URLs from bot.pagination import LinePaginator from bot.utils.checks import with_role_check diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index 1e7521054..2e54ccecb 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -5,8 +5,9 @@ from typing import Optional, Union import discord.errors from dateutil.relativedelta import relativedelta from discord import Colour, DMChannel, Member, Message, TextChannel -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import ( Channels, Colours, diff --git a/bot/cogs/free.py b/bot/cogs/free.py index 82285656b..bbc9f063b 100644 --- a/bot/cogs/free.py +++ b/bot/cogs/free.py @@ -3,8 +3,9 @@ from datetime import datetime from operator import itemgetter from discord import Colour, Embed, Member, utils -from discord.ext.commands import Bot, Cog, Context, command +from discord.ext.commands import Cog, Context, command +from bot.bot import Bot from bot.constants import Categories, Channels, Free, STAFF_ROLES from bot.decorators import redirect_output diff --git a/bot/cogs/help.py b/bot/cogs/help.py index 9607dbd8d..6385fa467 100644 --- a/bot/cogs/help.py +++ b/bot/cogs/help.py @@ -6,10 +6,11 @@ from typing import Union from discord import Colour, Embed, HTTPException, Message, Reaction, User from discord.ext import commands -from discord.ext.commands import Bot, CheckFailure, Cog as DiscordCog, Command, Context +from discord.ext.commands import CheckFailure, Cog as DiscordCog, Command, Context from fuzzywuzzy import fuzz, process from bot import constants +from bot.bot import Bot from bot.constants import Channels, STAFF_ROLES from bot.decorators import redirect_output from bot.pagination import ( diff --git a/bot/cogs/information.py b/bot/cogs/information.py index 530453600..56bd37bec 100644 --- a/bot/cogs/information.py +++ b/bot/cogs/information.py @@ -9,10 +9,11 @@ from typing import Any, Mapping, Optional import discord from discord import CategoryChannel, Colour, Embed, Member, Role, TextChannel, VoiceChannel, utils from discord.ext import commands -from discord.ext.commands import Bot, BucketType, Cog, Context, command, group +from discord.ext.commands import BucketType, Cog, Context, command, group from discord.utils import escape_markdown from bot import constants +from bot.bot import Bot from bot.decorators import InChannelCheckFailure, in_channel, with_role from bot.utils.checks import cooldown_with_role_bypass, with_role_check from bot.utils.time import time_since diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py index be9d33e3e..0c82e7962 100644 --- a/bot/cogs/jams.py +++ b/bot/cogs/jams.py @@ -4,6 +4,7 @@ from discord import Member, PermissionOverwrite, utils from discord.ext import commands from more_itertools import unique_everseen +from bot.bot import Bot from bot.constants import Roles from bot.decorators import with_role @@ -13,7 +14,7 @@ log = logging.getLogger(__name__) class CodeJams(commands.Cog): """Manages the code-jam related parts of our server.""" - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot): self.bot = bot @commands.command() @@ -108,7 +109,7 @@ class CodeJams(commands.Cog): ) -def setup(bot: commands.Bot) -> None: +def setup(bot: Bot) -> None: """Code Jams cog load.""" bot.add_cog(CodeJams(bot)) log.info("Cog loaded: CodeJams") diff --git a/bot/cogs/logging.py b/bot/cogs/logging.py index c92b619ff..44c771b42 100644 --- a/bot/cogs/logging.py +++ b/bot/cogs/logging.py @@ -1,8 +1,9 @@ import logging from discord import Embed -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog +from bot.bot import Bot from bot.constants import Channels, DEBUG_MODE diff --git a/bot/cogs/moderation/__init__.py b/bot/cogs/moderation/__init__.py index 7383ed44e..0cbdb3aa6 100644 --- a/bot/cogs/moderation/__init__.py +++ b/bot/cogs/moderation/__init__.py @@ -1,7 +1,6 @@ import logging -from discord.ext.commands import Bot - +from bot.bot import Bot from .infractions import Infractions from .management import ModManagement from .modlog import ModLog diff --git a/bot/cogs/moderation/infractions.py b/bot/cogs/moderation/infractions.py index 2713a1b68..7478e19ef 100644 --- a/bot/cogs/moderation/infractions.py +++ b/bot/cogs/moderation/infractions.py @@ -7,6 +7,7 @@ from discord.ext import commands from discord.ext.commands import Context, command from bot import constants +from bot.bot import Bot from bot.constants import Event from bot.decorators import respect_role_hierarchy from bot.utils.checks import with_role_check @@ -25,7 +26,7 @@ class Infractions(InfractionScheduler, commands.Cog): category = "Moderation" category_description = "Server moderation tools." - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot): super().__init__(bot, supported_infractions={"ban", "kick", "mute", "note", "warning"}) self.category = "Moderation" diff --git a/bot/cogs/moderation/management.py b/bot/cogs/moderation/management.py index abfe5c2b3..feae00b7c 100644 --- a/bot/cogs/moderation/management.py +++ b/bot/cogs/moderation/management.py @@ -9,6 +9,7 @@ from discord.ext import commands from discord.ext.commands import Context from bot import constants +from bot.bot import Bot from bot.converters import InfractionSearchQuery from bot.pagination import LinePaginator from bot.utils import time @@ -36,7 +37,7 @@ class ModManagement(commands.Cog): category = "Moderation" - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot): self.bot = bot @property diff --git a/bot/cogs/moderation/modlog.py b/bot/cogs/moderation/modlog.py index 0df752a97..35ef6cbcc 100644 --- a/bot/cogs/moderation/modlog.py +++ b/bot/cogs/moderation/modlog.py @@ -10,8 +10,9 @@ from dateutil.relativedelta import relativedelta from deepdiff import DeepDiff from discord import Colour from discord.abc import GuildChannel -from discord.ext.commands import Bot, Cog, Context +from discord.ext.commands import Cog, Context +from bot.bot import Bot from bot.constants import Channels, Colours, Emojis, Event, Guild as GuildConstant, Icons, URLs from bot.utils.time import humanize_delta from .utils import UserTypes diff --git a/bot/cogs/moderation/scheduler.py b/bot/cogs/moderation/scheduler.py index 3e0968121..937113ef4 100644 --- a/bot/cogs/moderation/scheduler.py +++ b/bot/cogs/moderation/scheduler.py @@ -7,10 +7,11 @@ from gettext import ngettext import dateutil.parser import discord -from discord.ext.commands import Bot, Context +from discord.ext.commands import Context from bot import constants from bot.api import ResponseCodeError +from bot.bot import Bot from bot.constants import Colours, STAFF_CHANNELS from bot.utils import time from bot.utils.scheduling import Scheduler diff --git a/bot/cogs/moderation/superstarify.py b/bot/cogs/moderation/superstarify.py index 9b3c62403..7631d9bbe 100644 --- a/bot/cogs/moderation/superstarify.py +++ b/bot/cogs/moderation/superstarify.py @@ -6,9 +6,10 @@ import typing as t from pathlib import Path from discord import Colour, Embed, Member -from discord.ext.commands import Bot, Cog, Context, command +from discord.ext.commands import Cog, Context, command from bot import constants +from bot.bot import Bot from bot.utils.checks import with_role_check from bot.utils.time import format_infraction from . import utils diff --git a/bot/cogs/off_topic_names.py b/bot/cogs/off_topic_names.py index 78792240f..18d9cfb01 100644 --- a/bot/cogs/off_topic_names.py +++ b/bot/cogs/off_topic_names.py @@ -4,9 +4,10 @@ import logging from datetime import datetime, timedelta from discord import Colour, Embed -from discord.ext.commands import BadArgument, Bot, Cog, Context, Converter, group +from discord.ext.commands import BadArgument, Cog, Context, Converter, group from bot.api import ResponseCodeError +from bot.bot import Bot from bot.constants import Channels, MODERATION_ROLES from bot.decorators import with_role from bot.pagination import LinePaginator diff --git a/bot/cogs/reddit.py b/bot/cogs/reddit.py index 0d06e9c26..c76fcd937 100644 --- a/bot/cogs/reddit.py +++ b/bot/cogs/reddit.py @@ -6,9 +6,10 @@ from datetime import datetime, timedelta from typing import List from discord import Colour, Embed, TextChannel -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group from discord.ext.tasks import loop +from bot.bot import Bot from bot.constants import Channels, ERROR_REPLIES, Emojis, Reddit as RedditConfig, STAFF_ROLES, Webhooks from bot.converters import Subreddit from bot.decorators import with_role diff --git a/bot/cogs/reminders.py b/bot/cogs/reminders.py index 81990704b..b805b24c5 100644 --- a/bot/cogs/reminders.py +++ b/bot/cogs/reminders.py @@ -8,8 +8,9 @@ from typing import Optional from dateutil.relativedelta import relativedelta from discord import Colour, Embed, Message -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.constants import Channels, Icons, NEGATIVE_REPLIES, POSITIVE_REPLIES, STAFF_ROLES from bot.converters import Duration from bot.pagination import LinePaginator diff --git a/bot/cogs/security.py b/bot/cogs/security.py index 316b33d6b..45d0eb2f5 100644 --- a/bot/cogs/security.py +++ b/bot/cogs/security.py @@ -1,6 +1,8 @@ import logging -from discord.ext.commands import Bot, Cog, Context, NoPrivateMessage +from discord.ext.commands import Cog, Context, NoPrivateMessage + +from bot.bot import Bot log = logging.getLogger(__name__) diff --git a/bot/cogs/site.py b/bot/cogs/site.py index 683613788..1d7bd03e4 100644 --- a/bot/cogs/site.py +++ b/bot/cogs/site.py @@ -1,8 +1,9 @@ import logging from discord import Colour, Embed -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.constants import URLs from bot.pagination import LinePaginator diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py index 55a187ac1..1ea61a8da 100644 --- a/bot/cogs/snekbox.py +++ b/bot/cogs/snekbox.py @@ -5,8 +5,9 @@ import textwrap from signal import Signals from typing import Optional, Tuple -from discord.ext.commands import Bot, Cog, Context, command, guild_only +from discord.ext.commands import Cog, Context, command, guild_only +from bot.bot import Bot from bot.constants import Channels, Roles, URLs from bot.decorators import in_channel from bot.utils.messages import wait_for_deletion diff --git a/bot/cogs/sync/__init__.py b/bot/cogs/sync/__init__.py index d4565f848..0da81c60e 100644 --- a/bot/cogs/sync/__init__.py +++ b/bot/cogs/sync/__init__.py @@ -1,7 +1,6 @@ import logging -from discord.ext.commands import Bot - +from bot.bot import Bot from .cog import Sync log = logging.getLogger(__name__) diff --git a/bot/cogs/sync/cog.py b/bot/cogs/sync/cog.py index aaa581f96..90d4c40fe 100644 --- a/bot/cogs/sync/cog.py +++ b/bot/cogs/sync/cog.py @@ -3,10 +3,11 @@ from typing import Callable, Iterable from discord import Guild, Member, Role from discord.ext import commands -from discord.ext.commands import Bot, Cog, Context +from discord.ext.commands import Cog, Context from bot import constants from bot.api import ResponseCodeError +from bot.bot import Bot from bot.cogs.sync import syncers log = logging.getLogger(__name__) diff --git a/bot/cogs/sync/syncers.py b/bot/cogs/sync/syncers.py index 2cc5a66e1..14cf51383 100644 --- a/bot/cogs/sync/syncers.py +++ b/bot/cogs/sync/syncers.py @@ -2,7 +2,8 @@ from collections import namedtuple from typing import Dict, Set, Tuple from discord import Guild -from discord.ext.commands import Bot + +from bot.bot import Bot # These objects are declared as namedtuples because tuples are hashable, # something that we make use of when diffing site roles against guild roles. @@ -52,7 +53,7 @@ async def sync_roles(bot: Bot, guild: Guild) -> Tuple[int, int, int]: Synchronize roles found on the given `guild` with the ones on the API. Arguments: - bot (discord.ext.commands.Bot): + bot (bot.bot.Bot): The bot instance that we're running with. guild (discord.Guild): @@ -169,7 +170,7 @@ async def sync_users(bot: Bot, guild: Guild) -> Tuple[int, int, None]: Synchronize users found in the given `guild` with the ones in the API. Arguments: - bot (discord.ext.commands.Bot): + bot (bot.bot.Bot): The bot instance that we're running with. guild (discord.Guild): diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index cd70e783a..2ece0095d 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -2,8 +2,9 @@ import logging import time from discord import Colour, Embed -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.constants import Channels, Cooldowns, MODERATION_ROLES, Roles from bot.converters import TagContentConverter, TagNameConverter from bot.decorators import with_role diff --git a/bot/cogs/token_remover.py b/bot/cogs/token_remover.py index 5a0d20e57..7af7ed63a 100644 --- a/bot/cogs/token_remover.py +++ b/bot/cogs/token_remover.py @@ -6,9 +6,10 @@ import struct from datetime import datetime from discord import Colour, Message -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Cog from discord.utils import snowflake_time +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import Channels, Colours, Event, Icons diff --git a/bot/cogs/utils.py b/bot/cogs/utils.py index 793fe4c1a..0ed996430 100644 --- a/bot/cogs/utils.py +++ b/bot/cogs/utils.py @@ -8,8 +8,9 @@ from typing import Tuple from dateutil import relativedelta from discord import Colour, Embed, Message, Role -from discord.ext.commands import Bot, Cog, Context, command +from discord.ext.commands import Cog, Context, command +from bot.bot import Bot from bot.constants import Channels, MODERATION_ROLES, Mention, STAFF_ROLES from bot.decorators import in_channel, with_role from bot.utils.time import humanize_delta diff --git a/bot/cogs/verification.py b/bot/cogs/verification.py index b5e8d4357..74eb0dbf8 100644 --- a/bot/cogs/verification.py +++ b/bot/cogs/verification.py @@ -3,8 +3,9 @@ from datetime import datetime from discord import Colour, Message, NotFound, Object from discord.ext import tasks -from discord.ext.commands import Bot, Cog, Context, command +from discord.ext.commands import Cog, Context, command +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import ( Bot as BotConfig, diff --git a/bot/cogs/watchchannels/__init__.py b/bot/cogs/watchchannels/__init__.py index 86e1050fa..e18aea88a 100644 --- a/bot/cogs/watchchannels/__init__.py +++ b/bot/cogs/watchchannels/__init__.py @@ -1,7 +1,6 @@ import logging -from discord.ext.commands import Bot - +from bot.bot import Bot from .bigbrother import BigBrother from .talentpool import TalentPool diff --git a/bot/cogs/watchchannels/bigbrother.py b/bot/cogs/watchchannels/bigbrother.py index 49783bb09..306ed4c64 100644 --- a/bot/cogs/watchchannels/bigbrother.py +++ b/bot/cogs/watchchannels/bigbrother.py @@ -3,8 +3,9 @@ from collections import ChainMap from typing import Union from discord import User -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group +from bot.bot import Bot from bot.cogs.moderation.utils import post_infraction from bot.constants import Channels, MODERATION_ROLES, Webhooks from bot.decorators import with_role diff --git a/bot/cogs/watchchannels/talentpool.py b/bot/cogs/watchchannels/talentpool.py index 4ec42dcc1..cc8feeeee 100644 --- a/bot/cogs/watchchannels/talentpool.py +++ b/bot/cogs/watchchannels/talentpool.py @@ -4,9 +4,10 @@ from collections import ChainMap from typing import Union from discord import Color, Embed, Member, User -from discord.ext.commands import Bot, Cog, Context, group +from discord.ext.commands import Cog, Context, group from bot.api import ResponseCodeError +from bot.bot import Bot from bot.constants import Channels, Guild, MODERATION_ROLES, STAFF_ROLES, Webhooks from bot.decorators import with_role from bot.pagination import LinePaginator diff --git a/bot/cogs/watchchannels/watchchannel.py b/bot/cogs/watchchannels/watchchannel.py index 0bf75a924..bd0622554 100644 --- a/bot/cogs/watchchannels/watchchannel.py +++ b/bot/cogs/watchchannels/watchchannel.py @@ -10,9 +10,10 @@ from typing import Optional import dateutil.parser import discord from discord import Color, Embed, HTTPException, Message, Object, errors -from discord.ext.commands import BadArgument, Bot, Cog, Context +from discord.ext.commands import BadArgument, Cog, Context from bot.api import ResponseCodeError +from bot.bot import Bot from bot.cogs.moderation import ModLog from bot.constants import BigBrother as BigBrotherConfig, Guild as GuildConfig, Icons from bot.pagination import LinePaginator diff --git a/bot/cogs/wolfram.py b/bot/cogs/wolfram.py index ab0ed2472..c3c193cb9 100644 --- a/bot/cogs/wolfram.py +++ b/bot/cogs/wolfram.py @@ -7,8 +7,9 @@ import discord from dateutil.relativedelta import relativedelta from discord import Embed from discord.ext import commands -from discord.ext.commands import Bot, BucketType, Cog, Context, check, group +from discord.ext.commands import BucketType, Cog, Context, check, group +from bot.bot import Bot from bot.constants import Colours, STAFF_ROLES, Wolfram from bot.pagination import ImagePaginator from bot.utils.time import humanize_delta @@ -151,7 +152,7 @@ async def get_pod_pages(ctx: Context, bot: Bot, query: str) -> Optional[List[Tup class Wolfram(Cog): """Commands for interacting with the Wolfram|Alpha API.""" - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot): self.bot = bot @group(name="wolfram", aliases=("wolf", "wa"), invoke_without_command=True) @@ -266,7 +267,7 @@ class Wolfram(Cog): await send_embed(ctx, message, color) -def setup(bot: commands.Bot) -> None: +def setup(bot: Bot) -> None: """Wolfram cog load.""" bot.add_cog(Wolfram(bot)) log.info("Cog loaded: Wolfram") diff --git a/bot/interpreter.py b/bot/interpreter.py index 76a3fc293..8b7268746 100644 --- a/bot/interpreter.py +++ b/bot/interpreter.py @@ -2,7 +2,9 @@ from code import InteractiveInterpreter from io import StringIO from typing import Any -from discord.ext.commands import Bot, Context +from discord.ext.commands import Context + +from bot.bot import Bot CODE_TEMPLATE = """ async def _func(): diff --git a/tests/helpers.py b/tests/helpers.py index b2daae92d..5df796c23 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -10,7 +10,9 @@ import unittest.mock from typing import Any, Iterable, Optional import discord -from discord.ext.commands import Bot, Context +from discord.ext.commands import Context + +from bot.bot import Bot for logger in logging.Logger.manager.loggerDict.values(): -- cgit v1.2.3 From 23acfce3521cd420a2df6eb51f036a2a54140ef6 Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sun, 8 Dec 2019 02:01:01 -0800 Subject: Fix test failures for setup log messages --- tests/bot/cogs/test_duck_pond.py | 12 ++---------- tests/bot/cogs/test_security.py | 11 +++-------- tests/bot/cogs/test_token_remover.py | 8 ++------ 3 files changed, 7 insertions(+), 24 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_duck_pond.py b/tests/bot/cogs/test_duck_pond.py index b801e86f1..d07b2bce1 100644 --- a/tests/bot/cogs/test_duck_pond.py +++ b/tests/bot/cogs/test_duck_pond.py @@ -578,15 +578,7 @@ class DuckPondSetupTests(unittest.TestCase): """Tests setup of the `DuckPond` cog.""" def test_setup(self): - """Setup of the cog should log a message at `INFO` level.""" + """Setup of the extension should call add_cog.""" bot = helpers.MockBot() - log = logging.getLogger('bot.cogs.duck_pond') - - with self.assertLogs(logger=log, level=logging.INFO) as log_watcher: - duck_pond.setup(bot) - - self.assertEqual(len(log_watcher.records), 1) - record = log_watcher.records[0] - self.assertEqual(record.levelno, logging.INFO) - + duck_pond.setup(bot) bot.add_cog.assert_called_once() diff --git a/tests/bot/cogs/test_security.py b/tests/bot/cogs/test_security.py index efa7a50b1..9d1a62f7e 100644 --- a/tests/bot/cogs/test_security.py +++ b/tests/bot/cogs/test_security.py @@ -1,4 +1,3 @@ -import logging import unittest from unittest.mock import MagicMock @@ -49,11 +48,7 @@ class SecurityCogLoadTests(unittest.TestCase): """Tests loading the `Security` cog.""" def test_security_cog_load(self): - """Cog loading logs a message at `INFO` level.""" + """Setup of the extension should call add_cog.""" bot = MagicMock() - with self.assertLogs(logger='bot.cogs.security', level=logging.INFO) as cm: - security.setup(bot) - bot.add_cog.assert_called_once() - - [line] = cm.output - self.assertIn("Cog loaded: Security", line) + security.setup(bot) + bot.add_cog.assert_called_once() diff --git a/tests/bot/cogs/test_token_remover.py b/tests/bot/cogs/test_token_remover.py index 3276cf5a5..a54b839d7 100644 --- a/tests/bot/cogs/test_token_remover.py +++ b/tests/bot/cogs/test_token_remover.py @@ -125,11 +125,7 @@ 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.""" + """Setup of the extension should call add_cog.""" bot = MockBot() - with self.assertLogs(logger='bot.cogs.token_remover', level=logging.INFO) as cm: - setup_cog(bot) - - [line] = cm.output + setup_cog(bot) bot.add_cog.assert_called_once() - self.assertIn("Cog loaded: TokenRemover", line) -- cgit v1.2.3 From 520346d0b472e5cb6c9091a8323b871d2e3821cc Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Fri, 13 Dec 2019 09:18:49 +0700 Subject: Added tests for `until_expiration` Similar to `format_infraction_with_duration` ( if not outright copying it ), added 3 tests for `until_expiration`: - None `expiry`. - Custom `max_units`. - Normal use cases. --- tests/bot/utils/test_time.py | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index 7f55dc3ec..bd04de28b 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -115,3 +115,48 @@ class TimeTests(unittest.TestCase): for expiry, date_from, max_units, expected in test_cases: with self.subTest(expiry=expiry, date_from=date_from, max_units=max_units, expected=expected): self.assertEqual(time.format_infraction_with_duration(expiry, date_from, max_units), expected) + + def test_until_expiration_with_duration_none_expiry(self): + """until_expiration should work for None expiry.""" + test_cases = ( + (None, None, None, None), + + # To make sure that date_from and max_units are not touched + (None, 'Why hello there!', None, None), + (None, None, float('inf'), None), + (None, 'Why hello there!', float('inf'), None), + ) + + for expiry, now, max_units, expected in test_cases: + with self.subTest(expiry=expiry, now=now, max_units=max_units, expected=expected): + self.assertEqual(time.until_expiration(expiry, now, max_units), expected) + + def test_until_expiration_with_duration_custom_units(self): + """until_expiration should work for custom max_units.""" + test_cases = ( + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 5, 5), 6, '11 hours, 55 minutes and 55 seconds'), + ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 20, '6 months, 28 days, 23 hours and 54 minutes') + ) + + for expiry, now, max_units, expected in test_cases: + with self.subTest(expiry=expiry, now=now, max_units=max_units, expected=expected): + self.assertEqual(time.until_expiration(expiry, now, max_units), expected) + + def test_until_expiration_normal_usage(self): + """until_expiration should work for normal usage, across various durations.""" + test_cases = ( + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 2, '12 hours and 55 seconds'), + ('2019-12-12T00:01:00Z', datetime(2019, 12, 11, 12, 0, 5), 1, '12 hours'), + ('2019-12-12T00:00:00Z', datetime(2019, 12, 11, 23, 59), 2, '1 minute'), + ('2019-11-23T20:09:00Z', datetime(2019, 11, 15, 20, 15), 2, '7 days and 23 hours'), + ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 2, '6 months and 28 days'), + ('2019-11-23T20:58:00Z', datetime(2019, 11, 23, 20, 53), 2, '5 minutes'), + ('2019-11-24T00:00:00Z', datetime(2019, 11, 23, 23, 59, 0), 2, '1 minute'), + ('2019-11-23T23:59:00Z', datetime(2017, 7, 21, 23, 0), 2, '2 years and 4 months'), + ('2019-11-23T23:59:00Z', datetime(2019, 11, 23, 23, 49, 5), 2, '9 minutes and 55 seconds'), + (None, datetime(2019, 11, 23, 23, 49, 5), 2, None), + ) + + for expiry, now, max_units, expected in test_cases: + with self.subTest(expiry=expiry, now=now, max_units=max_units, expected=expected): + self.assertEqual(time.until_expiration(expiry, now, max_units), expected) -- cgit v1.2.3 From 66d4b93593b95bfa6999b70aca53328d83710c44 Mon Sep 17 00:00:00 2001 From: Shirayuki Nekomata Date: Fri, 13 Dec 2019 09:29:06 +0700 Subject: Fixed a typo ( due to poor copy pasta and eyeballing skills ) --- tests/bot/utils/test_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/utils/test_time.py b/tests/bot/utils/test_time.py index bd04de28b..69f35f2f5 100644 --- a/tests/bot/utils/test_time.py +++ b/tests/bot/utils/test_time.py @@ -121,7 +121,7 @@ class TimeTests(unittest.TestCase): test_cases = ( (None, None, None, None), - # To make sure that date_from and max_units are not touched + # To make sure that now and max_units are not touched (None, 'Why hello there!', None, None), (None, None, float('inf'), None), (None, 'Why hello there!', float('inf'), None), -- cgit v1.2.3