1
1
package org .togetherjava .tjbot .features .moderation .scam ;
2
2
3
+ import net .dv8tion .jda .api .entities .Message ;
3
4
import org .junit .jupiter .api .BeforeEach ;
4
5
import org .junit .jupiter .api .DisplayName ;
5
6
import org .junit .jupiter .api .Test ;
9
10
import org .togetherjava .tjbot .config .Config ;
10
11
import org .togetherjava .tjbot .config .ScamBlockerConfig ;
11
12
13
+ import java .util .ArrayList ;
14
+ import java .util .Collections ;
12
15
import java .util .List ;
13
16
import java .util .Set ;
14
17
18
21
import static org .mockito .Mockito .when ;
19
22
20
23
final class ScamDetectorTest {
24
+ private static final int SUSPICIOUS_ATTACHMENTS_THRESHOLD = 3 ;
25
+ private static final String SUSPICIOUS_ATTACHMENT_NAME = "scam.png" ;
26
+
21
27
private ScamDetector scamDetector ;
22
28
23
29
@ BeforeEach
@@ -38,6 +44,10 @@ void setUp() {
38
44
when (scamConfig .getSuspiciousHostKeywords ())
39
45
.thenReturn (Set .of ("discord" , "nitro" , "premium" , "free" , "cheat" , "crypto" , "tele" ));
40
46
when (scamConfig .getIsHostSimilarToKeywordDistanceThreshold ()).thenReturn (2 );
47
+ when (scamConfig .getSuspiciousAttachmentsThreshold ())
48
+ .thenReturn (SUSPICIOUS_ATTACHMENTS_THRESHOLD );
49
+ when (scamConfig .getSuspiciousAttachmentNamePattern ())
50
+ .thenReturn (SUSPICIOUS_ATTACHMENT_NAME );
41
51
42
52
scamDetector = new ScamDetector (config );
43
53
}
@@ -121,6 +131,94 @@ void websitesWithTooManyDifferencesAreNotSuspicious() {
121
131
assertFalse (isScamResult );
122
132
}
123
133
134
+ @ Test
135
+ @ DisplayName ("Messages containing multiple suspicious attachments are flagged as scam" )
136
+ void detectsSuspiciousAttachments () {
137
+ // GIVEN an empty message containing suspicious attachments
138
+ String content = "" ;
139
+ Message .Attachment attachment = createImageAttachmentMock (SUSPICIOUS_ATTACHMENT_NAME );
140
+ List <Message .Attachment > attachments =
141
+ Collections .nCopies (SUSPICIOUS_ATTACHMENTS_THRESHOLD , attachment );
142
+ Message message = createMessageMock (content , attachments );
143
+
144
+ // WHEN analyzing it
145
+ boolean isScamResult = scamDetector .isScam (message );
146
+
147
+ // THEN flags it as scam
148
+ assertTrue (isScamResult );
149
+ }
150
+
151
+ @ Test
152
+ @ DisplayName ("Messages containing text content are not flagged for suspicious attachments" )
153
+ void ignoresAttachmentsIfContentProvided () {
154
+ // GIVEN a non-empty message containing suspicious attachments
155
+ String content = "Hello World" ;
156
+ Message .Attachment attachment = createImageAttachmentMock (SUSPICIOUS_ATTACHMENT_NAME );
157
+ List <Message .Attachment > attachments =
158
+ Collections .nCopies (SUSPICIOUS_ATTACHMENTS_THRESHOLD , attachment );
159
+ Message message = createMessageMock (content , attachments );
160
+
161
+ // WHEN analyzing it
162
+ boolean isScamResult = scamDetector .isScam (message );
163
+
164
+ // THEN flags it as harmless
165
+ assertFalse (isScamResult );
166
+ }
167
+
168
+ @ Test
169
+ @ DisplayName ("Messages containing not enough suspicious attachments are not flagged" )
170
+ void ignoresIfNotEnoughSuspiciousAttachments () {
171
+ // GIVEN an empty message containing some, but not enough suspicious attachments
172
+ String content = "" ;
173
+
174
+ Message .Attachment badAttachment = createImageAttachmentMock (SUSPICIOUS_ATTACHMENT_NAME );
175
+ Message .Attachment goodAttachment = createImageAttachmentMock ("good.png" );
176
+ int badAttachmentAmount = SUSPICIOUS_ATTACHMENTS_THRESHOLD - 1 ;
177
+ List <Message .Attachment > attachments =
178
+ new ArrayList <>(Collections .nCopies (badAttachmentAmount , badAttachment ));
179
+ attachments .add (goodAttachment );
180
+
181
+ Message message = createMessageMock (content , attachments );
182
+
183
+ // WHEN analyzing it
184
+ boolean isScamResult = scamDetector .isScam (message );
185
+
186
+ // THEN flags it as harmless
187
+ assertFalse (isScamResult );
188
+ }
189
+
190
+ @ Test
191
+ @ DisplayName ("Messages containing harmless attachments are not flagged" )
192
+ void ignoresHarmlessAttachments () {
193
+ // GIVEN an empty message containing only harmless attachments
194
+ String content = "" ;
195
+ Message .Attachment attachment = createImageAttachmentMock ("good.png" );
196
+ List <Message .Attachment > attachments =
197
+ Collections .nCopies (SUSPICIOUS_ATTACHMENTS_THRESHOLD , attachment );
198
+ Message message = createMessageMock (content , attachments );
199
+
200
+ // WHEN analyzing it
201
+ boolean isScamResult = scamDetector .isScam (message );
202
+
203
+ // THEN flags it as harmless
204
+ assertFalse (isScamResult );
205
+ }
206
+
207
+ private static Message createMessageMock (String content , List <Message .Attachment > attachments ) {
208
+ Message message = mock (Message .class );
209
+ when (message .getContentRaw ()).thenReturn (content );
210
+ when (message .getContentDisplay ()).thenReturn (content );
211
+ when (message .getAttachments ()).thenReturn (attachments );
212
+ return message ;
213
+ }
214
+
215
+ private static Message .Attachment createImageAttachmentMock (String name ) {
216
+ Message .Attachment attachment = mock (Message .Attachment .class );
217
+ when (attachment .isImage ()).thenReturn (true );
218
+ when (attachment .getFileName ()).thenReturn (name );
219
+ return attachment ;
220
+ }
221
+
124
222
private static List <String > provideRealScamMessages () {
125
223
return List .of ("""
126
224
🤩bro steam gived nitro - https://nitro-ds.online/LfgUfMzqYyx12""" ,
0 commit comments