示例#1
0
    def test_moderators_can_target_another_member(self, create_embed,
                                                  constants):
        """A moderator should be able to use `!user` targeting another user."""
        constants.MODERATION_ROLES = [self.moderator_role.id]
        constants.STAFF_ROLES = [self.moderator_role.id]

        ctx = helpers.MockContext(author=self.moderator,
                                  channel=helpers.MockTextChannel(id=50))

        asyncio.run(self.cog.user_info.callback(self.cog, ctx, self.target))

        create_embed.assert_called_once_with(ctx, self.target)
        ctx.send.assert_called_once()
示例#2
0
    async 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(id=1))
        admins_role = helpers.MockRole(name='Admins')
        admins_role.colour = 100

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

        embed = await self.cog.create_user_embed(ctx, user)

        self.assertIn("&Admins", embed.fields[1].value)
        self.assertNotIn("&Everyone", embed.fields[1].value)
示例#3
0
    def test_regular_user_can_explicitly_target_themselves(
            self, create_embed, constants):
        """A user should target itself with `!user` when a `user` argument was not provided."""
        constants.STAFF_ROLES = [self.moderator_role.id]
        constants.Channels.bot_commands = 50

        ctx = helpers.MockContext(author=self.author,
                                  channel=helpers.MockTextChannel(id=50))

        asyncio.run(self.cog.user_info.callback(self.cog, ctx, self.author))

        create_embed.assert_called_once_with(ctx, self.author)
        ctx.send.assert_called_once()
示例#4
0
    def test_staff_members_can_bypass_channel_restriction(
            self, create_embed, constants):
        """Staff members should be able to bypass the bot-commands channel restriction."""
        constants.STAFF_ROLES = [self.moderator_role.id]
        constants.Channels.bot_commands = 50

        ctx = helpers.MockContext(author=self.moderator,
                                  channel=helpers.MockTextChannel(id=200))

        asyncio.run(self.cog.user_info.callback(self.cog, ctx))

        create_embed.assert_called_once_with(ctx, self.moderator)
        ctx.send.assert_called_once()
示例#5
0
    def test_regular_member_cannot_use_command_outside_of_bot_commands(
            self, constants):
        """A regular user should not be able to use this command outside of bot-commands."""
        constants.MODERATION_ROLES = [self.moderator_role.id]
        constants.STAFF_ROLES = [self.moderator_role.id]
        constants.Channels.bot_commands = 50

        ctx = helpers.MockContext(author=self.author,
                                  channel=helpers.MockTextChannel(id=100))

        msg = "Sorry, but you may only use this command within <#50>."
        with self.assertRaises(InWhitelistCheckFailure, msg=msg):
            asyncio.run(self.cog.user_info.callback(self.cog, ctx))
示例#6
0
    def test_regular_user_may_use_command_in_bot_commands_channel(
            self, create_embed, constants):
        """A regular user should be allowed to use `!user` targeting themselves in bot-commands."""
        constants.STAFF_ROLES = [self.moderator_role.id]
        constants.Channels.bot_commands = 50

        ctx = helpers.MockContext(author=self.author,
                                  channel=helpers.MockTextChannel(id=50))

        asyncio.run(self.cog.user_info.callback(self.cog, ctx))

        create_embed.assert_called_once_with(ctx, self.author)
        ctx.send.assert_called_once()
示例#7
0
    async 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(id=1))
        user = helpers.MockMember()
        user.public_flags = unittest.mock.MagicMock(verified_bot=False)
        user.nick = None
        user.__str__ = unittest.mock.Mock(return_value="Mr. Hemlock")
        user.colour = 0

        embed = await self.cog.create_user_embed(ctx, user)

        self.assertEqual(embed.title, "Mr. Hemlock")
示例#8
0
    def test_on_raw_reaction_remove_ignores_removal_of_non_checkmark_reactions(self):
        """The `on_raw_reaction_remove` listener should ignore the removal of non-check mark emojis."""
        channel = helpers.MockTextChannel(id=98765)

        channel.fetch_message.side_effect = AssertionError(
            "Expected method to return before calling `channel.fetch_message`"
        )

        self.bot.get_all_channels.return_value = (channel, )

        payload = MagicMock(emoji=helpers.MockPartialEmoji(name=self.thumbs_up_emoji), channel_id=channel.id)

        self.assertIsNone(asyncio.run(self.cog.on_raw_reaction_remove(payload)))

        channel.fetch_message.assert_not_called()
示例#9
0
    def _raw_reaction_mocks(self, channel_id, message_id, user_id):
        """Sets up mocks for tests of the `on_raw_reaction_add` event listener."""
        channel = helpers.MockTextChannel(id=channel_id)
        self.bot.get_all_channels.return_value = (channel,)

        message = helpers.MockMessage(id=message_id)

        channel.fetch_message.return_value = message

        member = helpers.MockMember(id=user_id, roles=[self.staff_role])
        message.guild.members = (member,)

        payload = MagicMock(channel_id=channel_id, message_id=message_id, user_id=user_id)

        return channel, message, member, payload
