diff options
Diffstat (limited to 'tests/cogs')
| -rw-r--r-- | tests/cogs/__init__.py | 0 | ||||
| -rw-r--r-- | tests/cogs/sync/__init__.py | 0 | ||||
| -rw-r--r-- | tests/cogs/sync/test_roles.py | 103 | ||||
| -rw-r--r-- | tests/cogs/sync/test_users.py | 69 | ||||
| -rw-r--r-- | tests/cogs/test_antispam.py | 30 | ||||
| -rw-r--r-- | tests/cogs/test_information.py | 211 | ||||
| -rw-r--r-- | tests/cogs/test_security.py | 54 | ||||
| -rw-r--r-- | tests/cogs/test_token_remover.py | 133 | 
8 files changed, 0 insertions, 600 deletions
| diff --git a/tests/cogs/__init__.py b/tests/cogs/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/tests/cogs/__init__.py +++ /dev/null diff --git a/tests/cogs/sync/__init__.py b/tests/cogs/sync/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/tests/cogs/sync/__init__.py +++ /dev/null diff --git a/tests/cogs/sync/test_roles.py b/tests/cogs/sync/test_roles.py deleted file mode 100644 index c561ba447..000000000 --- a/tests/cogs/sync/test_roles.py +++ /dev/null @@ -1,103 +0,0 @@ -from bot.cogs.sync.syncers import Role, get_roles_for_sync - - -def test_get_roles_for_sync_empty_return_for_equal_roles(): -    api_roles = {Role(id=41, name='name', colour=33, permissions=0x8, position=1)} -    guild_roles = {Role(id=41, name='name', colour=33, permissions=0x8, position=1)} - -    assert get_roles_for_sync(guild_roles, api_roles) == (set(), set(), set()) - - -def test_get_roles_for_sync_returns_roles_to_update_with_non_id_diff(): -    api_roles = {Role(id=41, name='old name', colour=35, permissions=0x8, position=1)} -    guild_roles = {Role(id=41, name='new name', colour=33, permissions=0x8, position=2)} - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        set(), -        guild_roles, -        set(), -    ) - - -def test_get_roles_only_returns_roles_that_require_update(): -    api_roles = { -        Role(id=41, name='old name', colour=33, permissions=0x8, position=1), -        Role(id=53, name='other role', colour=55, permissions=0, position=3) -    } -    guild_roles = { -        Role(id=41, name='new name', colour=35, permissions=0x8, position=2), -        Role(id=53, name='other role', colour=55, permissions=0, position=3) -    } - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        set(), -        {Role(id=41, name='new name', colour=35, permissions=0x8, position=2)}, -        set(), -    ) - - -def test_get_roles_returns_new_roles_in_first_tuple_element(): -    api_roles = { -        Role(id=41, name='name', colour=35, permissions=0x8, position=1), -    } -    guild_roles = { -        Role(id=41, name='name', colour=35, permissions=0x8, position=1), -        Role(id=53, name='other role', colour=55, permissions=0, position=2) -    } - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        {Role(id=53, name='other role', colour=55, permissions=0, position=2)}, -        set(), -        set(), -    ) - - -def test_get_roles_returns_roles_to_update_and_new_roles(): -    api_roles = { -        Role(id=41, name='old name', colour=35, permissions=0x8, position=1), -    } -    guild_roles = { -        Role(id=41, name='new name', colour=40, permissions=0x16, position=2), -        Role(id=53, name='other role', colour=55, permissions=0, position=3) -    } - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        {Role(id=53, name='other role', colour=55, permissions=0, position=3)}, -        {Role(id=41, name='new name', colour=40, permissions=0x16, position=2)}, -        set(), -    ) - - -def test_get_roles_returns_roles_to_delete(): -    api_roles = { -        Role(id=41, name='name', colour=35, permissions=0x8, position=1), -        Role(id=61, name='to delete', colour=99, permissions=0x9, position=2), -    } -    guild_roles = { -        Role(id=41, name='name', colour=35, permissions=0x8, position=1), -    } - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        set(), -        set(), -        {Role(id=61, name='to delete', colour=99, permissions=0x9, position=2)}, -    ) - - -def test_get_roles_returns_roles_to_delete_update_and_new_roles(): -    api_roles = { -        Role(id=41, name='not changed', colour=35, permissions=0x8, position=1), -        Role(id=61, name='to delete', colour=99, permissions=0x9, position=2), -        Role(id=71, name='to update', colour=99, permissions=0x9, position=3), -    } -    guild_roles = { -        Role(id=41, name='not changed', colour=35, permissions=0x8, position=1), -        Role(id=81, name='to create', colour=99, permissions=0x9, position=4), -        Role(id=71, name='updated', colour=101, permissions=0x5, position=3), -    } - -    assert get_roles_for_sync(guild_roles, api_roles) == ( -        {Role(id=81, name='to create', colour=99, permissions=0x9, position=4)}, -        {Role(id=71, name='updated', colour=101, permissions=0x5, position=3)}, -        {Role(id=61, name='to delete', colour=99, permissions=0x9, position=2)}, -    ) diff --git a/tests/cogs/sync/test_users.py b/tests/cogs/sync/test_users.py deleted file mode 100644 index a863ae35b..000000000 --- a/tests/cogs/sync/test_users.py +++ /dev/null @@ -1,69 +0,0 @@ -from bot.cogs.sync.syncers import User, get_users_for_sync - - -def fake_user(**kwargs): -    kwargs.setdefault('id', 43) -    kwargs.setdefault('name', 'bob the test man') -    kwargs.setdefault('discriminator', 1337) -    kwargs.setdefault('avatar_hash', None) -    kwargs.setdefault('roles', (666,)) -    kwargs.setdefault('in_guild', True) -    return User(**kwargs) - - -def test_get_users_for_sync_returns_nothing_for_empty_params(): -    assert get_users_for_sync({}, {}) == (set(), set()) - - -def test_get_users_for_sync_returns_nothing_for_equal_users(): -    api_users = {43: fake_user()} -    guild_users = {43: fake_user()} - -    assert get_users_for_sync(guild_users, api_users) == (set(), set()) - - -def test_get_users_for_sync_returns_users_to_update_on_non_id_field_diff(): -    api_users = {43: fake_user()} -    guild_users = {43: fake_user(name='new fancy name')} - -    assert get_users_for_sync(guild_users, api_users) == ( -        set(), -        {fake_user(name='new fancy name')} -    ) - - -def test_get_users_for_sync_returns_users_to_create_with_new_ids_on_guild(): -    api_users = {43: fake_user()} -    guild_users = {43: fake_user(), 63: fake_user(id=63)} - -    assert get_users_for_sync(guild_users, api_users) == ( -        {fake_user(id=63)}, -        set() -    ) - - -def test_get_users_for_sync_updates_in_guild_field_on_user_leave(): -    api_users = {43: fake_user(), 63: fake_user(id=63)} -    guild_users = {43: fake_user()} - -    assert get_users_for_sync(guild_users, api_users) == ( -        set(), -        {fake_user(id=63, in_guild=False)} -    ) - - -def test_get_users_for_sync_updates_and_creates_users_as_needed(): -    api_users = {43: fake_user()} -    guild_users = {63: fake_user(id=63)} - -    assert get_users_for_sync(guild_users, api_users) == ( -        {fake_user(id=63)}, -        {fake_user(in_guild=False)} -    ) - - -def test_get_users_for_sync_does_not_duplicate_update_users(): -    api_users = {43: fake_user(in_guild=False)} -    guild_users = {} - -    assert get_users_for_sync(guild_users, api_users) == (set(), set()) diff --git a/tests/cogs/test_antispam.py b/tests/cogs/test_antispam.py deleted file mode 100644 index 67900b275..000000000 --- a/tests/cogs/test_antispam.py +++ /dev/null @@ -1,30 +0,0 @@ -import pytest - -from bot.cogs import antispam - - -def test_default_antispam_config_is_valid(): -    validation_errors = antispam.validate_config() -    assert not validation_errors - - -    ('config', 'expected'), -    ( -        ( -            {'invalid-rule': {}}, -            {'invalid-rule': "`invalid-rule` is not recognized as an antispam rule."} -        ), -        ( -            {'burst': {'interval': 10}}, -            {'burst': "Key `max` is required but not set for rule `burst`"} -        ), -        ( -            {'burst': {'max': 10}}, -            {'burst': "Key `interval` is required but not set for rule `burst`"} -        ) -    ) -) -def test_invalid_antispam_config_returns_validation_errors(config, expected): -    validation_errors = antispam.validate_config(config) -    assert validation_errors == expected diff --git a/tests/cogs/test_information.py b/tests/cogs/test_information.py deleted file mode 100644 index 184bd2595..000000000 --- a/tests/cogs/test_information.py +++ /dev/null @@ -1,211 +0,0 @@ -import asyncio -import logging -import textwrap -from datetime import datetime -from unittest.mock import MagicMock, patch - -import pytest -from discord import ( -    CategoryChannel, -    Colour, -    Permissions, -    Role, -    TextChannel, -    VoiceChannel, -) - -from bot.cogs import information -from bot.constants import Emojis -from bot.decorators import InChannelCheckFailure -from tests.helpers import AsyncMock - - -def cog(simple_bot): -    return information.Information(simple_bot) - - -def role(name: str, id_: int): -    r = MagicMock() -    r.name = name -    r.id = id_ -    r.mention = f'&{name}' -    return r - - -def member(status: str): -    m = MagicMock() -    m.status = status -    return m - - -def ctx(moderator_role, simple_ctx): -    simple_ctx.author.roles = [moderator_role] -    simple_ctx.guild.created_at = datetime(2001, 1, 1) -    simple_ctx.send = AsyncMock() -    return simple_ctx - - -def test_roles_info_command(cog, ctx): -    everyone_role = MagicMock() -    everyone_role.name = '@everyone'  # should be excluded in the output -    ctx.author.roles.append(everyone_role) -    ctx.guild.roles = ctx.author.roles - -    cog.roles_info.can_run = AsyncMock() -    cog.roles_info.can_run.return_value = True - -    coroutine = cog.roles_info.callback(cog, ctx) - -    assert asyncio.run(coroutine) is None  # no rval -    ctx.send.assert_called_once() -    _, kwargs = ctx.send.call_args -    embed = kwargs.pop('embed') -    assert embed.title == "Role information" -    assert embed.colour == Colour.blurple() -    assert embed.description == f"`{ctx.guild.roles[0].id}` - {ctx.guild.roles[0].mention}\n" -    assert embed.footer.text == "Total roles: 1" - - -def test_role_info_command(cog, ctx): -    dummy_role = MagicMock(spec=Role) -    dummy_role.name = "Dummy" -    dummy_role.colour = Colour.blurple() -    dummy_role.id = 112233445566778899 -    dummy_role.position = 10 -    dummy_role.permissions = Permissions(0) -    dummy_role.members = [ctx.author] - -    admin_role = MagicMock(spec=Role) -    admin_role.name = "Admin" -    admin_role.colour = Colour.red() -    admin_role.id = 998877665544332211 -    admin_role.position = 3 -    admin_role.permissions = Permissions(0) -    admin_role.members = [ctx.author] - -    ctx.guild.roles = [dummy_role, admin_role] - -    cog.role_info.can_run = AsyncMock() -    cog.role_info.can_run.return_value = True - -    coroutine = cog.role_info.callback(cog, ctx, dummy_role, admin_role) - -    assert asyncio.run(coroutine) is None - -    assert ctx.send.call_count == 2 - -    (_, dummy_kwargs), (_, admin_kwargs) = ctx.send.call_args_list - -    dummy_embed = dummy_kwargs["embed"] -    admin_embed = admin_kwargs["embed"] - -    assert dummy_embed.title == "Dummy info" -    assert dummy_embed.colour == Colour.blurple() - -    assert dummy_embed.fields[0].value == str(dummy_role.id) -    assert dummy_embed.fields[1].value == f"#{dummy_role.colour.value:0>6x}" -    assert dummy_embed.fields[2].value == "0.63 0.48 218" -    assert dummy_embed.fields[3].value == "1" -    assert dummy_embed.fields[4].value == "10" -    assert dummy_embed.fields[5].value == "0" - -    assert admin_embed.title == "Admin info" -    assert admin_embed.colour == Colour.red() - -# There is no argument passed in here that we can use to test, -# so the return value would change constantly. -@patch('bot.cogs.information.time_since') -def test_server_info_command(time_since_patch, cog, ctx, moderator_role): -    time_since_patch.return_value = '2 days ago' - -    ctx.guild.created_at = datetime(2001, 1, 1) -    ctx.guild.features = ('lemons', 'apples') -    ctx.guild.region = 'The Moon' -    ctx.guild.roles = [moderator_role] -    ctx.guild.channels = [ -        TextChannel( -            state={}, -            guild=ctx.guild, -            data={'id': 42, 'name': 'lemons-offering', 'position': 22, 'type': 'text'} -        ), -        CategoryChannel( -            state={}, -            guild=ctx.guild, -            data={'id': 5125, 'name': 'the-lemon-collection', 'position': 22, 'type': 'category'} -        ), -        VoiceChannel( -            state={}, -            guild=ctx.guild, -            data={'id': 15290, 'name': 'listen-to-lemon', 'position': 22, 'type': 'voice'} -        ) -    ] -    ctx.guild.members = [ -        member('online'), member('online'), -        member('idle'), -        member('dnd'), member('dnd'), member('dnd'), member('dnd'), -        member('offline'), member('offline'), member('offline') -    ] -    ctx.guild.member_count = 1_234 -    ctx.guild.icon_url = 'a-lemon.png' - -    coroutine = cog.server_info.callback(cog, ctx) -    assert asyncio.run(coroutine) is None  # no rval - -    time_since_patch.assert_called_once_with(ctx.guild.created_at, precision='days') -    _, kwargs = ctx.send.call_args -    embed = kwargs.pop('embed') -    assert embed.colour == Colour.blurple() -    assert embed.description == textwrap.dedent(f""" -        **Server information** -        Created: {time_since_patch.return_value} -        Voice region: {ctx.guild.region} -        Features: {', '.join(ctx.guild.features)} - -        **Counts** -        Members: {ctx.guild.member_count:,} -        Roles: {len(ctx.guild.roles)} -        Text: 1 -        Voice: 1 -        Channel categories: 1 - -        **Members** -        {Emojis.status_online} 2 -        {Emojis.status_idle} 1 -        {Emojis.status_dnd} 4 -        {Emojis.status_offline} 3 -        """) -    assert embed.thumbnail.url == 'a-lemon.png' - - -def test_user_info_on_other_users_from_non_moderator(ctx, cog): -    ctx.author = MagicMock() -    ctx.author.__eq__.return_value = False -    ctx.author.roles = [] -    coroutine = cog.user_info.callback(cog, ctx, user='scragly')  # skip checks, pass args - -    assert asyncio.run(coroutine) is None  # no rval -    ctx.send.assert_called_once_with( -        "You may not use this command on users other than yourself." -    ) - - -def test_user_info_in_wrong_channel_from_non_moderator(ctx, cog): -    ctx.author = MagicMock() -    ctx.author.__eq__.return_value = False -    ctx.author.roles = [] - -    coroutine = cog.user_info.callback(cog, ctx) -    message = 'Sorry, but you may only use this command within <#267659945086812160>.' -    with pytest.raises(InChannelCheckFailure, match=message): -        assert asyncio.run(coroutine) is None  # no rval - - -def test_setup(simple_bot, caplog): -    information.setup(simple_bot) -    simple_bot.add_cog.assert_called_once() -    [record] = caplog.records - -    assert record.message == "Cog loaded: Information" -    assert record.levelno == logging.INFO diff --git a/tests/cogs/test_security.py b/tests/cogs/test_security.py deleted file mode 100644 index 1efb460fe..000000000 --- a/tests/cogs/test_security.py +++ /dev/null @@ -1,54 +0,0 @@ -import logging -from unittest.mock import MagicMock - -import pytest -from discord.ext.commands import NoPrivateMessage - -from bot.cogs import security - - -def cog(): -    bot = MagicMock() -    return security.Security(bot) - - -def context(): -    return MagicMock() - - -def test_check_additions(cog): -    cog.bot.check.assert_any_call(cog.check_on_guild) -    cog.bot.check.assert_any_call(cog.check_not_bot) - - -def test_check_not_bot_for_humans(cog, context): -    context.author.bot = False -    assert cog.check_not_bot(context) - - -def test_check_not_bot_for_robots(cog, context): -    context.author.bot = True -    assert not cog.check_not_bot(context) - - -def test_check_on_guild_outside_of_guild(cog, context): -    context.guild = None - -    with pytest.raises(NoPrivateMessage, match="This command cannot be used in private messages."): -        cog.check_on_guild(context) - - -def test_check_on_guild_on_guild(cog, context): -    context.guild = "lemon's lemonade stand" -    assert cog.check_on_guild(context) - - -def test_security_cog_load(caplog): -    bot = MagicMock() -    security.setup(bot) -    bot.add_cog.assert_called_once() -    [record] = caplog.records -    assert record.message == "Cog loaded: Security" -    assert record.levelno == logging.INFO diff --git a/tests/cogs/test_token_remover.py b/tests/cogs/test_token_remover.py deleted file mode 100644 index 9d46b3a05..000000000 --- a/tests/cogs/test_token_remover.py +++ /dev/null @@ -1,133 +0,0 @@ -import asyncio -from unittest.mock import MagicMock - -import pytest -from discord import Colour - -from bot.cogs.token_remover import ( -    DELETION_MESSAGE_TEMPLATE, -    TokenRemover, -    setup as setup_cog, -) -from bot.constants import Channels, Colours, Event, Icons -from tests.helpers import AsyncMock - - -def token_remover(): -    bot = MagicMock() -    bot.get_cog.return_value = MagicMock() -    bot.get_cog.return_value.send_log_message = AsyncMock() -    return TokenRemover(bot=bot) - - -def message(): -    message = MagicMock() -    message.author.__str__.return_value = 'lemon' -    message.author.bot = False -    message.author.avatar_url_as.return_value = 'picture-lemon.png' -    message.author.id = 42 -    message.author.mention = '@lemon' -    message.channel.send = AsyncMock() -    message.channel.mention = '#lemonade-stand' -    message.content = '' -    message.delete = AsyncMock() -    message.id = 555 -    return message - - -    ('content', 'expected'), -    ( -        ('MTIz', True),  # 123 -        ('YWJj', False),  # abc -    ) -) -def test_is_valid_user_id(content: str, expected: bool): -    assert TokenRemover.is_valid_user_id(content) is expected - - -    ('content', 'expected'), -    ( -        ('DN9r_A', True),  # stolen from dapi, thanks to the author of the 'token' tag! -        ('MTIz', False),  # 123 -    ) -) -def test_is_valid_timestamp(content: str, expected: bool): -    assert TokenRemover.is_valid_timestamp(content) is expected - - -def test_mod_log_property(token_remover): -    token_remover.bot.get_cog.return_value = 'lemon' -    assert token_remover.mod_log == 'lemon' -    token_remover.bot.get_cog.assert_called_once_with('ModLog') - - -def test_ignores_bot_messages(token_remover, message): -    message.author.bot = True -    coroutine = token_remover.on_message(message) -    assert asyncio.run(coroutine) is None - - [email protected]('content', ('', 'lemon wins')) -def test_ignores_messages_without_tokens(token_remover, message, content): -    message.content = content -    coroutine = token_remover.on_message(message) -    assert asyncio.run(coroutine) is None - - [email protected]('content', ('foo.bar.baz', 'x.y.')) -def test_ignores_invalid_tokens(token_remover, message, content): -    message.content = content -    coroutine = token_remover.on_message(message) -    assert asyncio.run(coroutine) is None - - -    'content, censored_token', -    ( -        ('MTIz.DN9R_A.xyz', 'MTIz.DN9R_A.xxx'), -    ) -) -def test_censors_valid_tokens( -    token_remover, message, content, censored_token, caplog -): -    message.content = content -    coroutine = token_remover.on_message(message) -    assert asyncio.run(coroutine) is None  # still no rval - -    # asyncio logs some stuff about its reactor, discard it -    [_, record] = caplog.records -    assert record.message == ( -        "Censored a seemingly valid token sent by lemon (`42`) in #lemonade-stand, " -        f"token was `{censored_token}`" -    ) - -    message.delete.assert_called_once_with() -    message.channel.send.assert_called_once_with( -        DELETION_MESSAGE_TEMPLATE.format(mention='@lemon') -    ) -    token_remover.bot.get_cog.assert_called_with('ModLog') -    message.author.avatar_url_as.assert_called_once_with(static_format='png') - -    mod_log = token_remover.bot.get_cog.return_value -    mod_log.ignore.assert_called_once_with(Event.message_delete, message.id) -    mod_log.send_log_message.assert_called_once_with( -        icon_url=Icons.token_removed, -        colour=Colour(Colours.soft_red), -        title="Token removed!", -        text=record.message, -        thumbnail='picture-lemon.png', -        channel_id=Channels.mod_alerts -    ) - - -def test_setup(caplog): -    bot = MagicMock() -    setup_cog(bot) -    [record] = caplog.records - -    bot.add_cog.assert_called_once() -    assert record.message == "Cog loaded: TokenRemover" | 
