aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar scragly <[email protected]>2019-11-04 14:44:14 +1000
committerGravatar GitHub <[email protected]>2019-11-04 14:44:14 +1000
commitf390c9b474296008a1a566b4a751aea0cf27d4df (patch)
treeac0735ff98047454eb546062f6c20ee1f4051725
parentEnhance the output of the user command (diff)
parentChange invite filter message to accurately reflect the new rules (diff)
Merge branch 'master' into user-command-enhancements
-rw-r--r--bot/cogs/filtering.py2
-rw-r--r--bot/cogs/information.py10
-rw-r--r--bot/cogs/reddit.py5
-rw-r--r--bot/cogs/site.py4
-rw-r--r--tests/bot/test_utils.py52
5 files changed, 66 insertions, 7 deletions
diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py
index be9b95bc7..4195783f1 100644
--- a/bot/cogs/filtering.py
+++ b/bot/cogs/filtering.py
@@ -63,7 +63,7 @@ class Filtering(Cog):
"content_only": True,
"user_notification": Filter.notify_user_invites,
"notification_msg": (
- f"Per Rule 10, your invite link has been removed. {_staff_mistake_str}\n\n"
+ f"Per Rule 6, your invite link has been removed. {_staff_mistake_str}\n\n"
r"Our server rules can be found here: <https://pythondiscord.com/pages/rules>"
)
},
diff --git a/bot/cogs/information.py b/bot/cogs/information.py
index 4a3af7edd..530453600 100644
--- a/bot/cogs/information.py
+++ b/bot/cogs/information.py
@@ -10,6 +10,7 @@ import discord
from discord import CategoryChannel, Colour, Embed, Member, Role, TextChannel, VoiceChannel, utils
from discord.ext import commands
from discord.ext.commands import Bot, BucketType, Cog, Context, command, group
+from discord.utils import escape_markdown
from bot import constants
from bot.decorators import InChannelCheckFailure, in_channel, with_role
@@ -184,6 +185,13 @@ class Information(Cog):
"""Creates an embed containing information on the `user`."""
created = time_since(user.created_at, max_units=3)
+ # Custom status
+ custom_status = ''
+ for activity in user.activities:
+ if activity.name == 'Custom Status':
+ state = escape_markdown(activity.state)
+ custom_status = f'Status: {state}\n'
+
name = str(user)
if user.nick:
name = f"{user.nick} ({name})"
@@ -197,7 +205,7 @@ class Information(Cog):
Created: {created}
Profile: {user.mention}
ID: {user.id}
-
+ {custom_status}
**Member Information**
Joined: {joined}
Roles: {roles or None}
diff --git a/bot/cogs/reddit.py b/bot/cogs/reddit.py
index f947a7d78..0d06e9c26 100644
--- a/bot/cogs/reddit.py
+++ b/bot/cogs/reddit.py
@@ -2,7 +2,7 @@ import asyncio
import logging
import random
import textwrap
-from datetime import datetime
+from datetime import datetime, timedelta
from typing import List
from discord import Colour, Embed, TextChannel
@@ -130,7 +130,8 @@ class Reddit(Cog):
"""Post the top 5 posts daily, and the top 5 posts weekly."""
# once we upgrade to d.py 1.3 this can be removed and the loop can use the `time=datetime.time.min` parameter
now = datetime.utcnow()
- midnight_tomorrow = now.replace(day=now.day + 1, hour=0, minute=0, second=0)
+ tomorrow = now + timedelta(days=1)
+ midnight_tomorrow = tomorrow.replace(hour=0, minute=0, second=0)
seconds_until = (midnight_tomorrow - now).total_seconds()
await asyncio.sleep(seconds_until)
diff --git a/bot/cogs/site.py b/bot/cogs/site.py
index d95359159..683613788 100644
--- a/bot/cogs/site.py
+++ b/bot/cogs/site.py
@@ -3,8 +3,7 @@ import logging
from discord import Colour, Embed
from discord.ext.commands import Bot, Cog, Context, group
-from bot.constants import Channels, STAFF_ROLES, URLs
-from bot.decorators import redirect_output
+from bot.constants import URLs
from bot.pagination import LinePaginator
log = logging.getLogger(__name__)
@@ -105,7 +104,6 @@ class Site(Cog):
await ctx.send(embed=embed)
@site_group.command(aliases=['r', 'rule'], name='rules')
- @redirect_output(destination_channel=Channels.bot, bypass_roles=STAFF_ROLES)
async def site_rules(self, ctx: Context, *rules: int) -> None:
"""Provides a link to all rules or, if specified, displays specific rule(s)."""
rules_embed = Embed(title='Rules', color=Colour.blurple())
diff --git a/tests/bot/test_utils.py b/tests/bot/test_utils.py
new file mode 100644
index 000000000..58ae2a81a
--- /dev/null
+++ b/tests/bot/test_utils.py
@@ -0,0 +1,52 @@
+import unittest
+
+from bot import utils
+
+
+class CaseInsensitiveDictTests(unittest.TestCase):
+ """Tests for the `CaseInsensitiveDict` container."""
+
+ def test_case_insensitive_key_access(self):
+ """Tests case insensitive key access and storage."""
+ instance = utils.CaseInsensitiveDict()
+
+ key = 'LEMON'
+ value = 'trees'
+
+ instance[key] = value
+ self.assertIn(key, instance)
+ self.assertEqual(instance.get(key), value)
+ self.assertEqual(instance.get(key.casefold()), value)
+ self.assertEqual(instance.pop(key.casefold()), value)
+ self.assertNotIn(key, instance)
+ self.assertNotIn(key.casefold(), instance)
+
+ instance.setdefault(key, value)
+ del instance[key]
+ self.assertNotIn(key, instance)
+
+ def test_initialization_from_kwargs(self):
+ """Tests creating the dictionary from keyword arguments."""
+ instance = utils.CaseInsensitiveDict({'FOO': 'bar'})
+ self.assertEqual(instance['foo'], 'bar')
+
+ def test_update_from_other_mapping(self):
+ """Tests updating the dictionary from another mapping."""
+ instance = utils.CaseInsensitiveDict()
+ instance.update({'FOO': 'bar'})
+ self.assertEqual(instance['foo'], 'bar')
+
+
+class ChunkTests(unittest.TestCase):
+ """Tests the `chunk` method."""
+
+ def test_empty_chunking(self):
+ """Tests chunking on an empty iterable."""
+ generator = utils.chunks(iterable=[], size=5)
+ self.assertEqual(list(generator), [])
+
+ def test_list_chunking(self):
+ """Tests chunking a non-empty list."""
+ iterable = [1, 2, 3, 4, 5]
+ generator = utils.chunks(iterable=iterable, size=2)
+ self.assertEqual(list(generator), [[1, 2], [3, 4], [5]])