示例#10
0
    async def test_on_raw_reaction_remove_prevents_removal_of_green_checkmark_depending_on_the_duck_count(
            self):
        """The `on_raw_reaction_remove` listener prevents removal of the check mark on messages with enough ducks."""
        checkmark = helpers.MockPartialEmoji(name=self.checkmark_emoji)

        message = helpers.MockMessage(id=1234)

        channel = helpers.MockTextChannel(id=98765)
        channel.fetch_message.return_value = message

        self.bot.get_all_channels.return_value = (channel, )

        payload = MagicMock(channel_id=channel.id,
                            message_id=message.id,
                            emoji=checkmark)

        test_cases = (
            (constants.DuckPond.threshold - 1, False),
            (constants.DuckPond.threshold, True),
            (constants.DuckPond.threshold + 1, True),
        )
        for duck_count, should_re_add_checkmark in test_cases:
            with patch(f"{MODULE_PATH}.DuckPond.count_ducks",
                       new_callable=helpers.AsyncMock) as count_ducks:
                count_ducks.return_value = duck_count
                with self.subTest(
                        duck_count=duck_count,
                        should_re_add_checkmark=should_re_add_checkmark):
                    await self.cog.on_raw_reaction_remove(payload)

                    # Check if we fetched the message
                    channel.fetch_message.assert_called_once_with(message.id)

                    # Check if we actually counted the number of ducks
                    count_ducks.assert_called_once_with(message)

                    has_re_added_checkmark = message.add_reaction.called
                    self.assertEqual(should_re_add_checkmark,
                                     has_re_added_checkmark)

                    if should_re_add_checkmark:
                        message.add_reaction.assert_called_once_with(
                            self.checkmark_emoji)
                        message.add_reaction.reset_mock()

                    # reset mocks
                    channel.fetch_message.reset_mock()
                    message.reset_mock()
示例#11
0
    def setUp(self):
        """Set up steps executed before each test is run."""
        self.bot = helpers.MockBot()
        self.cog = information.Information(self.bot)

        self.moderator_role = helpers.MockRole(name="Moderators", id=2, position=10)
        self.flautist_role = helpers.MockRole(name="Flautists", id=3, position=2)
        self.bassist_role = helpers.MockRole(name="Bassists", id=4, position=3)

        self.author = helpers.MockMember(id=1, name="syntaxaire")
        self.moderator = helpers.MockMember(id=2, name="riffautae", roles=[self.moderator_role])
        self.target = helpers.MockMember(id=3, name="__fluzz__")

        # There's no way to mock the channel constant without deferring imports. The constant is
        # used as a default value for a parameter, which gets defined upon import.
        self.bot_command_channel = helpers.MockTextChannel(id=constants.Channels.bot_commands)
示例#12
0
    def test_mocks_rejects_access_to_attributes_not_part_of_spec(self):
        """Accessing attributes that are invalid for the objects they mock should fail."""
        mocks = (
            helpers.MockGuild(),
            helpers.MockRole(),
            helpers.MockMember(),
            helpers.MockBot(),
            helpers.MockContext(),
            helpers.MockTextChannel(),
            helpers.MockMessage(),
        )

        for mock in mocks:
            with self.subTest(mock=mock):
                with self.assertRaises(AttributeError):
                    mock.the_cake_is_a_lie
示例#13
0
    def test_mocks_allows_access_to_attributes_part_of_spec(self):
        """Accessing attributes that are valid for the objects they mock should succeed."""
        mocks = (
            (helpers.MockGuild(), 'name'),
            (helpers.MockRole(), 'hoist'),
            (helpers.MockMember(), 'display_name'),
            (helpers.MockBot(), 'user'),
            (helpers.MockContext(), 'invoked_with'),
            (helpers.MockTextChannel(), 'last_message'),
            (helpers.MockMessage(), 'mention_everyone'),
        )

        for mock, valid_attribute in mocks:
            with self.subTest(mock=mock):
                try:
                    getattr(mock, valid_attribute)
                except AttributeError:
                    msg = f"accessing valid attribute `{valid_attribute}` raised an AttributeError"
                    self.fail(msg)
示例#14
0
    async 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(id=50))

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

        infraction_counts.return_value = ("Infractions", "expanded infractions info")
        nomination_counts.return_value = ("Nominations", "nomination info")

        user = helpers.MockMember(id=314, roles=[moderators_role], top_role=moderators_role)
        embed = await 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"""
                Created: {"1 year ago"}
                Profile: {user.mention}
                ID: {user.id}
            """).strip(),
            embed.fields[0].value
        )

        self.assertEqual(
            textwrap.dedent(f"""
                Joined: {"1 year ago"}
                Verified: {"False"}
                Roles: &Moderators
            """).strip(),
            embed.fields[1].value
        )