Example #1
0
    async def test_command(self, parser_mock):
        """Test that the command passes in the correct arguments for different calls."""
        test_cases = (
            (),
            (15, ),
            (MockTextChannel(),),
            (MockTextChannel(), 15),
        )

        ctx = MockContext()
        parser_mock.return_value = (ctx.channel, 10)

        for case in test_cases:
            with self.subTest("Test command converters", args=case):
                await self.cog.silence.callback(self.cog, ctx, *case)

                try:
                    first_arg = case[0]
                except IndexError:
                    # Default value when the first argument is not passed
                    first_arg = None

                try:
                    second_arg = case[1]
                except IndexError:
                    # Default value when the second argument is not passed
                    second_arg = 10

                parser_mock.assert_called_with(ctx, first_arg, second_arg)
Example #2
0
    async def test_async_init_got_notifier(self, notifier):
        """Notifier was started with channel."""
        self.bot.get_channel.side_effect = lambda id_: MockTextChannel(id=id_)

        await self.cog._async_init()
        notifier.assert_called_once_with(MockTextChannel(id=Channels.mod_log))
        self.assertEqual(self.cog.notifier, notifier.return_value)
Example #3
0
    async def test_rescheduled_active(self):
        """Rescheduled active silences."""
        channels = [MockTextChannel(id=123), MockTextChannel(id=456)]
        self.bot.get_channel.side_effect = channels
        self.cog.unsilence_timestamps.items.return_value = [(123, 2000),
                                                            (456, 3000)]
        silence.datetime.now.return_value = datetime.fromtimestamp(
            1000, tz=timezone.utc)

        self.cog._unsilence_wrapper = mock.MagicMock()
        unsilence_return = self.cog._unsilence_wrapper.return_value

        await self.cog._reschedule()

        # Yuck.
        calls = [
            mock.call(1000, 123, unsilence_return),
            mock.call(2000, 456, unsilence_return)
        ]
        self.cog.scheduler.schedule_later.assert_has_calls(calls)

        unsilence_calls = [mock.call(channel) for channel in channels]
        self.cog._unsilence_wrapper.assert_has_calls(unsilence_calls)

        self.cog.notifier.add_channel.assert_not_called()
Example #4
0
    async def test_try_silence_silence_arguments(self):
        """Should run silence with the correct channel, duration, and kick arguments."""
        self.bot.get_command.return_value.can_run = AsyncMock(
            return_value=True)

        test_cases = (
            (MockTextChannel(),
             None),  # None represents the case when no argument is passed
            (MockTextChannel(), False),
            (MockTextChannel(), True))

        for channel, kick in test_cases:
            with self.subTest(kick=kick, channel=channel):
                self.ctx.reset_mock()
                self.ctx.invoked_with = "shh"

                self.ctx.message.content = f"!shh {channel.name} {kick if kick is not None else ''}"
                self.ctx.guild.text_channels = [channel]

                self.assertTrue(await self.cog.try_silence(self.ctx))
                self.ctx.invoke.assert_awaited_once_with(
                    self.bot.get_command.return_value,
                    duration_or_channel=channel,
                    duration=4,
                    kick=(kick if kick is not None else False))
Example #5
0
    async def test_unsilenced_expired(self):
        """Unsilenced expired silences."""
        channels = [MockTextChannel(id=123), MockTextChannel(id=456)]
        self.bot.get_channel.side_effect = channels
        self.cog.unsilence_timestamps.items.return_value = [(123, 100), (456, 200)]

        await self.cog._reschedule()

        self.cog._unsilence_wrapper.assert_any_call(channels[0])
        self.cog._unsilence_wrapper.assert_any_call(channels[1])

        self.cog.notifier.add_channel.assert_not_called()
        self.cog.scheduler.schedule_later.assert_not_called()
Example #6
0
    async def test_added_permanent_to_notifier(self):
        """Permanently silenced channels were added to the notifier."""
        channels = [MockTextChannel(id=123), MockTextChannel(id=456)]
        self.bot.get_channel.side_effect = channels
        self.cog.unsilence_timestamps.items.return_value = [(123, -1), (456, -1)]

        await self.cog._reschedule()

        self.cog.notifier.add_channel.assert_any_call(channels[0])
        self.cog.notifier.add_channel.assert_any_call(channels[1])

        self.cog._unsilence_wrapper.assert_not_called()
        self.cog.scheduler.schedule_later.assert_not_called()
