]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/notifications/moderation-notifications.ts
Fix live tests
[github/Chocobozzz/PeerTube.git] / server / tests / api / notifications / moderation-notifications.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import {
4 checkAbuseStateChange,
5 checkAutoInstanceFollowing,
6 CheckerBaseParams,
7 checkNewAbuseMessage,
8 checkNewAccountAbuseForModerators,
9 checkNewBlacklistOnMyVideo,
10 checkNewCommentAbuseForModerators,
11 checkNewInstanceFollower,
12 checkNewVideoAbuseForModerators,
13 checkNewVideoFromSubscription,
14 checkUserRegistered,
15 checkVideoAutoBlacklistForModerators,
16 checkVideoIsPublished,
17 MockInstancesIndex,
18 MockSmtpServer,
19 prepareNotificationsTest
20 } from '@server/tests/shared'
21 import { wait } from '@shared/core-utils'
22 import { buildUUID } from '@shared/extra-utils'
23 import { AbuseState, CustomConfig, UserNotification, UserRole, VideoPrivacy } from '@shared/models'
24 import { cleanupTests, PeerTubeServer, waitJobs } from '@shared/server-commands'
25
26 describe('Test moderation notifications', function () {
27 let servers: PeerTubeServer[] = []
28 let userToken1: string
29 let userToken2: string
30
31 let userNotifications: UserNotification[] = []
32 let adminNotifications: UserNotification[] = []
33 let adminNotificationsServer2: UserNotification[] = []
34 let emails: object[] = []
35
36 before(async function () {
37 this.timeout(120000)
38
39 const res = await prepareNotificationsTest(3)
40 emails = res.emails
41 userToken1 = res.userAccessToken
42 servers = res.servers
43 userNotifications = res.userNotifications
44 adminNotifications = res.adminNotifications
45 adminNotificationsServer2 = res.adminNotificationsServer2
46
47 userToken2 = await servers[1].users.generateUserAndToken('user2', UserRole.USER)
48 })
49
50 describe('Abuse for moderators notification', function () {
51 let baseParams: CheckerBaseParams
52
53 before(() => {
54 baseParams = {
55 server: servers[0],
56 emails,
57 socketNotifications: adminNotifications,
58 token: servers[0].accessToken
59 }
60 })
61
62 it('Should not send a notification to moderators on local abuse reported by an admin', async function () {
63 this.timeout(20000)
64
65 const name = 'video for abuse ' + buildUUID()
66 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
67
68 await servers[0].abuses.report({ videoId: video.id, reason: 'super reason' })
69
70 await waitJobs(servers)
71 await checkNewVideoAbuseForModerators({ ...baseParams, shortUUID: video.shortUUID, videoName: name, checkType: 'absence' })
72 })
73
74 it('Should send a notification to moderators on local video abuse', async function () {
75 this.timeout(20000)
76
77 const name = 'video for abuse ' + buildUUID()
78 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
79
80 await servers[0].abuses.report({ token: userToken1, videoId: video.id, reason: 'super reason' })
81
82 await waitJobs(servers)
83 await checkNewVideoAbuseForModerators({ ...baseParams, shortUUID: video.shortUUID, videoName: name, checkType: 'presence' })
84 })
85
86 it('Should send a notification to moderators on remote video abuse', async function () {
87 this.timeout(20000)
88
89 const name = 'video for abuse ' + buildUUID()
90 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
91
92 await waitJobs(servers)
93
94 const videoId = await servers[1].videos.getId({ uuid: video.uuid })
95 await servers[1].abuses.report({ token: userToken2, videoId, reason: 'super reason' })
96
97 await waitJobs(servers)
98 await checkNewVideoAbuseForModerators({ ...baseParams, shortUUID: video.shortUUID, videoName: name, checkType: 'presence' })
99 })
100
101 it('Should send a notification to moderators on local comment abuse', async function () {
102 this.timeout(20000)
103
104 const name = 'video for abuse ' + buildUUID()
105 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
106 const comment = await servers[0].comments.createThread({
107 token: userToken1,
108 videoId: video.id,
109 text: 'comment abuse ' + buildUUID()
110 })
111
112 await waitJobs(servers)
113
114 await servers[0].abuses.report({ token: userToken1, commentId: comment.id, reason: 'super reason' })
115
116 await waitJobs(servers)
117 await checkNewCommentAbuseForModerators({ ...baseParams, shortUUID: video.shortUUID, videoName: name, checkType: 'presence' })
118 })
119
120 it('Should send a notification to moderators on remote comment abuse', async function () {
121 this.timeout(20000)
122
123 const name = 'video for abuse ' + buildUUID()
124 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
125
126 await servers[0].comments.createThread({
127 token: userToken1,
128 videoId: video.id,
129 text: 'comment abuse ' + buildUUID()
130 })
131
132 await waitJobs(servers)
133
134 const { data } = await servers[1].comments.listThreads({ videoId: video.uuid })
135 const commentId = data[0].id
136 await servers[1].abuses.report({ token: userToken2, commentId, reason: 'super reason' })
137
138 await waitJobs(servers)
139 await checkNewCommentAbuseForModerators({ ...baseParams, shortUUID: video.shortUUID, videoName: name, checkType: 'presence' })
140 })
141
142 it('Should send a notification to moderators on local account abuse', async function () {
143 this.timeout(20000)
144
145 const username = 'user' + new Date().getTime()
146 const { account } = await servers[0].users.create({ username, password: 'donald' })
147 const accountId = account.id
148
149 await servers[0].abuses.report({ token: userToken1, accountId, reason: 'super reason' })
150
151 await waitJobs(servers)
152 await checkNewAccountAbuseForModerators({ ...baseParams, displayName: username, checkType: 'presence' })
153 })
154
155 it('Should send a notification to moderators on remote account abuse', async function () {
156 this.timeout(20000)
157
158 const username = 'user' + new Date().getTime()
159 const tmpToken = await servers[0].users.generateUserAndToken(username)
160 await servers[0].videos.upload({ token: tmpToken, attributes: { name: 'super video' } })
161
162 await waitJobs(servers)
163
164 const account = await servers[1].accounts.get({ accountName: username + '@' + servers[0].host })
165 await servers[1].abuses.report({ token: userToken2, accountId: account.id, reason: 'super reason' })
166
167 await waitJobs(servers)
168 await checkNewAccountAbuseForModerators({ ...baseParams, displayName: username, checkType: 'presence' })
169 })
170 })
171
172 describe('Abuse state change notification', function () {
173 let baseParams: CheckerBaseParams
174 let abuseId: number
175
176 before(async function () {
177 baseParams = {
178 server: servers[0],
179 emails,
180 socketNotifications: userNotifications,
181 token: userToken1
182 }
183
184 const name = 'abuse ' + buildUUID()
185 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
186
187 const body = await servers[0].abuses.report({ token: userToken1, videoId: video.id, reason: 'super reason' })
188 abuseId = body.abuse.id
189 })
190
191 it('Should send a notification to reporter if the abuse has been accepted', async function () {
192 this.timeout(10000)
193
194 await servers[0].abuses.update({ abuseId, body: { state: AbuseState.ACCEPTED } })
195 await waitJobs(servers)
196
197 await checkAbuseStateChange({ ...baseParams, abuseId, state: AbuseState.ACCEPTED, checkType: 'presence' })
198 })
199
200 it('Should send a notification to reporter if the abuse has been rejected', async function () {
201 this.timeout(10000)
202
203 await servers[0].abuses.update({ abuseId, body: { state: AbuseState.REJECTED } })
204 await waitJobs(servers)
205
206 await checkAbuseStateChange({ ...baseParams, abuseId, state: AbuseState.REJECTED, checkType: 'presence' })
207 })
208 })
209
210 describe('New abuse message notification', function () {
211 let baseParamsUser: CheckerBaseParams
212 let baseParamsAdmin: CheckerBaseParams
213 let abuseId: number
214 let abuseId2: number
215
216 before(async function () {
217 baseParamsUser = {
218 server: servers[0],
219 emails,
220 socketNotifications: userNotifications,
221 token: userToken1
222 }
223
224 baseParamsAdmin = {
225 server: servers[0],
226 emails,
227 socketNotifications: adminNotifications,
228 token: servers[0].accessToken
229 }
230
231 const name = 'abuse ' + buildUUID()
232 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
233
234 {
235 const body = await servers[0].abuses.report({ token: userToken1, videoId: video.id, reason: 'super reason' })
236 abuseId = body.abuse.id
237 }
238
239 {
240 const body = await servers[0].abuses.report({ token: userToken1, videoId: video.id, reason: 'super reason 2' })
241 abuseId2 = body.abuse.id
242 }
243 })
244
245 it('Should send a notification to reporter on new message', async function () {
246 this.timeout(10000)
247
248 const message = 'my super message to users'
249 await servers[0].abuses.addMessage({ abuseId, message })
250 await waitJobs(servers)
251
252 await checkNewAbuseMessage({ ...baseParamsUser, abuseId, message, toEmail: 'user_1@example.com', checkType: 'presence' })
253 })
254
255 it('Should not send a notification to the admin if sent by the admin', async function () {
256 this.timeout(10000)
257
258 const message = 'my super message that should not be sent to the admin'
259 await servers[0].abuses.addMessage({ abuseId, message })
260 await waitJobs(servers)
261
262 const toEmail = 'admin' + servers[0].internalServerNumber + '@example.com'
263 await checkNewAbuseMessage({ ...baseParamsAdmin, abuseId, message, toEmail, checkType: 'absence' })
264 })
265
266 it('Should send a notification to moderators', async function () {
267 this.timeout(10000)
268
269 const message = 'my super message to moderators'
270 await servers[0].abuses.addMessage({ token: userToken1, abuseId: abuseId2, message })
271 await waitJobs(servers)
272
273 const toEmail = 'admin' + servers[0].internalServerNumber + '@example.com'
274 await checkNewAbuseMessage({ ...baseParamsAdmin, abuseId: abuseId2, message, toEmail, checkType: 'presence' })
275 })
276
277 it('Should not send a notification to reporter if sent by the reporter', async function () {
278 this.timeout(10000)
279
280 const message = 'my super message that should not be sent to reporter'
281 await servers[0].abuses.addMessage({ token: userToken1, abuseId: abuseId2, message })
282 await waitJobs(servers)
283
284 const toEmail = 'user_1@example.com'
285 await checkNewAbuseMessage({ ...baseParamsUser, abuseId: abuseId2, message, toEmail, checkType: 'absence' })
286 })
287 })
288
289 describe('Video blacklist on my video', function () {
290 let baseParams: CheckerBaseParams
291
292 before(() => {
293 baseParams = {
294 server: servers[0],
295 emails,
296 socketNotifications: userNotifications,
297 token: userToken1
298 }
299 })
300
301 it('Should send a notification to video owner on blacklist', async function () {
302 this.timeout(10000)
303
304 const name = 'video for abuse ' + buildUUID()
305 const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
306
307 await servers[0].blacklist.add({ videoId: uuid })
308
309 await waitJobs(servers)
310 await checkNewBlacklistOnMyVideo({ ...baseParams, shortUUID, videoName: name, blacklistType: 'blacklist' })
311 })
312
313 it('Should send a notification to video owner on unblacklist', async function () {
314 this.timeout(10000)
315
316 const name = 'video for abuse ' + buildUUID()
317 const { uuid, shortUUID } = await servers[0].videos.upload({ token: userToken1, attributes: { name } })
318
319 await servers[0].blacklist.add({ videoId: uuid })
320
321 await waitJobs(servers)
322 await servers[0].blacklist.remove({ videoId: uuid })
323 await waitJobs(servers)
324
325 await wait(500)
326 await checkNewBlacklistOnMyVideo({ ...baseParams, shortUUID, videoName: name, blacklistType: 'unblacklist' })
327 })
328 })
329
330 describe('New registration', function () {
331 let baseParams: CheckerBaseParams
332
333 before(() => {
334 baseParams = {
335 server: servers[0],
336 emails,
337 socketNotifications: adminNotifications,
338 token: servers[0].accessToken
339 }
340 })
341
342 it('Should send a notification only to moderators when a user registers on the instance', async function () {
343 this.timeout(10000)
344
345 await servers[0].users.register({ username: 'user_45' })
346
347 await waitJobs(servers)
348
349 await checkUserRegistered({ ...baseParams, username: 'user_45', checkType: 'presence' })
350
351 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
352 await checkUserRegistered({ ...baseParams, ...userOverride, username: 'user_45', checkType: 'absence' })
353 })
354 })
355
356 describe('New instance follows', function () {
357 const instanceIndexServer = new MockInstancesIndex()
358 let config: any
359 let baseParams: CheckerBaseParams
360
361 before(async () => {
362 baseParams = {
363 server: servers[0],
364 emails,
365 socketNotifications: adminNotifications,
366 token: servers[0].accessToken
367 }
368
369 const port = await instanceIndexServer.initialize()
370 instanceIndexServer.addInstance(servers[1].host)
371
372 config = {
373 followings: {
374 instance: {
375 autoFollowIndex: {
376 indexUrl: `http://localhost:${port}/api/v1/instances/hosts`,
377 enabled: true
378 }
379 }
380 }
381 }
382 })
383
384 it('Should send a notification only to admin when there is a new instance follower', async function () {
385 this.timeout(60000)
386
387 await servers[2].follows.follow({ hosts: [ servers[0].url ] })
388
389 await waitJobs(servers)
390
391 await checkNewInstanceFollower({ ...baseParams, followerHost: 'localhost:' + servers[2].port, checkType: 'presence' })
392
393 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
394 await checkNewInstanceFollower({ ...baseParams, ...userOverride, followerHost: 'localhost:' + servers[2].port, checkType: 'absence' })
395 })
396
397 it('Should send a notification on auto follow back', async function () {
398 this.timeout(40000)
399
400 await servers[2].follows.unfollow({ target: servers[0] })
401 await waitJobs(servers)
402
403 const config = {
404 followings: {
405 instance: {
406 autoFollowBack: { enabled: true }
407 }
408 }
409 }
410 await servers[0].config.updateCustomSubConfig({ newConfig: config })
411
412 await servers[2].follows.follow({ hosts: [ servers[0].url ] })
413
414 await waitJobs(servers)
415
416 const followerHost = servers[0].host
417 const followingHost = servers[2].host
418 await checkAutoInstanceFollowing({ ...baseParams, followerHost, followingHost, checkType: 'presence' })
419
420 const userOverride = { socketNotifications: userNotifications, token: userToken1, check: { web: true, mail: false } }
421 await checkAutoInstanceFollowing({ ...baseParams, ...userOverride, followerHost, followingHost, checkType: 'absence' })
422
423 config.followings.instance.autoFollowBack.enabled = false
424 await servers[0].config.updateCustomSubConfig({ newConfig: config })
425 await servers[0].follows.unfollow({ target: servers[2] })
426 await servers[2].follows.unfollow({ target: servers[0] })
427 })
428
429 it('Should send a notification on auto instances index follow', async function () {
430 this.timeout(30000)
431 await servers[0].follows.unfollow({ target: servers[1] })
432
433 await servers[0].config.updateCustomSubConfig({ newConfig: config })
434
435 await wait(5000)
436 await waitJobs(servers)
437
438 const followerHost = servers[0].host
439 const followingHost = servers[1].host
440 await checkAutoInstanceFollowing({ ...baseParams, followerHost, followingHost, checkType: 'presence' })
441
442 config.followings.instance.autoFollowIndex.enabled = false
443 await servers[0].config.updateCustomSubConfig({ newConfig: config })
444 await servers[0].follows.unfollow({ target: servers[1] })
445 })
446 })
447
448 describe('Video-related notifications when video auto-blacklist is enabled', function () {
449 let userBaseParams: CheckerBaseParams
450 let adminBaseParamsServer1: CheckerBaseParams
451 let adminBaseParamsServer2: CheckerBaseParams
452 let uuid: string
453 let shortUUID: string
454 let videoName: string
455 let currentCustomConfig: CustomConfig
456
457 before(async () => {
458
459 adminBaseParamsServer1 = {
460 server: servers[0],
461 emails,
462 socketNotifications: adminNotifications,
463 token: servers[0].accessToken
464 }
465
466 adminBaseParamsServer2 = {
467 server: servers[1],
468 emails,
469 socketNotifications: adminNotificationsServer2,
470 token: servers[1].accessToken
471 }
472
473 userBaseParams = {
474 server: servers[0],
475 emails,
476 socketNotifications: userNotifications,
477 token: userToken1
478 }
479
480 currentCustomConfig = await servers[0].config.getCustomConfig()
481
482 const autoBlacklistTestsCustomConfig = {
483 ...currentCustomConfig,
484
485 autoBlacklist: {
486 videos: {
487 ofUsers: {
488 enabled: true
489 }
490 }
491 }
492 }
493
494 // enable transcoding otherwise own publish notification after transcoding not expected
495 autoBlacklistTestsCustomConfig.transcoding.enabled = true
496 await servers[0].config.updateCustomConfig({ newCustomConfig: autoBlacklistTestsCustomConfig })
497
498 await servers[0].subscriptions.add({ targetUri: 'user_1_channel@localhost:' + servers[0].port })
499 await servers[1].subscriptions.add({ targetUri: 'user_1_channel@localhost:' + servers[0].port })
500 })
501
502 it('Should send notification to moderators on new video with auto-blacklist', async function () {
503 this.timeout(120000)
504
505 videoName = 'video with auto-blacklist ' + buildUUID()
506 const video = await servers[0].videos.upload({ token: userToken1, attributes: { name: videoName } })
507 shortUUID = video.shortUUID
508 uuid = video.uuid
509
510 await waitJobs(servers)
511 await checkVideoAutoBlacklistForModerators({ ...adminBaseParamsServer1, shortUUID, videoName, checkType: 'presence' })
512 })
513
514 it('Should not send video publish notification if auto-blacklisted', async function () {
515 await checkVideoIsPublished({ ...userBaseParams, videoName, shortUUID, checkType: 'absence' })
516 })
517
518 it('Should not send a local user subscription notification if auto-blacklisted', async function () {
519 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'absence' })
520 })
521
522 it('Should not send a remote user subscription notification if auto-blacklisted', async function () {
523 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName, shortUUID, checkType: 'absence' })
524 })
525
526 it('Should send video published and unblacklist after video unblacklisted', async function () {
527 this.timeout(40000)
528
529 await servers[0].blacklist.remove({ videoId: uuid })
530
531 await waitJobs(servers)
532
533 // FIXME: Can't test as two notifications sent to same user and util only checks last one
534 // One notification might be better anyways
535 // await checkNewBlacklistOnMyVideo(userBaseParams, videoUUID, videoName, 'unblacklist')
536 // await checkVideoIsPublished(userBaseParams, videoName, videoUUID, 'presence')
537 })
538
539 it('Should send a local user subscription notification after removed from blacklist', async function () {
540 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName, shortUUID, checkType: 'presence' })
541 })
542
543 it('Should send a remote user subscription notification after removed from blacklist', async function () {
544 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName, shortUUID, checkType: 'presence' })
545 })
546
547 it('Should send unblacklist but not published/subscription notes after unblacklisted if scheduled update pending', async function () {
548 this.timeout(120000)
549
550 const updateAt = new Date(new Date().getTime() + 1000000)
551
552 const name = 'video with auto-blacklist and future schedule ' + buildUUID()
553
554 const attributes = {
555 name,
556 privacy: VideoPrivacy.PRIVATE,
557 scheduleUpdate: {
558 updateAt: updateAt.toISOString(),
559 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
560 }
561 }
562
563 const { shortUUID, uuid } = await servers[0].videos.upload({ token: userToken1, attributes })
564
565 await servers[0].blacklist.remove({ videoId: uuid })
566
567 await waitJobs(servers)
568 await checkNewBlacklistOnMyVideo({ ...userBaseParams, shortUUID, videoName: name, blacklistType: 'unblacklist' })
569
570 // FIXME: Can't test absence as two notifications sent to same user and util only checks last one
571 // One notification might be better anyways
572 // await checkVideoIsPublished(userBaseParams, name, uuid, 'absence')
573
574 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName: name, shortUUID, checkType: 'absence' })
575 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName: name, shortUUID, checkType: 'absence' })
576 })
577
578 it('Should not send publish/subscription notifications after scheduled update if video still auto-blacklisted', async function () {
579 this.timeout(40000)
580
581 // In 2 seconds
582 const updateAt = new Date(new Date().getTime() + 2000)
583
584 const name = 'video with schedule done and still auto-blacklisted ' + buildUUID()
585
586 const attributes = {
587 name,
588 privacy: VideoPrivacy.PRIVATE,
589 scheduleUpdate: {
590 updateAt: updateAt.toISOString(),
591 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
592 }
593 }
594
595 const { shortUUID } = await servers[0].videos.upload({ token: userToken1, attributes })
596
597 await wait(6000)
598 await checkVideoIsPublished({ ...userBaseParams, videoName: name, shortUUID, checkType: 'absence' })
599 await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName: name, shortUUID, checkType: 'absence' })
600 await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName: name, shortUUID, checkType: 'absence' })
601 })
602
603 it('Should not send a notification to moderators on new video without auto-blacklist', async function () {
604 this.timeout(120000)
605
606 const name = 'video without auto-blacklist ' + buildUUID()
607
608 // admin with blacklist right will not be auto-blacklisted
609 const { shortUUID } = await servers[0].videos.upload({ attributes: { name } })
610
611 await waitJobs(servers)
612 await checkVideoAutoBlacklistForModerators({ ...adminBaseParamsServer1, shortUUID, videoName: name, checkType: 'absence' })
613 })
614
615 after(async () => {
616 await servers[0].config.updateCustomConfig({ newCustomConfig: currentCustomConfig })
617
618 await servers[0].subscriptions.remove({ uri: 'user_1_channel@localhost:' + servers[0].port })
619 await servers[1].subscriptions.remove({ uri: 'user_1_channel@localhost:' + servers[0].port })
620 })
621 })
622
623 after(async function () {
624 MockSmtpServer.Instance.kill()
625
626 await cleanupTests(servers)
627 })
628 })