aboutsummaryrefslogtreecommitdiffstats
path: root/tests/cogs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cogs')
-rw-r--r--tests/cogs/__init__.py0
-rw-r--r--tests/cogs/sync/__init__.py0
-rw-r--r--tests/cogs/sync/test_roles.py103
-rw-r--r--tests/cogs/sync/test_users.py69
-rw-r--r--tests/cogs/test_antispam.py30
-rw-r--r--tests/cogs/test_information.py211
-rw-r--r--tests/cogs/test_security.py54
-rw-r--r--tests/cogs/test_token_remover.py133
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"