Exemple #1
0
    async def test_confirmation_result_large_diff(self):
        """Should return True if confirmed and False if _send_prompt fails or aborted."""
        author = helpers.MockMember()
        mock_message = helpers.MockMessage()

        subtests = (
            (True, mock_message, True, "confirmed"),
            (False, None, False, "_send_prompt failed"),
            (False, mock_message, False, "aborted"),
        )

        for expected_result, expected_message, confirmed, msg in subtests:
            with self.subTest(msg=msg):
                self.syncer._send_prompt = helpers.AsyncMock(
                    return_value=expected_message)
                self.syncer._wait_for_confirmation = helpers.AsyncMock(
                    return_value=confirmed)

                coro = self.syncer._get_confirmation_result(4, author)
                actual_result, actual_message = await coro

                self.syncer._send_prompt.assert_called_once_with(
                    None)  # message defaults to None
                self.assertIs(actual_result, expected_result)
                self.assertEqual(actual_message, expected_message)

                if expected_message:
                    self.syncer._wait_for_confirmation.assert_called_once_with(
                        author, expected_message)
Exemple #2
0
    async def test_sync_respects_confirmation_result(self):
        """The sync should abort if confirmation fails and continue if confirmed."""
        mock_message = helpers.MockMessage()
        subtests = (
            (True, mock_message),
            (False, None),
        )

        for confirmed, message in subtests:
            with self.subTest(confirmed=confirmed):
                self.syncer._sync.reset_mock()
                self.syncer._get_diff.reset_mock()

                diff = _Diff({1, 2, 3}, {4, 5}, None)
                self.syncer._get_diff.return_value = diff
                self.syncer._get_confirmation_result = helpers.AsyncMock(
                    return_value=(confirmed, message))

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

                self.syncer._get_diff.assert_called_once_with(guild)
                self.syncer._get_confirmation_result.assert_called_once()

                if confirmed:
                    self.syncer._sync.assert_called_once_with(diff)
                else:
                    self.syncer._sync.assert_not_called()
Exemple #3
0
    async def test_sync_confirmation_context_redirect(self):
        """If ctx is given, a new message should be sent and author should be ctx's author."""
        mock_member = helpers.MockMember()
        subtests = (
            (None, self.bot.user, None),
            (helpers.MockContext(author=mock_member), mock_member,
             helpers.MockMessage()),
        )

        for ctx, author, message in subtests:
            with self.subTest(ctx=ctx, author=author, message=message):
                if ctx is not None:
                    ctx.send.return_value = message

                self.syncer._get_confirmation_result = helpers.AsyncMock(
                    return_value=(False, None))

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

                if ctx is not None:
                    ctx.send.assert_called_once()

                self.syncer._get_confirmation_result.assert_called_once()
                self.assertEqual(
                    self.syncer._get_confirmation_result.call_args[0][1],
                    author)
                self.assertEqual(
                    self.syncer._get_confirmation_result.call_args[0][2],
                    message)
Exemple #4
0
    def test_async_mock_provides_coroutine_for_dunder_call(self):
        """Test if AsyncMock objects have a coroutine for their __call__ method."""
        async_mock = helpers.AsyncMock()
        self.assertTrue(inspect.iscoroutinefunction(async_mock.__call__))

        coroutine = async_mock()
        self.assertTrue(inspect.iscoroutine(coroutine))
        self.assertIsNotNone(asyncio.run(coroutine))
