async def test_nanowrimo(): await message("^nanowrimo") verify_message("Valid options are 'novel', 'profile', and 'info'.") with pytest.raises(commands.MissingRequiredArgument): await message("^nano novel") await empty_queue() await message("^nano novel craftspider") if not sent_queue.empty(): mes = await sent_queue.get() if mes.content != "Sorry, I couldn't find that user": await sent_queue.put(mes) verify_embed() with pytest.raises(commands.MissingRequiredArgument): await message("^nano profile") await empty_queue() await message("^nano profile craftspider") if not sent_queue.empty(): mes = await sent_queue.get() if mes.content != "Sorry, I couldn't find that user on the NaNo site": await sent_queue.put(mes) verify_embed() await message("^nano info") verify_embed()
async def test_choose(): with pytest.raises(commands.MissingRequiredArgument): await message("^choose") await empty_queue() # Clear out error message, that's tested somewhere else await message("^choose one_val") verify_message("I need at least two choices to choose between!") await message("^choose one, two") verify_message("I need at least two choices to choose between!", False)
async def test_ask_for_confirmation(msg_content, is_invalid, expected): author = dpytest.get_config().members[0] channel = dpytest.get_config().channels[0] message = dpytest.back.make_message(author=author, content=msg_content, channel=channel) x = await IntroCog.ask_for_confirmation(message, channel) assert x == expected if is_invalid: dpytest.verify_message()
async def test_message_peek(bot): guild = bot.guilds[0] channel = guild.text_channels[0] await channel.send("Hello, world !") # peek option doesn't remove the message fro the queue dpytest.verify_message("Hello, world !", peek=True) # verify_message (without peek) WILL remove message from the queue dpytest.verify_message("Hello, world !") await dpytest.empty_queue()
async def test_luck(bot, mocker): mocker.patch.object(dice, "roll_2d6", return_value=(3, 4, 7)) dpytest.configure(bot) await dpytest.message("!luck 8") dpytest.verify_message("**SUCCESS** 2d6(3+4) = `7` ≤ `8`") await dpytest.message("!luck 6") dpytest.verify_message("**FAILURE** 2d6(3+4) = `7` > `6`")
async def test_update_welcome_message_too_long(): import random, string guild = dpytest.get_config().guilds[0] old_message = IntroCog.get_guild_welcome_message(guild.id) new_message = "".join(random.choice(string.ascii_letters) for _ in range(1800)) msg_mock = dpytest.back.make_message('y', dpytest.get_config().members[0], dpytest.get_config().channels[0]) with mock.patch('cogs.IntroCog.wait_for_message', mock.AsyncMock(return_value=msg_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + "update_welcome_message " + new_message) dpytest.verify_message("Your welcome message is too long to send, sorry. The maximum character limit is 1600.") dpytest.verify_message(assert_nothing=True) assert DBManager.fetch_guild_welcome_message(guild.id) != new_message
async def test_custom_colour_invalid_colour_str(): guild: discord.Guild = dpytest.get_config().guilds[0] role = (await make_list_of_roles(guild, 1))[0] DBManager.add_colour_change_role_perms(guild.id, role.id) member: discord.Member = dpytest.get_config().members[0] await member.add_roles(role) await dpytest.message(KoalaBot.COMMAND_PREFIX + "custom_colour s34a21", member=0) dpytest.verify_message( f"Invalid colour string specified, make sure it's a valid colour hex.") assert len(member.roles) == 2
async def test_define_weapon(bot, mocker): mocker.patch.object(dice, "roll_d6", return_value=4) dpytest.configure(bot) await dpytest.message("!def weapon Stinger 2 2 3 3 4 5 6") dpytest.verify_message("Added weapon `Stinger` damage `[2, 2, 3, 3, 4, 5, 6]` ignore_armor=False") await dpytest.message("!damage stinger medium") # FIXME: Figure out how to test the embed content here dpytest.verify_embed(allow_text=True)
async def test_command_youtubelist_not_cancel(monkeypatch, mock_message_1, two_results, embed_two_results): monkeypatch.setattr(youtube, "search_youtube", lambda *args, **kwargs: two_results) # noqa: E501 await dpytest.message('!youtubelist 2 pastime paradise') dpytest.verify_embed(embed_two_results) # mock_message_1 fixture monkeypath wait_for, and '1' message is sent. dpytest.verify_message("https://www.youtube.com/watch?v=_H3Sv2zad6s")
async def test_command_youtubelist_cancel(monkeypatch, mock_cancel, two_results, embed_two_results): monkeypatch.setattr(youtube, "search_youtube", lambda *args, **kwargs: two_results) # noqa: E501 await dpytest.message('!youtubelist 2 pastime paradise') dpytest.verify_embed(embed_two_results) # mock_cancel fixture monkeypath wait_for, and 'cancel' message is sent. dpytest.verify_message("Annulé !")
async def test_other_timeout(command_word, prompt_message, announce_cog): guild: discord.Guild = dpytest.get_config().guilds[0] channel: discord.TextChannel = guild.channels[0] make_message(guild, announce_cog) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=None)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce ' + command_word, channel=channel) dpytest.verify_message(prompt_message) dpytest.verify_message("Okay, I'll cancel the command.")
async def test_discord_create_vote(): config = dpytest.get_config() guild = config.guilds[0] await dpytest.message(f"{KoalaBot.COMMAND_PREFIX}vote create Test Vote") dpytest.verify_message( f"Vote titled `Test Vote` created for guild {guild.name}. Use `{KoalaBot.COMMAND_PREFIX}help vote` to see how to configure it." ) in_db = db_manager.db_execute_select("SELECT * FROM Votes")[0] assert in_db assert in_db[1] == guild.members[0].id assert in_db[2] == guild.id
async def test_verify(): test_config = dpytest.get_config() guild = test_config.guilds[0] member = guild.members[0] dm = await member.create_dm() await dpytest.message(KoalaBot.COMMAND_PREFIX + "verify [email protected]", dm) dpytest.verify_message( "Please verify yourself using the command you have been emailed") entry = db_manager.db_execute_select( f"SELECT * FROM non_verified_emails WHERE u_id={member.id} AND email='*****@*****.**'" ) assert entry
async def test_enable_verification(): config = dpytest.get_config() guild = config.guilds[0] role = dpytest.back.make_role("testRole", guild, id_num=555) await dpytest.message(KoalaBot.COMMAND_PREFIX + "addVerification test.com <@&555>") dpytest.verify_message( "Verification enabled for <@&555> for emails ending with `test.com`") entry = db_manager.db_execute_select( "SELECT * FROM roles WHERE s_id=? AND r_id=?", (guild.id, role.id)) assert entry db_manager.db_execute_commit(f"DELETE FROM roles WHERE s_id={guild.id}")
async def test_disable_verification(): config = dpytest.get_config() guild = config.guilds[0] role = dpytest.back.make_role("testRole", guild, id_num=555) db_manager.db_execute_commit( f"INSERT INTO roles VALUES ({guild.id}, 555, 'egg.com')") await dpytest.message(KoalaBot.COMMAND_PREFIX + "removeVerification egg.com <@&555>") dpytest.verify_message("Emails ending with egg.com no longer give <@&555>") entry = db_manager.db_execute_select( "SELECT * FROM roles WHERE s_id=? AND r_id=?", (guild.id, role.id)) assert not entry
async def test_cancel(announce_cog): guild: discord.Guild = dpytest.get_config().guilds[0] channel: discord.TextChannel = guild.channels[0] make_message(guild, announce_cog) announce_cog.roles[guild.id] = [123, 234] assert guild.id in announce_cog.messages.keys() assert guild.id in announce_cog.roles.keys() await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce cancel', channel=channel) dpytest.verify_message("The announcement was cancelled successfully") assert guild.id not in announce_cog.messages.keys() assert guild.id not in announce_cog.roles.keys()
async def test_bot(): bot = ShinobuBot() dpytest.configure(bot) # Load any extensions/cogs you want to in here bot_channel = 165174405222236161 channel = bot.get_channel(bot_channel) await channel.send("Test Message") dpytest.verify_message("Test Message") await dpytest.message(":about") dpytest.verify_message("[Expected help output]")
async def test_better(bot, mocker): mocker.patch.object(dice, "roll_2d6", return_value=(4, 3, 7)) dpytest.configure(bot) await dpytest.message("!better 6") dpytest.verify_message( "**SUCCESS** 2d6(4+3) = `7` > `6`. Increase advanced skill by 1") await dpytest.message("!better 7") dpytest.verify_message( "**FAILURE** 2d6(4+3) = `7` ≤ `7`. Advanced skill unchanged")
async def test_better_more(bot, mocker): mocker.patch.object(dice, "roll_2d6", return_value=(6, 6, 12)) dpytest.configure(bot) await dpytest.message("!better 13") dpytest.verify_message( "**SUCCESS** 2d6(6+6)+2d6(6+6) = `24`. Increase advanced skill by 1") mocker.patch.object(dice, "roll_2d6", side_effect=((6, 6, 12), (6, 5, 11))) await dpytest.message("!better 12") dpytest.verify_message( "**FAILURE** 2d6(6+6)+2d6(6+5) = `23`. Advanced skill unchanged")
async def test_custom_colour_colour_is_protected(): guild: discord.Guild = dpytest.get_config().guilds[0] role = (await make_list_of_roles(guild, 1))[0] DBManager.add_colour_change_role_perms(guild.id, role.id) member: discord.Member = dpytest.get_config().members[0] await member.add_roles(role) fail_colour = discord.Colour.from_rgb(255, 255, 255) await dpytest.message(KoalaBot.COMMAND_PREFIX + "custom_colour FEFEFE", member=0) dpytest.verify_message( f"Colour chosen was too close to an already protected colour {hex(fail_colour.value)}. Please choose a different colour." ) assert "KoalaBot[0xFEFEFE]" not in [role.name for role in guild.roles]
async def test_announce_db_first_creation(announce_cog): guild: discord.Guild = dpytest.get_config().guilds[0] author: discord.Member = guild.members[0] channel: discord.TextChannel = guild.channels[0] assert announce_cog.announce_database_manager.get_last_use_date( guild.id) is None msg_mock: discord.Message = dpytest.back.make_message( 'testMessage', author, channel) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=msg_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce create', channel=channel) dpytest.verify_message( "Please enter a message, I'll wait for 60 seconds, no rush.") dpytest.verify_message( f"An announcement has been created for guild {guild.name}") dpytest.verify_embed() dpytest.verify_message() assert announce_cog.has_active_msg(guild.id) assert announce_cog.announce_database_manager.get_last_use_date( guild.id) is None await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce send', channel=channel) for _ in guild.members: dpytest.verify_embed() dpytest.verify_message("The announcement was made successfully") assert int(time.time( )) == announce_cog.announce_database_manager.get_last_use_date( guild.id)
async def test_restart_fail(): intents = discord.Intents.default() intents.members = True bot = commands.Bot(command_prefix='!', intents=intents) bot.gifs = [] bot.log = mock.Mock() bot.add_cog(Admin(bot)) dpytest.configure(bot) # MissingAnyRole is expected. # Test will pass if error "MissingAnyRole" is launched with pytest.raises(commands.MissingAnyRole): await dpytest.message('!restart') dpytest.verify_message("Nope.") # empty the queue await dpytest.empty_queue()
async def test_latex(): await message("^latex \\frac{1}{2}") if not sent_queue.empty(): mes = await sent_queue.get() if mes.content != "pdflatex command not found" and mes.content != "ghostscript command not found": await sent_queue.put(mes) verify_file() else: return else: pytest.fail() await message("^latex \\badcommand") verify_message()
async def test_create_multiple_message(announce_cog): guild: discord.Guild = dpytest.get_config().guilds[0] author: discord.Member = guild.members[0] channel: discord.TextChannel = guild.channels[0] msg_mock: discord.Message = dpytest.back.make_message( 'testMessage', author, channel) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=msg_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce create', channel=channel) dpytest.verify_message( "Please enter a message, I'll wait for 60 seconds, no rush.") dpytest.verify_message( f"An announcement has been created for guild {guild.name}") dpytest.verify_embed() dpytest.verify_message() assert announce_cog.has_active_msg(guild.id) assert announce_cog.messages[guild.id].description == "testMessage" assert announce_cog.messages[guild.id].title == "" msg2_mock: discord.Message = dpytest.back.make_message( 'testMessage2', author, channel) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=msg2_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce create', channel=channel) dpytest.verify_message( "There is currently an active announcement being created, you can use 'k!announce cancel' " "or 'k!announce send' to complete it") assert announce_cog.has_active_msg(guild.id) assert announce_cog.messages[guild.id].description == "testMessage" assert announce_cog.messages[guild.id].title == ""
async def test_rfr_delete_message(): config: dpytest.RunnerConfig = dpytest.get_config() guild: discord.Guild = config.guilds[0] channel: discord.TextChannel = guild.text_channels[0] message: discord.Message = await dpytest.message("rfr") msg_id = message.id DBManager.add_rfr_message(guild.id, channel.id, msg_id) await dpytest.empty_queue() with mock.patch( 'cogs.ReactForRole.ReactForRole.get_rfr_message_from_prompts', mock.AsyncMock(return_value=(message, channel))): with mock.patch('cogs.ReactForRole.ReactForRole.prompt_for_input', mock.AsyncMock(return_value="Y")): with mock.patch('discord.Message.delete') as mock_msg_delete: await dpytest.message(KoalaBot.COMMAND_PREFIX + "rfr deleteMessage") mock_msg_delete.assert_called_once() dpytest.verify_message( "Okay, this will delete an existing react for role message. I'll need some details first though." ) dpytest.verify_message() dpytest.verify_message() dpytest.verify_message() assert not independent_get_guild_rfr_message( guild.id, channel.id, msg_id)
async def test_colour(): config = get_config() guild = config.guilds[0] member = config.members[0] perms = dpytest.backend.make_role("Perms", guild, permissions=0x8) await dpytest.add_role(guild.me, perms) assert len(member.roles) == 1 await message("^colour BadColour") verify_message("Unrecognized colour format. Valid formats include `#123456`, `0x123456`, and some names such as " "teal or orange") assert len(member.roles) == 1 await message("^colour #8F008F") verify_message(f"{member.display_name}'s colour changed to #8f008f!") assert len(member.roles) == 2 role = guild.roles[1] assert member.roles[1] == role await message("^colour clear") verify_message("Talos colour removed") assert len(member.roles) == 1 assert role not in guild.roles await message("^colour list") verify_message()
async def test_member_join_verif_enabled(): test_config = dpytest.get_config() guild = dpytest.back.make_guild("testMemberJoin", id_num=1234) test_config.guilds.append(guild) dpytest.back.make_role("testRole", guild, id_num=555) db_manager.db_execute_commit("INSERT INTO roles VALUES (1234, 555, 'test.com')") welcome_message = f"""Welcome to testMemberJoin. This guild has verification enabled. Please verify one of the following emails to get the appropriate role using `{KoalaBot.COMMAND_PREFIX}verify [email protected]`. This email is stored so you don't need to verify it multiple times across servers. `test.com` for `@testRole`""" await dpytest.member_join(1) await asyncio.sleep(0.25) dpytest.verify_message(welcome_message) db_manager.db_execute_commit("DELETE FROM roles WHERE s_id=1234")
async def test_roulette_lives(monkeypatch): """ Test !roulette (user survives). We monkeypatch random so the user always survives. """ alive_mess = "Ouh c'était chaud !" # Monkeypatching random monkeypatch.setattr("random.randrange", lambda *args: 1) monkeypatch.setattr("random.choice", lambda *args: alive_mess) await dpytest.message('!roulette') dpytest.verify_message(alive_mess)
async def test_remove_role_from_none(announce_cog): guild: discord.Guild = dpytest.get_config().guilds[0] author: discord.Member = guild.members[0] channel: discord.TextChannel = guild.channels[0] roles = guild.roles make_message(guild, announce_cog) assert announce_cog.roles[guild.id] == [] msg_mock: discord.Message = dpytest.back.make_message( str(roles[0].id), author, channel) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=msg_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce remove', channel=channel) dpytest.verify_message( "Please enter the roles you want to remove separated by space, I'll wait for 60 seconds, no rush." ) dpytest.verify_message() assert announce_cog.has_active_msg(guild.id) assert announce_cog.roles[guild.id] == [] msg_mock: discord.Message = dpytest.back.make_message( "12345", author, channel) with mock.patch('discord.client.Client.wait_for', mock.AsyncMock(return_value=msg_mock)): await dpytest.message(KoalaBot.COMMAND_PREFIX + 'announce remove', channel=channel) dpytest.verify_message( "Please enter the roles you want to remove separated by space, I'll wait for 60 seconds, no rush." ) dpytest.verify_message() assert announce_cog.has_active_msg(guild.id) assert announce_cog.roles[guild.id] == []
async def test_send_welcome_message_timeout(): with mock.patch('cogs.IntroCog.wait_for_message', mock.AsyncMock(return_value=None)): await dpytest.message(KoalaBot.COMMAND_PREFIX + "send_welcome_message") dpytest.verify_message("This will DM 1 people. Are you sure you wish to do this? Y/N") dpytest.verify_message('Timed out.') dpytest.verify_message("Okay, I won't send out the welcome message then.") dpytest.verify_message(assert_nothing=True)
async def test_update_welcome_message_timeout(): guild = dpytest.get_config().guilds[0] old_message = IntroCog.get_guild_welcome_message(guild.id) new_message = "this is a non default message" # msg_mock = dpytest.back.make_message('y', dpytest.get_config().members[0], dpytest.get_config().channels[0]) with mock.patch('cogs.IntroCog.wait_for_message', mock.AsyncMock(return_value=None)): await dpytest.message(KoalaBot.COMMAND_PREFIX + "update_welcome_message " + new_message) dpytest.verify_message(f"""Your current welcome message is:\n\r{old_message}""") dpytest.verify_message(f"""Your new welcome message will be:\n\r{new_message}\n\r{IntroCog.BASE_LEGAL_MESSAGE}""" + """\n\rWould you like to update the message? Y/N?""") dpytest.verify_message("Timed out.") dpytest.verify_message("Okay, I won't update the welcome message then.") dpytest.verify_message(assert_nothing=True) assert DBManager.fetch_guild_welcome_message(guild.id) != new_message
async def test_on_member_join(): test_config = dpytest.get_config() client = test_config.client guild = dpytest.back.make_guild('TestMemberJoin', id_num=1234) test_config.guilds.append(guild) await dpytest.member_join(1, client.user) await asyncio.sleep(0.25) welcome_message = IntroCog.get_guild_welcome_message(guild.id) await dpytest.member_join(1) dpytest.verify_message(welcome_message) DBManager.update_guild_welcome_message(guild.id, 'This is an updated welcome message.') await asyncio.sleep(0.25) welcome_message = IntroCog.get_guild_welcome_message(guild.id) await dpytest.member_join(1) dpytest.verify_message(welcome_message)
async def test_wordwar(): with pytest.raises(commands.MissingRequiredArgument): await message("^ww") await empty_queue() await message("^ww bad") verify_message("Please specify the length of your word war (in minutes).") await message("^ww 0") verify_message("Please choose a length between 1 and 60 minutes.") await message("^ww 1") verify_message() await asyncio.sleep(61) verify_message()
async def test_hi(): await message("^hi") verify_message("Hello there TestUser")
async def test_aesthetic(): await message("^aesthetic Sphinx of black quartz, judge my vow") verify_message("Sphinx of black quartz, judge my vow")
async def test_playing(): await devmess("^playing Test Game") verify_message() verify_activity(discord.Game(name="Test Game"))
async def test_roll(): with pytest.raises(commands.MissingRequiredArgument): await message("^roll") await empty_queue() await message("^roll bad_data") verify_message("Either specify a single number for max roll or input NdN format") await message("^roll 0d1") verify_message("Minimum first value is 1") await message("^roll 1d0") verify_message("Minimum second value is 1") await message("^roll 1") verify_message("Result: 1") await message("^roll 1d1") verify_message("Result: 1") await message("^roll 2d1") verify_message("Total: 2\nIndividual Rolls: 1, 1")
async def test_ping(): await message("^ping") verify_message()
async def test_streaming(): await devmess("^streaming Test Stream") verify_message() verify_activity(discord.Streaming(name="Test Stream", url="http://www.twitch.tv/talos_bot_"))
async def test_watching(): await devmess("^watching Test Video") verify_message() verify_activity(discord.Activity(name="Test Video", type=discord.ActivityType.watching))
async def test_favor(): await message("^favor") verify_message("I'm afraid I can't do that, TestUser.")
async def test_version(): await message("^version") verify_message(f"Version: {testlos.VERSION}")
async def test_uptime(): await message("^uptime") verify_message()
async def test_listening(): await devmess("^listening Test Sound") verify_message() verify_activity(discord.Activity(name="Test Sound", type=discord.ActivityType.listening))
async def test_tos(): await message("^tos") verify_message()
async def test_idlist(): await devmess("^idlist") verify_message()
async def test_credits(): await message("^credits") verify_message()
async def test_master_nick(): await devmess("^master_nick Newnick") verify_message() for guild in get_config().guilds: assert guild.me.nick == "Newnick"
async def test_generate(): await message("^generate") verify_message("Valid options are 'prompt', 'crawl', and 'name'.") await message("^generate prompt") verify_message("Valid options are 'prompt', 'crawl', and 'name'.", False) await message("^generate crawl") verify_message("Valid options are 'prompt', 'crawl', and 'name'.", False) await message("^generate name") verify_message("Valid options are 'prompt', 'crawl', and 'name'.", False) await message("^generate name 0") verify_message("Number must be between 1 and 6 inclusive.") await message("^generate name 7") verify_message("Number must be between 1 and 6 inclusive.")
async def test_eval(): await devmess("^eval 1 + 1") verify_message("```py\n2\n```")