From 9f4d602bfa02fce088aaed28ee598c116b655683 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Wed, 22 Jul 2020 16:20:48 +0200 Subject: Change ValidPythonIdentifier tests to PackageName. --- tests/bot/test_converters.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/bot/test_converters.py b/tests/bot/test_converters.py index ca8cb6825..a3c071168 100644 --- a/tests/bot/test_converters.py +++ b/tests/bot/test_converters.py @@ -10,9 +10,9 @@ from bot.converters import ( Duration, HushDurationConverter, ISODateTime, + PackageName, TagContentConverter, TagNameConverter, - ValidPythonIdentifier, ) @@ -78,24 +78,23 @@ class ConverterTests(unittest.TestCase): with self.assertRaises(BadArgument, msg=exception_message): asyncio.run(TagNameConverter.convert(self.context, invalid_name)) - def test_valid_python_identifier_for_valid(self): - """ValidPythonIdentifier returns valid identifiers unchanged.""" - test_values = ('foo', 'lemon') + def test_package_name_for_valid(self): + """PackageName returns valid package names unchanged.""" + test_values = ('foo', 'le_mon') for name in test_values: with self.subTest(identifier=name): - conversion = asyncio.run(ValidPythonIdentifier.convert(self.context, name)) + conversion = asyncio.run(PackageName.convert(self.context, name)) self.assertEqual(name, conversion) - def test_valid_python_identifier_for_invalid(self): - """ValidPythonIdentifier raises the proper exception for invalid identifiers.""" - test_values = ('nested.stuff', '#####') + def test_package_name_for_invalid(self): + """PackageName raises the proper exception for invalid package names.""" + test_values = ('text_with_a_dot.', 'UpperCaseName', "num83r") for name in test_values: with self.subTest(identifier=name): - exception_message = f'`{name}` is not a valid Python identifier' - with self.assertRaises(BadArgument, msg=exception_message): - asyncio.run(ValidPythonIdentifier.convert(self.context, name)) + with self.assertRaises(BadArgument): + asyncio.run(PackageName.convert(self.context, name)) def test_duration_converter_for_valid(self): """Duration returns the correct `datetime` for valid duration strings.""" -- cgit v1.2.3 From 27e60e94bd1fe6784c2b7674433bb175255fa217 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sun, 21 Feb 2021 14:06:54 +0100 Subject: Update token remover unittests --- tests/bot/exts/filters/test_token_remover.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/filters/test_token_remover.py b/tests/bot/exts/filters/test_token_remover.py index f99cc3370..51feae9cb 100644 --- a/tests/bot/exts/filters/test_token_remover.py +++ b/tests/bot/exts/filters/test_token_remover.py @@ -291,7 +291,7 @@ class TokenRemoverTests(unittest.IsolatedAsyncioTestCase): channel=self.msg.channel.mention, user_id=token.user_id, timestamp=token.timestamp, - hmac="x" * len(token.hmac), + hmac="xxxxxxxxxxxxxxxxxxxxxxxxjf4", ) @autospec("bot.exts.filters.token_remover", "UNKNOWN_USER_LOG_MESSAGE") @@ -318,7 +318,7 @@ class TokenRemoverTests(unittest.IsolatedAsyncioTestCase): return_value = TokenRemover.format_userid_log_message(msg, token) - self.assertEqual(return_value, (known_user_log_message.format.return_value, False)) + self.assertEqual(return_value, (known_user_log_message.format.return_value, True)) known_user_log_message.format.assert_called_once_with( user_id=472265943062413332, -- cgit v1.2.3 From 8f6d11a7694d6dea50d94d7918f686834283c858 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Sun, 21 Feb 2021 02:54:09 +0100 Subject: Add unittests for _split_signature --- tests/bot/exts/info/doc/__init__.py | 0 tests/bot/exts/info/doc/test_parsing.py | 59 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 tests/bot/exts/info/doc/__init__.py create mode 100644 tests/bot/exts/info/doc/test_parsing.py (limited to 'tests') diff --git a/tests/bot/exts/info/doc/__init__.py b/tests/bot/exts/info/doc/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/bot/exts/info/doc/test_parsing.py b/tests/bot/exts/info/doc/test_parsing.py new file mode 100644 index 000000000..f302b38fc --- /dev/null +++ b/tests/bot/exts/info/doc/test_parsing.py @@ -0,0 +1,59 @@ +from unittest import TestCase + +from bot.exts.info.doc import _parsing as parsing + + +class SignatureSplitter(TestCase): + + def test_basic_split(self): + test_cases = ( + ("0,0,0", ["0", "0", "0"]), + ("0,a=0,a=0", ["0", "a=0", "a=0"]), + ) + self._run_tests(test_cases) + + def test_commas_ignored_in_brackets(self): + test_cases = ( + ("0,[0,0],0,[0,0],0", ["0", "[0,0]", "0", "[0,0]", "0"]), + ("(0,),0,(0,(0,),0),0", ["(0,)", "0", "(0,(0,),0)", "0"]), + ) + self._run_tests(test_cases) + + def test_mixed_brackets(self): + tests_cases = ( + ("[0,{0},0],0,{0:0},0", ["[0,{0},0]", "0", "{0:0}", "0"]), + ("([0],0,0),0,(0,0),0", ["([0],0,0)", "0", "(0,0)", "0"]), + ("([(0,),(0,)],0),0", ["([(0,),(0,)],0)", "0"]), + ) + self._run_tests(tests_cases) + + def test_string_contents_ignored(self): + test_cases = ( + ("'0,0',0,',',0", ["'0,0'", "0", "','", "0"]), + ("0,[']',0],0", ["0", "[']',0]", "0"]), + ("{0,0,'}}',0,'{'},0", ["{0,0,'}}',0,'{'}", "0"]), + ) + self._run_tests(test_cases) + + def test_mixed_quotes(self): + test_cases = ( + ("\"0',0',\",'0,0',0", ["\"0',0',\"", "'0,0'", "0"]), + ("\",',\",'\",',0", ["\",',\"", "'\",'", "0"]), + ) + self._run_tests(test_cases) + + def test_real_signatures(self): + test_cases = ( + ("start, stop[, step]", ["start", " stop[, step]"]), + ("object=b'', encoding='utf-8', errors='strict'", ["object=b''", " encoding='utf-8'", " errors='strict'"]), + ( + "typename, field_names, *, rename=False, defaults=None, module=None", + ["typename", " field_names", " *", " rename=False", " defaults=None", " module=None"] + ), + ) + self._run_tests(test_cases) + + def _run_tests(self, test_cases): + for input_string, expected_output in test_cases: + with self.subTest(input_string=input_string): + self.assertEqual(list(parsing._split_parameters(input_string)), expected_output) -- cgit v1.2.3 From 47ed2339e55eb2a0bc245b45c1f0df9cc8b9af36 Mon Sep 17 00:00:00 2001 From: swfarnsworth Date: Thu, 25 Feb 2021 00:53:12 -0500 Subject: Instructions to dispute an infraction vary by infraction type. Previously, the user was instructed to email the appeals email for infraction types that don't remove one from the server. They are now instructed to DM ModMail except for Ban-type infractions. Also removed the URL string literal from the hyperlink to that URL. --- bot/exts/moderation/infraction/_utils.py | 44 +++++++++++----------- tests/bot/exts/moderation/infraction/test_utils.py | 6 +-- 2 files changed, 26 insertions(+), 24 deletions(-) (limited to 'tests') diff --git a/bot/exts/moderation/infraction/_utils.py b/bot/exts/moderation/infraction/_utils.py index e766c1e5c..e58c2b22f 100644 --- a/bot/exts/moderation/infraction/_utils.py +++ b/bot/exts/moderation/infraction/_utils.py @@ -22,7 +22,6 @@ INFRACTION_ICONS = { "voice_ban": (Icons.voice_state_red, Icons.voice_state_green), } RULES_URL = "https://pythondiscord.com/pages/rules" -APPEALABLE_INFRACTIONS = ("ban", "mute", "voice_ban") # Type aliases UserObject = t.Union[discord.Member, discord.User] @@ -31,8 +30,10 @@ Infraction = t.Dict[str, t.Union[str, int, bool]] APPEAL_EMAIL = "appeals@pythondiscord.com" -INFRACTION_TITLE = f"Please review our rules over at {RULES_URL}" -INFRACTION_APPEAL_FOOTER = f"To appeal this infraction, send an e-mail to {APPEAL_EMAIL}" +INFRACTION_TITLE = "Please review our rules" +INFRACTION_APPEAL_EMAIL_FOOTER = f"To appeal this infraction, send an e-mail to {APPEAL_EMAIL}" +INFRACTION_APPEAL_MODMAIL_FOOTER = ('If you would like to discuss or appeal this infraction, ' + 'send a message to the ModMail bot') INFRACTION_AUTHOR_NAME = "Infraction information" INFRACTION_DESCRIPTION_TEMPLATE = ( @@ -71,13 +72,13 @@ async def post_user(ctx: Context, user: UserSnowflake) -> t.Optional[dict]: async def post_infraction( - ctx: Context, - user: UserSnowflake, - infr_type: str, - reason: str, - expires_at: datetime = None, - hidden: bool = False, - active: bool = True + ctx: Context, + user: UserSnowflake, + infr_type: str, + reason: str, + expires_at: datetime = None, + hidden: bool = False, + active: bool = True ) -> t.Optional[dict]: """Posts an infraction to the API.""" if isinstance(user, (discord.Member, discord.User)) and user.bot: @@ -150,11 +151,11 @@ async def get_active_infraction( async def notify_infraction( - user: UserObject, - infr_type: str, - expires_at: t.Optional[str] = None, - reason: t.Optional[str] = None, - icon_url: str = Icons.token_removed + user: UserObject, + infr_type: str, + expires_at: t.Optional[str] = None, + reason: t.Optional[str] = None, + icon_url: str = Icons.token_removed ) -> bool: """DM a user about their new infraction and return True if the DM is successful.""" log.trace(f"Sending {user} a DM about their {infr_type} infraction.") @@ -178,17 +179,18 @@ async def notify_infraction( embed.title = INFRACTION_TITLE embed.url = RULES_URL - if infr_type in APPEALABLE_INFRACTIONS: - embed.set_footer(text=INFRACTION_APPEAL_FOOTER) + embed.set_footer( + text=INFRACTION_APPEAL_EMAIL_FOOTER if infr_type == 'Ban' else INFRACTION_APPEAL_MODMAIL_FOOTER + ) return await send_private_embed(user, embed) async def notify_pardon( - user: UserObject, - title: str, - content: str, - icon_url: str = Icons.user_verified + user: UserObject, + title: str, + content: str, + icon_url: str = Icons.user_verified ) -> bool: """DM a user about their pardoned infraction and return True if the DM is successful.""" log.trace(f"Sending {user} a DM about their pardoned infraction.") diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index 5b62463e0..ef6127344 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -146,7 +146,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.token_removed - ).set_footer(text=utils.INFRACTION_APPEAL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), "send_result": True }, { @@ -200,7 +200,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.defcon_denied - ).set_footer(text=utils.INFRACTION_APPEAL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), "send_result": False }, { @@ -218,7 +218,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.defcon_denied - ).set_footer(text=utils.INFRACTION_APPEAL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), "send_result": True } ] -- cgit v1.2.3 From 75f2b9d5e922db8aca2c873c214455fded02fc4d Mon Sep 17 00:00:00 2001 From: swfarnsworth Date: Sun, 28 Feb 2021 11:33:26 -0500 Subject: Update the tests to reflect changes in expected behavior. The DM sent to infracted users now instructs them to DM modmail if they want to discuss non-ban infractions, so the tests now check if that instruction is present. Note that there already exists a superfluous test for note infractions, for which no DM is sent by design. --- tests/bot/exts/moderation/infraction/test_utils.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index ef6127344..ee9ff650c 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -146,7 +146,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.token_removed - ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_MODMAIL_FOOTER), "send_result": True }, { @@ -164,9 +164,11 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.token_removed - ), + ).set_footer(text=utils.INFRACTION_APPEAL_MODMAIL_FOOTER), "send_result": False }, + # Note that this test case asserts that the DM that *would* get sent to the user is formatted + # correctly, even though that message is deliberately never sent. { "args": (self.user, "note", None, None, Icons.defcon_denied), "expected_output": Embed( @@ -182,7 +184,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.defcon_denied - ), + ).set_footer(text=utils.INFRACTION_APPEAL_MODMAIL_FOOTER), "send_result": False }, { @@ -200,7 +202,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.defcon_denied - ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_MODMAIL_FOOTER), "send_result": False }, { @@ -218,7 +220,7 @@ class ModerationUtilsTests(unittest.IsolatedAsyncioTestCase): name=utils.INFRACTION_AUTHOR_NAME, url=utils.RULES_URL, icon_url=Icons.defcon_denied - ).set_footer(text=utils.INFRACTION_APPEAL_EMAIL_FOOTER), + ).set_footer(text=utils.INFRACTION_APPEAL_MODMAIL_FOOTER), "send_result": True } ] -- cgit v1.2.3 From 74cbe44625a1e6e2e39f77b2663794d3ab5aaf58 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Fri, 5 Mar 2021 18:22:46 +0100 Subject: Correct tests cases The tests were not adjusted after the converter was corrected to accept digits --- tests/bot/test_converters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/test_converters.py b/tests/bot/test_converters.py index 231798a92..4af84dde5 100644 --- a/tests/bot/test_converters.py +++ b/tests/bot/test_converters.py @@ -80,7 +80,7 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase): async def test_package_name_for_valid(self): """PackageName returns valid package names unchanged.""" - test_values = ('foo', 'le_mon') + test_values = ('foo', 'le_mon', 'num83r') for name in test_values: with self.subTest(identifier=name): @@ -89,7 +89,7 @@ class ConverterTests(unittest.IsolatedAsyncioTestCase): async def test_package_name_for_invalid(self): """PackageName raises the proper exception for invalid package names.""" - test_values = ('text_with_a_dot.', 'UpperCaseName', "num83r") + test_values = ('text_with_a_dot.', 'UpperCaseName', 'dashed-name') for name in test_values: with self.subTest(identifier=name): -- cgit v1.2.3 From dc7eef432189aaaf0ea8b0d16588852306104957 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Sun, 7 Mar 2021 05:18:02 +0100 Subject: Handle arbitrary amount of backslashes preceding the quote char Tests for this were added additionally --- bot/exts/info/doc/_parsing.py | 19 ++++++++----------- tests/bot/exts/info/doc/test_parsing.py | 7 +++++++ 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/bot/exts/info/doc/_parsing.py b/bot/exts/info/doc/_parsing.py index fc38ff82a..57c991ae0 100644 --- a/bot/exts/info/doc/_parsing.py +++ b/bot/exts/info/doc/_parsing.py @@ -46,15 +46,6 @@ _BRACKET_PAIRS = { } -def _is_closing_quote(search_string: str, index: int) -> bool: - """Check whether the quote at `index` inside `search_string` can be a closing quote.""" - if search_string[index - 1] != "\\": - return True # The quote is not escaped. - elif search_string[index - 2] == "\\": - return True - return False - - def _split_parameters(parameters_string: str) -> Iterator[str]: """ Split parameters of a signature into individual parameter strings on commas. @@ -70,9 +61,15 @@ def _split_parameters(parameters_string: str) -> Iterator[str]: if character in {"'", '"'}: # Skip everything inside of strings, regardless of the depth. quote_character = character # The closing quote must equal the opening quote. - for index, character in enumerated_string: - if character == quote_character and _is_closing_quote(parameters_string, index): + preceding_backslashes = 0 + for _, character in enumerated_string: + # If an odd number of backslashes precedes the quote, it was escaped. + if character == quote_character and not preceding_backslashes % 2: break + if character == "\\": + preceding_backslashes += 1 + else: + preceding_backslashes = 0 elif current_search is None: if (current_search := _BRACKET_PAIRS.get(character)) is not None: diff --git a/tests/bot/exts/info/doc/test_parsing.py b/tests/bot/exts/info/doc/test_parsing.py index f302b38fc..1663d8491 100644 --- a/tests/bot/exts/info/doc/test_parsing.py +++ b/tests/bot/exts/info/doc/test_parsing.py @@ -42,6 +42,13 @@ class SignatureSplitter(TestCase): ) self._run_tests(test_cases) + def test_quote_escaped(self): + test_cases = ( + (r"'\',','\\',0", [r"'\','", r"'\\'", "0"]), + (r"'0\',0\\\'\\',0", [r"'0\',0\\\'\\'", "0"]), + ) + self._run_tests(test_cases) + def test_real_signatures(self): test_cases = ( ("start, stop[, step]", ["start", " stop[, step]"]), -- cgit v1.2.3 From f76e47bf9b1d9956a36d891e3aa64593c65568c8 Mon Sep 17 00:00:00 2001 From: xithrius Date: Mon, 8 Mar 2021 03:35:54 -0800 Subject: Fixed unittest for purge infraction. --- tests/bot/exts/moderation/infraction/test_infractions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py index 86c2617ea..08f39cd50 100644 --- a/tests/bot/exts/moderation/infraction/test_infractions.py +++ b/tests/bot/exts/moderation/infraction/test_infractions.py @@ -39,7 +39,7 @@ class TruncationTests(unittest.IsolatedAsyncioTestCase): delete_message_days=0 ) self.cog.apply_infraction.assert_awaited_once_with( - self.ctx, {"foo": "bar"}, self.target, self.ctx.guild.ban.return_value + self.ctx, {"foo": "bar", "purge": ""}, self.target, self.ctx.guild.ban.return_value ) @patch("bot.exts.moderation.infraction._utils.post_infraction") -- cgit v1.2.3 From 2759409123d458a4a0a274b835bebb3cc728b83a Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 27 Mar 2021 13:49:22 -0400 Subject: Fix tests for paste uploads. Accounts for no redirects on extensions that are not `.py`. --- tests/bot/utils/test_services.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/utils/test_services.py b/tests/bot/utils/test_services.py index 1b48f6560..3b71022db 100644 --- a/tests/bot/utils/test_services.py +++ b/tests/bot/utils/test_services.py @@ -30,9 +30,9 @@ class PasteTests(unittest.IsolatedAsyncioTestCase): """Url with specified extension is returned on successful requests.""" key = "paste_key" test_cases = ( - (f"https://paste_service.com/{key}.txt", "txt"), + (f"https://paste_service.com/{key}.txt?noredirect", "txt"), (f"https://paste_service.com/{key}.py", "py"), - (f"https://paste_service.com/{key}", ""), + (f"https://paste_service.com/{key}?noredirect", ""), ) response = MagicMock( json=AsyncMock(return_value={"key": key}) -- cgit v1.2.3 From 61ab2cd4d434def0743e767acdb3f816c20e4dce Mon Sep 17 00:00:00 2001 From: Ben Soyka Date: Sun, 4 Apr 2021 22:35:53 -0600 Subject: Update information tests for new embed color logic --- tests/bot/exts/info/test_information.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index 80731c9f0..b1b7d37ae 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -283,6 +283,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): user = helpers.MockMember() user.nick = None user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") + user.colour = 0 embed = await self.cog.create_user_embed(ctx, user) @@ -298,6 +299,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): user = helpers.MockMember() user.nick = "Cat lover" user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") + user.colour = 0 embed = await self.cog.create_user_embed(ctx, user) @@ -314,7 +316,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): admins_role.colour = 100 # A `MockMember` has the @Everyone role by default; we add the Admins to that. - user = helpers.MockMember(roles=[admins_role], top_role=admins_role) + user = helpers.MockMember(roles=[admins_role], top_role=admins_role, colour=100) embed = await self.cog.create_user_embed(ctx, user) @@ -337,7 +339,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): infraction_counts.return_value = ("Infractions", "expanded infractions info") nomination_counts.return_value = ("Nominations", "nomination info") - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role) + user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) embed = await self.cog.create_user_embed(ctx, user) infraction_counts.assert_called_once_with(user) @@ -371,7 +373,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): infraction_counts.return_value = ("Infractions", "basic infractions info") - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role) + user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) embed = await self.cog.create_user_embed(ctx, user) infraction_counts.assert_called_once_with(user) @@ -409,7 +411,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): moderators_role = helpers.MockRole(name='Moderators') moderators_role.colour = 100 - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role) + user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) embed = await self.cog.create_user_embed(ctx, user) self.assertEqual(embed.colour, discord.Colour(moderators_role.colour)) @@ -422,7 +424,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should be created with a blurple colour if the user has no assigned roles.""" ctx = helpers.MockContext() - user = helpers.MockMember(id=217) + user = helpers.MockMember(id=217, colour=discord.Colour.blurple()) embed = await self.cog.create_user_embed(ctx, user) self.assertEqual(embed.colour, discord.Colour.blurple()) @@ -435,7 +437,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed thumbnail should be set to the user's avatar in `png` format.""" ctx = helpers.MockContext() - user = helpers.MockMember(id=217) + user = helpers.MockMember(id=217, colour=0) user.avatar_url_as.return_value = "avatar url" embed = await self.cog.create_user_embed(ctx, user) -- cgit v1.2.3 From 835a0a6f4a45018d21dacbfbf69afe07361155aa Mon Sep 17 00:00:00 2001 From: Ben Soyka Date: Mon, 5 Apr 2021 08:56:22 -0600 Subject: Minor test changes for the !user embed --- tests/bot/exts/info/test_information.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index b1b7d37ae..a996ce477 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -313,10 +313,9 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """Created `!user` embeds should not contain mention of the @everyone-role.""" ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1)) admins_role = helpers.MockRole(name='Admins') - admins_role.colour = 100 # A `MockMember` has the @Everyone role by default; we add the Admins to that. - user = helpers.MockMember(roles=[admins_role], top_role=admins_role, colour=100) + user = helpers.MockMember(roles=[admins_role], colour=100) embed = await self.cog.create_user_embed(ctx, user) @@ -334,12 +333,11 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=50)) moderators_role = helpers.MockRole(name='Moderators') - moderators_role.colour = 100 infraction_counts.return_value = ("Infractions", "expanded infractions info") nomination_counts.return_value = ("Nominations", "nomination info") - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) + user = helpers.MockMember(id=314, roles=[moderators_role], colour=100) embed = await self.cog.create_user_embed(ctx, user) infraction_counts.assert_called_once_with(user) @@ -369,11 +367,10 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=100)) moderators_role = helpers.MockRole(name='Moderators') - moderators_role.colour = 100 infraction_counts.return_value = ("Infractions", "basic infractions info") - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) + user = helpers.MockMember(id=314, roles=[moderators_role], colour=100) embed = await self.cog.create_user_embed(ctx, user) infraction_counts.assert_called_once_with(user) @@ -409,12 +406,11 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): ctx = helpers.MockContext() moderators_role = helpers.MockRole(name='Moderators') - moderators_role.colour = 100 - user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role, colour=100) + user = helpers.MockMember(id=314, roles=[moderators_role], colour=100) embed = await self.cog.create_user_embed(ctx, user) - self.assertEqual(embed.colour, discord.Colour(moderators_role.colour)) + self.assertEqual(embed.colour, discord.Colour(100)) @unittest.mock.patch( f"{COG_PATH}.basic_user_infraction_counts", @@ -424,7 +420,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should be created with a blurple colour if the user has no assigned roles.""" ctx = helpers.MockContext() - user = helpers.MockMember(id=217, colour=discord.Colour.blurple()) + user = helpers.MockMember(id=217, colour=discord.Colour.default()) embed = await self.cog.create_user_embed(ctx, user) self.assertEqual(embed.colour, discord.Colour.blurple()) -- cgit v1.2.3 From 93c9e536a3e771db2ac03054a5c2470883d59f1f Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sat, 17 Apr 2021 18:52:19 +0200 Subject: Tests: members shouldn't have any public flags --- tests/bot/exts/info/test_information.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index a996ce477..d2ecee033 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -281,9 +281,13 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should use the string representation of the user if they don't have a nick.""" ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1)) user = helpers.MockMember() + public_flags = unittest.mock.MagicMock() + public_flags.__iter__.return_value = iter(()) + public_flags.verified_bot = False user.nick = None user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") user.colour = 0 + user.public_flags = public_flags embed = await self.cog.create_user_embed(ctx, user) @@ -297,9 +301,13 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should use the nick if it's available.""" ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1)) user = helpers.MockMember() + public_flags = unittest.mock.MagicMock() + public_flags.__iter__.return_value = iter(()) + public_flags.verified_bot = False user.nick = "Cat lover" user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") user.colour = 0 + user.public_flags = public_flags embed = await self.cog.create_user_embed(ctx, user) -- cgit v1.2.3 From 9aa2b42aa04724a4ebc74d3ff6c339c33547dce3 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Tue, 20 Apr 2021 17:20:44 +0200 Subject: Tests: AsyncMock is now in the standard library! The `tests/README.md` file still referenced our old custom `AsyncMock` that has been removed in favour of the standard library one that has been introduced in 3.8. This commit fixes this by updating the section. --- tests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/README.md b/tests/README.md index 4f62edd68..092324123 100644 --- a/tests/README.md +++ b/tests/README.md @@ -114,7 +114,7 @@ class BotCogTests(unittest.TestCase): ### Mocking coroutines -By default, the `unittest.mock.Mock` and `unittest.mock.MagicMock` classes cannot mock coroutines, since the `__call__` method they provide is synchronous. In anticipation of the `AsyncMock` that will be [introduced in Python 3.8](https://docs.python.org/3.9/whatsnew/3.8.html#unittest), we have added an `AsyncMock` helper to [`helpers.py`](/tests/helpers.py). Do note that this drop-in replacement only implements an asynchronous `__call__` method, not the additional assertions that will come with the new `AsyncMock` type in Python 3.8. +By default, the `unittest.mock.Mock` and `unittest.mock.MagicMock` classes cannot mock coroutines, since the `__call__` method they provide is synchronous. The [`AsyncMock`](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.AsyncMock) that has been [introduced in Python 3.8](https://docs.python.org/3.9/whatsnew/3.8.html#unittest) is an asynchronous version of `MagicMock` that can be used anywhere a coroutine is expected. ### Special mocks for some `discord.py` types -- cgit v1.2.3 From 1fdd5aabd4ef5e356f358fdb6e9b26a5b5da99ce Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sat, 24 Apr 2021 17:04:48 +0200 Subject: Tests: simplify public flags handling Co_authored-by: Numerlor <25886452+Numerlor@users.noreply.github.com> --- tests/bot/exts/info/test_information.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index d2ecee033..770660fe3 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -281,13 +281,10 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should use the string representation of the user if they don't have a nick.""" ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1)) user = helpers.MockMember() - public_flags = unittest.mock.MagicMock() - public_flags.__iter__.return_value = iter(()) - public_flags.verified_bot = False + user.public_flags = unittest.mock.MagicMock(verified_bot=False) user.nick = None user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") user.colour = 0 - user.public_flags = public_flags embed = await self.cog.create_user_embed(ctx, user) @@ -301,13 +298,10 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): """The embed should use the nick if it's available.""" ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1)) user = helpers.MockMember() - public_flags = unittest.mock.MagicMock() - public_flags.__iter__.return_value = iter(()) - public_flags.verified_bot = False + user.public_flags = unittest.mock.MagicMock(verified_bot=False) user.nick = "Cat lover" user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock") user.colour = 0 - user.public_flags = public_flags embed = await self.cog.create_user_embed(ctx, user) -- cgit v1.2.3