diff options
| author | 2022-08-19 15:18:25 +0100 | |
|---|---|---|
| committer | 2022-08-19 15:18:25 +0100 | |
| commit | b923b52ed199d58abddb2cf2511025017a5758b6 (patch) | |
| tree | 87c10b3cf54fcabbab07c73243635cf690b0700a /tests/helpers.py | |
| parent | Merge branch 'python-discord:main' into patreon (diff) | |
| parent | Merge pull request #2260 from Dorukyum/channel.guild-nullable (diff) | |
Merge branch 'main' into patreon
Diffstat (limited to '')
| -rw-r--r-- | tests/helpers.py | 162 | 
1 files changed, 96 insertions, 66 deletions
diff --git a/tests/helpers.py b/tests/helpers.py index bd1418ab9..687e15b96 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -7,12 +7,12 @@ import unittest.mock  from asyncio import AbstractEventLoop  from typing import Iterable, Optional -import disnake +import discord  from aiohttp import ClientSession -from disnake.ext.commands import Context +from botcore.async_stats import AsyncStatsClient +from botcore.site_api import APIClient +from discord.ext.commands import Context -from bot.api import APIClient -from bot.async_stats import AsyncStatsClient  from bot.bot import Bot  from tests._autospec import autospec  # noqa: F401 other modules import it via this module @@ -26,11 +26,11 @@ for logger in logging.Logger.manager.loggerDict.values():      logger.setLevel(logging.CRITICAL) -class HashableMixin(disnake.mixins.EqualityComparable): +class HashableMixin(discord.mixins.EqualityComparable):      """ -    Mixin that provides similar hashing and equality functionality as disnake's `Hashable` mixin. +    Mixin that provides similar hashing and equality functionality as discord.py's `Hashable` mixin. -    Note: disnake`s `Hashable` mixin bit-shifts `self.id` (`>> 22`); to prevent hash-collisions +    Note: discord.py`s `Hashable` mixin bit-shifts `self.id` (`>> 22`); to prevent hash-collisions      for the relative small `id` integers we generally use in tests, this bit-shift is omitted.      """ @@ -39,22 +39,22 @@ class HashableMixin(disnake.mixins.EqualityComparable):  class ColourMixin: -    """A mixin for Mocks that provides the aliasing of (accent_)color->(accent_)colour like disnake does.""" +    """A mixin for Mocks that provides the aliasing of (accent_)color->(accent_)colour like discord.py does."""      @property -    def color(self) -> disnake.Colour: +    def color(self) -> discord.Colour:          return self.colour      @color.setter -    def color(self, color: disnake.Colour) -> None: +    def color(self, color: discord.Colour) -> None:          self.colour = color      @property -    def accent_color(self) -> disnake.Colour: +    def accent_color(self) -> discord.Colour:          return self.accent_colour      @accent_color.setter -    def accent_color(self, color: disnake.Colour) -> None: +    def accent_color(self, color: discord.Colour) -> None:          self.accent_colour = color @@ -63,7 +63,7 @@ class CustomMockMixin:      Provides common functionality for our custom Mock types.      The `_get_child_mock` method automatically returns an AsyncMock for coroutine methods of the mock -    object. As disnake also uses synchronous methods that nonetheless return coroutine objects, the +    object. As discord.py also uses synchronous methods that nonetheless return coroutine objects, the      class attribute `additional_spec_asyncs` can be overwritten with an iterable containing additional      attribute names that should also mocked with an AsyncMock instead of a regular MagicMock/Mock. The      class method `spec_set` can be overwritten with the object that should be uses as the specification @@ -119,7 +119,7 @@ class CustomMockMixin:          return klass(**kw) -# Create a guild instance to get a realistic Mock of `disnake.Guild` +# Create a guild instance to get a realistic Mock of `discord.Guild`  guild_data = {      'id': 1,      'name': 'guild', @@ -139,20 +139,20 @@ guild_data = {      'owner_id': 1,      'afk_channel_id': 464033278631084042,  } -guild_instance = disnake.Guild(data=guild_data, state=unittest.mock.MagicMock()) +guild_instance = discord.Guild(data=guild_data, state=unittest.mock.MagicMock())  class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):      """ -    A `Mock` subclass to mock `disnake.Guild` objects. +    A `Mock` subclass to mock `discord.Guild` objects. -    A MockGuild instance will follow the specifications of a `disnake.Guild` instance. This means +    A MockGuild instance will follow the specifications of a `discord.Guild` instance. This means      that if the code you're testing tries to access an attribute or method that normally does not -    exist for a `disnake.Guild` object this will raise an `AttributeError`. This is to make sure our -    tests fail if the code we're testing uses a `disnake.Guild` object in the wrong way. +    exist for a `discord.Guild` object this will raise an `AttributeError`. This is to make sure our +    tests fail if the code we're testing uses a `discord.Guild` object in the wrong way.      One restriction of that is that if the code tries to access an attribute that normally does not -    exist for `disnake.Guild` instance but was added dynamically, this will raise an exception with +    exist for `discord.Guild` instance but was added dynamically, this will raise an exception with      the mocked object. To get around that, you can set the non-standard attribute explicitly for the      instance of `MockGuild`: @@ -160,10 +160,10 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):      >>> guild.attribute_that_normally_does_not_exist = unittest.mock.MagicMock()      In addition to attribute simulation, mocked guild object will pass an `isinstance` check against -    `disnake.Guild`: +    `discord.Guild`:      >>> guild = MockGuild() -    >>> isinstance(guild, disnake.Guild) +    >>> isinstance(guild, discord.Guild)      True      For more info, see the `Mocking` section in `tests/README.md`. @@ -171,7 +171,7 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):      spec_set = guild_instance      def __init__(self, roles: Optional[Iterable[MockRole]] = None, **kwargs) -> None: -        default_kwargs = {'id': next(self.discord_id), 'members': []} +        default_kwargs = {'id': next(self.discord_id), 'members': [], "chunked": True}          super().__init__(**collections.ChainMap(kwargs, default_kwargs))          self.roles = [MockRole(name="@everyone", position=1, id=0)] @@ -179,16 +179,16 @@ class MockGuild(CustomMockMixin, unittest.mock.Mock, HashableMixin):              self.roles.extend(roles) -# Create a Role instance to get a realistic Mock of `disnake.Role` +# Create a Role instance to get a realistic Mock of `discord.Role`  role_data = {'name': 'role', 'id': 1} -role_instance = disnake.Role(guild=guild_instance, state=unittest.mock.MagicMock(), data=role_data) +role_instance = discord.Role(guild=guild_instance, state=unittest.mock.MagicMock(), data=role_data)  class MockRole(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):      """ -    A Mock subclass to mock `disnake.Role` objects. +    A Mock subclass to mock `discord.Role` objects. -    Instances of this class will follow the specifications of `disnake.Role` instances. For more +    Instances of this class will follow the specifications of `discord.Role` instances. For more      information, see the `MockGuild` docstring.      """      spec_set = role_instance @@ -198,40 +198,40 @@ class MockRole(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):              'id': next(self.discord_id),              'name': 'role',              'position': 1, -            'colour': disnake.Colour(0xdeadbf), -            'permissions': disnake.Permissions(), +            'colour': discord.Colour(0xdeadbf), +            'permissions': discord.Permissions(),          }          super().__init__(**collections.ChainMap(kwargs, default_kwargs))          if isinstance(self.colour, int): -            self.colour = disnake.Colour(self.colour) +            self.colour = discord.Colour(self.colour)          if isinstance(self.permissions, int): -            self.permissions = disnake.Permissions(self.permissions) +            self.permissions = discord.Permissions(self.permissions)          if 'mention' not in kwargs:              self.mention = f'&{self.name}'      def __lt__(self, other): -        """Simplified position-based comparisons similar to those of `disnake.Role`.""" +        """Simplified position-based comparisons similar to those of `discord.Role`."""          return self.position < other.position      def __ge__(self, other): -        """Simplified position-based comparisons similar to those of `disnake.Role`.""" +        """Simplified position-based comparisons similar to those of `discord.Role`."""          return self.position >= other.position -# Create a Member instance to get a realistic Mock of `disnake.Member` +# Create a Member instance to get a realistic Mock of `discord.Member`  member_data = {'user': 'lemon', 'roles': [1]}  state_mock = unittest.mock.MagicMock() -member_instance = disnake.Member(data=member_data, guild=guild_instance, state=state_mock) +member_instance = discord.Member(data=member_data, guild=guild_instance, state=state_mock)  class MockMember(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):      """      A Mock subclass to mock Member objects. -    Instances of this class will follow the specifications of `disnake.Member` instances. For more +    Instances of this class will follow the specifications of `discord.Member` instances. For more      information, see the `MockGuild` docstring.      """      spec_set = member_instance @@ -249,11 +249,11 @@ class MockMember(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin              self.mention = f"@{self.name}" -# Create a User instance to get a realistic Mock of `disnake.User` +# Create a User instance to get a realistic Mock of `discord.User`  _user_data_mock = collections.defaultdict(unittest.mock.MagicMock, {      "accent_color": 0  }) -user_instance = disnake.User( +user_instance = discord.User(      data=unittest.mock.MagicMock(get=unittest.mock.Mock(side_effect=_user_data_mock.get)),      state=unittest.mock.MagicMock()  ) @@ -263,7 +263,7 @@ class MockUser(CustomMockMixin, unittest.mock.Mock, ColourMixin, HashableMixin):      """      A Mock subclass to mock User objects. -    Instances of this class will follow the specifications of `disnake.User` instances. For more +    Instances of this class will follow the specifications of `discord.User` instances. For more      information, see the `MockGuild` docstring.      """      spec_set = user_instance @@ -305,13 +305,17 @@ class MockBot(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Bot objects. -    Instances of this class will follow the specifications of `disnake.ext.commands.Bot` instances. +    Instances of this class will follow the specifications of `discord.ext.commands.Bot` instances.      For more information, see the `MockGuild` docstring.      """      spec_set = Bot(          command_prefix=unittest.mock.MagicMock(),          loop=_get_mock_loop(),          redis_session=unittest.mock.MagicMock(), +        http_session=unittest.mock.MagicMock(), +        allowed_roles=[1], +        guild_id=1, +        intents=discord.Intents.all(),      )      additional_spec_asyncs = ("wait_for", "redis_ready") @@ -322,9 +326,10 @@ class MockBot(CustomMockMixin, unittest.mock.MagicMock):          self.api_client = MockAPIClient(loop=self.loop)          self.http_session = unittest.mock.create_autospec(spec=ClientSession, spec_set=True)          self.stats = unittest.mock.create_autospec(spec=AsyncStatsClient, spec_set=True) +        self.add_cog = unittest.mock.AsyncMock() -# Create a TextChannel instance to get a realistic MagicMock of `disnake.TextChannel` +# Create a TextChannel instance to get a realistic MagicMock of `discord.TextChannel`  channel_data = {      'id': 1,      'type': 'TextChannel', @@ -334,20 +339,22 @@ channel_data = {      'position': 1,      'nsfw': False,      'last_message_id': 1, +    'bitrate': 1337, +    'user_limit': 25,  }  state = unittest.mock.MagicMock()  guild = unittest.mock.MagicMock() -text_channel_instance = disnake.TextChannel(state=state, guild=guild, data=channel_data) +text_channel_instance = discord.TextChannel(state=state, guild=guild, data=channel_data)  channel_data["type"] = "VoiceChannel" -voice_channel_instance = disnake.VoiceChannel(state=state, guild=guild, data=channel_data) +voice_channel_instance = discord.VoiceChannel(state=state, guild=guild, data=channel_data)  class MockTextChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):      """      A MagicMock subclass to mock TextChannel objects. -    Instances of this class will follow the specifications of `disnake.TextChannel` instances. For +    Instances of this class will follow the specifications of `discord.TextChannel` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = text_channel_instance @@ -364,7 +371,7 @@ class MockVoiceChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):      """      A MagicMock subclass to mock VoiceChannel objects. -    Instances of this class will follow the specifications of `disnake.VoiceChannel` instances. For +    Instances of this class will follow the specifications of `discord.VoiceChannel` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = voice_channel_instance @@ -381,14 +388,14 @@ class MockVoiceChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):  state = unittest.mock.MagicMock()  me = unittest.mock.MagicMock()  dm_channel_data = {"id": 1, "recipients": [unittest.mock.MagicMock()]} -dm_channel_instance = disnake.DMChannel(me=me, state=state, data=dm_channel_data) +dm_channel_instance = discord.DMChannel(me=me, state=state, data=dm_channel_data)  class MockDMChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):      """      A MagicMock subclass to mock TextChannel objects. -    Instances of this class will follow the specifications of `disnake.TextChannel` instances. For +    Instances of this class will follow the specifications of `discord.TextChannel` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = dm_channel_instance @@ -398,17 +405,17 @@ class MockDMChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):          super().__init__(**collections.ChainMap(kwargs, default_kwargs)) -# Create CategoryChannel instance to get a realistic MagicMock of `disnake.CategoryChannel` +# Create CategoryChannel instance to get a realistic MagicMock of `discord.CategoryChannel`  category_channel_data = {      'id': 1, -    'type': disnake.ChannelType.category, +    'type': discord.ChannelType.category,      'name': 'category',      'position': 1,  }  state = unittest.mock.MagicMock()  guild = unittest.mock.MagicMock() -category_channel_instance = disnake.CategoryChannel( +category_channel_instance = discord.CategoryChannel(      state=state, guild=guild, data=category_channel_data  ) @@ -419,13 +426,13 @@ class MockCategoryChannel(CustomMockMixin, unittest.mock.Mock, HashableMixin):          super().__init__(**collections.ChainMap(default_kwargs, kwargs)) -# Create a Message instance to get a realistic MagicMock of `disnake.Message` +# Create a Message instance to get a realistic MagicMock of `discord.Message`  message_data = {      'id': 1,      'webhook_id': 431341013479718912,      'attachments': [],      'embeds': [], -    'application': 'Python Discord', +    'application': {"id": 4, "description": "A Python Bot", "name": "Python Discord", "icon": None},      'activity': 'mocking',      'channel': unittest.mock.MagicMock(),      'edited_timestamp': '2019-10-14T15:33:48+00:00', @@ -438,10 +445,11 @@ message_data = {  }  state = unittest.mock.MagicMock()  channel = unittest.mock.MagicMock() -message_instance = disnake.Message(state=state, channel=channel, data=message_data) +channel.type = discord.ChannelType.text +message_instance = discord.Message(state=state, channel=channel, data=message_data) -# Create a Context instance to get a realistic MagicMock of `disnake.ext.commands.Context` +# Create a Context instance to get a realistic MagicMock of `discord.ext.commands.Context`  context_instance = Context(      message=unittest.mock.MagicMock(),      prefix="$", @@ -455,7 +463,7 @@ class MockContext(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Context objects. -    Instances of this class will follow the specifications of `disnake.ext.commands.Context` +    Instances of this class will follow the specifications of `discord.ext.commands.Context`      instances. For more information, see the `MockGuild` docstring.      """      spec_set = context_instance @@ -471,24 +479,46 @@ class MockContext(CustomMockMixin, unittest.mock.MagicMock):          self.invoked_from_error_handler = kwargs.get('invoked_from_error_handler', False) -attachment_instance = disnake.Attachment(data=unittest.mock.MagicMock(id=1), state=unittest.mock.MagicMock()) +attachment_instance = discord.Attachment(data=unittest.mock.MagicMock(id=1), state=unittest.mock.MagicMock())  class MockAttachment(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Attachment objects. -    Instances of this class will follow the specifications of `disnake.Attachment` instances. For +    Instances of this class will follow the specifications of `discord.Attachment` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = attachment_instance +message_reference_instance = discord.MessageReference( +    message_id=unittest.mock.MagicMock(id=1), +    channel_id=unittest.mock.MagicMock(id=2), +    guild_id=unittest.mock.MagicMock(id=3) +) + + +class MockMessageReference(CustomMockMixin, unittest.mock.MagicMock): +    """ +    A MagicMock subclass to mock MessageReference objects. + +    Instances of this class will follow the specification of `discord.MessageReference` instances. +    For more information, see the `MockGuild` docstring. +    """ +    spec_set = message_reference_instance + +    def __init__(self, *, reference_author_is_bot: bool = False, **kwargs): +        super().__init__(**kwargs) +        referenced_msg_author = MockMember(name="bob", bot=reference_author_is_bot) +        self.resolved = MockMessage(author=referenced_msg_author) + +  class MockMessage(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Message objects. -    Instances of this class will follow the specifications of `disnake.Message` instances. For more +    Instances of this class will follow the specifications of `discord.Message` instances. For more      information, see the `MockGuild` docstring.      """      spec_set = message_instance @@ -501,14 +531,14 @@ class MockMessage(CustomMockMixin, unittest.mock.MagicMock):  emoji_data = {'require_colons': True, 'managed': True, 'id': 1, 'name': 'hyperlemon'} -emoji_instance = disnake.Emoji(guild=MockGuild(), state=unittest.mock.MagicMock(), data=emoji_data) +emoji_instance = discord.Emoji(guild=MockGuild(), state=unittest.mock.MagicMock(), data=emoji_data)  class MockEmoji(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Emoji objects. -    Instances of this class will follow the specifications of `disnake.Emoji` instances. For more +    Instances of this class will follow the specifications of `discord.Emoji` instances. For more      information, see the `MockGuild` docstring.      """      spec_set = emoji_instance @@ -518,27 +548,27 @@ class MockEmoji(CustomMockMixin, unittest.mock.MagicMock):          self.guild = kwargs.get('guild', MockGuild()) -partial_emoji_instance = disnake.PartialEmoji(animated=False, name='guido') +partial_emoji_instance = discord.PartialEmoji(animated=False, name='guido')  class MockPartialEmoji(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock PartialEmoji objects. -    Instances of this class will follow the specifications of `disnake.PartialEmoji` instances. For +    Instances of this class will follow the specifications of `discord.PartialEmoji` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = partial_emoji_instance -reaction_instance = disnake.Reaction(message=MockMessage(), data={'me': True}, emoji=MockEmoji()) +reaction_instance = discord.Reaction(message=MockMessage(), data={'me': True}, emoji=MockEmoji())  class MockReaction(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Reaction objects. -    Instances of this class will follow the specifications of `disnake.Reaction` instances. For +    Instances of this class will follow the specifications of `discord.Reaction` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = reaction_instance @@ -556,14 +586,14 @@ class MockReaction(CustomMockMixin, unittest.mock.MagicMock):          self.__str__.return_value = str(self.emoji) -webhook_instance = disnake.Webhook(data=unittest.mock.MagicMock(), session=unittest.mock.MagicMock()) +webhook_instance = discord.Webhook(data=unittest.mock.MagicMock(), session=unittest.mock.MagicMock())  class MockAsyncWebhook(CustomMockMixin, unittest.mock.MagicMock):      """      A MagicMock subclass to mock Webhook objects using an AsyncWebhookAdapter. -    Instances of this class will follow the specifications of `disnake.Webhook` instances. For +    Instances of this class will follow the specifications of `discord.Webhook` instances. For      more information, see the `MockGuild` docstring.      """      spec_set = webhook_instance  |