Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 6m9s
CI/CD Pipeline / Security Scanning (push) Successful in 26s
CI/CD Pipeline / Tests (3.11) (push) Failing after 5m24s
CI/CD Pipeline / Tests (3.12) (push) Failing after 5m23s
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Deploy to Staging (push) Has been skipped
CI/CD Pipeline / Deploy to Production (push) Has been skipped
CI/CD Pipeline / Notification (push) Successful in 1s
161 lines
5.8 KiB
Python
161 lines
5.8 KiB
Python
"""Tests for the automod service."""
|
|
|
|
import pytest
|
|
|
|
from guardden.services.automod import AutomodService
|
|
|
|
|
|
@pytest.fixture
|
|
def automod() -> AutomodService:
|
|
"""Create an automod service instance."""
|
|
return AutomodService()
|
|
|
|
|
|
class TestBannedWords:
|
|
"""Tests for banned word filtering."""
|
|
|
|
def test_simple_match(self, automod: AutomodService) -> None:
|
|
"""Test simple text matching."""
|
|
banned = [_make_banned_word("badword")]
|
|
result = automod.check_banned_words("This contains badword in it", banned)
|
|
assert result is not None
|
|
assert result.should_delete
|
|
|
|
def test_case_insensitive(self, automod: AutomodService) -> None:
|
|
"""Test case insensitive matching."""
|
|
banned = [_make_banned_word("BadWord")]
|
|
result = automod.check_banned_words("this contains BADWORD here", banned)
|
|
assert result is not None
|
|
|
|
def test_no_match(self, automod: AutomodService) -> None:
|
|
"""Test no match returns None."""
|
|
banned = [_make_banned_word("badword")]
|
|
result = automod.check_banned_words("This is a clean message", banned)
|
|
assert result is None
|
|
|
|
def test_regex_pattern(self, automod: AutomodService) -> None:
|
|
"""Test regex pattern matching."""
|
|
banned = [_make_banned_word(r"bad\w+", is_regex=True)]
|
|
result = automod.check_banned_words("This is badword and badstuff", banned)
|
|
assert result is not None
|
|
|
|
def test_action_warn(self, automod: AutomodService) -> None:
|
|
"""Test warn action is set."""
|
|
banned = [_make_banned_word("badword", action="warn")]
|
|
result = automod.check_banned_words("badword", banned)
|
|
assert result is not None
|
|
assert result.should_warn
|
|
|
|
def test_action_strike(self, automod: AutomodService) -> None:
|
|
"""Test strike action is set."""
|
|
banned = [_make_banned_word("badword", action="strike")]
|
|
result = automod.check_banned_words("badword", banned)
|
|
assert result is not None
|
|
assert result.should_strike
|
|
|
|
|
|
class TestScamDetection:
|
|
"""Tests for scam/phishing detection."""
|
|
|
|
def test_discord_nitro_scam(self, automod: AutomodService) -> None:
|
|
"""Test detection of fake Discord Nitro links."""
|
|
result = automod.check_scam_links("Free nitro at discord-nitro.gift")
|
|
assert result is not None
|
|
assert result.should_delete
|
|
|
|
def test_steam_scam(self, automod: AutomodService) -> None:
|
|
"""Test detection of Steam scam patterns."""
|
|
result = automod.check_scam_links("Check out this steam-community-giveaway.xyz")
|
|
assert result is not None
|
|
|
|
def test_legitimate_discord_link(self, automod: AutomodService) -> None:
|
|
"""Test that legitimate Discord links pass."""
|
|
result = automod.check_scam_links("Join us at discord.gg/example")
|
|
assert result is None
|
|
|
|
def test_suspicious_tld_with_keyword(self, automod: AutomodService) -> None:
|
|
"""Test suspicious TLD with impersonation keyword."""
|
|
result = automod.check_scam_links("Visit discord-verify.xyz to claim")
|
|
assert result is not None
|
|
|
|
def test_allowlisted_domain(self, automod: AutomodService) -> None:
|
|
"""Test allowlisted domains skip suspicious TLD checks."""
|
|
result = automod.check_scam_links(
|
|
"Visit https://discordapp.xyz for updates",
|
|
allowlist=["discordapp.xyz"],
|
|
)
|
|
assert result is None
|
|
|
|
def test_normal_url(self, automod: AutomodService) -> None:
|
|
"""Test normal URLs pass."""
|
|
result = automod.check_scam_links("Check out https://github.com/example")
|
|
assert result is None
|
|
|
|
|
|
class TestInviteLinks:
|
|
"""Tests for Discord invite link detection."""
|
|
|
|
def test_discord_gg_invite(self, automod: AutomodService) -> None:
|
|
"""Test discord.gg invite detection."""
|
|
result = automod.check_invite_links("Join discord.gg/example", allow_invites=False)
|
|
assert result is not None
|
|
assert result.should_delete
|
|
|
|
def test_discordapp_invite(self, automod: AutomodService) -> None:
|
|
"""Test discordapp.com invite detection."""
|
|
result = automod.check_invite_links(
|
|
"Join https://discordapp.com/invite/abc123", allow_invites=False
|
|
)
|
|
assert result is not None
|
|
|
|
def test_allowed_invites(self, automod: AutomodService) -> None:
|
|
"""Test invites pass when allowed."""
|
|
result = automod.check_invite_links("Join discord.gg/example", allow_invites=True)
|
|
assert result is None
|
|
|
|
|
|
class TestCapsDetection:
|
|
"""Tests for excessive caps detection."""
|
|
|
|
def test_excessive_caps(self, automod: AutomodService) -> None:
|
|
"""Test detection of all caps message."""
|
|
result = automod.check_all_caps("THIS IS ALL CAPS MESSAGE HERE")
|
|
assert result is not None
|
|
|
|
def test_normal_caps(self, automod: AutomodService) -> None:
|
|
"""Test normal message passes."""
|
|
result = automod.check_all_caps("This is a Normal Message with Some Caps")
|
|
assert result is None
|
|
|
|
def test_short_message_ignored(self, automod: AutomodService) -> None:
|
|
"""Test short messages are ignored."""
|
|
result = automod.check_all_caps("HI THERE")
|
|
assert result is None
|
|
|
|
|
|
class MockBannedWord:
|
|
"""Mock BannedWord for testing without database."""
|
|
|
|
def __init__(
|
|
self,
|
|
pattern: str,
|
|
is_regex: bool = False,
|
|
action: str = "delete",
|
|
) -> None:
|
|
self.id = 1
|
|
self.guild_id = 123
|
|
self.pattern = pattern
|
|
self.is_regex = is_regex
|
|
self.action = action
|
|
self.reason = None
|
|
self.added_by = 456
|
|
|
|
|
|
def _make_banned_word(
|
|
pattern: str,
|
|
is_regex: bool = False,
|
|
action: str = "delete",
|
|
) -> MockBannedWord:
|
|
"""Create a mock BannedWord object for testing."""
|
|
return MockBannedWord(pattern, is_regex, action)
|