From be9cb47eddb2c4920a7e0956a79ca555a7243bf7 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 11:15:05 +0300 Subject: EH Tests: Created test cases set + already handled error test Created test that make sure when error is already handled in local error handler, this don't await `ctx.send` to make sure that this don't move forward. --- tests/bot/cogs/test_error_handler.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/bot/cogs/test_error_handler.py (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py new file mode 100644 index 000000000..6aca03030 --- /dev/null +++ b/tests/bot/cogs/test_error_handler.py @@ -0,0 +1,22 @@ +import unittest + +from discord.ext.commands import errors + +from bot.cogs.error_handler import ErrorHandler +from tests.helpers import MockBot, MockContext + + +class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): + """Tests for error handler functionality.""" + + def setUp(self): + self.bot = MockBot() + self.ctx = MockContext(bot=self.bot) + self.cog = ErrorHandler(self.bot) + + async def test_error_handler_already_handled(self): + """Should not do anything when error is already handled by local error handler.""" + error = errors.CommandError() + error.handled = "foo" + await self.cog.on_command_error(self.ctx, error) + self.ctx.send.assert_not_awaited() -- cgit v1.2.3 From 8229d2191bf3c3dfd4eeca5188e6463d41c6c6ff Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 12:58:57 +0300 Subject: EH Tests: Created test for `CommandNotFound` error when call isn't by EH --- tests/bot/cogs/test_error_handler.py | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 6aca03030..510c66b29 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -1,4 +1,5 @@ import unittest +from unittest.mock import AsyncMock, patch from discord.ext.commands import errors @@ -20,3 +21,51 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): error.handled = "foo" await self.cog.on_command_error(self.ctx, error) self.ctx.send.assert_not_awaited() + + async def test_error_handler_command_not_found_error_not_invoked_by_handler(self): + """Should try first (un)silence channel, when fail and channel is not verification channel try to get tag.""" + error = errors.CommandNotFound() + test_cases = ( + { + "try_silence_return": True, + "patch_verification_id": False, + "called_try_get_tag": False + }, + { + "try_silence_return": False, + "patch_verification_id": True, + "called_try_get_tag": False + }, + { + "try_silence_return": False, + "patch_verification_id": False, + "called_try_get_tag": True + } + ) + self.cog.try_silence = AsyncMock() + self.cog.try_get_tag = AsyncMock() + + for case in test_cases: + with self.subTest(try_silence_return=case["try_silence_return"], try_get_tag=case["called_try_get_tag"]): + self.ctx.reset_mock() + self.cog.try_silence.reset_mock(return_value=True) + self.cog.try_get_tag.reset_mock() + + self.cog.try_silence.return_value = case["try_silence_return"] + self.ctx.channel.id = 1234 + + if case["patch_verification_id"]: + with patch("bot.cogs.error_handler.Channels.verification", new=1234): + self.assertIsNone(await self.cog.on_command_error(self.ctx, error)) + else: + self.assertIsNone(await self.cog.on_command_error(self.ctx, error)) + if case["try_silence_return"]: + self.cog.try_get_tag.assert_not_awaited() + self.cog.try_silence.assert_awaited_once() + else: + self.cog.try_silence.assert_awaited_once() + if case["patch_verification_id"]: + self.cog.try_get_tag.assert_not_awaited() + else: + self.cog.try_get_tag.assert_awaited_once() + self.ctx.send.assert_not_awaited() -- cgit v1.2.3 From 28e83216c6c976064e3295911df428baad3419e9 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 13:03:23 +0300 Subject: EH Tests: Remove class member `cog` + other small changes - Added `assertIsNone` to `test_error_handler_already_handled`. - Removed `ErrorHandlerTests.cog`, moved it to each test recreation. --- tests/bot/cogs/test_error_handler.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 510c66b29..3945bbb90 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -13,13 +13,13 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): def setUp(self): self.bot = MockBot() self.ctx = MockContext(bot=self.bot) - self.cog = ErrorHandler(self.bot) async def test_error_handler_already_handled(self): """Should not do anything when error is already handled by local error handler.""" + cog = ErrorHandler(self.bot) error = errors.CommandError() error.handled = "foo" - await self.cog.on_command_error(self.ctx, error) + self.assertIsNone(await cog.on_command_error(self.ctx, error)) self.ctx.send.assert_not_awaited() async def test_error_handler_command_not_found_error_not_invoked_by_handler(self): @@ -42,30 +42,31 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): "called_try_get_tag": True } ) - self.cog.try_silence = AsyncMock() - self.cog.try_get_tag = AsyncMock() + cog = ErrorHandler(self.bot) + cog.try_silence = AsyncMock() + cog.try_get_tag = AsyncMock() for case in test_cases: with self.subTest(try_silence_return=case["try_silence_return"], try_get_tag=case["called_try_get_tag"]): self.ctx.reset_mock() - self.cog.try_silence.reset_mock(return_value=True) - self.cog.try_get_tag.reset_mock() + cog.try_silence.reset_mock(return_value=True) + cog.try_get_tag.reset_mock() - self.cog.try_silence.return_value = case["try_silence_return"] + cog.try_silence.return_value = case["try_silence_return"] self.ctx.channel.id = 1234 if case["patch_verification_id"]: with patch("bot.cogs.error_handler.Channels.verification", new=1234): - self.assertIsNone(await self.cog.on_command_error(self.ctx, error)) + self.assertIsNone(await cog.on_command_error(self.ctx, error)) else: - self.assertIsNone(await self.cog.on_command_error(self.ctx, error)) + self.assertIsNone(await cog.on_command_error(self.ctx, error)) if case["try_silence_return"]: - self.cog.try_get_tag.assert_not_awaited() - self.cog.try_silence.assert_awaited_once() + cog.try_get_tag.assert_not_awaited() + cog.try_silence.assert_awaited_once() else: - self.cog.try_silence.assert_awaited_once() + cog.try_silence.assert_awaited_once() if case["patch_verification_id"]: - self.cog.try_get_tag.assert_not_awaited() + cog.try_get_tag.assert_not_awaited() else: - self.cog.try_get_tag.assert_awaited_once() + cog.try_get_tag.assert_awaited_once() self.ctx.send.assert_not_awaited() -- cgit v1.2.3 From 28e962bcaa47efca836ad20df5721266336d028e Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 14:29:07 +0300 Subject: Test Helpers: Added new attribute to `MockContext` Added `invoked_from_error_handler` attribute that is `False` default. --- tests/helpers.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/helpers.py b/tests/helpers.py index 2b79a6c2a..0e1581e23 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -368,6 +368,7 @@ message_instance = discord.Message(state=state, channel=channel, data=message_da # Create a Context instance to get a realistic MagicMock of `discord.ext.commands.Context` context_instance = Context(message=unittest.mock.MagicMock(), prefix=unittest.mock.MagicMock()) +context_instance.invoked_from_error_handler = None class MockContext(CustomMockMixin, unittest.mock.MagicMock): @@ -385,6 +386,7 @@ class MockContext(CustomMockMixin, unittest.mock.MagicMock): self.guild = kwargs.get('guild', MockGuild()) self.author = kwargs.get('author', MockMember()) self.channel = kwargs.get('channel', MockTextChannel()) + self.invoked_from_error_handler = kwargs.get('invoked_from_error_handler', False) attachment_instance = discord.Attachment(data=unittest.mock.MagicMock(id=1), state=unittest.mock.MagicMock()) -- cgit v1.2.3 From 68ba2920c86a6705aebbb7ea1249123cec699827 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 14:31:18 +0300 Subject: EH Tests: Added another test for `CommandNotFound` error handling Added test for case when `Context.invoked_from_error_handler` is `True` --- tests/bot/cogs/test_error_handler.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 3945bbb90..16b4e9742 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -16,6 +16,7 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): async def test_error_handler_already_handled(self): """Should not do anything when error is already handled by local error handler.""" + self.ctx.reset_mock() cog = ErrorHandler(self.bot) error = errors.CommandError() error.handled = "foo" @@ -70,3 +71,19 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): else: cog.try_get_tag.assert_awaited_once() self.ctx.send.assert_not_awaited() + + async def test_error_handler_command_not_found_error_invoked_by_handler(self): + """Should do nothing when error is `CommandNotFound` and have attribute `invoked_from_error_handler`.""" + ctx = MockContext(bot=self.bot, invoked_from_error_handler=True) + + cog = ErrorHandler(self.bot) + cog.try_silence = AsyncMock() + cog.try_get_tag = AsyncMock() + + error = errors.CommandNotFound() + + self.assertIsNone(await cog.on_command_error(ctx, error)) + + cog.try_silence.assert_not_awaited() + cog.try_get_tag.assert_not_awaited() + self.ctx.send.assert_not_awaited() -- cgit v1.2.3 From 8eacf9c3070443aa213f50484cf2d7510f768d08 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 15:02:46 +0300 Subject: EH Tests: Added test for `UserInputError` handling on handler --- tests/bot/cogs/test_error_handler.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 16b4e9742..a974b421a 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -87,3 +87,12 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): cog.try_silence.assert_not_awaited() cog.try_get_tag.assert_not_awaited() self.ctx.send.assert_not_awaited() + + async def test_error_handler_user_input_error(self): + """Should await `ErrorHandler.handle_user_input_error` when error is `UserInputError`.""" + self.ctx.reset_mock() + cog = ErrorHandler(self.bot) + cog.handle_user_input_error = AsyncMock() + error = errors.UserInputError() + self.assertIsNone(await cog.on_command_error(self.ctx, error)) + cog.handle_user_input_error.assert_awaited_once_with(self.ctx, error) -- cgit v1.2.3 From c050dee853a2fb7432b263cda30becf760310377 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 15:51:48 +0300 Subject: EH Tests: Added test for `CheckFailure` handling on handler --- tests/bot/cogs/test_error_handler.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index a974b421a..1cae8a517 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -96,3 +96,12 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): error = errors.UserInputError() self.assertIsNone(await cog.on_command_error(self.ctx, error)) cog.handle_user_input_error.assert_awaited_once_with(self.ctx, error) + + async def test_error_handler_check_failure(self): + """Should await `ErrorHandler.handle_check_failure` when error is `CheckFailure`.""" + self.ctx.reset_mock() + cog = ErrorHandler(self.bot) + cog.handle_check_failure = AsyncMock() + error = errors.CheckFailure() + self.assertIsNone(await cog.on_command_error(self.ctx, error)) + cog.handle_check_failure.assert_awaited_once_with(self.ctx, error) -- cgit v1.2.3 From ae9766a2cc01ddcc15b4d64568e2cfc67673f138 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 15:57:01 +0300 Subject: EH Tests: Added test for `CommandOnCooldown` handling on handler --- tests/bot/cogs/test_error_handler.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 1cae8a517..2acca7450 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -105,3 +105,11 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): error = errors.CheckFailure() self.assertIsNone(await cog.on_command_error(self.ctx, error)) cog.handle_check_failure.assert_awaited_once_with(self.ctx, error) + + async def test_error_handler_command_on_cooldown(self): + """Should send error with `ctx.send` when error is `CommandOnCooldown`.""" + self.ctx.reset_mock() + cog = ErrorHandler(self.bot) + error = errors.CommandOnCooldown(10, 9) + self.assertIsNone(await cog.on_command_error(self.ctx, error)) + self.ctx.send.assert_awaited_once_with(error) -- cgit v1.2.3 From 6d9698fd3b6fd0b6a02898546c665ef7f302127a Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 16:08:37 +0300 Subject: EH Tests: Added test for `CommandInvokeError` handling on handler --- tests/bot/cogs/test_error_handler.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 2acca7450..09543b56d 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, patch from discord.ext.commands import errors +from bot.api import ResponseCodeError from bot.cogs.error_handler import ErrorHandler from tests.helpers import MockBot, MockContext @@ -113,3 +114,24 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): error = errors.CommandOnCooldown(10, 9) self.assertIsNone(await cog.on_command_error(self.ctx, error)) self.ctx.send.assert_awaited_once_with(error) + + async def test_error_handler_command_invoke_error(self): + """Should call `handle_api_error` or `handle_unexpected_error` depending on original error.""" + cog = ErrorHandler(self.bot) + cog.handle_api_error = AsyncMock() + cog.handle_unexpected_error = AsyncMock() + test_cases = ( + { + "args": (self.ctx, errors.CommandInvokeError(ResponseCodeError(AsyncMock()))), + "expect_mock_call": cog.handle_api_error + }, + { + "args": (self.ctx, errors.CommandInvokeError(TypeError)), + "expect_mock_call": cog.handle_unexpected_error + } + ) + + for case in test_cases: + with self.subTest(args=case["args"], expect_mock_call=case["expect_mock_call"]): + self.assertIsNone(await cog.on_command_error(*case["args"])) + case["expect_mock_call"].assert_awaited_once_with(self.ctx, case["args"][1].original) -- cgit v1.2.3 From cf89c5be49bfe57934d2fea9408a44f78c4db3b6 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 16:18:40 +0300 Subject: EH Tests: Added test for 3 errors handling on handler These 3 errors is: - `ConversionError` - `MaxConcurrencyReached` - `ExtensionError` --- tests/bot/cogs/test_error_handler.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 09543b56d..bc67e9d7c 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -1,5 +1,5 @@ import unittest -from unittest.mock import AsyncMock, patch +from unittest.mock import AsyncMock, MagicMock, patch from discord.ext.commands import errors @@ -135,3 +135,19 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): with self.subTest(args=case["args"], expect_mock_call=case["expect_mock_call"]): self.assertIsNone(await cog.on_command_error(*case["args"])) case["expect_mock_call"].assert_awaited_once_with(self.ctx, case["args"][1].original) + + async def test_error_handler_three_other_errors(self): + """Should call `handle_unexpected_error` when `ConversionError`, `MaxConcurrencyReached` or `ExtensionError`.""" + cog = ErrorHandler(self.bot) + cog.handle_unexpected_error = AsyncMock() + errs = ( + errors.ConversionError(MagicMock(), MagicMock()), + errors.MaxConcurrencyReached(1, MagicMock()), + errors.ExtensionError(name="foo") + ) + + for err in errs: + with self.subTest(error=err): + cog.handle_unexpected_error.reset_mock() + self.assertIsNone(await cog.on_command_error(self.ctx, err)) + cog.handle_unexpected_error.assert_awaited_once_with(self.ctx, err) -- cgit v1.2.3 From 800909176c3799b12d8bbb41fba4be336b199933 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 16:25:59 +0300 Subject: EH Tests: Created test for all other errors --- tests/bot/cogs/test_error_handler.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index bc67e9d7c..d0a5ba21b 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -151,3 +151,11 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): cog.handle_unexpected_error.reset_mock() self.assertIsNone(await cog.on_command_error(self.ctx, err)) cog.handle_unexpected_error.assert_awaited_once_with(self.ctx, err) + + @patch("bot.cogs.error_handler.log") + async def test_error_handler_other_errors(self, log_mock): + """Should `log.debug` other errors.""" + cog = ErrorHandler(self.bot) + error = errors.DisabledCommand() # Use this just as a other error + self.assertIsNone(await cog.on_command_error(self.ctx, error)) + log_mock.debug.assert_called_once() -- cgit v1.2.3 From faf9737548c82cff5369ec145530f6fc86f8c0cc Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 19:17:25 +0300 Subject: EH Tests: Created first test for `try_silence` --- tests/bot/cogs/test_error_handler.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index d0a5ba21b..f409cf6bc 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -5,6 +5,7 @@ from discord.ext.commands import errors from bot.api import ResponseCodeError from bot.cogs.error_handler import ErrorHandler +from bot.cogs.moderation.silence import Silence from tests.helpers import MockBot, MockContext @@ -159,3 +160,20 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): error = errors.DisabledCommand() # Use this just as a other error self.assertIsNone(await cog.on_command_error(self.ctx, error)) log_mock.debug.assert_called_once() + + +class TrySilenceTests(unittest.IsolatedAsyncioTestCase): + """Test for helper functions that handle `CommandNotFound` error.""" + + def setUp(self): + self.bot = MockBot() + + async def test_try_silence_context_invoked_from_error_handler(self): + """Should set `Context.invoked_from_error_handler` to `True`.""" + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + ctx.invoked_with = "foo" + self.bot.get_command.return_value = Silence(self.bot).silence + await cog.try_silence(ctx) + self.assertTrue(hasattr(ctx, "invoked_from_error_handler")) + self.assertTrue(ctx.invoked_from_error_handler) -- cgit v1.2.3 From c1ac5c00d211eda081aec948fe74a6a083854e49 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 19:20:55 +0300 Subject: EH Tests: Created `try_silence` test for `get_command` --- tests/bot/cogs/test_error_handler.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index f409cf6bc..90f4c64a6 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -177,3 +177,12 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): await cog.try_silence(ctx) self.assertTrue(hasattr(ctx, "invoked_from_error_handler")) self.assertTrue(ctx.invoked_from_error_handler) + + async def test_try_silence_get_command(self): + """Should call `get_command` with `silence`.""" + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + ctx.invoked_with = "foo" + self.bot.get_command.return_value = Silence(self.bot).silence + await cog.try_silence(ctx) + self.bot.get_command.assert_called_once_with("silence") -- cgit v1.2.3 From 187998fe0436f60b831a4bf5af44c37e37d1ea34 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 19:24:19 +0300 Subject: EH Tests: Created `try_silence` test to check no permission response --- tests/bot/cogs/test_error_handler.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 90f4c64a6..941b57ecb 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -167,13 +167,13 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): def setUp(self): self.bot = MockBot() + self.bot.get_command.return_value = Silence(self.bot).silence async def test_try_silence_context_invoked_from_error_handler(self): """Should set `Context.invoked_from_error_handler` to `True`.""" cog = ErrorHandler(self.bot) ctx = MockContext(bot=self.bot) ctx.invoked_with = "foo" - self.bot.get_command.return_value = Silence(self.bot).silence await cog.try_silence(ctx) self.assertTrue(hasattr(ctx, "invoked_from_error_handler")) self.assertTrue(ctx.invoked_from_error_handler) @@ -183,6 +183,13 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): cog = ErrorHandler(self.bot) ctx = MockContext(bot=self.bot) ctx.invoked_with = "foo" - self.bot.get_command.return_value = Silence(self.bot).silence await cog.try_silence(ctx) self.bot.get_command.assert_called_once_with("silence") + + async def test_try_silence_no_permissions_to_run(self): + """Should return `False` because missing permissions.""" + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + ctx.invoked_with = "foo" + self.bot.get_command.return_value.can_run = AsyncMock(return_value=False) + self.assertFalse(await cog.try_silence(ctx)) -- cgit v1.2.3 From ec3b4eefbf3f1e67a0ade32522667fcc397539c5 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 19:46:15 +0300 Subject: EH Tests: Created `try_silence` test to check no permission with except --- tests/bot/cogs/test_error_handler.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 941b57ecb..8c51467e5 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -193,3 +193,11 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): ctx.invoked_with = "foo" self.bot.get_command.return_value.can_run = AsyncMock(return_value=False) self.assertFalse(await cog.try_silence(ctx)) + + async def test_try_silence_no_permissions_to_run_command_error(self): + """Should return `False` because `CommandError` raised (no permissions).""" + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + ctx.invoked_with = "foo" + self.bot.get_command.return_value.can_run = AsyncMock(side_effect=errors.CommandError()) + self.assertFalse(await cog.try_silence(ctx)) -- cgit v1.2.3 From f324b0166516687100ad1362807d59be9918b739 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 19:54:47 +0300 Subject: EH Tests: Created `try_silence` test to test silence command calling --- tests/bot/cogs/test_error_handler.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 8c51467e5..30326d445 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -201,3 +201,20 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): ctx.invoked_with = "foo" self.bot.get_command.return_value.can_run = AsyncMock(side_effect=errors.CommandError()) self.assertFalse(await cog.try_silence(ctx)) + + async def test_try_silence_silencing(self): + """Should run silence command with correct arguments.""" + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + self.bot.get_command.return_value.can_run = AsyncMock(return_value=True) + test_cases = ("shh", "shhh", "shhhhhh", "shhhhhhhhhhhhhhhhhhh") + + for case in test_cases: + with self.subTest(message=case): + ctx.reset_mock() + ctx.invoked_with = case + self.assertTrue(await cog.try_silence(ctx)) + ctx.invoke.assert_awaited_once_with( + self.bot.get_command.return_value, + duration=min(case.count("h")*2, 15) + ) -- cgit v1.2.3 From 2c488838dec67daa40e11249c9e578c1450ce594 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 20:05:19 +0300 Subject: EH Tests: Created `try_silence` test to test unsilence command calling --- tests/bot/cogs/test_error_handler.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 30326d445..610d3ace5 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -218,3 +218,20 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): self.bot.get_command.return_value, duration=min(case.count("h")*2, 15) ) + + async def test_try_silence_unsilence(self): + """Should call unsilence command.""" + bot = MockBot() + silence = Silence(bot) + silence.silence.can_run = AsyncMock(return_value=True) + cog = ErrorHandler(bot) + ctx = MockContext(bot=bot) + test_cases = ("unshh", "unshhhhh", "unshhhhhhhhh") + + for case in test_cases: + with self.subTest(message=case): + bot.get_command.side_effect = (silence.silence, silence.unsilence) + ctx.reset_mock() + ctx.invoked_with = case + self.assertTrue(await cog.try_silence(ctx)) + ctx.invoke.assert_awaited_once_with(silence.unsilence) -- cgit v1.2.3 From 555857c07829b537e048ae030e6b864576d4ef8a Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 20:07:16 +0300 Subject: EH Tests: Added test for `try_silence` no match message --- tests/bot/cogs/test_error_handler.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 610d3ace5..8be562473 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -235,3 +235,9 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): ctx.invoked_with = case self.assertTrue(await cog.try_silence(ctx)) ctx.invoke.assert_awaited_once_with(silence.unsilence) + + async def test_try_silence_no_match(self): + cog = ErrorHandler(self.bot) + ctx = MockContext(bot=self.bot) + ctx.invoked_with = "foo" + self.assertFalse(await cog.try_silence(ctx)) -- cgit v1.2.3 From 048916fbf6ecf272c89e325055ff5d755276d75b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Mon, 18 May 2020 20:12:57 +0300 Subject: EH Tests: Cleanup `try_silence` tests --- tests/bot/cogs/test_error_handler.py | 66 +++++++++++++++--------------------- 1 file changed, 27 insertions(+), 39 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 8be562473..bfb1cfe61 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -167,77 +167,65 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): def setUp(self): self.bot = MockBot() - self.bot.get_command.return_value = Silence(self.bot).silence + self.silence = Silence(self.bot) + self.bot.get_command.return_value = self.silence.silence + self.ctx = MockContext(bot=self.bot) + self.cog = ErrorHandler(self.bot) async def test_try_silence_context_invoked_from_error_handler(self): """Should set `Context.invoked_from_error_handler` to `True`.""" - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) - ctx.invoked_with = "foo" - await cog.try_silence(ctx) - self.assertTrue(hasattr(ctx, "invoked_from_error_handler")) - self.assertTrue(ctx.invoked_from_error_handler) + self.ctx.invoked_with = "foo" + await self.cog.try_silence(self.ctx) + self.assertTrue(hasattr(self.ctx, "invoked_from_error_handler")) + self.assertTrue(self.ctx.invoked_from_error_handler) async def test_try_silence_get_command(self): """Should call `get_command` with `silence`.""" - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) - ctx.invoked_with = "foo" - await cog.try_silence(ctx) + self.ctx.invoked_with = "foo" + await self.cog.try_silence(self.ctx) self.bot.get_command.assert_called_once_with("silence") async def test_try_silence_no_permissions_to_run(self): """Should return `False` because missing permissions.""" - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) - ctx.invoked_with = "foo" + self.ctx.invoked_with = "foo" self.bot.get_command.return_value.can_run = AsyncMock(return_value=False) - self.assertFalse(await cog.try_silence(ctx)) + self.assertFalse(await self.cog.try_silence(self.ctx)) async def test_try_silence_no_permissions_to_run_command_error(self): """Should return `False` because `CommandError` raised (no permissions).""" - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) - ctx.invoked_with = "foo" + self.ctx.invoked_with = "foo" self.bot.get_command.return_value.can_run = AsyncMock(side_effect=errors.CommandError()) - self.assertFalse(await cog.try_silence(ctx)) + self.assertFalse(await self.cog.try_silence(self.ctx)) async def test_try_silence_silencing(self): """Should run silence command with correct arguments.""" - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) self.bot.get_command.return_value.can_run = AsyncMock(return_value=True) test_cases = ("shh", "shhh", "shhhhhh", "shhhhhhhhhhhhhhhhhhh") for case in test_cases: with self.subTest(message=case): - ctx.reset_mock() - ctx.invoked_with = case - self.assertTrue(await cog.try_silence(ctx)) - ctx.invoke.assert_awaited_once_with( + self.ctx.reset_mock() + self.ctx.invoked_with = case + self.assertTrue(await self.cog.try_silence(self.ctx)) + self.ctx.invoke.assert_awaited_once_with( self.bot.get_command.return_value, duration=min(case.count("h")*2, 15) ) async def test_try_silence_unsilence(self): """Should call unsilence command.""" - bot = MockBot() - silence = Silence(bot) - silence.silence.can_run = AsyncMock(return_value=True) - cog = ErrorHandler(bot) - ctx = MockContext(bot=bot) + self.silence.silence.can_run = AsyncMock(return_value=True) test_cases = ("unshh", "unshhhhh", "unshhhhhhhhh") for case in test_cases: with self.subTest(message=case): - bot.get_command.side_effect = (silence.silence, silence.unsilence) - ctx.reset_mock() - ctx.invoked_with = case - self.assertTrue(await cog.try_silence(ctx)) - ctx.invoke.assert_awaited_once_with(silence.unsilence) + self.bot.get_command.side_effect = (self.silence.silence, self.silence.unsilence) + self.ctx.reset_mock() + self.ctx.invoked_with = case + self.assertTrue(await self.cog.try_silence(self.ctx)) + self.ctx.invoke.assert_awaited_once_with(self.silence.unsilence) async def test_try_silence_no_match(self): - cog = ErrorHandler(self.bot) - ctx = MockContext(bot=self.bot) - ctx.invoked_with = "foo" - self.assertFalse(await cog.try_silence(ctx)) + """Should return `False` when message don't match.""" + self.ctx.invoked_with = "foo" + self.assertFalse(await self.cog.try_silence(self.ctx)) -- cgit v1.2.3 From 33231d5881063c720ab54b295d36030b4b304002 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:18:55 +0300 Subject: EH Tests: Added tests for `get_help_command`in `OtherErrorHandlerTests` --- tests/bot/cogs/test_error_handler.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index bfb1cfe61..615c0e455 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -229,3 +229,35 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): """Should return `False` when message don't match.""" self.ctx.invoked_with = "foo" self.assertFalse(await self.cog.try_silence(self.ctx)) + + +class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): + """Other `ErrorHandler` tests.""" + + def setUp(self): + self.bot = MockBot() + self.ctx = MockContext() + + async def test_get_help_command_command_specified(self): + """Should return coroutine of help command of specified command.""" + self.ctx.command = "foo" + result = ErrorHandler.get_help_command(self.ctx) + expected = self.ctx.send_help("foo") + self.assertEqual(result.__qualname__, expected.__qualname__) + self.assertEqual(result.cr_frame.f_locals, expected.cr_frame.f_locals) + + # Await coroutines to avoid warnings + await result + await expected + + async def test_get_help_command_no_command_specified(self): + """Should return coroutine of help command.""" + self.ctx.command = None + result = ErrorHandler.get_help_command(self.ctx) + expected = self.ctx.send_help() + self.assertEqual(result.__qualname__, expected.__qualname__) + self.assertEqual(result.cr_frame.f_locals, expected.cr_frame.f_locals) + + # Await coroutines to avoid warnings + await result + await expected -- cgit v1.2.3 From eb9909f90706803694a37ae30336c3d6a4b475ab Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:27:49 +0300 Subject: EH Tests: Added test for `try_get_tag` `get_command` calling --- tests/bot/cogs/test_error_handler.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 615c0e455..b92a67fbe 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -6,6 +6,7 @@ from discord.ext.commands import errors from bot.api import ResponseCodeError from bot.cogs.error_handler import ErrorHandler from bot.cogs.moderation.silence import Silence +from bot.cogs.tags import Tags from tests.helpers import MockBot, MockContext @@ -231,6 +232,24 @@ class TrySilenceTests(unittest.IsolatedAsyncioTestCase): self.assertFalse(await self.cog.try_silence(self.ctx)) +class TryGetTagTests(unittest.IsolatedAsyncioTestCase): + """Tests for `try_get_tag` function.""" + + def setUp(self): + self.bot = MockBot() + self.ctx = MockContext() + self.tag = Tags(self.bot) + self.cog = ErrorHandler(self.bot) + self.bot.get_command.return_value = self.tag.get_command + + async def test_try_get_tag_get_command(self): + """Should call `Bot.get_command` with `tags get` argument.""" + self.bot.get_command.reset_mock() + self.ctx.invoked_with = "my_some_not_existing_tag" + await self.cog.try_get_tag(self.ctx) + self.bot.get_command.assert_called_once_with("tags get") + + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 1a796c472273a0e1d98ae52a13550791592f856c Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:30:25 +0300 Subject: EH Tests: Added test for `try_get_tag` `invoked_from_error_handler` --- tests/bot/cogs/test_error_handler.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index b92a67fbe..35c223fcc 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -249,6 +249,13 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): await self.cog.try_get_tag(self.ctx) self.bot.get_command.assert_called_once_with("tags get") + async def test_try_get_tag_invoked_from_error_handler(self): + """`self.ctx` should have `invoked_from_error_handler` `True`.""" + self.ctx.invoked_from_error_handler = False + self.ctx.invoked_with = "my_some_not_existing_tag" + await self.cog.try_get_tag(self.ctx) + self.assertTrue(self.ctx.invoked_from_error_handler) + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 0ffded4eaa2427a04f43aa3bb6088c3ac1e91f0e Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:35:15 +0300 Subject: EH Tests: Added test for `try_get_tag` checks fail --- tests/bot/cogs/test_error_handler.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 35c223fcc..ba05076dd 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -245,17 +245,23 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): async def test_try_get_tag_get_command(self): """Should call `Bot.get_command` with `tags get` argument.""" self.bot.get_command.reset_mock() - self.ctx.invoked_with = "my_some_not_existing_tag" + self.ctx.invoked_with = "foo" await self.cog.try_get_tag(self.ctx) self.bot.get_command.assert_called_once_with("tags get") async def test_try_get_tag_invoked_from_error_handler(self): """`self.ctx` should have `invoked_from_error_handler` `True`.""" self.ctx.invoked_from_error_handler = False - self.ctx.invoked_with = "my_some_not_existing_tag" + self.ctx.invoked_with = "foo" await self.cog.try_get_tag(self.ctx) self.assertTrue(self.ctx.invoked_from_error_handler) + async def test_try_get_tag_no_permissions(self): + """Should return `False` because checks fail.""" + self.tag.get_command.can_run = AsyncMock(return_value=False) + self.ctx.invoked_with = "foo" + self.assertFalse(await self.cog.try_get_tag(self.ctx)) + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From c2d111f32a04a4f0c5a7b02d4418b2c628b0115a Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:41:07 +0300 Subject: EH Tests: Added test for `try_get_tag` error handling --- tests/bot/cogs/test_error_handler.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index ba05076dd..a22724aff 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -257,10 +257,19 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertTrue(self.ctx.invoked_from_error_handler) async def test_try_get_tag_no_permissions(self): - """Should return `False` because checks fail.""" + """Test how to handle checks failing.""" self.tag.get_command.can_run = AsyncMock(return_value=False) self.ctx.invoked_with = "foo" - self.assertFalse(await self.cog.try_get_tag(self.ctx)) + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + + async def test_try_get_tag_command_error(self): + """Should call `on_command_error` when `CommandError` raised.""" + err = errors.CommandError() + self.tag.get_command.can_run = AsyncMock(side_effect=err) + self.cog.on_command_error = AsyncMock() + self.ctx.invoked_with = "foo" + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + self.cog.on_command_error.assert_awaited_once_with(self.ctx, err) class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): -- cgit v1.2.3 From 2c1cbc21e5f7046f765d9ed5145a4f06464a8f6f Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:49:40 +0300 Subject: EH Tests: Added test for `try_get_tag` successful tag name converting --- tests/bot/cogs/test_error_handler.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index a22724aff..c95453c8c 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -271,6 +271,15 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) self.cog.on_command_error.assert_awaited_once_with(self.ctx, err) + @patch("bot.cogs.error_handler.TagNameConverter") + async def test_try_get_tag_convert_success(self, tag_converter): + """Converting tag should successful.""" + self.ctx.invoked_with = "foo" + tag_converter.convert = AsyncMock(return_value="foo") + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + tag_converter.convert.assert_awaited_once_with(self.ctx, "foo") + self.ctx.invoke.assert_awaited_once() + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 558b5d86c37f81dd71b19aed9ef9dc4a1d899dd0 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:52:30 +0300 Subject: EH Tests: Added test for `try_get_tag` tag name converting failing --- tests/bot/cogs/test_error_handler.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index c95453c8c..dfebf3379 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -280,6 +280,15 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): tag_converter.convert.assert_awaited_once_with(self.ctx, "foo") self.ctx.invoke.assert_awaited_once() + @patch("bot.cogs.error_handler.TagNameConverter") + async def test_try_get_tag_convert_fail(self, tag_converter): + """Converting tag should raise `BadArgument`.""" + self.ctx.reset_mock() + self.ctx.invoked_with = "bar" + tag_converter.convert = AsyncMock(side_effect=errors.BadArgument()) + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + self.ctx.invoke.assert_not_awaited() + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 9e4e9ef3f00f03e8e4b5260e458a1fc5c9318a57 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 08:58:41 +0300 Subject: EH Tests: Added test for `try_get_tag` `ctx.invoke` calling --- tests/bot/cogs/test_error_handler.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index dfebf3379..43092f082 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -289,6 +289,13 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) self.ctx.invoke.assert_not_awaited() + async def test_try_get_tag_ctx_invoke(self): + """Should call `ctx.invoke` with proper args/kwargs.""" + self.ctx.reset_mock() + self.ctx.invoked_with = "foo" + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + self.ctx.invoke.assert_awaited_once_with(self.tag.get_command, tag_name="foo") + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 1715b2e0461b142009757b04f257cf999779a668 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 09:01:48 +0300 Subject: EH Tests: Added test for `try_get_tag` `ResponseCodeError` ignore --- tests/bot/cogs/test_error_handler.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 43092f082..6dda85304 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -296,6 +296,12 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) self.ctx.invoke.assert_awaited_once_with(self.tag.get_command, tag_name="foo") + async def test_try_get_tag_response_code_error_suppress(self): + """Should suppress `ResponseCodeError` when calling `ctx.invoke`.""" + self.ctx.invoked_with = "foo" + self.ctx.invoke.side_effect = ResponseCodeError(MagicMock()) + self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 98c30a30f24feb227bf7e921e825b7124515d640 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 09:14:25 +0300 Subject: EH Tests: Created test for `handle_user_input_error` `get_help_command` --- tests/bot/cogs/test_error_handler.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 6dda85304..377fc5228 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -303,6 +303,22 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) +class UserInputErrorHandlerTests(unittest.IsolatedAsyncioTestCase): + """Tests for `handle_user_input_error`.""" + + def setUp(self): + self.bot = MockBot() + self.ctx = MockContext(bot=self.bot) + self.cog = ErrorHandler(self.bot) + + @patch("bot.cogs.error_handler.ErrorHandler.get_help_command") + async def test_handle_input_error_handler_get_help_command_call(self, get_help_command): + """Should call `ErrorHandler.get_help_command`.""" + get_help_command.return_value = self.ctx.send_help(self.ctx) + await self.cog.handle_user_input_error(self.ctx, errors.UserInputError()) + get_help_command.assert_called_once_with(self.ctx) + + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 18938a9238ac1bd7412aa636190d23de155cc15d Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 09:51:55 +0300 Subject: EH Tests: Create test for `handle_input_error` --- tests/bot/cogs/test_error_handler.py | 42 ++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 377fc5228..e3d22e82b 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -311,12 +311,42 @@ class UserInputErrorHandlerTests(unittest.IsolatedAsyncioTestCase): self.ctx = MockContext(bot=self.bot) self.cog = ErrorHandler(self.bot) - @patch("bot.cogs.error_handler.ErrorHandler.get_help_command") - async def test_handle_input_error_handler_get_help_command_call(self, get_help_command): - """Should call `ErrorHandler.get_help_command`.""" - get_help_command.return_value = self.ctx.send_help(self.ctx) - await self.cog.handle_user_input_error(self.ctx, errors.UserInputError()) - get_help_command.assert_called_once_with(self.ctx) + async def test_handle_input_error_handler_errors(self): + """Should handle each error probably.""" + test_cases = ( + { + "error": errors.MissingRequiredArgument(MagicMock()), + "call_prepared": True + }, + { + "error": errors.TooManyArguments(), + "call_prepared": True + }, + { + "error": errors.BadArgument(), + "call_prepared": True + }, + { + "error": errors.BadUnionArgument(MagicMock(), MagicMock(), MagicMock()), + "call_prepared": False + }, + { + "error": errors.ArgumentParsingError(), + "call_prepared": False + }, + { + "error": errors.UserInputError(), + "call_prepared": True + } + ) + + for case in test_cases: + with self.subTest(error=case["error"], call_prepared=case["call_prepared"]): + self.ctx.reset_mock() + self.assertIsNone(await self.cog.handle_user_input_error(self.ctx, case["error"])) + self.ctx.send.assert_awaited_once() + if case["call_prepared"]: + self.ctx.send_help.assert_awaited_once() class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): -- cgit v1.2.3 From 42083621a48972c784a910961a2357a6b9be4aca Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 10:02:57 +0300 Subject: EH Tests: Create test for `handle_check_failure` --- tests/bot/cogs/test_error_handler.py | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index e3d22e82b..b12d21f75 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -7,6 +7,7 @@ from bot.api import ResponseCodeError from bot.cogs.error_handler import ErrorHandler from bot.cogs.moderation.silence import Silence from bot.cogs.tags import Tags +from bot.decorators import InWhitelistCheckFailure from tests.helpers import MockBot, MockContext @@ -349,6 +350,53 @@ class UserInputErrorHandlerTests(unittest.IsolatedAsyncioTestCase): self.ctx.send_help.assert_awaited_once() +class CheckFailureHandlingTests(unittest.IsolatedAsyncioTestCase): + """Tests for `handle_check_failure`.""" + + def setUp(self): + self.bot = MockBot() + self.ctx = MockContext(bot=self.bot) + self.cog = ErrorHandler(self.bot) + + async def test_handle_check_failure_errors(self): + """Should await `ctx.send` when error is check failure.""" + test_cases = ( + { + "error": errors.BotMissingPermissions(MagicMock()), + "call_ctx_send": True + }, + { + "error": errors.BotMissingRole(MagicMock()), + "call_ctx_send": True + }, + { + "error": errors.BotMissingAnyRole(MagicMock()), + "call_ctx_send": True + }, + { + "error": errors.NoPrivateMessage(), + "call_ctx_send": True + }, + { + "error": InWhitelistCheckFailure(1234), + "call_ctx_send": True + }, + { + "error": ResponseCodeError(MagicMock()), + "call_ctx_send": False + } + ) + + for case in test_cases: + with self.subTest(error=case["error"], call_ctx_send=case["call_ctx_send"]): + self.ctx.reset_mock() + await self.cog.handle_check_failure(self.ctx, case["error"]) + if case["call_ctx_send"]: + self.ctx.send.assert_awaited_once() + else: + self.ctx.send.assert_not_awaited() + + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From decd712419d2daecd15d29efdeb6d74a64ec7946 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 10:06:01 +0300 Subject: EH Tests: Merge test classes --- tests/bot/cogs/test_error_handler.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index b12d21f75..32c7c4f46 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -304,8 +304,8 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) -class UserInputErrorHandlerTests(unittest.IsolatedAsyncioTestCase): - """Tests for `handle_user_input_error`.""" +class IndividualErrorHandlerTests(unittest.IsolatedAsyncioTestCase): + """Individual error categories handler tests.""" def setUp(self): self.bot = MockBot() @@ -348,15 +348,8 @@ class UserInputErrorHandlerTests(unittest.IsolatedAsyncioTestCase): self.ctx.send.assert_awaited_once() if case["call_prepared"]: self.ctx.send_help.assert_awaited_once() - - -class CheckFailureHandlingTests(unittest.IsolatedAsyncioTestCase): - """Tests for `handle_check_failure`.""" - - def setUp(self): - self.bot = MockBot() - self.ctx = MockContext(bot=self.bot) - self.cog = ErrorHandler(self.bot) + else: + self.ctx.send_help.assert_not_awaited() async def test_handle_check_failure_errors(self): """Should await `ctx.send` when error is check failure.""" -- cgit v1.2.3 From 6bd696132a76068dc14f97e8fffbce2781823de2 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 12:44:26 +0300 Subject: EH Tests: Create tests for `handle_api_error` --- tests/bot/cogs/test_error_handler.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 32c7c4f46..5766727e8 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -389,6 +389,39 @@ class IndividualErrorHandlerTests(unittest.IsolatedAsyncioTestCase): else: self.ctx.send.assert_not_awaited() + @patch("bot.cogs.error_handler.log") + async def test_handle_api_error(self, log_mock): + """Should `ctx.send` on HTTP error codes, `log.debug|warning` depends on code.""" + test_cases = ( + { + "error": ResponseCodeError(AsyncMock(status=400)), + "log_level": "debug" + }, + { + "error": ResponseCodeError(AsyncMock(status=404)), + "log_level": "debug" + }, + { + "error": ResponseCodeError(AsyncMock(status=550)), + "log_level": "warning" + }, + { + "error": ResponseCodeError(AsyncMock(status=1000)), + "log_level": "warning" + } + ) + + for case in test_cases: + with self.subTest(error=case["error"], log_level=case["log_level"]): + self.ctx.reset_mock() + log_mock.reset_mock() + await self.cog.handle_api_error(self.ctx, case["error"]) + self.ctx.send.assert_awaited_once() + if case["log_level"] == "warning": + log_mock.warning.assert_called_once() + else: + log_mock.debug.assert_called_once() + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 658f73170100e826fe47ea9f23178a5d071f3932 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 12:50:43 +0300 Subject: EH Tests: Create test for `ErrorHandler` `setup` function --- tests/bot/cogs/test_error_handler.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index 5766727e8..fbe0d58d5 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, MagicMock, patch from discord.ext.commands import errors from bot.api import ResponseCodeError -from bot.cogs.error_handler import ErrorHandler +from bot.cogs.error_handler import ErrorHandler, setup from bot.cogs.moderation.silence import Silence from bot.cogs.tags import Tags from bot.decorators import InWhitelistCheckFailure @@ -453,3 +453,13 @@ class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): # Await coroutines to avoid warnings await result await expected + + +class ErrorHandlerSetupTests(unittest.TestCase): + """Tests for `ErrorHandler` `setup` function.""" + + def test_setup(self): + """Should call `bot.add_cog` with `ErrorHandler`.""" + bot = MockBot() + setup(bot) + bot.add_cog.assert_called_once() -- cgit v1.2.3 From 96ddcdd3bd12cc9ceb47aa10d17e7354be9e1218 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 19 May 2020 13:08:52 +0300 Subject: EH Tests: Create test for `handle_unexpected_error` --- tests/bot/cogs/test_error_handler.py | 39 ++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/cogs/test_error_handler.py b/tests/bot/cogs/test_error_handler.py index fbe0d58d5..08b1e0230 100644 --- a/tests/bot/cogs/test_error_handler.py +++ b/tests/bot/cogs/test_error_handler.py @@ -1,5 +1,5 @@ import unittest -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, call, patch from discord.ext.commands import errors @@ -8,7 +8,7 @@ from bot.cogs.error_handler import ErrorHandler, setup from bot.cogs.moderation.silence import Silence from bot.cogs.tags import Tags from bot.decorators import InWhitelistCheckFailure -from tests.helpers import MockBot, MockContext +from tests.helpers import MockBot, MockContext, MockGuild class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): @@ -422,6 +422,41 @@ class IndividualErrorHandlerTests(unittest.IsolatedAsyncioTestCase): else: log_mock.debug.assert_called_once() + @patch("bot.cogs.error_handler.push_scope") + @patch("bot.cogs.error_handler.log") + async def test_handle_unexpected_error(self, log_mock, push_scope_mock): + """Should `ctx.send` this error, error log this and sent to Sentry.""" + for case in (None, MockGuild()): + with self.subTest(guild=case): + self.ctx.reset_mock() + log_mock.reset_mock() + push_scope_mock.reset_mock() + + self.ctx.guild = case + await self.cog.handle_unexpected_error(self.ctx, errors.CommandError()) + + self.ctx.send.assert_awaited_once() + log_mock.error.assert_called_once() + push_scope_mock.assert_called_once() + + set_tag_calls = [ + call("command", self.ctx.command.qualified_name), + call("message_id", self.ctx.message.id), + call("channel_id", self.ctx.channel.id), + ] + set_extra_calls = [ + call("full_message", self.ctx.message.content) + ] + if case: + url = ( + f"https://discordapp.com/channels/" + f"{self.ctx.guild.id}/{self.ctx.channel.id}/{self.ctx.message.id}" + ) + set_extra_calls.append(call("jump_to", url)) + + push_scope_mock.set_tag.has_calls(set_tag_calls) + push_scope_mock.set_extra.has_calls(set_extra_calls) + class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" -- cgit v1.2.3 From 8716902624668f2cef80656f5e9fae335a0559f2 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 27 Sep 2020 08:29:03 +0300 Subject: EH Tests: Fix order of imports --- tests/bot/exts/backend/test_error_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index e8b9c7708..e3641ba21 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -4,10 +4,10 @@ from unittest.mock import AsyncMock, MagicMock, call, patch from discord.ext.commands import errors from bot.api import ResponseCodeError +from bot.decorators import InWhitelistCheckFailure from bot.exts.backend.error_handler import ErrorHandler, setup -from bot.exts.moderation.silence import Silence from bot.exts.info.tags import Tags -from bot.decorators import InWhitelistCheckFailure +from bot.exts.moderation.silence import Silence from tests.helpers import MockBot, MockContext, MockGuild -- cgit v1.2.3 From 5f250690523a4a1c631834d2a8e64898614c5932 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sun, 27 Sep 2020 08:44:03 +0300 Subject: EH tests: Fix InWhitelistCheckFailure import path --- tests/bot/exts/backend/test_error_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index e3641ba21..4a0adb03e 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -4,10 +4,10 @@ from unittest.mock import AsyncMock, MagicMock, call, patch from discord.ext.commands import errors from bot.api import ResponseCodeError -from bot.decorators import InWhitelistCheckFailure from bot.exts.backend.error_handler import ErrorHandler, setup from bot.exts.info.tags import Tags from bot.exts.moderation.silence import Silence +from bot.utils.checks import InWhitelistCheckFailure from tests.helpers import MockBot, MockContext, MockGuild -- cgit v1.2.3 From ee0cd08a113192a5e49ddb10c9ef2527d9a4d77b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Fri, 19 Feb 2021 12:50:16 +0200 Subject: Remove verification channel special case from error handler tests We don't have a verification channel anymore, so this have no point and this just give errors. --- tests/bot/exts/backend/test_error_handler.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index 4a0adb03e..ea21a9f58 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -28,22 +28,19 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): self.ctx.send.assert_not_awaited() async def test_error_handler_command_not_found_error_not_invoked_by_handler(self): - """Should try first (un)silence channel, when fail and channel is not verification channel try to get tag.""" + """Should try first (un)silence channel, when fail, try to get tag.""" error = errors.CommandNotFound() test_cases = ( { "try_silence_return": True, - "patch_verification_id": False, "called_try_get_tag": False }, { "try_silence_return": False, - "patch_verification_id": True, "called_try_get_tag": False }, { "try_silence_return": False, - "patch_verification_id": False, "called_try_get_tag": True } ) @@ -60,20 +57,15 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): cog.try_silence.return_value = case["try_silence_return"] self.ctx.channel.id = 1234 - if case["patch_verification_id"]: - with patch("bot.exts.backend.error_handler.Channels.verification", new=1234): - self.assertIsNone(await cog.on_command_error(self.ctx, error)) - else: - self.assertIsNone(await cog.on_command_error(self.ctx, error)) + self.assertIsNone(await cog.on_command_error(self.ctx, error)) + if case["try_silence_return"]: cog.try_get_tag.assert_not_awaited() cog.try_silence.assert_awaited_once() else: cog.try_silence.assert_awaited_once() - if case["patch_verification_id"]: - cog.try_get_tag.assert_not_awaited() - else: - cog.try_get_tag.assert_awaited_once() + cog.try_get_tag.assert_awaited_once() + self.ctx.send.assert_not_awaited() async def test_error_handler_command_not_found_error_invoked_by_handler(self): -- cgit v1.2.3 From 3855b4f81e678d93db99adbd7701599b0b29748c Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Fri, 19 Feb 2021 17:17:19 +0200 Subject: Update error handler tests to match with recent changes --- tests/bot/exts/backend/test_error_handler.py | 81 ++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index ea21a9f58..9b7b66cb2 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -4,11 +4,13 @@ from unittest.mock import AsyncMock, MagicMock, call, patch from discord.ext.commands import errors from bot.api import ResponseCodeError +from bot.errors import InvalidInfractedUser, LockedResourceError +from bot.exts.backend.branding._errors import BrandingError from bot.exts.backend.error_handler import ErrorHandler, setup from bot.exts.info.tags import Tags from bot.exts.moderation.silence import Silence from bot.utils.checks import InWhitelistCheckFailure -from tests.helpers import MockBot, MockContext, MockGuild +from tests.helpers import MockBot, MockContext, MockGuild, MockRole class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): @@ -123,20 +125,58 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): { "args": (self.ctx, errors.CommandInvokeError(TypeError)), "expect_mock_call": cog.handle_unexpected_error + }, + { + "args": (self.ctx, errors.CommandInvokeError(LockedResourceError("abc", "test"))), + "expect_mock_call": "send" + }, + { + "args": (self.ctx, errors.CommandInvokeError(BrandingError())), + "expect_mock_call": "send" + }, + { + "args": (self.ctx, errors.CommandInvokeError(InvalidInfractedUser(self.ctx.author))), + "expect_mock_call": "send" } ) for case in test_cases: with self.subTest(args=case["args"], expect_mock_call=case["expect_mock_call"]): + self.ctx.send.reset_mock() self.assertIsNone(await cog.on_command_error(*case["args"])) - case["expect_mock_call"].assert_awaited_once_with(self.ctx, case["args"][1].original) + if case["expect_mock_call"] == "send": + self.ctx.send.assert_awaited_once() + else: + case["expect_mock_call"].assert_awaited_once_with( + self.ctx, case["args"][1].original + ) - async def test_error_handler_three_other_errors(self): - """Should call `handle_unexpected_error` when `ConversionError`, `MaxConcurrencyReached` or `ExtensionError`.""" + async def test_error_handler_conversion_error(self): + """Should call `handle_api_error` or `handle_unexpected_error` depending on original error.""" + cog = ErrorHandler(self.bot) + cog.handle_api_error = AsyncMock() + cog.handle_unexpected_error = AsyncMock() + cases = ( + { + "error": errors.ConversionError(AsyncMock(), ResponseCodeError(AsyncMock())), + "mock_function_to_call": cog.handle_api_error + }, + { + "error": errors.ConversionError(AsyncMock(), TypeError), + "mock_function_to_call": cog.handle_unexpected_error + } + ) + + for case in cases: + with self.subTest(**case): + self.assertIsNone(await cog.on_command_error(self.ctx, case["error"])) + case["mock_function_to_call"].assert_awaited_once_with(self.ctx, case["error"].original) + + async def test_error_handler_two_other_errors(self): + """Should call `handle_unexpected_error` if error is `MaxConcurrencyReached` or `ExtensionError`.""" cog = ErrorHandler(self.bot) cog.handle_unexpected_error = AsyncMock() errs = ( - errors.ConversionError(MagicMock(), MagicMock()), errors.MaxConcurrencyReached(1, MagicMock()), errors.ExtensionError(name="foo") ) @@ -289,11 +329,34 @@ class TryGetTagTests(unittest.IsolatedAsyncioTestCase): self.assertIsNone(await self.cog.try_get_tag(self.ctx)) self.ctx.invoke.assert_awaited_once_with(self.tag.get_command, tag_name="foo") - async def test_try_get_tag_response_code_error_suppress(self): - """Should suppress `ResponseCodeError` when calling `ctx.invoke`.""" + async def test_dont_call_suggestion_tag_sent(self): + """Should never call command suggestion if tag is already sent.""" self.ctx.invoked_with = "foo" - self.ctx.invoke.side_effect = ResponseCodeError(MagicMock()) - self.assertIsNone(await self.cog.try_get_tag(self.ctx)) + self.ctx.invoke = AsyncMock(return_value=True) + self.cog.send_command_suggestion = AsyncMock() + + await self.cog.try_get_tag(self.ctx) + self.cog.send_command_suggestion.assert_not_awaited() + + @patch("bot.exts.backend.error_handler.MODERATION_ROLES", new=[1234]) + async def test_dont_call_suggestion_if_user_mod(self): + """Should not call command suggestion if user is a mod.""" + self.ctx.invoked_with = "foo" + self.ctx.invoke = AsyncMock(return_value=False) + self.ctx.author.roles = [MockRole(id=1234)] + self.cog.send_command_suggestion = AsyncMock() + + await self.cog.try_get_tag(self.ctx) + self.cog.send_command_suggestion.assert_not_awaited() + + async def test_call_suggestion(self): + """Should call command suggestion if user is not a mod.""" + self.ctx.invoked_with = "foo" + self.ctx.invoke = AsyncMock(return_value=False) + self.cog.send_command_suggestion = AsyncMock() + + await self.cog.try_get_tag(self.ctx) + self.cog.send_command_suggestion.assert_awaited_once_with(self.ctx, "foo") class IndividualErrorHandlerTests(unittest.IsolatedAsyncioTestCase): -- cgit v1.2.3 From 9ffe5b0146354936c7c67e43bd6682195ccedfdd Mon Sep 17 00:00:00 2001 From: kosayoda Date: Wed, 28 Apr 2021 16:43:52 +0800 Subject: Remove BrandingError check. This was removed in the branding manager rewrite: https://github.com/python-discord/bot/pull/1463/ --- tests/bot/exts/backend/test_error_handler.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'tests') diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index 9b7b66cb2..1b4729cbc 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -5,7 +5,6 @@ from discord.ext.commands import errors from bot.api import ResponseCodeError from bot.errors import InvalidInfractedUser, LockedResourceError -from bot.exts.backend.branding._errors import BrandingError from bot.exts.backend.error_handler import ErrorHandler, setup from bot.exts.info.tags import Tags from bot.exts.moderation.silence import Silence @@ -130,10 +129,6 @@ class ErrorHandlerTests(unittest.IsolatedAsyncioTestCase): "args": (self.ctx, errors.CommandInvokeError(LockedResourceError("abc", "test"))), "expect_mock_call": "send" }, - { - "args": (self.ctx, errors.CommandInvokeError(BrandingError())), - "expect_mock_call": "send" - }, { "args": (self.ctx, errors.CommandInvokeError(InvalidInfractedUser(self.ctx.author))), "expect_mock_call": "send" -- cgit v1.2.3 From e6bb1b321d9b657309c4c4c6f445f33a0e9e563e Mon Sep 17 00:00:00 2001 From: kosayoda Date: Wed, 28 Apr 2021 16:45:18 +0800 Subject: Address error behavior update. BadUnionArgument sends command help after: https://github.com/python-discord/bot/pull/1434 --- bot/exts/backend/error_handler.py | 4 ++-- tests/bot/exts/backend/test_error_handler.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/bot/exts/backend/error_handler.py b/bot/exts/backend/error_handler.py index f3bb3426a..d8de177f5 100644 --- a/bot/exts/backend/error_handler.py +++ b/bot/exts/backend/error_handler.py @@ -230,12 +230,12 @@ class ErrorHandler(Cog): elif isinstance(e, errors.BadUnionArgument): embed = self._get_error_embed("Bad argument", f"{e}\n{e.errors[-1]}") await ctx.send(embed=embed) - await prepared_help_command + await self.get_help_command(ctx) self.bot.stats.incr("errors.bad_union_argument") elif isinstance(e, errors.ArgumentParsingError): embed = self._get_error_embed("Argument parsing error", str(e)) await ctx.send(embed=embed) - prepared_help_command.close() + self.get_help_command(ctx).close() self.bot.stats.incr("errors.argument_parsing_error") else: embed = self._get_error_embed( diff --git a/tests/bot/exts/backend/test_error_handler.py b/tests/bot/exts/backend/test_error_handler.py index 1b4729cbc..bd4fb5942 100644 --- a/tests/bot/exts/backend/test_error_handler.py +++ b/tests/bot/exts/backend/test_error_handler.py @@ -379,7 +379,7 @@ class IndividualErrorHandlerTests(unittest.IsolatedAsyncioTestCase): }, { "error": errors.BadUnionArgument(MagicMock(), MagicMock(), MagicMock()), - "call_prepared": False + "call_prepared": True }, { "error": errors.ArgumentParsingError(), -- cgit v1.2.3