Esempio n. 1
0
 def setUp(self):
     self.bot = MockBot()
     self.admin_role = MockRole(name="Admins", id=Roles.admins)
     self.command_user = MockMember([self.admin_role])
     self.guild = MockGuild([self.admin_role])
     self.ctx = MockContext(bot=self.bot, author=self.command_user, guild=self.guild)
     self.cog = jams.CodeJams(self.bot)
Esempio n. 2
0
 def setUp(self):
     self.bot = MockBot()
     self.mod = MockMember(top_role=10)
     self.user = MockMember(top_role=1, roles=[MockRole(id=123456)])
     self.guild = MockGuild()
     self.ctx = MockContext(bot=self.bot, author=self.mod)
     self.cog = Infractions(self.bot)
Esempio n. 3
0
 def setUp(self):
     self.bot = MockBot()
     self.cog = Infractions(self.bot)
     self.user = MockMember(id=1234, top_role=MockRole(id=3577, position=10))
     self.target = MockMember(id=1265, top_role=MockRole(id=9876, position=0))
     self.guild = MockGuild(id=4567)
     self.ctx = MockContext(bot=self.bot, author=self.user, guild=self.guild)
Esempio n. 4
0
    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)
Esempio n. 5
0
 def setUp(self):
     self.bot = MockBot()
     self.mod = MockMember(roles=[MockRole(id=7890123, position=10)])
     self.user = MockMember(roles=[MockRole(id=123456, position=1)])
     self.guild = MockGuild()
     self.ctx = MockContext(bot=self.bot, author=self.mod)
     self.cog = Infractions(self.bot)
Esempio n. 6
0
 def setUp(self):
     self.me = MockMember(id=7890, roles=[MockRole(id=7890, position=5)])
     self.bot = MockBot()
     self.cog = Infractions(self.bot)
     self.user = MockMember(id=1234, roles=[MockRole(id=3577, position=10)])
     self.target = MockMember(id=1265,
                              roles=[MockRole(id=9876, position=1)])
     self.guild = MockGuild(id=4567)
     self.ctx = MockContext(me=self.me,
                            bot=self.bot,
                            author=self.user,
                            guild=self.guild)
Esempio n. 7
0
    async def test_force_voice_sync_no_channel(self):
        """Test to ensure _force_voice_sync can create its own voice channel if one is not available."""
        await self.cog._async_init()

        channel = MockVoiceChannel(guild=MockGuild(afk_channel=None))
        new_channel = MockVoiceChannel(delete=AsyncMock())
        channel.guild.create_voice_channel.return_value = new_channel

        await self.cog._force_voice_sync(channel)

        # Check channel creation
        overwrites = {
            channel.guild.default_role: PermissionOverwrite(speak=False, connect=False, view_channel=False)
        }
        channel.guild.create_voice_channel.assert_awaited_once_with("mute-temp", overwrites=overwrites)

        # Check bot deleted channel
        new_channel.delete.assert_awaited_once()
