class OtherErrorHandlerTests(unittest.IsolatedAsyncioTestCase): """Other `ErrorHandler` tests.""" def setUp(self): self.bot = MockBot() self.ctx = MockContext() async def test_get_help_command_command_specified(self): """Should return coroutine of help command of specified command.""" self.ctx.command = "foo" result = ErrorHandler.get_help_command(self.ctx) expected = self.ctx.send_help("foo") self.assertEqual(result.__qualname__, expected.__qualname__) self.assertEqual(result.cr_frame.f_locals, expected.cr_frame.f_locals) # Await coroutines to avoid warnings await result await expected async def test_get_help_command_no_command_specified(self): """Should return coroutine of help command.""" self.ctx.command = None result = ErrorHandler.get_help_command(self.ctx) expected = self.ctx.send_help() self.assertEqual(result.__qualname__, expected.__qualname__) self.assertEqual(result.cr_frame.f_locals, expected.cr_frame.f_locals) # Await coroutines to avoid warnings await result await expected
async def test_send_eval_with_non_zero_eval(self): """Test the send_eval function with a code returning a non-zero code.""" ctx = MockContext() ctx.message = MockMessage() ctx.send = AsyncMock() ctx.author.mention = '@LemonLemonishBeard#0042' self.cog.post_eval = AsyncMock(return_value={ 'stdout': 'ERROR', 'returncode': 127 }) self.cog.get_results_message = MagicMock( return_value=('Return code 127', 'Beard got stuck in the eval')) self.cog.get_status_emoji = MagicMock(return_value=':nope!:') self.cog.format_output = AsyncMock() # This function isn't called mocked_filter_cog = MagicMock() mocked_filter_cog.filter_eval = AsyncMock(return_value=False) self.bot.get_cog.return_value = mocked_filter_cog await self.cog.send_eval(ctx, 'MyAwesomeCode') ctx.send.assert_called_once_with( '@LemonLemonishBeard#0042 :nope!: Return code 127.\n\n```\nBeard got stuck in the eval\n```' ) self.cog.post_eval.assert_called_once_with('MyAwesomeCode') self.cog.get_status_emoji.assert_called_once_with({ 'stdout': 'ERROR', 'returncode': 127 }) self.cog.get_results_message.assert_called_once_with({ 'stdout': 'ERROR', 'returncode': 127 }) self.cog.format_output.assert_not_called()
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_send_eval(self): """Test the send_eval function.""" ctx = MockContext() ctx.message = MockMessage() ctx.send = AsyncMock() ctx.author.mention = '@LemonLemonishBeard#0042' self.cog.post_eval = AsyncMock(return_value={ 'stdout': '', 'returncode': 0 }) self.cog.get_results_message = MagicMock(return_value=('Return code 0', '')) self.cog.get_status_emoji = MagicMock(return_value=':yay!:') self.cog.format_output = AsyncMock(return_value=('[No output]', None)) await self.cog.send_eval(ctx, 'MyAwesomeCode') ctx.send.assert_called_once_with( '@LemonLemonishBeard#0042 :yay!: Return code 0.\n\n```py\n[No output]\n```' ) self.cog.post_eval.assert_called_once_with('MyAwesomeCode') self.cog.get_status_emoji.assert_called_once_with({ 'stdout': '', 'returncode': 0 }) self.cog.get_results_message.assert_called_once_with({ 'stdout': '', 'returncode': 0 }) self.cog.format_output.assert_called_once_with('')
async def test_send_eval_with_paste_link(self): """Test the send_eval function with a too long output that generate a paste link.""" ctx = MockContext() ctx.message = MockMessage() ctx.send = AsyncMock() ctx.author.mention = '@LemonLemonishBeard#0042' self.cog.post_eval = AsyncMock(return_value={ 'stdout': 'Way too long beard', 'returncode': 0 }) self.cog.get_results_message = MagicMock(return_value=('Return code 0', '')) self.cog.get_status_emoji = MagicMock(return_value=':yay!:') self.cog.format_output = AsyncMock(return_value=('Way too long beard', 'lookatmybeard.com')) await self.cog.send_eval(ctx, 'MyAwesomeCode') ctx.send.assert_called_once_with( '@LemonLemonishBeard#0042 :yay!: Return code 0.' '\n\n```py\nWay too long beard\n```\nFull output: lookatmybeard.com' ) self.cog.post_eval.assert_called_once_with('MyAwesomeCode') self.cog.get_status_emoji.assert_called_once_with({ 'stdout': 'Way too long beard', 'returncode': 0 }) self.cog.get_results_message.assert_called_once_with({ 'stdout': 'Way too long beard', 'returncode': 0 }) self.cog.format_output.assert_called_once_with('Way too long beard')
def setUp(self) -> None: self.bot = MockBot() self.cog = Silence(self.bot) self.ctx = MockContext() self.cog._verified_role = None # Set event so command callbacks can continue. self.cog._get_instance_vars_event.set()
async def test_eval_command_call_help(self): """Test if the eval command call the help command if no code is provided.""" ctx = MockContext() ctx.invoke = AsyncMock() await self.cog.eval_command.callback(self.cog, ctx=ctx, code='') ctx.invoke.assert_called_once_with(self.bot.get_command("help"), "eval")
async def test_eval_command_reject_two_eval_at_the_same_time(self): """Test if the eval command rejects an eval if the author already have a running eval.""" ctx = MockContext() ctx.author.id = 42 ctx.author.mention = '@LemonLemonishBeard#0042' ctx.send = AsyncMock() self.cog.jobs = (42,) await self.cog.eval_command(self.cog, ctx=ctx, code='MyAwesomeCode') ctx.send.assert_called_once_with( "@LemonLemonishBeard#0042 You've already got a job running - please wait for it to finish!" )
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)
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)
async def test_duration_only(self): """Test the parser when just the duration argument is passed.""" ctx = MockContext() channel, duration = self.cog.parse_silence_args(ctx, 15, 10) self.assertEqual(ctx.channel, channel) self.assertEqual(15, duration)
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)
async def test_no_arguments(self): """Test the parser when no arguments are passed to the command.""" ctx = MockContext() channel, duration = self.cog.parse_silence_args(ctx, None, 10) self.assertEqual(ctx.channel, channel) self.assertEqual(10, duration)
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)
async def test_silenced_not_added_to_notifier(self): """Channel was not added to the notifier if it was already silenced.""" with mock.patch.object(self.cog, "_set_silence_overwrites", return_value=False): await self.cog.silence.callback(self.cog, MockContext(), 15) self.cog.notifier.add_channel.assert_not_called()
async def test_temp_not_added_to_notifier(self): """Channel was not added to notifier if a duration was set for the silence.""" with mock.patch.object(self.cog, "_set_silence_overwrites", return_value=True): await self.cog.silence.callback(self.cog, MockContext(), 15) self.cog.notifier.add_channel.assert_not_called()
async def test_sent_correct_message(self): """Appropriate failure/success message was sent by the command.""" test_cases = ( ( 0.0001, silence.MSG_SILENCE_SUCCESS.format(duration=0.0001), True, ), ( None, silence.MSG_SILENCE_PERMANENT, True, ), ( 5, silence.MSG_SILENCE_FAIL, False, ), ) for duration, message, was_silenced in test_cases: ctx = MockContext() with mock.patch.object(self.cog, "_set_silence_overwrites", return_value=was_silenced): with self.subTest(was_silenced=was_silenced, message=message, duration=duration): await self.cog.silence.callback(self.cog, ctx, duration) ctx.send.assert_called_once_with(message)
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)
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)
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)
async def test_continue_eval_does_not_continue(self): ctx = MockContext(message=MockMessage(clear_reactions=AsyncMock())) self.bot.wait_for.side_effect = asyncio.TimeoutError actual = await self.cog.continue_eval(ctx, MockMessage()) self.assertEqual(actual, None) ctx.message.clear_reaction.assert_called_once_with(snekbox.REEVAL_EMOJI)
async def test_get_code(self): """Should return 1st arg (or None) if eval cmd in message, otherwise return full content.""" prefix = constants.Bot.prefix subtests = ( (self.cog.eval_command, f"{prefix}{self.cog.eval_command.name} print(1)", "print(1)"), (self.cog.eval_command, f"{prefix}{self.cog.eval_command.name}", None), (MagicMock(spec=commands.Command), f"{prefix}tags get foo"), (None, "print(123)") ) for command, content, *expected_code in subtests: if not expected_code: expected_code = content else: [expected_code] = expected_code with self.subTest(content=content, expected_code=expected_code): self.bot.get_context.reset_mock() self.bot.get_context.return_value = MockContext(command=command) message = MockMessage(content=content) actual_code = await self.cog.get_code(message) self.bot.get_context.assert_awaited_once_with(message) self.assertEqual(actual_code, expected_code)
async def test_continue_eval_does_continue(self, partial_mock): """Test that the continue_eval function does continue if required conditions are met.""" ctx = MockContext(message=MockMessage(add_reaction=AsyncMock(), clear_reactions=AsyncMock())) response = MockMessage(delete=AsyncMock()) new_msg = MockMessage() self.bot.wait_for.side_effect = ((None, new_msg), None) expected = "NewCode" self.cog.get_code = create_autospec(self.cog.get_code, spec_set=True, return_value=expected) actual = await self.cog.continue_eval(ctx, response) self.cog.get_code.assert_awaited_once_with(new_msg) self.assertEqual(actual, expected) self.bot.wait_for.assert_has_awaits( ( call( 'message_edit', check=partial_mock(snekbox.predicate_eval_message_edit, ctx), timeout=snekbox.REEVAL_TIMEOUT, ), call('reaction_add', check=partial_mock(snekbox.predicate_eval_emoji_reaction, ctx), timeout=10) ) ) ctx.message.add_reaction.assert_called_once_with(snekbox.REEVAL_EMOJI) ctx.message.clear_reaction.assert_called_once_with(snekbox.REEVAL_EMOJI) response.delete.assert_called_once()
def test_predicate_eval_emoji_reaction(self): """Test the predicate_eval_emoji_reaction function.""" valid_reaction = MockReaction(message=MockMessage(id=1)) valid_reaction.__str__.return_value = snekbox.REEVAL_EMOJI valid_ctx = MockContext(message=MockMessage(id=1), author=MockUser(id=2)) valid_user = MockUser(id=2) invalid_reaction_id = MockReaction(message=MockMessage(id=42)) invalid_reaction_id.__str__.return_value = snekbox.REEVAL_EMOJI invalid_user_id = MockUser(id=42) invalid_reaction_str = MockReaction(message=MockMessage(id=1)) invalid_reaction_str.__str__.return_value = ':longbeard:' cases = ((invalid_reaction_id, valid_user, False, 'invalid reaction ID'), (valid_reaction, invalid_user_id, False, 'invalid user ID'), (invalid_reaction_str, valid_user, False, 'invalid reaction __str__'), (valid_reaction, valid_user, True, 'matching attributes')) for reaction, user, expected, testname in cases: with self.subTest( msg=f'Test with {testname} and expected return {expected}' ): actual = snekbox.predicate_eval_emoji_reaction( valid_ctx, reaction, user) self.assertEqual(actual, expected)
def setUp(self): """Sets up fresh objects for each test.""" self.bot = MockBot() self.cog = information.Information(self.bot) self.ctx = MockContext() self.ctx.author.roles.append(self.moderator_role)
async def test_cog_check(self, role_check): """Role check was called with `MODERATION_ROLES`""" ctx = MockContext() role_check.return_value.predicate = mock.AsyncMock() await self.cog.cog_check(ctx) role_check.assert_called_once_with(*(1, 2, 3)) role_check.return_value.predicate.assert_awaited_once_with(ctx)
def setUp(self) -> None: self.bot_inst = MockBot() self.bot_cog = bot.Bot(self.bot_inst) self.alias_inst = Alias(self.bot_cog) self.big_bro_inst = BigBrother(self.bot_cog) self.bot_cog.add_cog(self.alias_inst) self.bot_cog.add_cog(self.big_bro_inst) self.ctx = MockContext() warnings.simplefilter("ignore", (ResourceWarning, DeprecationWarning))
async def test_scheduled_task(self): """An unsilence task was scheduled.""" ctx = MockContext(channel=self.channel, invoke=mock.MagicMock()) await self.cog.silence.callback(self.cog, ctx, 5) args = (300, ctx.channel.id, ctx.invoke.return_value) self.cog.scheduler.schedule_later.assert_called_once_with(*args) ctx.invoke.assert_called_once_with(self.cog.unsilence)
async def test_unsilence_role(self): """Tests unsilence_wrapper applies permission to the correct role.""" test_cases = ( (MockTextChannel(), self.cog.bot.get_guild(Guild.id).default_role), (MockVoiceChannel(), self.cog.bot.get_guild(Guild.id).get_role(Roles.voice_verified)) ) for channel, role in test_cases: with self.subTest(channel=channel, role=role): await self.cog._unsilence_wrapper(channel, MockContext()) channel.overwrites_for.assert_called_with(role)
async def test_cached_unsilence_time(self, datetime_mock): """The UTC POSIX timestamp for the unsilence was cached.""" now_timestamp = 100 duration = 15 timestamp = now_timestamp + duration * 60 datetime_mock.now.return_value = datetime.fromtimestamp(now_timestamp, tz=timezone.utc) ctx = MockContext(channel=self.channel) await self.cog.silence.callback(self.cog, ctx, duration) self.cog.unsilence_timestamps.set.assert_awaited_once_with(ctx.channel.id, timestamp) datetime_mock.now.assert_called_once_with(tz=timezone.utc) # Ensure it's using an aware dt.