Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions bot/exts/info/information.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,11 @@ async def create_user_embed(self, ctx: Context, user: MemberOrUser) -> Embed:
"Member information",
membership
),
await self.user_messages(user),
]

# Show more verbose output in moderation channels for infractions and nominations
if is_mod_channel(ctx.channel):
fields.append(await self.user_messages(user))
fields.append(await self.expanded_user_infraction_counts(user))
fields.append(await self.user_nomination_counts(user))
else:
Expand Down Expand Up @@ -420,13 +420,8 @@ async def user_messages(self, user: MemberOrUser) -> Tuple[Union[bool, str], Tup
if e.status == 404:
activity_output = "No activity"
Comment thread
Bluenix2 marked this conversation as resolved.
else:
activity_output.append(user_activity["total_messages"] or "No messages")

if (activity_blocks := user_activity.get("activity_blocks")) is not None:
# activity_blocks is not included in the response if the user has a lot of messages
activity_output.append(activity_blocks or "No activity") # Special case when activity_blocks is 0.
else:
activity_output.append("Too many to count!")
activity_output.append(f"{user_activity['total_messages']:,}" or "No messages")
activity_output.append(f"{user_activity['activity_blocks']:,}" or "No activity")

activity_output = "\n".join(
f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output)
Expand Down
5 changes: 1 addition & 4 deletions bot/exts/moderation/voice_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,8 @@ async def voice_verify(self, ctx: Context, *_) -> None:
),
"total_messages": data["total_messages"] < GateConf.minimum_messages,
"voice_banned": data["voice_banned"],
"activity_blocks": data["activity_blocks"] < GateConf.minimum_activity_blocks,
}
if activity_blocks := data.get("activity_blocks"):
# activity_blocks is not included in the response if the user has a lot of messages.
# Only check if the user has enough activity blocks if it is included.
checks["activity_blocks"] = activity_blocks < GateConf.minimum_activity_blocks

failed = any(checks.values())
failed_reasons = [MESSAGE_FIELD_MAP[key] for key, value in checks.items() if value is True]
Expand Down
43 changes: 41 additions & 2 deletions tests/bot/exts/info/test_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ def setUp(self):
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_uses_string_representation_of_user_in_title_if_nick_is_not_available(self):
"""The embed should use the string representation of the user if they don't have a nick."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1))
Expand All @@ -293,6 +297,10 @@ async def test_create_user_embed_uses_string_representation_of_user_in_title_if_
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_uses_nick_in_title_if_available(self):
"""The embed should use the nick if it's available."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1))
Expand All @@ -310,6 +318,10 @@ async def test_create_user_embed_uses_nick_in_title_if_available(self):
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_ignores_everyone_role(self):
"""Created `!user` embeds should not contain mention of the @everyone-role."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=1))
Expand All @@ -325,6 +337,10 @@ async def test_create_user_embed_ignores_everyone_role(self):

@unittest.mock.patch(f"{COG_PATH}.expanded_user_infraction_counts", new_callable=unittest.mock.AsyncMock)
@unittest.mock.patch(f"{COG_PATH}.user_nomination_counts", new_callable=unittest.mock.AsyncMock)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_expanded_information_in_moderation_channels(
self,
nomination_counts,
Expand Down Expand Up @@ -363,13 +379,19 @@ async def test_create_user_embed_expanded_information_in_moderation_channels(
)

@unittest.mock.patch(f"{COG_PATH}.basic_user_infraction_counts", new_callable=unittest.mock.AsyncMock)
async def test_create_user_embed_basic_information_outside_of_moderation_channels(self, infraction_counts):
@unittest.mock.patch(f"{COG_PATH}.user_messages", new_callable=unittest.mock.AsyncMock)
async def test_create_user_embed_basic_information_outside_of_moderation_channels(
self,
user_messages,
infraction_counts,
):
"""The embed should contain only basic infraction data outside of mod channels."""
ctx = helpers.MockContext(channel=helpers.MockTextChannel(id=100))

moderators_role = helpers.MockRole(name='Moderators')

infraction_counts.return_value = ("Infractions", "basic infractions info")
user_messages.return_value = ("Messages", "user message counts")

user = helpers.MockMember(id=314, roles=[moderators_role], colour=100)
embed = await self.cog.create_user_embed(ctx, user)
Expand All @@ -394,14 +416,23 @@ async def test_create_user_embed_basic_information_outside_of_moderation_channel
)

self.assertEqual(
"basic infractions info",
"user message counts",
embed.fields[2].value
)

self.assertEqual(
"basic infractions info",
embed.fields[3].value
)

@unittest.mock.patch(
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_uses_top_role_colour_when_user_has_roles(self):
"""The embed should be created with the colour of the top role, if a top role is available."""
ctx = helpers.MockContext()
Expand All @@ -417,6 +448,10 @@ async def test_create_user_embed_uses_top_role_colour_when_user_has_roles(self):
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_uses_og_blurple_colour_when_user_has_no_roles(self):
"""The embed should be created with the og blurple colour if the user has no assigned roles."""
ctx = helpers.MockContext()
Expand All @@ -430,6 +465,10 @@ async def test_create_user_embed_uses_og_blurple_colour_when_user_has_no_roles(s
f"{COG_PATH}.basic_user_infraction_counts",
new=unittest.mock.AsyncMock(return_value=("Infractions", "basic infractions"))
)
@unittest.mock.patch(
f"{COG_PATH}.user_messages",
new=unittest.mock.AsyncMock(return_value=("Messsages", "user message count"))
)
async def test_create_user_embed_uses_png_format_of_user_avatar_as_thumbnail(self):
"""The embed thumbnail should be set to the user's avatar in `png` format."""
ctx = helpers.MockContext()
Expand Down