aboutsummaryrefslogtreecommitdiffstats
path: root/tests/bot/rules/test_duplicates.py
blob: 59e0fb6efccb831a2afc24eff096da982dc1bdbe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from typing import Iterable

from bot.rules import duplicates
from tests.bot.rules import DisallowedCase, RuleTest
from tests.helpers import MockMessage, async_test


def make_msg(author: str, content: str) -> MockMessage:
    """Give a MockMessage instance with `author` and `content` attrs."""
    return MockMessage(author=author, content=content)


class DuplicatesRuleTests(RuleTest):
    """Tests the `duplicates` antispam rule."""

    def setUp(self):
        self.apply = duplicates.apply
        self.config = {"max": 2, "interval": 10}

    @async_test
    async def test_allows_messages_within_limit(self):
        """Cases which do not violate the rule."""
        cases = (
            [make_msg("alice", "A"), make_msg("alice", "A")],
            [make_msg("alice", "A"), make_msg("alice", "B"), make_msg("alice", "C")],  # Non-duplicate
            [make_msg("alice", "A"), make_msg("bob", "A"), make_msg("alice", "A")],  # Different author
        )

        await self.run_allowed(cases)

    @async_test
    async def test_disallows_messages_beyond_limit(self):
        """Cases with too many duplicate messages from the same author."""
        cases = (
            DisallowedCase(
                [make_msg("alice", "A"), make_msg("alice", "A"), make_msg("alice", "A")],
                ("alice",),
                3,
            ),
            DisallowedCase(
                [make_msg("bob", "A"), make_msg("alice", "A"), make_msg("bob", "A"), make_msg("bob", "A")],
                ("bob",),
                3,  # 4 duplicate messages, but only 3 from bob
            ),
            DisallowedCase(
                [make_msg("bob", "A"), make_msg("bob", "B"), make_msg("bob", "A"), make_msg("bob", "A")],
                ("bob",),
                3,  # 4 message from bob, but only 3 duplicates
            ),
        )

        await self.run_disallowed(cases)

    def relevant_messages(self, case: DisallowedCase) -> Iterable[MockMessage]:
        last_message = case.recent_messages[0]
        return tuple(
            msg
            for msg in case.recent_messages
            if (
                msg.author == last_message.author
                and msg.content == last_message.content
            )
        )

    def get_report(self, case: DisallowedCase) -> str:
        return f"sent {case.n_violations} duplicated messages in {self.config['interval']}s"