Example #7
0
    async def test_kick_not_called(self, ctx, sync, kick):
        """Tests that silence command does not call kick on a text channel."""
        channel = MockTextChannel()
        await self.cog.silence.callback(self.cog, ctx, channel, 10, kick=True)

        sync.assert_not_called()
        kick.assert_not_called()
Example #8
0
 async def test_instance_vars_got_notifier(self, notifier):
     """Notifier was started with channel."""
     mod_log = MockTextChannel()
     self.bot.get_channel.side_effect = (None, mod_log)
     await self.cog._get_instance_vars()
     notifier.assert_called_once_with(mod_log)
     self.bot.get_channel.side_effect = None
Example #9
0
def get_mock_category(channel_count: int, name: str) -> CategoryChannel:
    """Return a mocked code jam category."""
    category = create_autospec(CategoryChannel, spec_set=True, instance=True)
    category.name = name
    category.channels = [MockTextChannel() for _ in range(channel_count)]

    return category
Example #10
0
 async def test_unsilence_private_removed_notifier(self, notifier):
     """Channel was removed from `notifier` on unsilence."""
     perm_overwrite = MagicMock(send_messages=False)
     channel = MockTextChannel(overwrites_for=Mock(
         return_value=perm_overwrite))
     await self.cog._unsilence(channel)
     notifier.remove_channel.assert_called_once_with(channel)
Example #11
0
 async def test_silence_private_silenced_channel(self):
     """Channel had `send_message` permissions revoked."""
     channel = MockTextChannel()
     self.assertTrue(await self.cog._silence(channel, False, None))
     channel.set_permissions.assert_called_once()
     self.assertFalse(
         channel.set_permissions.call_args.kwargs['send_messages'])
Example #12
0
    def setUp(self) -> None:
        self.bot = MockBot(get_channel=lambda _: MockTextChannel())
        self.cog = silence.Silence(self.bot)
        self.cog._init_task = asyncio.Future()
        self.cog._init_task.set_result(None)

        overwrites_cache = mock.create_autospec(self.cog.previous_overwrites, spec_set=True)
        self.cog.previous_overwrites = overwrites_cache

        asyncio.run(self.cog._async_init())  # Populate instance attributes.

        self.cog.scheduler.__contains__.return_value = True
        overwrites_cache.get.return_value = '{"send_messages": true, "add_reactions": false}'
        self.channel = MockTextChannel()
        self.overwrite = PermissionOverwrite(stream=True, send_messages=False, add_reactions=False)
        self.channel.overwrites_for.return_value = self.overwrite
Example #13
0
    async def test_set_slowmode_no_channel(self) -> None:
        """Set slowmode without a given channel."""
        test_cases = (
            ('helpers', 23, True, f'{Emojis.check_mark} The slowmode delay for #helpers is now 23 seconds.'),
            ('mods', 76526, False, f'{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours.'),
            ('admins', 97, True, f'{Emojis.check_mark} The slowmode delay for #admins is now 1 minute and 37 seconds.')
        )

        for channel_name, seconds, edited, result_msg in test_cases:
            with self.subTest(
                channel_mention=channel_name,
                seconds=seconds,
                edited=edited,
                result_msg=result_msg
            ):
                self.ctx.channel = MockTextChannel(name=channel_name)

                await self.cog.set_slowmode(self.cog, self.ctx, None, relativedelta(seconds=seconds))

                if edited:
                    self.ctx.channel.edit.assert_awaited_once_with(slowmode_delay=float(seconds))
                else:
                    self.ctx.channel.edit.assert_not_called()

                self.ctx.send.assert_called_once_with(result_msg)

            self.ctx.reset_mock()
Example #14
0
    async def test_sent_correct_message(self):
        """Appropriate failure/success message was sent by the command."""
        unsilenced_overwrite = PermissionOverwrite(send_messages=True, add_reactions=True)
        test_cases = (
            (True, silence.MSG_UNSILENCE_SUCCESS, unsilenced_overwrite),
            (False, silence.MSG_UNSILENCE_FAIL, unsilenced_overwrite),
            (False, silence.MSG_UNSILENCE_MANUAL, self.text_overwrite),
            (False, silence.MSG_UNSILENCE_MANUAL, PermissionOverwrite(send_messages=False)),
            (False, silence.MSG_UNSILENCE_MANUAL, PermissionOverwrite(add_reactions=False)),
        )

        targets = (None, MockTextChannel())

        for (was_unsilenced, message, overwrite), target in itertools.product(test_cases, targets):
            ctx = MockContext()
            ctx.channel.overwrites_for.return_value = overwrite
            if target:
                target.overwrites_for.return_value = overwrite

            with mock.patch.object(self.cog, "_unsilence", return_value=was_unsilenced):
                with mock.patch.object(self.cog, "send_message") as send_message:
                    with self.subTest(was_unsilenced=was_unsilenced, overwrite=overwrite, target=target):
                        await self.cog.unsilence.callback(self.cog, ctx, channel=target)

                        call_args = (message, ctx.channel, target or ctx.channel)
                        send_message.assert_awaited_once_with(*call_args, alert_target=was_unsilenced)