Exemple #5
0
    async def test_confirmation_result_small_diff(self):
        """Should always return True and the given message if the diff size is too small."""
        author = helpers.MockMember()
        expected_message = helpers.MockMessage()

        for size in (3, 2):
            with self.subTest(size=size):
                self.syncer._send_prompt = helpers.AsyncMock()
                self.syncer._wait_for_confirmation = helpers.AsyncMock()

                coro = self.syncer._get_confirmation_result(
                    size, author, expected_message)
                result, actual_message = await coro

                self.assertTrue(result)
                self.assertEqual(actual_message, expected_message)
                self.syncer._send_prompt.assert_not_called()
                self.syncer._wait_for_confirmation.assert_not_called()
    def test_role_info_command(self):
        """Tests the `role info` command."""
        dummy_role = helpers.MockRole(name="Dummy",
                                      role_id=112233445566778899,
                                      colour=discord.Colour.blurple(),
                                      position=10,
                                      members=[self.ctx.author],
                                      permissions=discord.Permissions(0))

        admin_role = helpers.MockRole(
            name="Admins",
            role_id=998877665544332211,
            colour=discord.Colour.red(),
            position=3,
            members=[self.ctx.author],
            permissions=discord.Permissions(0),
        )

        self.ctx.guild.roles.append([dummy_role, admin_role])

        self.cog.role_info.can_run = helpers.AsyncMock()
        self.cog.role_info.can_run.return_value = True

        coroutine = self.cog.role_info.callback(self.cog, self.ctx, dummy_role,
                                                admin_role)

        self.assertIsNone(asyncio.run(coroutine))

        self.assertEqual(self.ctx.send.call_count, 2)

        (_, dummy_kwargs), (_, admin_kwargs) = self.ctx.send.call_args_list

        dummy_embed = dummy_kwargs["embed"]
        admin_embed = admin_kwargs["embed"]

        self.assertEqual(dummy_embed.title, "Dummy info")
        self.assertEqual(dummy_embed.colour, discord.Colour.blurple())

        self.assertEqual(dummy_embed.fields[0].value, str(dummy_role.id))
        self.assertEqual(dummy_embed.fields[1].value,
                         f"#{dummy_role.colour.value:0>6x}")
        self.assertEqual(dummy_embed.fields[2].value, "0.63 0.48 218")
        self.assertEqual(dummy_embed.fields[3].value, "1")
        self.assertEqual(dummy_embed.fields[4].value, "10")
        self.assertEqual(dummy_embed.fields[5].value, "0")

        self.assertEqual(admin_embed.title, "Admins info")
        self.assertEqual(admin_embed.colour, discord.Colour.red())
Exemple #7
0
    def test_roles_command_command(self):
        """Test if the `role_info` command correctly returns the `moderator_role`."""
        self.ctx.guild.roles.append(self.moderator_role)

        self.cog.roles_info.can_run = helpers.AsyncMock()
        self.cog.roles_info.can_run.return_value = True

        coroutine = self.cog.roles_info.callback(self.cog, self.ctx)

        self.assertIsNone(asyncio.run(coroutine))
        self.ctx.send.assert_called_once()

        _, kwargs = self.ctx.send.call_args
        embed = kwargs.pop('embed')

        self.assertEqual(embed.title, "Role information")
        self.assertEqual(embed.colour, discord.Colour.blurple())
        self.assertEqual(embed.description, f"`{self.moderator_role.id}` - {self.moderator_role.mention}\n")
        self.assertEqual(embed.footer.text, "Total roles: 1")
Exemple #8
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 = helpers.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])
Exemple #9
0
    async def test_sync_diff_size(self):
        """The diff size should be correctly calculated."""
        subtests = (
            (6, _Diff({1, 2}, {3, 4}, {5, 6})),
            (5, _Diff({1, 2, 3}, None, {4, 5})),
            (0, _Diff(None, None, None)),
            (0, _Diff(set(), set(), set())),
        )

        for size, diff in subtests:
            with self.subTest(size=size, diff=diff):
                self.syncer._get_diff.reset_mock()
                self.syncer._get_diff.return_value = diff
                self.syncer._get_confirmation_result = helpers.AsyncMock(
                    return_value=(False, None))

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

                self.syncer._get_diff.assert_called_once_with(guild)
                self.syncer._get_confirmation_result.assert_called_once()
                self.assertEqual(
                    self.syncer._get_confirmation_result.call_args[0][0], size)
Exemple #10
0
            def __init__(self, **kwargs):
                super().__init__(spec=helpers.bot_instance, **kwargs)

                # Fake attribute
                self.release_the_walrus = helpers.AsyncMock()
Exemple #11
0
 def setUp(self):
     """Common set-up steps done before for each test."""
     self.bot = helpers.MockBot()
     self.bot.api_client.get = helpers.AsyncMock()
     self.cog = information.Information(self.bot)
