aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/moderation/infraction/infractions.py12
-rw-r--r--tests/bot/exts/moderation/infraction/test_infractions.py15
2 files changed, 24 insertions, 3 deletions
diff --git a/bot/exts/moderation/infraction/infractions.py b/bot/exts/moderation/infraction/infractions.py
index 18e937e87..78c326c47 100644
--- a/bot/exts/moderation/infraction/infractions.py
+++ b/bot/exts/moderation/infraction/infractions.py
@@ -257,6 +257,10 @@ class Infractions(InfractionScheduler, commands.Cog):
self.mod_log.ignore(Event.member_update, user.id)
async def action() -> None:
+ # Skip members that left the server
+ if not isinstance(user, Member):
+ return
+
await user.add_roles(self._muted_role, reason=reason)
log.trace(f"Attempting to kick {user} from voice because they've been muted.")
@@ -351,9 +355,13 @@ class Infractions(InfractionScheduler, commands.Cog):
if reason:
reason = textwrap.shorten(reason, width=512, placeholder="...")
- await user.move_to(None, reason="Disconnected from voice to apply voiceban.")
+ action = None
+
+ # Skip members that left the server
+ if isinstance(user, Member):
+ await user.move_to(None, reason="Disconnected from voice to apply voiceban.")
+ action = user.remove_roles(self._voice_verified_role, reason=reason)
- action = user.remove_roles(self._voice_verified_role, reason=reason)
await self.apply_infraction(ctx, infraction, user, action)
# endregion
diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py
index bf557a484..4ba5a4feb 100644
--- a/tests/bot/exts/moderation/infraction/test_infractions.py
+++ b/tests/bot/exts/moderation/infraction/test_infractions.py
@@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
from bot.constants import Event
from bot.exts.moderation.infraction.infractions import Infractions
-from tests.helpers import MockBot, MockContext, MockGuild, MockMember, MockRole
+from tests.helpers import MockBot, MockContext, MockGuild, MockMember, MockRole, MockUser
class TruncationTests(unittest.IsolatedAsyncioTestCase):
@@ -164,6 +164,19 @@ class VoiceBanTests(unittest.IsolatedAsyncioTestCase):
)
self.cog.apply_infraction.assert_awaited_once_with(self.ctx, {"foo": "bar"}, self.user, "my_return_value")
+ @patch("bot.exts.moderation.infraction._utils.get_active_infraction", return_value=None)
+ @patch("bot.exts.moderation.infraction._utils.post_infraction")
+ @patch("bot.exts.moderation.infraction.infractions.Infractions.apply_infraction")
+ async def test_voice_ban_user_left_guild(self, apply_infraction_mock, post_infraction_mock, _):
+ """Should voice ban user that left the guild without throwing an error."""
+ infraction = {"foo": "bar"}
+ post_infraction_mock.return_value = {"foo": "bar"}
+
+ user = MockUser()
+ await self.cog.voiceban(self.cog, self.ctx, user, reason=None)
+ post_infraction_mock.assert_called_once_with(self.ctx, user, "voice_ban", None, active=True)
+ apply_infraction_mock.assert_called_once_with(self.ctx, infraction, user, None)
+
async def test_voice_unban_user_not_found(self):
"""Should include info to return dict when user was not found from guild."""
self.guild.get_member.return_value = None