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"
|