Example #15
0
    async def test_set_slowmode_with_channel(self) -> None:
        """Set slowmode with a given channel."""
        test_cases = (
            ('bot-commands', 12, True, f'{Emojis.check_mark} The slowmode delay for #bot-commands is now 12 seconds.'),
            ('mod-spam', 21, True, f'{Emojis.check_mark} The slowmode delay for #mod-spam is now 21 seconds.'),
            ('admin-spam', 4323598, False, f'{Emojis.cross_mark} The slowmode delay must be between 0 and 6 hours.')
        )

        for channel_name, seconds, edited, result_msg in test_cases:
            with self.subTest(
                channel_mention=channel_name,
                seconds=seconds,
                edited=edited,
                result_msg=result_msg
            ):
                text_channel = MockTextChannel(name=channel_name)

                await self.cog.set_slowmode(self.cog, self.ctx, text_channel, relativedelta(seconds=seconds))

                if edited:
                    text_channel.edit.assert_awaited_once_with(slowmode_delay=float(seconds))
                else:
                    text_channel.edit.assert_not_called()

                self.ctx.send.assert_called_once_with(result_msg)

            self.ctx.reset_mock()
Example #16
0
    async def test_all_args(self):
        """Test the parser when both channel and duration are passed."""
        expected_channel = MockTextChannel()
        actual_channel, duration = self.cog.parse_silence_args(MockContext(), expected_channel, 15)

        self.assertEqual(expected_channel, actual_channel)
        self.assertEqual(15, duration)
Example #17
0
    async def test_channel_only(self):
        """Test the parser when just the channel argument is passed."""
        expected_channel = MockTextChannel()
        actual_channel, duration = self.cog.parse_silence_args(MockContext(), expected_channel, 10)

        self.assertEqual(expected_channel, actual_channel)
        self.assertEqual(10, duration)
Example #18
0
    async def test_get_slowmode_no_channel(self) -> None:
        """Get slowmode without a given channel."""
        self.ctx.channel = MockTextChannel(name='python-general',
                                           slowmode_delay=5)

        await self.cog.get_slowmode(self.cog, self.ctx, None)
        self.ctx.send.assert_called_once_with(
            "The slowmode delay for #python-general is 5 seconds.")
Example #19
0
 async def test_unsilence_private_removed_muted_channel(self, _):
     """Channel was removed from `muted_channels` on unsilence."""
     perm_overwrite = MagicMock(send_messages=False)
     channel = MockTextChannel(overwrites_for=Mock(
         return_value=perm_overwrite))
     with mock.patch.object(self.cog, "muted_channels") as muted_channels:
         await self.cog._unsilence(channel)
     muted_channels.discard.assert_called_once_with(channel)
Example #20
0
    def setUp(self):
        """For each test, ensure `bot.get_channel` returns a channel with 1 arbitrary message."""
        super().setUp()  # First ensure we get `cog_instance` from parent

        incidents_history = MagicMock(
            return_value=MockAsyncIterable([MockMessage()]))
        self.cog_instance.bot.get_channel = MagicMock(
            return_value=MockTextChannel(history=incidents_history))
Example #21
0
    def setUp(self) -> None:
        self.bot = MockBot()
        self.cog = silence.Silence(self.bot)

        self.text_channels = [MockTextChannel() for _ in range(2)]
        self.bot.get_channel.return_value = self.text_channels[1]

        self.voice_channel = MockVoiceChannel()
Example #22
0
    async def test_get_slowmode_with_channel(self) -> None:
        """Get slowmode with a given channel."""
        text_channel = MockTextChannel(name='python-language',
                                       slowmode_delay=2)

        await self.cog.get_slowmode(self.cog, self.ctx, text_channel)
        self.ctx.send.assert_called_once_with(
            'The slowmode delay for #python-language is 2 seconds.')
