Пример #1
0
    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()
Пример #2
0
    async def test_user_not_found_none_post_infraction(self, post_user_mock):
        """Should abort and return `None` when a new user fails to be posted."""
        self.bot.api_client.post.side_effect = ResponseCodeError(MagicMock(status=400), {"user": "******"})

        actual = await utils.post_infraction(self.ctx, self.user, "mute", "Test reason")
        self.assertIsNone(actual)
        post_user_mock.assert_awaited_once_with(self.ctx, self.user)
Пример #3
0
    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()
Пример #4
0
    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
            },
            {
                "args": (self.ctx, errors.CommandInvokeError(LockedResourceError("abc", "test"))),
                "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"]))
                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
                    )
Пример #5
0
    async def test_unknown_error_post_infraction(self):
        """Should send an error message to chat when a non-400 error occurs."""
        self.ctx.bot.api_client.post.side_effect = ResponseCodeError(AsyncMock(), AsyncMock())
        self.ctx.bot.api_client.post.side_effect.status = 500

        actual = await utils.post_infraction(self.ctx, self.user, "ban", "Test reason")
        self.assertIsNone(actual)

        self.assertTrue("500" in self.ctx.send.call_args[0][0])
Пример #6
0
    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 = {
            "actor": self.ctx.author.id,
            "hidden": False,
            "reason": "Test reason",
            "type": "mute",
            "user": self.user.id,
            "active": True
        }

        self.bot.api_client.post.side_effect = [ResponseCodeError(MagicMock(status=400), {"user": "******"}), "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)
Пример #7
0
    async def test_sync_message_edited(self):
        """The message should be edited if one was sent, even if the sync has an API error."""
        subtests = (
            (None, None, False),
            (helpers.MockMessage(), None, True),
            (helpers.MockMessage(), ResponseCodeError(mock.MagicMock()), True),
        )

        for message, side_effect, should_edit in subtests:
            with self.subTest(message=message, side_effect=side_effect, should_edit=should_edit):
                TestSyncer._sync.side_effect = side_effect
                ctx = helpers.MockContext()
                ctx.send.return_value = message

                await TestSyncer.sync(self.guild, ctx)

                if should_edit:
                    message.edit.assert_called_once()
                    self.assertIn("content", message.edit.call_args[1])
Пример #8
0
    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)
Пример #9
0
    async def test_sync_message_edited(self):
        """The message should be edited if one was sent, even if the sync has an API error."""
        subtests = (
            (None, None, False),
            (helpers.MockMessage(), None, True),
            (helpers.MockMessage(), ResponseCodeError(mock.MagicMock()), True),
        )

        for message, side_effect, should_edit in subtests:
            with self.subTest(message=message,
                              side_effect=side_effect,
                              should_edit=should_edit):
                self.syncer._sync.side_effect = side_effect
                self.syncer._get_confirmation_result = mock.AsyncMock(
                    return_value=(True, message))

                guild = helpers.MockGuild()
                await self.syncer.sync(guild)

                if should_edit:
                    message.edit.assert_called_once()
                    self.assertIn("content", message.edit.call_args[1])
Пример #10
0
    async def test_post_user(self):
        """Should POST a new user and return the response if successful or otherwise send an error message."""
        user = MockUser(discriminator=5678, id=1234, name="Test user")
        not_user = MagicMock(discriminator=3333, id=5678, name="Wrong user")
        test_cases = [
            {
                "user": user,
                "post_result": "bar",
                "raise_error": None,
                "payload": {
                    "discriminator": 5678,
                    "id": self.user.id,
                    "in_guild": False,
                    "name": "Test user",
                    "roles": []
                }
            },
            {
                "user": self.member,
                "post_result": "foo",
                "raise_error": ResponseCodeError(MagicMock(status=400), "foo"),
                "payload": {
                    "discriminator": 0,
                    "id": self.member.id,
                    "in_guild": False,
                    "name": "Name unknown",
                    "roles": []
                }
            },
            {
                "user": not_user,
                "post_result": "bar",
                "raise_error": None,
                "payload": {
                    "discriminator": not_user.discriminator,
                    "id": not_user.id,
                    "in_guild": False,
                    "name": not_user.name,
                    "roles": []
                }
            }
        ]

        for case in test_cases:
            user = case["user"]
            post_result = case["post_result"]
            raise_error = case["raise_error"]
            payload = case["payload"]

            with self.subTest(user=user, post_result=post_result, raise_error=raise_error, payload=payload):
                self.bot.api_client.post.reset_mock(side_effect=True)
                self.ctx.bot.api_client.post.return_value = post_result

                self.ctx.bot.api_client.post.side_effect = raise_error

                result = await utils.post_user(self.ctx, user)

                if raise_error:
                    self.assertIsNone(result)
                    self.ctx.send.assert_awaited_once()
                    self.assertIn(str(raise_error.status), self.ctx.send.call_args[0][0])
                else:
                    self.assertEqual(result, post_result)
                    self.bot.api_client.post.assert_awaited_once_with("bot/users", json=payload)
Пример #11
0
    def response_error(status: int) -> ResponseCodeError:
        """Fixture to return a ResponseCodeError with the given status code."""
        response = mock.MagicMock()
        response.status = status

        return ResponseCodeError(response)