|
1 | 1 | import unittest |
2 | | -from unittest.mock import patch |
| 2 | +from unittest.mock import AsyncMock, patch |
3 | 3 |
|
4 | 4 | from bot.constants import Roles |
5 | 5 | from bot.exts.filtering._filter_context import Event, FilterContext |
@@ -238,3 +238,66 @@ def test_clean_ban_mentions_removes_moderator_and_broad_mentions(self, resolve_m |
238 | 238 | cleaned = _clean_ban_mentions(mentions) |
239 | 239 |
|
240 | 240 | self.assertSetEqual(cleaned, {"other-role", "12345"}) |
| 241 | + |
| 242 | + |
| 243 | +class InfractionActionTests(unittest.IsolatedAsyncioTestCase): |
| 244 | + """Tests for infraction action behavior in filtering.""" |
| 245 | + |
| 246 | + @patch("bot.exts.filtering._settings_types.actions.infraction_and_notification.infraction_utils.get_active_infraction") |
| 247 | + @patch("bot.exts.filtering._settings_types.actions.infraction_and_notification.bot_module.instance") |
| 248 | + async def test_ban_action_marks_already_banned_when_active_ban_exists(self, bot_instance, get_active_infraction): |
| 249 | + """A pre-existing active ban should be reported as already banned without invoking the ban command.""" |
| 250 | + member = MockMember(id=123) |
| 251 | + channel = MockTextChannel(id=345) |
| 252 | + alerts_channel = MockTextChannel(id=999) |
| 253 | + message = MockMessage(author=member, channel=channel) |
| 254 | + ctx = FilterContext(Event.MESSAGE, member, channel, "", message) |
| 255 | + |
| 256 | + ban_command = AsyncMock() |
| 257 | + bot_instance.get_command.return_value = ban_command |
| 258 | + bot_instance.get_channel.return_value = alerts_channel |
| 259 | + get_active_infraction.return_value = {"id": 42, "type": "ban"} |
| 260 | + |
| 261 | + action = InfractionAndNotification( |
| 262 | + infraction_type="BAN", |
| 263 | + infraction_reason="reason", |
| 264 | + infraction_duration=InfractionDuration(0), |
| 265 | + dm_content="", |
| 266 | + dm_embed="", |
| 267 | + infraction_channel=0, |
| 268 | + ) |
| 269 | + |
| 270 | + await action.action(ctx) |
| 271 | + |
| 272 | + self.assertEqual(ctx.action_descriptions, ["already banned"]) |
| 273 | + ban_command.assert_not_awaited() |
| 274 | + get_active_infraction.assert_awaited_once() |
| 275 | + |
| 276 | + @patch("bot.exts.filtering._settings_types.actions.infraction_and_notification.infraction_utils.get_active_infraction") |
| 277 | + @patch("bot.exts.filtering._settings_types.actions.infraction_and_notification.bot_module.instance") |
| 278 | + async def test_ban_action_marks_banned_when_no_active_ban(self, bot_instance, get_active_infraction): |
| 279 | + """A successful ban path should preserve the existing banned action description.""" |
| 280 | + member = MockMember(id=123) |
| 281 | + channel = MockTextChannel(id=345) |
| 282 | + alerts_channel = MockTextChannel(id=999) |
| 283 | + message = MockMessage(author=member, channel=channel) |
| 284 | + ctx = FilterContext(Event.MESSAGE, member, channel, "", message) |
| 285 | + |
| 286 | + ban_command = AsyncMock() |
| 287 | + bot_instance.get_command.return_value = ban_command |
| 288 | + bot_instance.get_channel.return_value = alerts_channel |
| 289 | + get_active_infraction.return_value = None |
| 290 | + |
| 291 | + action = InfractionAndNotification( |
| 292 | + infraction_type="BAN", |
| 293 | + infraction_reason="reason", |
| 294 | + infraction_duration=InfractionDuration(0), |
| 295 | + dm_content="", |
| 296 | + dm_embed="", |
| 297 | + infraction_channel=0, |
| 298 | + ) |
| 299 | + |
| 300 | + await action.action(ctx) |
| 301 | + |
| 302 | + self.assertEqual(ctx.action_descriptions, ["banned"]) |
| 303 | + ban_command.assert_awaited_once() |
0 commit comments