Example #23
0
    async def test_reset_slowmode_sets_delay_to_zero(self) -> None:
        """Reset slowmode with a given channel."""
        text_channel = MockTextChannel(name='meta', slowmode_delay=1)
        self.cog.set_slowmode = mock.AsyncMock()

        await self.cog.reset_slowmode(self.cog, self.ctx, text_channel)
        self.cog.set_slowmode.assert_awaited_once_with(
            self.ctx, text_channel, relativedelta(seconds=0))
Example #24
0
    async def test_reset_slowmode_with_channel(self) -> None:
        """Reset slowmode with a given channel."""
        text_channel = MockTextChannel(name='meta', slowmode_delay=1)

        await self.cog.reset_slowmode(self.cog, self.ctx, text_channel)
        self.ctx.send.assert_called_once_with(
            f'{Emojis.check_mark} The slowmode delay for #meta has been reset to 0 seconds.'
        )
Example #25
0
 def setUp(self) -> None:
     """Prepare a mock message which should qualify as an incident."""
     self.incident = MockMessage(
         channel=MockTextChannel(id=123),
         content="this is an incident",
         author=MockUser(bot=False),
         pinned=False,
     )
Example #26
0
    async def test_reset_slowmode_no_channel(self) -> None:
        """Reset slowmode without a given channel."""
        self.ctx.channel = MockTextChannel(name='careers', slowmode_delay=6)

        await self.cog.reset_slowmode(self.cog, self.ctx, None)
        self.ctx.send.assert_called_once_with(
            f'{Emojis.check_mark} The slowmode delay for #careers has been reset to 0 seconds.'
        )
Example #27
0
    async def test_skipped_already_unsilenced(self):
        """Permissions were not set and `False` was returned for an already unsilenced channel."""
        self.cog.scheduler.__contains__.return_value = False
        self.cog.previous_overwrites.get.return_value = None
        channel = MockTextChannel()

        self.assertFalse(await self.cog._unsilence(channel))
        channel.set_permissions.assert_not_called()
Example #28
0
    def setUp(self) -> None:
        self.bot = MockBot(get_channel=lambda _: MockTextChannel())
        self.cog = silence.Silence(self.bot)
        self.cog._init_task = asyncio.Future()
        self.cog._init_task.set_result(None)

        # Avoid unawaited coroutine warnings.
        self.cog.scheduler.schedule_later.side_effect = lambda delay, task_id, coro: coro.close()

        asyncio.run(self.cog._async_init())  # Populate instance attributes.

        self.text_channel = MockTextChannel()
        self.text_overwrite = PermissionOverwrite(send_messages=True, add_reactions=False)
        self.text_channel.overwrites_for.return_value = self.text_overwrite

        self.voice_channel = MockVoiceChannel()
        self.voice_overwrite = PermissionOverwrite(connect=True, speak=True)
        self.voice_channel.overwrites_for.return_value = self.voice_overwrite
Example #29
0
    async def test_skipped_already_silenced(self):
        """Permissions were not set and `False` was returned for an already silenced channel."""
        subtests = (
            (False, MockTextChannel(), PermissionOverwrite(send_messages=False, add_reactions=False)),
            (True, MockTextChannel(), PermissionOverwrite(send_messages=True, add_reactions=True)),
            (True, MockTextChannel(), PermissionOverwrite(send_messages=False, add_reactions=False)),
            (False, MockVoiceChannel(), PermissionOverwrite(connect=False, speak=False)),
            (True, MockVoiceChannel(), PermissionOverwrite(connect=True, speak=True)),
            (True, MockVoiceChannel(), PermissionOverwrite(connect=False, speak=False)),
        )

        for contains, channel, overwrite in subtests:
            with self.subTest(contains=contains, is_text=isinstance(channel, MockTextChannel), overwrite=overwrite):
                self.cog.scheduler.__contains__.return_value = contains
                channel.overwrites_for.return_value = overwrite

                self.assertFalse(await self.cog._set_silence_overwrites(channel))
                channel.set_permissions.assert_not_called()
Example #30
0
 async def test_unsilence_private_unsilenced_channel(self, _):
     """Channel had `send_message` permissions restored"""
     perm_overwrite = MagicMock(send_messages=False)
     channel = MockTextChannel(overwrites_for=Mock(
         return_value=perm_overwrite))
     self.assertTrue(await self.cog._unsilence(channel))
     channel.set_permissions.assert_called_once()
     self.assertIsNone(
         channel.set_permissions.call_args.kwargs['send_messages'])