Exemple #12
0
class UserEmbedTests(unittest.TestCase):
    """Tests for the creation of the `!user` embed."""
    def setUp(self):
        """Common set-up steps done before for each test."""
        self.bot = helpers.MockBot()
        self.bot.api_client.get = helpers.AsyncMock()
        self.cog = information.Information(self.bot)

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_uses_string_representation_of_user_in_title_if_nick_is_not_available(
            self):
        """The embed should use the string representation of the user if they don't have a nick."""
        ctx = helpers.MockContext(channel=helpers.MockTextChannel(
            channel_id=1))
        user = helpers.MockMember()
        user.nick = None
        user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock")

        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        self.assertEqual(embed.title, "Mr. Hemlock")

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_uses_nick_in_title_if_available(self):
        """The embed should use the nick if it's available."""
        ctx = helpers.MockContext(channel=helpers.MockTextChannel(
            channel_id=1))
        user = helpers.MockMember()
        user.nick = "Cat lover"
        user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock")

        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        self.assertEqual(embed.title, "Cat lover (Mr. Hemlock)")

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_ignores_everyone_role(self):
        """Created `!user` embeds should not contain mention of the @everyone-role."""
        ctx = helpers.MockContext(channel=helpers.MockTextChannel(
            channel_id=1))
        admins_role = helpers.MockRole('Admins')
        admins_role.colour = 100

        # A `MockMember` has the @Everyone role by default; we add the Admins to that.
        user = helpers.MockMember(roles=[admins_role], top_role=admins_role)

        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        self.assertIn("&Admins", embed.description)
        self.assertNotIn("&Everyone", embed.description)

    @unittest.mock.patch(f"{COG_PATH}.expanded_user_infraction_counts",
                         new_callable=helpers.AsyncMock)
    @unittest.mock.patch(f"{COG_PATH}.user_nomination_counts",
                         new_callable=helpers.AsyncMock)
    def test_create_user_embed_expanded_information_in_moderation_channels(
            self, nomination_counts, infraction_counts):
        """The embed should contain expanded infractions and nomination info in mod channels."""
        ctx = helpers.MockContext(channel=helpers.MockTextChannel(
            channel_id=50))

        moderators_role = helpers.MockRole('Moderators')
        moderators_role.colour = 100

        infraction_counts.return_value = "expanded infractions info"
        nomination_counts.return_value = "nomination info"

        user = helpers.MockMember(user_id=314,
                                  roles=[moderators_role],
                                  top_role=moderators_role)
        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        infraction_counts.assert_called_once_with(user)
        nomination_counts.assert_called_once_with(user)

        self.assertEqual(
            textwrap.dedent(f"""
                **User Information**
                Created: {"1 year ago"}
                Profile: {user.mention}
                ID: {user.id}

                **Member Information**
                Joined: {"1 year ago"}
                Roles: &Moderators

                expanded infractions info

                nomination info
            """).strip(), embed.description)

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new_callable=helpers.AsyncMock)
    def test_create_user_embed_basic_information_outside_of_moderation_channels(
            self, infraction_counts):
        """The embed should contain only basic infraction data outside of mod channels."""
        ctx = helpers.MockContext(channel=helpers.MockTextChannel(
            channel_id=100))

        moderators_role = helpers.MockRole('Moderators')
        moderators_role.colour = 100

        infraction_counts.return_value = "basic infractions info"

        user = helpers.MockMember(user_id=314,
                                  roles=[moderators_role],
                                  top_role=moderators_role)
        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        infraction_counts.assert_called_once_with(user)

        self.assertEqual(
            textwrap.dedent(f"""
                **User Information**
                Created: {"1 year ago"}
                Profile: {user.mention}
                ID: {user.id}

                **Member Information**
                Joined: {"1 year ago"}
                Roles: &Moderators

                basic infractions info
            """).strip(), embed.description)

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_uses_top_role_colour_when_user_has_roles(self):
        """The embed should be created with the colour of the top role, if a top role is available."""
        ctx = helpers.MockContext()

        moderators_role = helpers.MockRole('Moderators')
        moderators_role.colour = 100

        user = helpers.MockMember(user_id=314,
                                  roles=[moderators_role],
                                  top_role=moderators_role)
        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        self.assertEqual(embed.colour, discord.Colour(moderators_role.colour))

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_uses_blurple_colour_when_user_has_no_roles(
            self):
        """The embed should be created with a blurple colour if the user has no assigned roles."""
        ctx = helpers.MockContext()

        user = helpers.MockMember(user_id=217)
        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        self.assertEqual(embed.colour, discord.Colour.blurple())

    @unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts",
                         new=helpers.AsyncMock(return_value=""))
    def test_create_user_embed_uses_png_format_of_user_avatar_as_thumbnail(
            self):
        """The embed thumbnail should be set to the user's avatar in `png` format."""
        ctx = helpers.MockContext()

        user = helpers.MockMember(user_id=217)
        user.avatar_url_as.return_value = "avatar url"
        embed = asyncio.run(self.cog.create_user_embed(ctx, user))

        user.avatar_url_as.assert_called_once_with(format="png")
        self.assertEqual(embed.thumbnail.url, "avatar url")
Exemple #13
0
class TestSyncer(Syncer):
    """Syncer subclass with mocks for abstract methods for testing purposes."""

    name = "test"
    _get_diff = helpers.AsyncMock()
    _sync = helpers.AsyncMock()
Exemple #14
0
 def setUp(self):
     super().setUp()
     self.cog.patch_user = helpers.AsyncMock(spec_set=self.cog.patch_user)