aboutsummaryrefslogtreecommitdiffstats
path: root/tests/helpers.py (unfollow)
Commit message (Collapse)AuthorLines
2019-10-30Update docstring and remove redundant attributeGravatar Sebastiaan Zeeff-4/+9
I accidentally forgot to update the docstring of `CustomMockMixin`, which changed quite dramatically in scope with the last commit. This commit remedies that. In addition, I inadvertently forgot to remove the `child_mock_type` class attribute from `MockRole`. Since it uses the default value, it is no longer necessary to specify it in the child class as well.
2019-10-30Enhance custom mock helpersGravatar Sebastiaan Zeeff-161/+150
I have enhanced the custom mocks defined in `tests/helpers.py` in a couple of important ways. 1. Automatically create AsyncMock attributes using `inspect` Our previous approach, hard-coding AsynckMock attributes for all the coroutine function methods defined for the class we are trying to mock is prone to human error and not resilient against changes introduced in updates of the library we are using. Instead, I have now created a helper method in our `CustomMockMixin` (formerly `GetChildMockMixin`) that automatically inspects the spec instance we've passed for `coroutine functions` using the `inspect` module. It then sets the according attributes with instances of the AsyncMock class. There is one caveat: `discord.py` very rarely defines regular methods that return a coroutine object. Since the returned coroutine should still be awaited, these regular methods should also be mocked with an AsyncMock. However, since they are regular methods, `inspect` does not detect them and they have to be added manually. (The only case of this I've found so far is `Client.wait_for`.) 2. Properly set special attributes using `kwargs.get` As we want attributes that point to other discord.py objects to use our custom mocks (.e.g, `Message.author` should use `MockMember`), the `__init__` method of our custom mocks make sure to correctly instantiate these attributes. However, the way we previously did that means we can't instantiate the custom mock with a mock instance we provide, since this special instantiation would overwrite the custom object we'd passed. I've solved this by using `kwargs.get`, with a new mock as the default value. This makes sure we only create a new mock if we didn't pass a custom one: ```py class MockMesseage: def __init__(self, **kwargs): self.author = kwargs.get('author', MockMember()) ``` As you can see, we will only create a new MockMember if we did not pass an `author` argument. 3. Factoring out duplicate lines Since our `CustomMockMixin` is a parent to all of our custom mock types, it makes sense to use it to factor out common code of all of our custom mocks. I've made the following changes: - Set a default child mock type in the mixin. - Create an `__init__` that takes care of the `inspect` of point 1 This means we won't have to repeat this in all of the child classes. 4. Three new Mock types: Emoji, PartialEmoji, and Reaction I have added three more custom mocks: - MockEmoji - MockPartialEmoji - MockReaction
2019-10-29Use 'local' emojis for reddit webhook embedGravatar Sebastiaan Zeeff-3/+3
Apparently, webhooks cannot use external emojis. For now, I have added the emojis to the guild directly and updated the IDs in this commit. I don't really like having "utility" emojis on the main guild, but the alternative would be to not use webhooks, which is a change we will need to discuss before we apply it. (I don't see anything against it now we just send a daily digest, although, in principle, this is precisely what a webhook is meant for.)
2019-10-29Enhance Reddit webhook embedsGravatar Sebastiaan Zeeff-3/+11
https://github.com/python-discord/bot/issues/634 I have changes the appearance of the embed generated for the reddit webhook. The changes: - Bold markdown around the links to prevent it breaking on android. - Stylized the meta-data line with newly created emoji-based icons. - Removed redundant mentions of the subreddit from the embed itself. The emojis were uploaded to the `Emojis II` guild and the IDs have been added to the constants files. In addition, I've set the reddit logo as the default avatar for the webhook in the guild. This commit closes #634
2019-10-28Remove redirection on rules commandGravatar Manuel Ignacio Pérez Alcolea-3/+1
Previously restricted for the staff. This change was suggested due its possible usefulness for regular users.
2019-10-28Change generation of child mocksGravatar Sebastiaan Zeeff-36/+67
- https://docs.python.org/3/library/unittest.mock.html We previously used an override of the `__new__` method to prevent our custom mock types from instantiating their children with their own type instead of a general mock type like `MagicMock` or `Mock`. As it turns out, the Python documentation suggests another method of doing this that does not involve overriding `__new__`. This commit implements this new method to make sure we're using the idiomatic way of handling this. The suggested method is overriding the `_get_child_mock` method in the subclass. To make our code DRY, I've created a mixin that should come BEFORE the mock type we're subclassing in the MRO. --- In addition, I have also added this new mixin to our `AsyncMock` class to make sure that its `__call__` method returns a proper mock object after it has been awaited. This makes sure that subsequent attribute access on the returned object is mocked as expected.
2019-10-28Chain words before length checkGravatar kosayoda-10/+6
2019-10-25Remove bold tag when no channel is availableGravatar kraktus-2/+2
2019-10-24Requested changesGravatar kraktus-3/+1
2019-10-24Fix incorrect type hint for return valueGravatar kosayoda-2/+2
2019-10-24Prepend emoji indicative of success of !evalGravatar kosayoda-1/+12
2019-10-23Use standart filter conditions even if DEBUG_MODE is on.Gravatar Akarys42-5/+1
The old method filtered only in #dev-test but this channel no longer exists
2019-10-23Substract one to now calculationGravatar Akarys42-2/+2
Avoid aving `Your reminder will arrive in 59 minutes and 59 seconds!` instead of `Your reminder will arrive in 1 hour!`
2019-10-22Add test cases for in_channel_checkGravatar Atul Mishra-0/+8
2019-10-22Modify in_channel_check to accept list of channelsGravatar Atul Mishra-7/+7
- Update test cases for in_channel_check
2019-10-21Show total infraction count only in staff channelsGravatar Akarys42-1/+3
2019-10-21Create STAFF_CHANNELS constantGravatar Akarys42-2/+15
2019-10-21Update send_reminder message creationGravatar Akarys42-6/+6
It is now truly backward compatible and use a more DRY method
2019-10-21Fix typo in channel nameGravatar Atul Mishra-1/+1
2019-10-21Add #admin-spam channel to moderation channels listGravatar Atul Mishra-2/+4
- Change doc string for cog_check method
2019-10-21Add a footer and one-line a stringGravatar kraktus-7/+4
2019-10-21Fixing formatting for timedelta.Gravatar Shirayuki Nekomata-2/+2
- Now it will only show the amount of days. - Quality of Life: Also show `day` instead of `days` when it's just 1 day.
2019-10-21Update defcon.pyGravatar Shirayuki Nekomata-11/+3
- Update docstrings for `build_defcon_msg()` and `send_defcon_log()` - It is now taking in an `Action` directly instead of a string.
2019-10-21Update defcon.pyGravatar Shirayuki Nekomata-14/+9
- Remove the unneccessary `get_info()` method of Enum `Action`. - Pass Enum `Action` directly to `build_defcon_msg()` and `send_defcon_log()` - Right now, only `_defcon_action()` is using them.
2019-10-21Update defcon.pyGravatar Shirayuki Nekomata-22/+21
- Renamed `DefconInfoLog` to `Action` - Added `ActionInfo` namedtuple. - Use `Action` consistently for `_defcon_action()` and `send_defcon_log()`
2019-10-20Apply suggestions from review, and add correct webhook ID.Gravatar mathsman5133-11/+15
- More informative docstrings for `Reddit.channel` and `get_top_posts` - Add the `amount` parameter, defaulting to 5. - Pin a max of 12 weeks worth of top posts.
2019-10-19Do not display an expiry for notes or warnings.Gravatar Johannes Christ-1/+7
2019-10-19Pluralize "infractions" as necessary.Gravatar Johannes Christ-1/+3
2019-10-19Add missing channels to the configGravatar Atul Mishra-0/+2
2019-10-19Add moderation channels check to cog_checkGravatar Atul Mishra-2/+11
2019-10-19Update defcon.pyGravatar Shirayuki Nekomata-63/+37
- Further unify defcon actions in `_defcon_action` - Thanks to Mark's suggestions. - Changed from a Dict to an Enum for defcon log info.
2019-10-17Bugfix - ensure .py attachment is prioritized over other non-whitelistedGravatar bendiller-1/+0
2019-10-17Address reviewer requestGravatar bendiller-3/+4
2019-10-17Fix defcon having wrong text when disabling.Gravatar Shirayuki Nekomata-50/+46
#### Closes #539 This pull request fixes the issue for wrong status in the embed, as well as unifying certains if else to prevent similar future errors. Most notable code is here: ```python log_msg = f"**Staffer:** {actor} (`{actor.id}`)\n" if change.lower() == "enabled": icon = Icons.defcon_enabled color = Colours.soft_green status_msg = "DEFCON enabled" log_msg += f"**Days:** {self.days.days}\n\n" elif change.lower() == "disabled": icon = Icons.defcon_disabled color = Colours.soft_red status_msg = "DEFCON enabled" elif change.lower() == "updated": icon = Icons.defcon_updated color = Colour.blurple() status_msg = "DEFCON updated" log_msg += f"**Days:** {self.days.days}\n\n" ``` To remedy this issue, the class will now have a private class variable ```py _defcon_log_info: Dict[str, Tuple] = { 'enabled': (Icons.defcon_enabled, Colours.soft_green, "**Days:** {days}\n\n"), 'disabled': (Icons.defcon_disabled, Colours.soft_red, ""), 'updated': (Icons.defcon_updated, Colour.blurple(), "**Days:** {days}\n\n"), } ``` Another big change is the introduction of `_defcon_action` to unify the process all defcon actions has to go through: - Try to do the action. - Log error if there is any. - Send log message.
2019-10-16Improve code readability and provide early exit from loopGravatar bendiller-8/+13
2019-10-15Fix rule alias.Gravatar kosayoda-6/+6
Allow rule alias to take rule numbers, passes them to the `site rules` command. Rules are now 1-indexed to conform with the representation on the website.
2019-10-15Rename `triggered` to `match`Gravatar kosayoda-8/+6
2019-10-15Utilise `tasks.loop` and a webhook for reddit postingsGravatar mathsman5133-147/+80
2019-10-14Improve code readability and docstringGravatar bendiller-13/+33
2019-10-14Remove empty tests.cogs folderGravatar Sebastiaan Zeeff-0/+0
2019-10-14Make test_token_remover use our discord MocksGravatar Sebastiaan Zeeff-8/+5
This commit replaces the standard MagicMocks by our specialized mocks for discord.py objects. It also adds the missing `channel` attribute to the `tests.helpers.MockMessage` mock and moves the file to the correct folder.
2019-10-14Use `MockBot`.Gravatar Johannes Christ-3/+3
2019-10-14Move the `token_remover` cog tests to `unittest`.Gravatar Johannes Christ-0/+139
2019-10-14Add more specialized Mocks to tests.helpersGravatar Sebastiaan Zeeff-181/+383
This commit introduces some new Mock-types to the already existing Mock-types for discord.py objects. The total list is now: - MockGuild - MockRole - MockMember - MockBot - MockContext - MockTextChannel - MockMessage In addition, I've added all coroutines in the documentation for these discord.py objects as `AsyncMock` attributes to ease testing. Tests ensure that the attributes set for the Mocks exist for the actual discord.py objects as well.
2019-10-14Implement a bypassable cooldown decoratorGravatar Ava-3/+50