From fb419bc8f0525e8296abc5017a0d316adb22d4c4 Mon Sep 17 00:00:00 2001 From: wookie184 Date: Thu, 4 Aug 2022 17:32:12 +0100 Subject: Fix tests --- .../exts/moderation/infraction/test_infractions.py | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py index 052048053..9636f0146 100644 --- a/tests/bot/exts/moderation/infraction/test_infractions.py +++ b/tests/bot/exts/moderation/infraction/test_infractions.py @@ -35,17 +35,20 @@ class TruncationTests(unittest.IsolatedAsyncioTestCase): self.cog.apply_infraction = AsyncMock() self.bot.get_cog.return_value = AsyncMock() self.cog.mod_log.ignore = Mock() - self.ctx.guild.ban = Mock() + self.ctx.guild.ban = AsyncMock() await self.cog.apply_ban(self.ctx, self.target, "foo bar" * 3000) - self.ctx.guild.ban.assert_called_once_with( + self.cog.apply_infraction.assert_awaited_once_with( + self.ctx, {"foo": "bar", "purge": ""}, self.target, ANY + ) + + action = self.cog.apply_infraction.call_args.args[-1] + await action() + self.ctx.guild.ban.assert_awaited_once_with( self.target, reason=textwrap.shorten("foo bar" * 3000, 512, placeholder="..."), delete_message_days=0 ) - self.cog.apply_infraction.assert_awaited_once_with( - self.ctx, {"foo": "bar", "purge": ""}, self.target, self.ctx.guild.ban.return_value - ) @patch("bot.exts.moderation.infraction._utils.post_infraction") async def test_apply_kick_reason_truncation(self, post_infraction_mock): @@ -54,14 +57,17 @@ class TruncationTests(unittest.IsolatedAsyncioTestCase): self.cog.apply_infraction = AsyncMock() self.cog.mod_log.ignore = Mock() - self.target.kick = Mock() + self.target.kick = AsyncMock() await self.cog.apply_kick(self.ctx, self.target, "foo bar" * 3000) - self.target.kick.assert_called_once_with(reason=textwrap.shorten("foo bar" * 3000, 512, placeholder="...")) self.cog.apply_infraction.assert_awaited_once_with( - self.ctx, {"foo": "bar"}, self.target, self.target.kick.return_value + self.ctx, {"foo": "bar"}, self.target, ANY ) + action = self.cog.apply_infraction.call_args.args[-1] + await action() + self.target.kick.assert_awaited_once_with(reason=textwrap.shorten("foo bar" * 3000, 512, placeholder="...")) + @patch("bot.exts.moderation.infraction.infractions.constants.Roles.voice_verified", new=123456) class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): @@ -141,8 +147,8 @@ class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): async def action_tester(self, action, reason: str) -> None: """Helper method to test voice mute action.""" - self.assertTrue(inspect.iscoroutine(action)) - await action + self.assertTrue(inspect.iscoroutinefunction(action)) + await action() self.user.move_to.assert_called_once_with(None, reason=ANY) self.user.remove_roles.assert_called_once_with(self.cog._voice_verified_role, reason=reason) @@ -194,8 +200,8 @@ class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): # Test action action = self.cog.apply_infraction.call_args[0][-1] - self.assertTrue(inspect.iscoroutine(action)) - await action + self.assertTrue(inspect.iscoroutinefunction(action)) + await action() async def test_voice_unmute_user_not_found(self): """Should include info to return dict when user was not found from guild.""" -- cgit v1.2.3 From 0e6242f7f4c41329e9270724a9780511f7165240 Mon Sep 17 00:00:00 2001 From: ionite34 Date: Thu, 28 Jul 2022 04:54:26 -0400 Subject: Updated tests - Refactored tests for new time duration arguments --- .../exts/moderation/infraction/test_infractions.py | 11 ++++---- tests/bot/exts/moderation/infraction/test_utils.py | 29 +++++++++++++--------- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py index 052048053..a18a4d23b 100644 --- a/tests/bot/exts/moderation/infraction/test_infractions.py +++ b/tests/bot/exts/moderation/infraction/test_infractions.py @@ -79,13 +79,13 @@ class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): """Should call voice mute applying function without expiry.""" self.cog.apply_voice_mute = AsyncMock() self.assertIsNone(await self.cog.voicemute(self.cog, self.ctx, self.user, reason="foobar")) - self.cog.apply_voice_mute.assert_awaited_once_with(self.ctx, self.user, "foobar", expires_at=None) + self.cog.apply_voice_mute.assert_awaited_once_with(self.ctx, self.user, "foobar", duration_or_expiry=None) async def test_temporary_voice_mute(self): """Should call voice mute applying function with expiry.""" self.cog.apply_voice_mute = AsyncMock() self.assertIsNone(await self.cog.tempvoicemute(self.cog, self.ctx, self.user, "baz", reason="foobar")) - self.cog.apply_voice_mute.assert_awaited_once_with(self.ctx, self.user, "foobar", expires_at="baz") + self.cog.apply_voice_mute.assert_awaited_once_with(self.ctx, self.user, "foobar", duration_or_expiry="baz") async def test_voice_unmute(self): """Should call infraction pardoning function.""" @@ -189,7 +189,8 @@ class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): user = MockUser() await self.cog.voicemute(self.cog, self.ctx, user, reason=None) - post_infraction_mock.assert_called_once_with(self.ctx, user, "voice_mute", None, active=True, expires_at=None) + post_infraction_mock.assert_called_once_with(self.ctx, user, "voice_mute", None, active=True, + duration_or_expiry=None) apply_infraction_mock.assert_called_once_with(self.cog, self.ctx, infraction, user, ANY) # Test action @@ -273,7 +274,7 @@ class CleanBanTests(unittest.IsolatedAsyncioTestCase): self.user, "FooBar", purge_days=1, - expires_at=None, + duration_or_expiry=None, ) async def test_cleanban_doesnt_purge_messages_if_clean_cog_available(self): @@ -285,7 +286,7 @@ class CleanBanTests(unittest.IsolatedAsyncioTestCase): self.ctx, self.user, "FooBar", - expires_at=None, + duration_or_expiry=None, ) @patch("bot.exts.moderation.infraction.infractions.Age") diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index 5cf02033d..4c78c0bd8 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -318,14 +318,17 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "user": self.member.id, "active": False, "expires_at": now.isoformat(), - "dm_sent": False + "dm_sent": False, + "last_applied": datetime(2020, 1, 1).isoformat(), } - self.ctx.bot.api_client.post.return_value = "foo" - actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) + # Patch the time.now(tz=timezone.utc) function to return a specific time + with patch("bot.exts.moderation.infraction._utils.datetime.now", return_value=datetime(2020, 1, 1)): + self.ctx.bot.api_client.post.return_value = "foo" + actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) - self.assertEqual(actual, "foo") - self.ctx.bot.api_client.post.assert_awaited_once_with("bot/infractions", json=payload) + self.assertEqual(actual, "foo") + self.ctx.bot.api_client.post.assert_awaited_once_with("bot/infractions", json=payload) async def test_unknown_error_post_infraction(self): """Should send an error message to chat when a non-400 error occurs.""" @@ -356,12 +359,14 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "type": "mute", "user": self.user.id, "active": True, - "dm_sent": False + "dm_sent": False, + "last_applied": datetime(2020, 1, 1), } - self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] - - actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason") - self.assertEqual(actual, "foo") - self.bot.api_client.post.assert_has_awaits([call("bot/infractions", json=payload)] * 2) - post_user_mock.assert_awaited_once_with(self.ctx, self.user) + # Patch the time.now(tz=timezone.utc) function to return a specific time + with patch("bot.exts.moderation.infraction._utils.datetime.now", return_value=datetime(2020, 1, 1)): + self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] + actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason") + self.assertEqual(actual, "foo") + self.bot.api_client.post.assert_has_awaits([call("bot/infractions", json=payload)] * 2) + post_user_mock.assert_awaited_once_with(self.ctx, self.user) -- cgit v1.2.3 From 035b5accf78f8623b40e0612e3c057f0ef2b93a7 Mon Sep 17 00:00:00 2001 From: ionite34 Date: Thu, 28 Jul 2022 05:04:38 -0400 Subject: Fixed test patches --- tests/bot/exts/moderation/infraction/test_utils.py | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 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 4c78c0bd8..def06932b 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -307,7 +307,8 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): self.user = MockUser(id=1234) self.ctx = MockContext(bot=self.bot, author=self.member) - async def test_normal_post_infraction(self): + @patch("bot.exts.moderation.infraction._utils.datetime", wraps=datetime) + async def test_normal_post_infraction(self, mock_datetime): """Should return response from POST request if there are no errors.""" now = datetime.now() payload = { @@ -322,13 +323,13 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "last_applied": datetime(2020, 1, 1).isoformat(), } - # Patch the time.now(tz=timezone.utc) function to return a specific time - with patch("bot.exts.moderation.infraction._utils.datetime.now", return_value=datetime(2020, 1, 1)): - self.ctx.bot.api_client.post.return_value = "foo" - actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) + # Patch the datetime.now function to return a specific time + mock_datetime.now.return_value = datetime(2020, 1, 1) + self.ctx.bot.api_client.post.return_value = "foo" + actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) - self.assertEqual(actual, "foo") - self.ctx.bot.api_client.post.assert_awaited_once_with("bot/infractions", json=payload) + self.assertEqual(actual, "foo") + self.ctx.bot.api_client.post.assert_awaited_once_with("bot/infractions", json=payload) async def test_unknown_error_post_infraction(self): """Should send an error message to chat when a non-400 error occurs.""" @@ -349,8 +350,9 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): self.assertIsNone(actual) post_user_mock.assert_awaited_once_with(self.ctx, self.user) + @patch("bot.exts.moderation.infraction._utils.datetime", wraps=datetime) @patch("bot.exts.moderation.infraction._utils.post_user", return_value="bar") - async def test_first_fail_second_success_user_post_infraction(self, post_user_mock): + async def test_first_fail_second_success_user_post_infraction(self, post_user_mock, mock_datetime): """Should post the user if they don't exist, POST infraction again, and return the response if successful.""" payload = { "actor": self.ctx.author.id, @@ -363,10 +365,10 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "last_applied": datetime(2020, 1, 1), } - # Patch the time.now(tz=timezone.utc) function to return a specific time - with patch("bot.exts.moderation.infraction._utils.datetime.now", return_value=datetime(2020, 1, 1)): - self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] - actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason") - self.assertEqual(actual, "foo") - self.bot.api_client.post.assert_has_awaits([call("bot/infractions", json=payload)] * 2) - post_user_mock.assert_awaited_once_with(self.ctx, self.user) + # Patch the datetime.now function to return a specific time + mock_datetime.now.return_value = datetime(2020, 1, 1) + self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] + actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason") + self.assertEqual(actual, "foo") + self.bot.api_client.post.assert_has_awaits([call("bot/infractions", json=payload)] * 2) + post_user_mock.assert_awaited_once_with(self.ctx, self.user) -- cgit v1.2.3 From 8db7ef5df087e43804d07dabe2037af18adcb0d6 Mon Sep 17 00:00:00 2001 From: ionite34 Date: Thu, 28 Jul 2022 05:19:30 -0400 Subject: Added isoformat for test payload --- tests/bot/exts/moderation/infraction/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index def06932b..d3a908b28 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -362,7 +362,7 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "user": self.user.id, "active": True, "dm_sent": False, - "last_applied": datetime(2020, 1, 1), + "last_applied": datetime(2020, 1, 1).isoformat(), } # Patch the datetime.now function to return a specific time -- cgit v1.2.3 From 3280ac48a9031b727bdde69909729093593bd967 Mon Sep 17 00:00:00 2001 From: ionite34 Date: Thu, 28 Jul 2022 06:11:11 -0400 Subject: Fixed tests - Corrected datetime patching --- tests/bot/exts/moderation/infraction/test_utils.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 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 d3a908b28..b1f23e31c 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -307,8 +307,7 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): self.user = MockUser(id=1234) self.ctx = MockContext(bot=self.bot, author=self.member) - @patch("bot.exts.moderation.infraction._utils.datetime", wraps=datetime) - async def test_normal_post_infraction(self, mock_datetime): + async def test_normal_post_infraction(self): """Should return response from POST request if there are no errors.""" now = datetime.now() payload = { @@ -320,16 +319,18 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "active": False, "expires_at": now.isoformat(), "dm_sent": False, - "last_applied": datetime(2020, 1, 1).isoformat(), } - # Patch the datetime.now function to return a specific time - mock_datetime.now.return_value = datetime(2020, 1, 1) self.ctx.bot.api_client.post.return_value = "foo" actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) self.assertEqual(actual, "foo") - self.ctx.bot.api_client.post.assert_awaited_once_with("bot/infractions", json=payload) + self.ctx.bot.api_client.post.assert_awaited_once() + await_args = str(self.ctx.bot.api_client.post.await_args) + # Check existing keys present, allow for additional keys (e.g. `last_applied`) + for key, value in payload.items(): + self.assertTrue(key in await_args) + self.assertTrue(str(value) in await_args) async def test_unknown_error_post_infraction(self): """Should send an error message to chat when a non-400 error occurs.""" -- cgit v1.2.3 From e74ff62122935da349d38a8c06eef14d1e3ba9aa Mon Sep 17 00:00:00 2001 From: ionite34 Date: Sat, 6 Aug 2022 13:47:49 -0400 Subject: Refactored test to not use datetime patch - Used new method of dict subset comparison instead of datetime patching for better compat. with argument types --- tests/bot/exts/moderation/infraction/test_utils.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 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 b1f23e31c..5ba0f4273 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -1,7 +1,7 @@ import unittest from collections import namedtuple from datetime import datetime -from unittest.mock import AsyncMock, MagicMock, call, patch +from unittest.mock import AsyncMock, MagicMock, patch from botcore.site_api import ResponseCodeError from discord import Embed, Forbidden, HTTPException, NotFound @@ -351,11 +351,10 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): self.assertIsNone(actual) post_user_mock.assert_awaited_once_with(self.ctx, self.user) - @patch("bot.exts.moderation.infraction._utils.datetime", wraps=datetime) @patch("bot.exts.moderation.infraction._utils.post_user", return_value="bar") - async def test_first_fail_second_success_user_post_infraction(self, post_user_mock, mock_datetime): + async def test_first_fail_second_success_user_post_infraction(self, post_user_mock): """Should post the user if they don't exist, POST infraction again, and return the response if successful.""" - payload = { + expected = { "actor": self.ctx.author.id, "hidden": False, "reason": "Test reason", @@ -363,13 +362,17 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): "user": self.user.id, "active": True, "dm_sent": False, - "last_applied": datetime(2020, 1, 1).isoformat(), } - # Patch the datetime.now function to return a specific time - mock_datetime.now.return_value = datetime(2020, 1, 1) self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "foo"}), "foo"] actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason") self.assertEqual(actual, "foo") - self.bot.api_client.post.assert_has_awaits([call("bot/infractions", json=payload)] * 2) + await_args = self.bot.api_client.post.await_args_list + self.assertEqual(len(await_args), 2, "Expected 2 awaits") + + # Since `last_applied` is based on current time, just check if expected is a subset of payload + for args in await_args: + payload: dict = args.kwargs["json"] + self.assertEqual(payload, payload | expected) + post_user_mock.assert_awaited_once_with(self.ctx, self.user) -- cgit v1.2.3 From d93afa3dbe16404a60e23acaf394affcda5aff89 Mon Sep 17 00:00:00 2001 From: ionite34 Date: Sat, 6 Aug 2022 13:57:51 -0400 Subject: Updated previous tests to use subset method --- tests/bot/exts/moderation/infraction/test_utils.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 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 5ba0f4273..6c9af2555 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -310,7 +310,7 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): async def test_normal_post_infraction(self): """Should return response from POST request if there are no errors.""" now = datetime.now() - payload = { + expected = { "actor": self.ctx.author.id, "hidden": True, "reason": "Test reason", @@ -323,14 +323,12 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): self.ctx.bot.api_client.post.return_value = "foo" actual = await utils.post_infraction(self.ctx, self.member, "ban", "Test reason", now, True, False) - self.assertEqual(actual, "foo") self.ctx.bot.api_client.post.assert_awaited_once() - await_args = str(self.ctx.bot.api_client.post.await_args) - # Check existing keys present, allow for additional keys (e.g. `last_applied`) - for key, value in payload.items(): - self.assertTrue(key in await_args) - self.assertTrue(str(value) in await_args) + + # Since `last_applied` is based on current time, just check if expected is a subset of payload + payload: dict = self.ctx.bot.api_client.post.await_args_list[0].kwargs["json"] + self.assertEqual(payload, payload | expected) async def test_unknown_error_post_infraction(self): """Should send an error message to chat when a non-400 error occurs.""" -- cgit v1.2.3 From 08a6bbc306d1ec54998b690eeeb258548e8e08fa Mon Sep 17 00:00:00 2001 From: ionite34 Date: Sat, 13 Aug 2022 15:45:52 -0400 Subject: Corrected test use of utcnow Corrected test case to use `datetime.utcnow()` to be consistent with target --- tests/bot/exts/moderation/infraction/test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/exts/moderation/infraction/test_utils.py b/tests/bot/exts/moderation/infraction/test_utils.py index 6c9af2555..29dadf372 100644 --- a/tests/bot/exts/moderation/infraction/test_utils.py +++ b/tests/bot/exts/moderation/infraction/test_utils.py @@ -309,7 +309,7 @@ class TestPostInfraction(unittest.IsolatedAsyncioTestCase): async def test_normal_post_infraction(self): """Should return response from POST request if there are no errors.""" - now = datetime.now() + now = datetime.utcnow() expected = { "actor": self.ctx.author.id, "hidden": True, -- cgit v1.2.3 From 9434646723e3ab38543576194f2b5fc0f2e680e0 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 17 Aug 2022 18:02:21 -0400 Subject: add: test for reasoned and reasonless pardons --- tests/bot/exts/moderation/infraction/test_infractions.py | 8 +++++++- 1 file changed, 7 insertions(+), 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 052048053..c9006588c 100644 --- a/tests/bot/exts/moderation/infraction/test_infractions.py +++ b/tests/bot/exts/moderation/infraction/test_infractions.py @@ -90,8 +90,14 @@ class VoiceMuteTests(unittest.IsolatedAsyncioTestCase): async def test_voice_unmute(self): """Should call infraction pardoning function.""" self.cog.pardon_infraction = AsyncMock() + self.assertIsNone(await self.cog.unvoicemute(self.cog, self.ctx, self.user, pardon_reason="foobar")) + self.cog.pardon_infraction.assert_awaited_once_with(self.ctx, "voice_mute", self.user, "foobar") + + async def test_voice_unmute_reasonless(self): + """Should call infraction pardoning function without a pardon reason.""" + self.cog.pardon_infraction = AsyncMock() self.assertIsNone(await self.cog.unvoicemute(self.cog, self.ctx, self.user)) - self.cog.pardon_infraction.assert_awaited_once_with(self.ctx, "voice_mute", self.user) + self.cog.pardon_infraction.assert_awaited_once_with(self.ctx, "voice_mute", self.user, None) @patch("bot.exts.moderation.infraction.infractions._utils.post_infraction") @patch("bot.exts.moderation.infraction.infractions._utils.get_active_infraction") -- cgit v1.2.3 From 74d2b2153e5f6e53f26c9386898868b2e87aa0fb Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Fri, 19 Aug 2022 15:10:13 +0100 Subject: fix "isistance" typo --- tests/test_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_helpers.py b/tests/test_helpers.py index f3040b305..b2686b1d0 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -14,7 +14,7 @@ class DiscordMocksTests(unittest.TestCase): """Test if the default initialization of MockRole results in the correct object.""" role = helpers.MockRole() - # The `spec` argument makes sure `isistance` checks with `discord.Role` pass + # The `spec` argument makes sure `isinstance` checks with `discord.Role` pass self.assertIsInstance(role, discord.Role) self.assertEqual(role.name, "role") -- cgit v1.2.3 From 8028690d4eae27e57dfe1429b8067eabaa94eef9 Mon Sep 17 00:00:00 2001 From: Aleksey Zasorin Date: Fri, 16 Sep 2022 10:42:16 -0700 Subject: Removed "redis_ready" from additional_spec_asyncs in MockBot (#2275) The attribute was removed from Bot in fc05849 --- tests/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/helpers.py b/tests/helpers.py index 687e15b96..a4b919dcb 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -317,7 +317,7 @@ class MockBot(CustomMockMixin, unittest.mock.MagicMock): guild_id=1, intents=discord.Intents.all(), ) - additional_spec_asyncs = ("wait_for", "redis_ready") + additional_spec_asyncs = ("wait_for",) def __init__(self, **kwargs) -> None: super().__init__(**kwargs) -- cgit v1.2.3 From 738f2ee0e8e321d01e867a1d3f963d6991e6f22a Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Mon, 19 Sep 2022 16:50:30 +0100 Subject: add test that checks for the sent content if one invalid index is present in the input --- tests/bot/exts/info/test_information.py | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index d896b7652..c14453bd8 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -2,6 +2,7 @@ import textwrap import unittest import unittest.mock from datetime import datetime +from textwrap import shorten import discord @@ -573,3 +574,48 @@ class UserCommandTests(unittest.IsolatedAsyncioTestCase): create_embed.assert_called_once_with(ctx, self.target, False) ctx.send.assert_called_once() + + +class RuleCommandTests(unittest.IsolatedAsyncioTestCase): + """Tests for the `!rule` command.""" + + def setUp(self) -> None: + """Set up steps executed before each test is run.""" + self.bot = helpers.MockBot() + self.cog = information.Information(self.bot) + self.ctx = helpers.MockContext(author=helpers.MockMember(id=1, name="Bellaluma")) + self.full_rules = [ + ( + "First rule", + ["first", "number_one"] + ), + ( + "Second rule", + ["second", "number_two"] + ), + ( + "Third rule", + ["third", "number_three"] + ) + ] + self.bot.api_client.get.return_value = self.full_rules + + async def test_return_none_if_one_rule_number_is_invalid(self): + + test_cases = [ + (('1', '6', '7', '8'), (6, 7, 8)), + (('10', "first"), (10, )), + (("first", 10), (10, )) + ] + + for raw_user_input, extracted_rule_numbers in test_cases: + invalid = ", ".join( + str(rule_number) for rule_number in extracted_rule_numbers + if rule_number < 1 or rule_number > len(self.full_rules)) + + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + + self.assertEqual( + self.ctx.send.call_args, + unittest.mock.call(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ..."))) + self.assertEqual(None, final_rule_numbers) -- cgit v1.2.3 From 45b27ed9ac6a1ca55547defd1922fafcc7ac1ab9 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Mon, 19 Sep 2022 17:32:47 +0100 Subject: test the cases where default rules message is supposed to be sent --- tests/bot/exts/info/test_information.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index c14453bd8..61e8895b9 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -619,3 +619,34 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): self.ctx.send.call_args, unittest.mock.call(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ..."))) self.assertEqual(None, final_rule_numbers) + + async def test_return_correct_rule_numberstest_return_correct_rule_numbers(self): + + test_cases = [ + (("1", "2", "first"), {1, 2}), + (("1", "hello", "2", "second"), {1}), + (("second", "third", "unknown", "999"), {2, 3}) + ] + + for raw_user_input, expected_matched_rule_numbers in test_cases: + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) + + async def test_return_default_rules_when_no_input_or_no_match_are_found(self): + test_cases = [ + ((), None), + (("hello", "2", "second"), None), + (("hello", "999"), None), + ] + + description = ( + "The rules and guidelines that apply to this community can be found on" + " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" + " all members of the community to have read and understood these." + ) + + for raw_user_input, expected_matched_rule_numbers in test_cases: + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + embed = self.ctx.send.call_args.kwargs['embed'] + self.assertEqual(description, embed.description) + self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) -- cgit v1.2.3 From 2e25073f807e02a72fe4cf2bbfa5cefe5024c8d7 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Mon, 19 Sep 2022 20:23:33 +0100 Subject: fix redundant test name --- tests/bot/exts/info/test_information.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index 61e8895b9..626c12c86 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -620,7 +620,7 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): unittest.mock.call(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ..."))) self.assertEqual(None, final_rule_numbers) - async def test_return_correct_rule_numberstest_return_correct_rule_numbers(self): + async def test_return_correct_rule_numbers(self): test_cases = [ (("1", "2", "first"), {1, 2}), -- cgit v1.2.3 From ae0c94b1d4dc676519301fe67a21425e5649effe Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Mon, 19 Sep 2022 22:57:54 +0100 Subject: add DEFAULT_RULES_DESCRIPTION to avoid duplication --- bot/constants.py | 6 ++++++ bot/exts/info/information.py | 8 ++------ tests/bot/exts/info/test_information.py | 9 ++------- 3 files changed, 10 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/bot/constants.py b/bot/constants.py index 68a96876f..b1d392822 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -774,3 +774,9 @@ ERROR_REPLIES = [ "Noooooo!!", "I can't believe you've done this", ] + +DEFAULT_RULES_DESCRIPTION = ( + "The rules and guidelines that apply to this community can be found on" + " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" + " all members of the community to have read and understood these." +) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index d4f0ce008..a4816450f 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -13,6 +13,7 @@ from discord.utils import escape_markdown from bot import constants from bot.bot import Bot +from bot.constants import DEFAULT_RULES_DESCRIPTION from bot.converters import MemberOrUser from bot.decorators import in_whitelist from bot.errors import NonExistentRoleError @@ -545,12 +546,7 @@ class Information(Cog): if not rule_numbers and not keywords: # Neither rules nor keywords were submitted. Return the default description. - rules_embed.description = ( - "The rules and guidelines that apply to this community can be found on" - " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" - " all members of the community to have read and understood these." - ) - + rules_embed.description = DEFAULT_RULES_DESCRIPTION await ctx.send(embed=rules_embed) return diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index 626c12c86..c0cfac430 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -7,6 +7,7 @@ from textwrap import shorten import discord from bot import constants +from bot.constants import DEFAULT_RULES_DESCRIPTION from bot.exts.info import information from bot.utils.checks import InWhitelistCheckFailure from tests import helpers @@ -639,14 +640,8 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): (("hello", "999"), None), ] - description = ( - "The rules and guidelines that apply to this community can be found on" - " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" - " all members of the community to have read and understood these." - ) - for raw_user_input, expected_matched_rule_numbers in test_cases: final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) embed = self.ctx.send.call_args.kwargs['embed'] - self.assertEqual(description, embed.description) + self.assertEqual(DEFAULT_RULES_DESCRIPTION, embed.description) self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) -- cgit v1.2.3 From 06b2cde5e4cf7f5a9b914e4f4d1599d949773ecc Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Mon, 19 Sep 2022 23:01:01 +0100 Subject: use subTest to isolate assertions --- tests/bot/exts/info/test_information.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index c0cfac430..157c7141b 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -610,16 +610,17 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): ] for raw_user_input, extracted_rule_numbers in test_cases: - invalid = ", ".join( - str(rule_number) for rule_number in extracted_rule_numbers - if rule_number < 1 or rule_number > len(self.full_rules)) + with self.subTest(identifier=raw_user_input): + invalid = ", ".join( + str(rule_number) for rule_number in extracted_rule_numbers + if rule_number < 1 or rule_number > len(self.full_rules)) - final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) - self.assertEqual( - self.ctx.send.call_args, - unittest.mock.call(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ..."))) - self.assertEqual(None, final_rule_numbers) + self.assertEqual( + self.ctx.send.call_args, + unittest.mock.call(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ..."))) + self.assertEqual(None, final_rule_numbers) async def test_return_correct_rule_numbers(self): @@ -630,8 +631,9 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): ] for raw_user_input, expected_matched_rule_numbers in test_cases: - final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) - self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) + with self.subTest(identifier=raw_user_input): + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) async def test_return_default_rules_when_no_input_or_no_match_are_found(self): test_cases = [ @@ -641,7 +643,8 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): ] for raw_user_input, expected_matched_rule_numbers in test_cases: - final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) - embed = self.ctx.send.call_args.kwargs['embed'] - self.assertEqual(DEFAULT_RULES_DESCRIPTION, embed.description) - self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) + with self.subTest(identifier=raw_user_input): + final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) + embed = self.ctx.send.call_args.kwargs['embed'] + self.assertEqual(DEFAULT_RULES_DESCRIPTION, embed.description) + self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) -- cgit v1.2.3 From edc9c4089d2f7f7cb70b813b3cfdcf52ab834714 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Tue, 20 Sep 2022 08:36:29 +0100 Subject: move DEFAULT_RULES_DESCRIPTION under information.py --- bot/constants.py | 6 ------ bot/exts/info/information.py | 7 ++++++- tests/bot/exts/info/test_information.py | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/bot/constants.py b/bot/constants.py index b1d392822..68a96876f 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -774,9 +774,3 @@ ERROR_REPLIES = [ "Noooooo!!", "I can't believe you've done this", ] - -DEFAULT_RULES_DESCRIPTION = ( - "The rules and guidelines that apply to this community can be found on" - " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" - " all members of the community to have read and understood these." -) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index a4816450f..2592e093d 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -13,7 +13,6 @@ from discord.utils import escape_markdown from bot import constants from bot.bot import Bot -from bot.constants import DEFAULT_RULES_DESCRIPTION from bot.converters import MemberOrUser from bot.decorators import in_whitelist from bot.errors import NonExistentRoleError @@ -26,6 +25,12 @@ from bot.utils.members import get_or_fetch_member log = get_logger(__name__) +DEFAULT_RULES_DESCRIPTION = ( + "The rules and guidelines that apply to this community can be found on" + " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" + " all members of the community to have read and understood these." +) + class Information(Cog): """A cog with commands for generating embeds with server info, such as server stats and user info.""" diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index 157c7141b..9f5143c01 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -7,7 +7,6 @@ from textwrap import shorten import discord from bot import constants -from bot.constants import DEFAULT_RULES_DESCRIPTION from bot.exts.info import information from bot.utils.checks import InWhitelistCheckFailure from tests import helpers @@ -646,5 +645,5 @@ class RuleCommandTests(unittest.IsolatedAsyncioTestCase): with self.subTest(identifier=raw_user_input): final_rule_numbers = await self.cog.rules(self.cog, self.ctx, *raw_user_input) embed = self.ctx.send.call_args.kwargs['embed'] - self.assertEqual(DEFAULT_RULES_DESCRIPTION, embed.description) + self.assertEqual(information.DEFAULT_RULES_DESCRIPTION, embed.description) self.assertEqual(expected_matched_rule_numbers, final_rule_numbers) -- cgit v1.2.3