Esempio n. 8
0
class JamCreateTeamTests(unittest.IsolatedAsyncioTestCase):
    """Tests for `createteam` command."""

    def setUp(self):
        self.bot = MockBot()
        self.admin_role = MockRole(name="Admins", id=Roles.admins)
        self.command_user = MockMember([self.admin_role])
        self.guild = MockGuild([self.admin_role])
        self.ctx = MockContext(bot=self.bot, author=self.command_user, guild=self.guild)
        self.cog = jams.CodeJams(self.bot)

    async def test_too_small_amount_of_team_members_passed(self):
        """Should `ctx.send` and exit early when too small amount of members."""
        for case in (1, 2):
            with self.subTest(amount_of_members=case):
                self.cog.create_channels = AsyncMock()
                self.cog.add_roles = AsyncMock()

                self.ctx.reset_mock()
                members = (MockMember() for _ in range(case))
                await self.cog.createteam(self.cog, self.ctx, "foo", members)

                self.ctx.send.assert_awaited_once()
                self.cog.create_channels.assert_not_awaited()
                self.cog.add_roles.assert_not_awaited()

    async def test_duplicate_members_provided(self):
        """Should `ctx.send` and exit early because duplicate members provided and total there is only 1 member."""
        self.cog.create_channels = AsyncMock()
        self.cog.add_roles = AsyncMock()

        member = MockMember()
        await self.cog.createteam(self.cog, self.ctx, "foo", (member for _ in range(5)))

        self.ctx.send.assert_awaited_once()
        self.cog.create_channels.assert_not_awaited()
        self.cog.add_roles.assert_not_awaited()

    async def test_result_sending(self):
        """Should call `ctx.send` when everything goes right."""
        self.cog.create_channels = AsyncMock()
        self.cog.add_roles = AsyncMock()

        members = [MockMember() for _ in range(5)]
        await self.cog.createteam(self.cog, self.ctx, "foo", members)

        self.cog.create_channels.assert_awaited_once()
        self.cog.add_roles.assert_awaited_once()
        self.ctx.send.assert_awaited_once()

    async def test_category_doesnt_exist(self):
        """Should create a new code jam category."""
        subtests = (
            [],
            [get_mock_category(jams.MAX_CHANNELS - 1, jams.CATEGORY_NAME)],
            [get_mock_category(jams.MAX_CHANNELS - 2, "other")],
        )

        for categories in subtests:
            self.guild.reset_mock()
            self.guild.categories = categories

            with self.subTest(categories=categories):
                actual_category = await self.cog.get_category(self.guild)

                self.guild.create_category_channel.assert_awaited_once()
                category_overwrites = self.guild.create_category_channel.call_args[1]["overwrites"]

                self.assertFalse(category_overwrites[self.guild.default_role].read_messages)
                self.assertTrue(category_overwrites[self.guild.me].read_messages)
                self.assertEqual(self.guild.create_category_channel.return_value, actual_category)

    async def test_category_channel_exist(self):
        """Should not try to create category channel."""
        expected_category = get_mock_category(jams.MAX_CHANNELS - 2, jams.CATEGORY_NAME)
        self.guild.categories = [
            get_mock_category(jams.MAX_CHANNELS - 2, "other"),
            expected_category,
            get_mock_category(0, jams.CATEGORY_NAME),
        ]

        actual_category = await self.cog.get_category(self.guild)
        self.assertEqual(expected_category, actual_category)

    async def test_channel_overwrites(self):
        """Should have correct permission overwrites for users and roles."""
        leader = MockMember()
        members = [leader] + [MockMember() for _ in range(4)]
        overwrites = self.cog.get_overwrites(members, self.guild)

        # Leader permission overwrites
        self.assertTrue(overwrites[leader].manage_messages)
        self.assertTrue(overwrites[leader].read_messages)
        self.assertTrue(overwrites[leader].manage_webhooks)
        self.assertTrue(overwrites[leader].connect)

        # Other members permission overwrites
        for member in members[1:]:
            self.assertTrue(overwrites[member].read_messages)
            self.assertTrue(overwrites[member].connect)

        # Everyone and verified role overwrite
        self.assertFalse(overwrites[self.guild.default_role].read_messages)
        self.assertFalse(overwrites[self.guild.default_role].connect)
        self.assertFalse(overwrites[self.guild.get_role(Roles.verified)].read_messages)
        self.assertFalse(overwrites[self.guild.get_role(Roles.verified)].connect)

    async def test_team_channels_creation(self):
        """Should create new voice and text channel for team."""
        members = [MockMember() for _ in range(5)]

        self.cog.get_overwrites = MagicMock()
        self.cog.get_category = AsyncMock()
        self.ctx.guild.create_text_channel.return_value = MockTextChannel(mention="foobar-channel")
        actual = await self.cog.create_channels(self.guild, "my-team", members)

        self.assertEqual("foobar-channel", actual)
        self.cog.get_overwrites.assert_called_once_with(members, self.guild)
        self.cog.get_category.assert_awaited_once_with(self.guild)

        self.guild.create_text_channel.assert_awaited_once_with(
            "my-team",
            overwrites=self.cog.get_overwrites.return_value,
            category=self.cog.get_category.return_value
        )
        self.guild.create_voice_channel.assert_awaited_once_with(
            "My Team",
            overwrites=self.cog.get_overwrites.return_value,
            category=self.cog.get_category.return_value
        )

    async def test_jam_roles_adding(self):
        """Should add team leader role to leader and jam role to every team member."""
        leader_role = MockRole(name="Team Leader")
        jam_role = MockRole(name="Jammer")
        self.guild.get_role.side_effect = [leader_role, jam_role]

        leader = MockMember()
        members = [leader] + [MockMember() for _ in range(4)]
        await self.cog.add_roles(self.guild, members)

        leader.add_roles.assert_any_await(leader_role)
        for member in members:
            member.add_roles.assert_any_await(jam_role)
