aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/cogs.py8
-rw-r--r--bot/cogs/filtering.py2
-rw-r--r--bot/cogs/logging.py4
-rw-r--r--bot/cogs/moderation.py2
-rw-r--r--bot/cogs/site.py15
-rw-r--r--bot/cogs/superstarify/__init__.py2
-rw-r--r--bot/cogs/verification.py4
-rw-r--r--bot/constants.py2
-rw-r--r--config-default.yml4
-rw-r--r--tests/cogs/test_token_remover.py133
-rw-r--r--tests/helpers.py10
-rw-r--r--tox.ini2
12 files changed, 167 insertions, 21 deletions
diff --git a/bot/cogs/cogs.py b/bot/cogs/cogs.py
index ebdbf5ad8..7283aae6d 100644
--- a/bot/cogs/cogs.py
+++ b/bot/cogs/cogs.py
@@ -60,7 +60,7 @@ class Cogs:
embed.set_author(
name="Python Bot (Cogs)",
- url=URLs.gitlab_bot_repo,
+ url=URLs.github_bot_repo,
icon_url=URLs.bot_avatar
)
@@ -113,7 +113,7 @@ class Cogs:
embed.set_author(
name="Python Bot (Cogs)",
- url=URLs.gitlab_bot_repo,
+ url=URLs.github_bot_repo,
icon_url=URLs.bot_avatar
)
@@ -168,7 +168,7 @@ class Cogs:
embed.set_author(
name="Python Bot (Cogs)",
- url=URLs.gitlab_bot_repo,
+ url=URLs.github_bot_repo,
icon_url=URLs.bot_avatar
)
@@ -269,7 +269,7 @@ class Cogs:
embed.colour = Colour.blurple()
embed.set_author(
name="Python Bot (Cogs)",
- url=URLs.gitlab_bot_repo,
+ url=URLs.github_bot_repo,
icon_url=URLs.bot_avatar
)
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py
index 418297fc4..77f6eece5 100644
--- a/bot/cogs/filtering.py
+++ b/bot/cogs/filtering.py
@@ -59,7 +59,7 @@ class Filtering:
"user_notification": Filter.notify_user_invites,
"notification_msg": (
f"Per Rule 10, your invite link has been removed. {_staff_mistake_str}\n\n"
- r"Our server rules can be found here: <https://pythondiscord.com/about/rules>"
+ r"Our server rules can be found here: <https://pythondiscord.com/pages/rules>"
)
},
"filter_domains": {
diff --git a/bot/cogs/logging.py b/bot/cogs/logging.py
index 6b8462f3b..b31db60d9 100644
--- a/bot/cogs/logging.py
+++ b/bot/cogs/logging.py
@@ -23,8 +23,8 @@ class Logging:
embed = Embed(description="Connected!")
embed.set_author(
name="Python Bot",
- url="https://gitlab.com/discord-python/projects/bot",
- icon_url="https://gitlab.com/python-discord/branding/raw/master/logos/logo_circle/logo_circle.png"
+ url="https://github.com/python-discord/bot",
+ icon_url="https://github.com/python-discord/branding/blob/master/logos/logo_circle/logo_circle.png"
)
if not DEBUG_MODE:
diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py
index fb791c933..532a44f4d 100644
--- a/bot/cogs/moderation.py
+++ b/bot/cogs/moderation.py
@@ -28,7 +28,7 @@ INFRACTION_ICONS = {
"Kick": Icons.sign_out,
"Ban": Icons.user_ban
}
-RULES_URL = "https://pythondiscord.com/about/rules"
+RULES_URL = "https://pythondiscord.com/pages/rules"
APPEALABLE_INFRACTIONS = ("Ban", "Mute")
diff --git a/bot/cogs/site.py b/bot/cogs/site.py
index b5e63fb41..b540827bf 100644
--- a/bot/cogs/site.py
+++ b/bot/cogs/site.py
@@ -46,15 +46,18 @@ class Site:
async def site_resources(self, ctx: Context):
"""Info about the site's Resources page."""
- url = f"{PAGES_URL}/resources"
+ learning_url = f"{PAGES_URL}/resources"
+ tools_url = f"{PAGES_URL}/tools"
- embed = Embed(title="Resources")
- embed.set_footer(text=url)
+ embed = Embed(title="Resources & Tools")
+ embed.set_footer(text=f"{learning_url} | {tools_url}")
embed.colour = Colour.blurple()
embed.description = (
- f"The [Resources page]({url}) on our website contains a "
+ f"The [Resources page]({learning_url}) on our website contains a "
"list of hand-selected goodies that we regularly recommend "
- "to both beginners and experts."
+ f"to both beginners and experts. The [Tools page]({tools_url}) "
+ "contains a couple of the most popular tools for programming in "
+ "Python."
)
await ctx.send(embed=embed)
@@ -111,7 +114,7 @@ class Site:
# Rules were not submitted. Return the default description.
rules_embed.description = (
"The rules and guidelines that apply to this community can be found on"
- " our [rules page](https://pythondiscord.com/about/rules). We expect"
+ f" our [rules page]({PAGES_URL}/rules). We expect"
" all members of the community to have read and understood these."
)
diff --git a/bot/cogs/superstarify/__init__.py b/bot/cogs/superstarify/__init__.py
index cccd91304..b2e31db3e 100644
--- a/bot/cogs/superstarify/__init__.py
+++ b/bot/cogs/superstarify/__init__.py
@@ -15,7 +15,7 @@ from bot.decorators import with_role
from bot.utils.moderation import post_infraction
log = logging.getLogger(__name__)
-NICKNAME_POLICY_URL = "https://pythondiscord.com/about/rules#nickname-policy"
+NICKNAME_POLICY_URL = "https://pythondiscord.com/pages/rules/#wiki-toc-nickname-policy"
class Superstarify:
diff --git a/bot/cogs/verification.py b/bot/cogs/verification.py
index 6b42c9213..efbcda166 100644
--- a/bot/cogs/verification.py
+++ b/bot/cogs/verification.py
@@ -14,8 +14,8 @@ Hello! Welcome to the server, and thanks for verifying yourself!
For your records, these are the documents you accepted:
-`1)` Our rules, here: <https://pythondiscord.com/about/rules>
-`2)` Our privacy policy, here: <https://pythondiscord.com/about/privacy> - you can find information on how to have \
+`1)` Our rules, here: <https://pythondiscord.com/pages/rules>
+`2)` Our privacy policy, here: <https://pythondiscord.com/pages/privacy> - you can find information on how to have \
your information removed here as well.
Feel free to review them at any point!
diff --git a/bot/constants.py b/bot/constants.py
index 4e14a85a8..d5b73bd1d 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -412,7 +412,7 @@ class URLs(metaclass=YAMLGetter):
# Misc endpoints
bot_avatar: str
deploy: str
- gitlab_bot_repo: str
+ github_bot_repo: str
status: str
# Site endpoints
diff --git a/config-default.yml b/config-default.yml
index c9fc3b954..fd83e69a4 100644
--- a/config-default.yml
+++ b/config-default.yml
@@ -95,7 +95,7 @@ guild:
bot: 267659945086812160
checkpoint_test: 422077681434099723
defcon: 464469101889454091
- devlog: &DEVLOG 409308876241108992
+ devlog: &DEVLOG 622895325144940554
devtest: &DEVTEST 414574275865870337
help_0: 303906576991780866
help_1: 303906556754395136
@@ -273,7 +273,7 @@ urls:
# Misc URLs
bot_avatar: "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png"
- gitlab_bot_repo: "https://gitlab.com/python-discord/projects/bot"
+ github_bot_repo: "https://github.com/python-discord/bot"
anti_spam:
# Clean messages that violate a rule.
diff --git a/tests/cogs/test_token_remover.py b/tests/cogs/test_token_remover.py
new file mode 100644
index 000000000..9d46b3a05
--- /dev/null
+++ b/tests/cogs/test_token_remover.py
@@ -0,0 +1,133 @@
+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"
diff --git a/tests/helpers.py b/tests/helpers.py
new file mode 100644
index 000000000..57c6fcc1a
--- /dev/null
+++ b/tests/helpers.py
@@ -0,0 +1,10 @@
+from unittest.mock import MagicMock
+
+
+__all__ = ('AsyncMock',)
+
+
+# TODO: Remove me on 3.8
+class AsyncMock(MagicMock):
+ async def __call__(self, *args, **kwargs):
+ return super(AsyncMock, self).__call__(*args, **kwargs)
diff --git a/tox.ini b/tox.ini
index c84827570..21097cd97 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[flake8]
max-line-length=120
-application_import_names=bot
+application_import_names=bot,tests
exclude=.cache,.venv
ignore=B311,W503,E226,S311,T000
import-order-style=pycharm