diff --git a/src/cmds/core/user.py b/src/cmds/core/user.py index fb8f9ea..66a3dda 100644 --- a/src/cmds/core/user.py +++ b/src/cmds/core/user.py @@ -67,6 +67,8 @@ async def kick(self, ctx: ApplicationContext, user: Member, reason: str, evidenc -> Interaction | WebhookMessage: """Kick a user from the server.""" member = await self.bot.get_member_or_user(ctx.guild, user.id) + if not isinstance(member, discord.Member): + return await ctx.respond("User seems to have already left the server.") if not member: return await ctx.respond(f"User {user} not found.") if member_is_staff(member): diff --git a/tests/src/cmds/core/test_user.py b/tests/src/cmds/core/test_user.py index 8541456..d569c49 100644 --- a/tests/src/cmds/core/test_user.py +++ b/tests/src/cmds/core/test_user.py @@ -40,6 +40,25 @@ async def test_kick_success(self, ctx, guild, bot, session): ctx.guild.kick.assert_called_once_with(user=user_to_kick, reason="Violation of rules") ctx.respond.assert_called_once_with("User to Kick got the boot!") + @pytest.mark.asyncio + async def test_kick_fail_user_left(self, ctx, guild, bot, session): + ctx.user = helpers.MockMember(id=1, name="Test Moderator") + user_to_kick = helpers.MockMember(id=2, name="User to Kick", bot=False) + ctx.guild = guild + ctx.guild.kick = AsyncMock() + bot.get_member_or_user = AsyncMock(return_value=None) + + # Ensure the member_is_staff mock doesn't block execution + with patch('src.cmds.core.user.member_is_staff', return_value=False): + cog = user.UserCog(bot) + await cog.kick.callback(cog, ctx, user_to_kick, "Violation of rules") + + # Assertions + bot.get_member_or_user.assert_called_once_with(ctx.guild, user_to_kick.id) + ctx.guild.kick.assert_not_called() # No kick should occur + ctx.respond.assert_called_once_with("User seems to have already left the server.") + + def test_setup(self, bot): """Test the setup method of the cog.""" # Invoke the command