Esempio n. 9
0
class JamCodejamCreateTests(unittest.IsolatedAsyncioTestCase):
    """Tests for `codejam create` command."""

    def setUp(self):
        self.bot = MockBot()
        self.admin_role = MockRole(name="Admins", id=Roles.admins)
        self.command_user = MockMember([self.admin_role])
        self.guild = MockGuild([self.admin_role])
        self.ctx = MockContext(bot=self.bot, author=self.command_user, guild=self.guild)
        self.cog = _cog.CodeJams(self.bot)

    async def test_message_without_attachments(self):
        """If no link or attachments are provided, commands.BadArgument should be raised."""
        self.ctx.message.attachments = []

        with self.assertRaises(BadArgument):
            await self.cog.create(self.cog, self.ctx, None)

    @patch.object(_channels, "create_team_channel")
    @patch.object(_channels, "create_team_leader_channel")
    async def test_result_sending(self, create_leader_channel, create_team_channel):
        """Should call `ctx.send` when everything goes right."""
        self.ctx.message.attachments = [MockAttachment()]
        self.ctx.message.attachments[0].read = AsyncMock()
        self.ctx.message.attachments[0].read.return_value = TEST_CSV

        team_leaders = MockRole()

        self.guild.get_member.return_value = MockMember()

        self.ctx.guild.create_role = AsyncMock()
        self.ctx.guild.create_role.return_value = team_leaders
        self.cog.add_roles = AsyncMock()

        await self.cog.create(self.cog, self.ctx, None)

        create_team_channel.assert_awaited()
        create_leader_channel.assert_awaited_once_with(
            self.ctx.guild, team_leaders
        )
        self.ctx.send.assert_awaited_once()

    async def test_link_returning_non_200_status(self):
        """When the URL passed returns a non 200 status, it should send a message informing them."""
        self.bot.http_session.get.return_value = mock = MagicMock()
        mock.status = 404
        await self.cog.create(self.cog, self.ctx, "https://not-a-real-link.com")

        self.ctx.send.assert_awaited_once()

    @patch.object(_channels, "_send_status_update")
    async def test_category_doesnt_exist(self, update):
        """Should create a new code jam category."""
        subtests = (
            [],
            [get_mock_category(_channels.MAX_CHANNELS, _channels.CATEGORY_NAME)],
            [get_mock_category(_channels.MAX_CHANNELS - 2, "other")],
        )

        for categories in subtests:
            update.reset_mock()
            self.guild.reset_mock()
            self.guild.categories = categories

            with self.subTest(categories=categories):
                actual_category = await _channels._get_category(self.guild)

                update.assert_called_once()
                self.guild.create_category_channel.assert_awaited_once()
                category_overwrites = self.guild.create_category_channel.call_args[1]["overwrites"]

                self.assertFalse(category_overwrites[self.guild.default_role].read_messages)
                self.assertTrue(category_overwrites[self.guild.me].read_messages)
                self.assertEqual(self.guild.create_category_channel.return_value, actual_category)

    async def test_category_channel_exist(self):
        """Should not try to create category channel."""
        expected_category = get_mock_category(_channels.MAX_CHANNELS - 2, _channels.CATEGORY_NAME)
        self.guild.categories = [
            get_mock_category(_channels.MAX_CHANNELS - 2, "other"),
            expected_category,
            get_mock_category(0, _channels.CATEGORY_NAME),
        ]

        actual_category = await _channels._get_category(self.guild)
        self.assertEqual(expected_category, actual_category)

    async def test_channel_overwrites(self):
        """Should have correct permission overwrites for users and roles."""
        leader = (MockMember(), True)
        members = [leader] + [(MockMember(), False) for _ in range(4)]
        overwrites = _channels._get_overwrites(members, self.guild)

        for member, _ in members:
            self.assertTrue(overwrites[member].read_messages)

    @patch.object(_channels, "_get_overwrites")
    @patch.object(_channels, "_get_category")
    @autospec(_channels, "_add_team_leader_roles", pass_mocks=False)
    async def test_team_channels_creation(self, get_category, get_overwrites):
        """Should create a text channel for a team."""
        team_leaders = MockRole()
        members = [(MockMember(), True)] + [(MockMember(), False) for _ in range(5)]
        category = MockCategoryChannel()
        category.create_text_channel = AsyncMock()

        get_category.return_value = category
        await _channels.create_team_channel(self.guild, "my-team", members, team_leaders)

        category.create_text_channel.assert_awaited_once_with(
            "my-team",
            overwrites=get_overwrites.return_value
        )

    async def test_jam_roles_adding(self):
        """Should add team leader role to leader and jam role to every team member."""
        leader_role = MockRole(name="Team Leader")

        leader = MockMember()
        members = [(leader, True)] + [(MockMember(), False) for _ in range(4)]
        await _channels._add_team_leader_roles(members, leader_role)

        leader.add_roles.assert_awaited_once_with(leader_role)
        for member, is_leader in members:
            if not is_leader:
                member.add_roles.assert_not_awaited()
Esempio n. 10
0
    def test_server_info_command(self, time_since_patch):
        time_since_patch.return_value = '2 days ago'

        self.ctx.guild = MockGuild(
            features=('lemons', 'apples'),
            region="The Moon",
            roles=[self.moderator_role],
            channels=[
                discord.TextChannel(state={},
                                    guild=self.ctx.guild,
                                    data={
                                        'id': 42,
                                        'name': 'lemons-offering',
                                        'position': 22,
                                        'type': 'text'
                                    }),
                discord.CategoryChannel(state={},
                                        guild=self.ctx.guild,
                                        data={
                                            'id': 5125,
                                            'name': 'the-lemon-collection',
                                            'position': 22,
                                            'type': 'category'
                                        }),
                discord.VoiceChannel(state={},
                                     guild=self.ctx.guild,
                                     data={
                                         'id': 15290,
                                         'name': 'listen-to-lemon',
                                         'position': 22,
                                         'type': 'voice'
                                     })
            ],
            members=[
                *(MockMember(status='online') for _ in range(2)),
                *(MockMember(status='idle') for _ in range(1)),
                *(MockMember(status='dnd') for _ in range(4)),
                *(MockMember(status='offline') for _ in range(3)),
            ],
            member_count=1_234,
            icon_url='a-lemon.jpg',
        )

        coroutine = self.cog.server_info.callback(self.cog, self.ctx)
        self.assertIsNone(asyncio.run(coroutine))

        time_since_patch.assert_called_once_with(self.ctx.guild.created_at,
                                                 precision='days')
        _, kwargs = self.ctx.send.call_args
        embed = kwargs.pop('embed')
        self.assertEqual(embed.colour, discord.Colour.blurple())
        self.assertEqual(
            embed.description,
            textwrap.dedent(f"""
                **Server information**
                Created: {time_since_patch.return_value}
                Voice region: {self.ctx.guild.region}
                Features: {', '.join(self.ctx.guild.features)}

                **Counts**
                Members: {self.ctx.guild.member_count:,}
                Roles: {len(self.ctx.guild.roles)}
                Text: 1
                Voice: 1
                Channel categories: 1

                **Members**
                {constants.Emojis.status_online} 2
                {constants.Emojis.status_idle} 1
                {constants.Emojis.status_dnd} 4
                {constants.Emojis.status_offline} 3
                """))
        self.assertEqual(embed.thumbnail.url, 'a-lemon.jpg')