add quarantine videos feature (#1637)
[oweals/peertube.git] / server / tests / api / users / user-notifications.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import {
6   addVideoToBlacklist,
7   createUser,
8   doubleFollow,
9   flushAndRunMultipleServers,
10   flushTests,
11   getMyUserInformation,
12   immutableAssign,
13   registerUser,
14   removeVideoFromBlacklist,
15   reportVideoAbuse,
16   updateMyUser,
17   updateVideo,
18   updateVideoChannel,
19   userLogin,
20   wait,
21   getCustomConfig,
22   updateCustomConfig
23 } from '../../../../shared/utils'
24 import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
25 import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
26 import { waitJobs } from '../../../../shared/utils/server/jobs'
27 import { getUserNotificationSocket } from '../../../../shared/utils/socket/socket-io'
28 import {
29   checkCommentMention,
30   CheckerBaseParams,
31   checkMyVideoImportIsFinished,
32   checkNewActorFollow,
33   checkNewBlacklistOnMyVideo,
34   checkNewCommentOnMyVideo,
35   checkNewVideoAbuseForModerators,
36   checkVideoAutoBlacklistForModerators,
37   checkNewVideoFromSubscription,
38   checkUserRegistered,
39   checkVideoIsPublished,
40   getLastNotification,
41   getUserNotifications,
42   markAsReadNotifications,
43   updateMyNotificationSettings,
44   markAsReadAllNotifications
45 } from '../../../../shared/utils/users/user-notifications'
46 import {
47   User,
48   UserNotification,
49   UserNotificationSetting,
50   UserNotificationSettingValue,
51   UserNotificationType
52 } from '../../../../shared/models/users'
53 import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
54 import { addUserSubscription, removeUserSubscription } from '../../../../shared/utils/users/user-subscriptions'
55 import { VideoPrivacy } from '../../../../shared/models/videos'
56 import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
57 import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
58 import * as uuidv4 from 'uuid/v4'
59 import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/utils/users/blocklist'
60 import { CustomConfig } from '../../../../shared/models/server'
61
62 const expect = chai.expect
63
64 async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalParams: any = {}) {
65   const name = 'remote video ' + uuidv4()
66
67   const data = Object.assign({ name }, additionalParams)
68   const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data)
69
70   await waitJobs(servers)
71
72   return { uuid: res.body.video.uuid, name }
73 }
74
75 async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParams: any = {}) {
76   const name = 'local video ' + uuidv4()
77
78   const data = Object.assign({ name }, additionalParams)
79   const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data)
80
81   await waitJobs(servers)
82
83   return { uuid: res.body.video.uuid, name }
84 }
85
86 describe('Test users notifications', function () {
87   let servers: ServerInfo[] = []
88   let userAccessToken: string
89   let userNotifications: UserNotification[] = []
90   let adminNotifications: UserNotification[] = []
91   let adminNotificationsServer2: UserNotification[] = []
92   const emails: object[] = []
93   let channelId: number
94
95   const allNotificationSettings: UserNotificationSetting = {
96     newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
97     newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
98     videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
99     videoAutoBlacklistAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
100     blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
101     myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
102     myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
103     commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
104     newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
105     newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
106   }
107
108   before(async function () {
109     this.timeout(120000)
110
111     await MockSmtpServer.Instance.collectEmails(emails)
112
113     await flushTests()
114
115     const overrideConfig = {
116       smtp: {
117         hostname: 'localhost'
118       }
119     }
120     servers = await flushAndRunMultipleServers(2, overrideConfig)
121
122     // Get the access tokens
123     await setAccessTokensToServers(servers)
124
125     // Server 1 and server 2 follow each other
126     await doubleFollow(servers[0], servers[1])
127
128     await waitJobs(servers)
129
130     const user = {
131       username: 'user_1',
132       password: 'super password'
133     }
134     await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000)
135     userAccessToken = await userLogin(servers[0], user)
136
137     await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings)
138     await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, allNotificationSettings)
139     await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings)
140
141     {
142       const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken)
143       socket.on('new-notification', n => userNotifications.push(n))
144     }
145     {
146       const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken)
147       socket.on('new-notification', n => adminNotifications.push(n))
148     }
149     {
150       const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken)
151       socket.on('new-notification', n => adminNotificationsServer2.push(n))
152     }
153
154     {
155       const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
156       channelId = resChannel.body.videoChannels[0].id
157     }
158   })
159
160   describe('New video from my subscription notification', function () {
161     let baseParams: CheckerBaseParams
162
163     before(() => {
164       baseParams = {
165         server: servers[0],
166         emails,
167         socketNotifications: userNotifications,
168         token: userAccessToken
169       }
170     })
171
172     it('Should not send notifications if the user does not follow the video publisher', async function () {
173       this.timeout(10000)
174
175       await uploadVideoByLocalAccount(servers)
176
177       const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
178       expect(notification).to.be.undefined
179
180       expect(emails).to.have.lengthOf(0)
181       expect(userNotifications).to.have.lengthOf(0)
182     })
183
184     it('Should send a new video notification if the user follows the local video publisher', async function () {
185       this.timeout(15000)
186
187       await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9001')
188       await waitJobs(servers)
189
190       const { name, uuid } = await uploadVideoByLocalAccount(servers)
191       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
192     })
193
194     it('Should send a new video notification from a remote account', async function () {
195       this.timeout(50000) // Server 2 has transcoding enabled
196
197       await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9002')
198       await waitJobs(servers)
199
200       const { name, uuid } = await uploadVideoByRemoteAccount(servers)
201       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
202     })
203
204     it('Should send a new video notification on a scheduled publication', async function () {
205       this.timeout(20000)
206
207       // In 2 seconds
208       let updateAt = new Date(new Date().getTime() + 2000)
209
210       const data = {
211         privacy: VideoPrivacy.PRIVATE,
212         scheduleUpdate: {
213           updateAt: updateAt.toISOString(),
214           privacy: VideoPrivacy.PUBLIC
215         }
216       }
217       const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
218
219       await wait(6000)
220       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
221     })
222
223     it('Should send a new video notification on a remote scheduled publication', async function () {
224       this.timeout(50000)
225
226       // In 2 seconds
227       let updateAt = new Date(new Date().getTime() + 2000)
228
229       const data = {
230         privacy: VideoPrivacy.PRIVATE,
231         scheduleUpdate: {
232           updateAt: updateAt.toISOString(),
233           privacy: VideoPrivacy.PUBLIC
234         }
235       }
236       const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
237       await waitJobs(servers)
238
239       await wait(6000)
240       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
241     })
242
243     it('Should not send a notification before the video is published', async function () {
244       this.timeout(20000)
245
246       let updateAt = new Date(new Date().getTime() + 1000000)
247
248       const data = {
249         privacy: VideoPrivacy.PRIVATE,
250         scheduleUpdate: {
251           updateAt: updateAt.toISOString(),
252           privacy: VideoPrivacy.PUBLIC
253         }
254       }
255       const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
256
257       await wait(6000)
258       await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
259     })
260
261     it('Should send a new video notification when a video becomes public', async function () {
262       this.timeout(10000)
263
264       const data = { privacy: VideoPrivacy.PRIVATE }
265       const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
266
267       await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
268
269       await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
270
271       await wait(500)
272       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
273     })
274
275     it('Should send a new video notification when a remote video becomes public', async function () {
276       this.timeout(20000)
277
278       const data = { privacy: VideoPrivacy.PRIVATE }
279       const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
280
281       await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
282
283       await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
284
285       await waitJobs(servers)
286       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
287     })
288
289     it('Should not send a new video notification when a video becomes unlisted', async function () {
290       this.timeout(20000)
291
292       const data = { privacy: VideoPrivacy.PRIVATE }
293       const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
294
295       await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
296
297       await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
298     })
299
300     it('Should not send a new video notification when a remote video becomes unlisted', async function () {
301       this.timeout(20000)
302
303       const data = { privacy: VideoPrivacy.PRIVATE }
304       const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
305
306       await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
307
308       await waitJobs(servers)
309       await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
310     })
311
312     it('Should send a new video notification after a video import', async function () {
313       this.timeout(100000)
314
315       const name = 'video import ' + uuidv4()
316
317       const attributes = {
318         name,
319         channelId,
320         privacy: VideoPrivacy.PUBLIC,
321         targetUrl: getYoutubeVideoUrl()
322       }
323       const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
324       const uuid = res.body.video.uuid
325
326       await waitJobs(servers)
327
328       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
329     })
330   })
331
332   describe('Comment on my video notifications', function () {
333     let baseParams: CheckerBaseParams
334
335     before(() => {
336       baseParams = {
337         server: servers[0],
338         emails,
339         socketNotifications: userNotifications,
340         token: userAccessToken
341       }
342     })
343
344     it('Should not send a new comment notification after a comment on another video', async function () {
345       this.timeout(10000)
346
347       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
348       const uuid = resVideo.body.video.uuid
349
350       const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
351       const commentId = resComment.body.comment.id
352
353       await wait(500)
354       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
355     })
356
357     it('Should not send a new comment notification if I comment my own video', async function () {
358       this.timeout(10000)
359
360       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
361       const uuid = resVideo.body.video.uuid
362
363       const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
364       const commentId = resComment.body.comment.id
365
366       await wait(500)
367       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
368     })
369
370     it('Should not send a new comment notification if the account is muted', async function () {
371       this.timeout(10000)
372
373       await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
374
375       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
376       const uuid = resVideo.body.video.uuid
377
378       const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
379       const commentId = resComment.body.comment.id
380
381       await wait(500)
382       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
383
384       await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
385     })
386
387     it('Should send a new comment notification after a local comment on my video', async function () {
388       this.timeout(10000)
389
390       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
391       const uuid = resVideo.body.video.uuid
392
393       const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
394       const commentId = resComment.body.comment.id
395
396       await wait(500)
397       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
398     })
399
400     it('Should send a new comment notification after a remote comment on my video', async function () {
401       this.timeout(10000)
402
403       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
404       const uuid = resVideo.body.video.uuid
405
406       await waitJobs(servers)
407
408       const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
409       const commentId = resComment.body.comment.id
410
411       await waitJobs(servers)
412       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
413     })
414
415     it('Should send a new comment notification after a local reply on my video', async function () {
416       this.timeout(10000)
417
418       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
419       const uuid = resVideo.body.video.uuid
420
421       const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
422       const threadId = resThread.body.comment.id
423
424       const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
425       const commentId = resComment.body.comment.id
426
427       await wait(500)
428       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
429     })
430
431     it('Should send a new comment notification after a remote reply on my video', async function () {
432       this.timeout(10000)
433
434       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
435       const uuid = resVideo.body.video.uuid
436       await waitJobs(servers)
437
438       const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
439       const threadId = resThread.body.comment.id
440
441       const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
442       const commentId = resComment.body.comment.id
443
444       await waitJobs(servers)
445       await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
446     })
447   })
448
449   describe('Mention notifications', function () {
450     let baseParams: CheckerBaseParams
451
452     before(async () => {
453       baseParams = {
454         server: servers[0],
455         emails,
456         socketNotifications: userNotifications,
457         token: userAccessToken
458       }
459
460       await updateMyUser({
461         url: servers[0].url,
462         accessToken: servers[0].accessToken,
463         displayName: 'super root name'
464       })
465
466       await updateMyUser({
467         url: servers[1].url,
468         accessToken: servers[1].accessToken,
469         displayName: 'super root 2 name'
470       })
471     })
472
473     it('Should not send a new mention comment notification if I mention the video owner', async function () {
474       this.timeout(10000)
475
476       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
477       const uuid = resVideo.body.video.uuid
478
479       const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
480       const commentId = resComment.body.comment.id
481
482       await wait(500)
483       await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
484     })
485
486     it('Should not send a new mention comment notification if I mention myself', async function () {
487       this.timeout(10000)
488
489       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
490       const uuid = resVideo.body.video.uuid
491
492       const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello')
493       const commentId = resComment.body.comment.id
494
495       await wait(500)
496       await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
497     })
498
499     it('Should not send a new mention notification if the account is muted', async function () {
500       this.timeout(10000)
501
502       await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
503
504       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
505       const uuid = resVideo.body.video.uuid
506
507       const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
508       const commentId = resComment.body.comment.id
509
510       await wait(500)
511       await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
512
513       await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
514     })
515
516     it('Should not send a new mention notification if the remote account mention a local account', async function () {
517       this.timeout(20000)
518
519       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
520       const uuid = resVideo.body.video.uuid
521
522       await waitJobs(servers)
523       const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, '@user_1 hello')
524       const threadId = resThread.body.comment.id
525
526       await waitJobs(servers)
527       await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'absence')
528     })
529
530     it('Should send a new mention notification after local comments', async function () {
531       this.timeout(10000)
532
533       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
534       const uuid = resVideo.body.video.uuid
535
536       const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1')
537       const threadId = resThread.body.comment.id
538
539       await wait(500)
540       await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence')
541
542       const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1')
543       const commentId = resComment.body.comment.id
544
545       await wait(500)
546       await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence')
547     })
548
549     it('Should send a new mention notification after remote comments', async function () {
550       this.timeout(20000)
551
552       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
553       const uuid = resVideo.body.video.uuid
554
555       await waitJobs(servers)
556       const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'hello @user_1@localhost:9001 1')
557       const threadId = resThread.body.comment.id
558
559       await waitJobs(servers)
560       await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'presence')
561
562       const text = '@user_1@localhost:9001 hello 2 @root@localhost:9001'
563       const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, text)
564       const commentId = resComment.body.comment.id
565
566       await waitJobs(servers)
567       await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root 2 name', 'presence')
568     })
569   })
570
571   describe('Video abuse for moderators notification' , function () {
572     let baseParams: CheckerBaseParams
573
574     before(() => {
575       baseParams = {
576         server: servers[0],
577         emails,
578         socketNotifications: adminNotifications,
579         token: servers[0].accessToken
580       }
581     })
582
583     it('Should send a notification to moderators on local video abuse', async function () {
584       this.timeout(10000)
585
586       const name = 'video for abuse ' + uuidv4()
587       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
588       const uuid = resVideo.body.video.uuid
589
590       await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
591
592       await waitJobs(servers)
593       await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
594     })
595
596     it('Should send a notification to moderators on remote video abuse', async function () {
597       this.timeout(10000)
598
599       const name = 'video for abuse ' + uuidv4()
600       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
601       const uuid = resVideo.body.video.uuid
602
603       await waitJobs(servers)
604
605       await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
606
607       await waitJobs(servers)
608       await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
609     })
610   })
611
612   describe('Video blacklist on my video', function () {
613     let baseParams: CheckerBaseParams
614
615     before(() => {
616       baseParams = {
617         server: servers[0],
618         emails,
619         socketNotifications: userNotifications,
620         token: userAccessToken
621       }
622     })
623
624     it('Should send a notification to video owner on blacklist', async function () {
625       this.timeout(10000)
626
627       const name = 'video for abuse ' + uuidv4()
628       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
629       const uuid = resVideo.body.video.uuid
630
631       await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
632
633       await waitJobs(servers)
634       await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'blacklist')
635     })
636
637     it('Should send a notification to video owner on unblacklist', async function () {
638       this.timeout(10000)
639
640       const name = 'video for abuse ' + uuidv4()
641       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
642       const uuid = resVideo.body.video.uuid
643
644       await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
645
646       await waitJobs(servers)
647       await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
648       await waitJobs(servers)
649
650       await wait(500)
651       await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'unblacklist')
652     })
653   })
654
655   describe('My video is published', function () {
656     let baseParams: CheckerBaseParams
657
658     before(() => {
659       baseParams = {
660         server: servers[1],
661         emails,
662         socketNotifications: adminNotificationsServer2,
663         token: servers[1].accessToken
664       }
665     })
666
667     it('Should not send a notification if transcoding is not enabled', async function () {
668       this.timeout(10000)
669
670       const { name, uuid } = await uploadVideoByLocalAccount(servers)
671       await waitJobs(servers)
672
673       await checkVideoIsPublished(baseParams, name, uuid, 'absence')
674     })
675
676     it('Should not send a notification if the wait transcoding is false', async function () {
677       this.timeout(50000)
678
679       await uploadVideoByRemoteAccount(servers, { waitTranscoding: false })
680       await waitJobs(servers)
681
682       const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
683       if (notification) {
684         expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
685       }
686     })
687
688     it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
689       this.timeout(50000)
690
691       const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
692       await waitJobs(servers)
693
694       await checkVideoIsPublished(baseParams, name, uuid, 'presence')
695     })
696
697     it('Should send a notification with a transcoded video', async function () {
698       this.timeout(50000)
699
700       const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true })
701       await waitJobs(servers)
702
703       await checkVideoIsPublished(baseParams, name, uuid, 'presence')
704     })
705
706     it('Should send a notification when an imported video is transcoded', async function () {
707       this.timeout(50000)
708
709       const name = 'video import ' + uuidv4()
710
711       const attributes = {
712         name,
713         channelId,
714         privacy: VideoPrivacy.PUBLIC,
715         targetUrl: getYoutubeVideoUrl(),
716         waitTranscoding: true
717       }
718       const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
719       const uuid = res.body.video.uuid
720
721       await waitJobs(servers)
722       await checkVideoIsPublished(baseParams, name, uuid, 'presence')
723     })
724
725     it('Should send a notification when the scheduled update has been proceeded', async function () {
726       this.timeout(70000)
727
728       // In 2 seconds
729       let updateAt = new Date(new Date().getTime() + 2000)
730
731       const data = {
732         privacy: VideoPrivacy.PRIVATE,
733         scheduleUpdate: {
734           updateAt: updateAt.toISOString(),
735           privacy: VideoPrivacy.PUBLIC
736         }
737       }
738       const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
739
740       await wait(6000)
741       await checkVideoIsPublished(baseParams, name, uuid, 'presence')
742     })
743
744     it('Should not send a notification before the video is published', async function () {
745       this.timeout(20000)
746
747       let updateAt = new Date(new Date().getTime() + 100000)
748
749       const data = {
750         privacy: VideoPrivacy.PRIVATE,
751         scheduleUpdate: {
752           updateAt: updateAt.toISOString(),
753           privacy: VideoPrivacy.PUBLIC
754         }
755       }
756       const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
757
758       await wait(6000)
759       await checkVideoIsPublished(baseParams, name, uuid, 'absence')
760     })
761   })
762
763   describe('My video is imported', function () {
764     let baseParams: CheckerBaseParams
765
766     before(() => {
767       baseParams = {
768         server: servers[0],
769         emails,
770         socketNotifications: adminNotifications,
771         token: servers[0].accessToken
772       }
773     })
774
775     it('Should send a notification when the video import failed', async function () {
776       this.timeout(70000)
777
778       const name = 'video import ' + uuidv4()
779
780       const attributes = {
781         name,
782         channelId,
783         privacy: VideoPrivacy.PRIVATE,
784         targetUrl: getBadVideoUrl()
785       }
786       const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
787       const uuid = res.body.video.uuid
788
789       await waitJobs(servers)
790       await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence')
791     })
792
793     it('Should send a notification when the video import succeeded', async function () {
794       this.timeout(70000)
795
796       const name = 'video import ' + uuidv4()
797
798       const attributes = {
799         name,
800         channelId,
801         privacy: VideoPrivacy.PRIVATE,
802         targetUrl: getYoutubeVideoUrl()
803       }
804       const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
805       const uuid = res.body.video.uuid
806
807       await waitJobs(servers)
808       await checkMyVideoImportIsFinished(baseParams, name, uuid, getYoutubeVideoUrl(), true, 'presence')
809     })
810   })
811
812   describe('New registration', function () {
813     let baseParams: CheckerBaseParams
814
815     before(() => {
816       baseParams = {
817         server: servers[0],
818         emails,
819         socketNotifications: adminNotifications,
820         token: servers[0].accessToken
821       }
822     })
823
824     it('Should send a notification only to moderators when a user registers on the instance', async function () {
825       this.timeout(10000)
826
827       await registerUser(servers[0].url, 'user_45', 'password')
828
829       await waitJobs(servers)
830
831       await checkUserRegistered(baseParams, 'user_45', 'presence')
832
833       const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
834       await checkUserRegistered(immutableAssign(baseParams, userOverride), 'user_45', 'absence')
835     })
836   })
837
838   describe('New actor follow', function () {
839     let baseParams: CheckerBaseParams
840     let myChannelName = 'super channel name'
841     let myUserName = 'super user name'
842
843     before(async () => {
844       baseParams = {
845         server: servers[0],
846         emails,
847         socketNotifications: userNotifications,
848         token: userAccessToken
849       }
850
851       await updateMyUser({
852         url: servers[0].url,
853         accessToken: servers[0].accessToken,
854         displayName: 'super root name'
855       })
856
857       await updateMyUser({
858         url: servers[0].url,
859         accessToken: userAccessToken,
860         displayName: myUserName
861       })
862
863       await updateMyUser({
864         url: servers[1].url,
865         accessToken: servers[1].accessToken,
866         displayName: 'super root 2 name'
867       })
868
869       await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName })
870     })
871
872     it('Should notify when a local channel is following one of our channel', async function () {
873       this.timeout(10000)
874
875       await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
876       await waitJobs(servers)
877
878       await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence')
879
880       await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
881     })
882
883     it('Should notify when a remote channel is following one of our channel', async function () {
884       this.timeout(10000)
885
886       await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
887       await waitJobs(servers)
888
889       await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence')
890
891       await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
892     })
893
894     it('Should notify when a local account is following one of our channel', async function () {
895       this.timeout(10000)
896
897       await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001')
898
899       await waitJobs(servers)
900
901       await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
902     })
903
904     it('Should notify when a remote account is following one of our channel', async function () {
905       this.timeout(10000)
906
907       await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001')
908
909       await waitJobs(servers)
910
911       await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
912     })
913   })
914
915   describe('Video-related notifications when video auto-blacklist is enabled', function () {
916     let userBaseParams: CheckerBaseParams
917     let adminBaseParamsServer1: CheckerBaseParams
918     let adminBaseParamsServer2: CheckerBaseParams
919     let videoUUID: string
920     let videoName: string
921     let currentCustomConfig: CustomConfig
922
923     before(async () => {
924
925       adminBaseParamsServer1 = {
926         server: servers[0],
927         emails,
928         socketNotifications: adminNotifications,
929         token: servers[0].accessToken
930       }
931
932       adminBaseParamsServer2 = {
933         server: servers[1],
934         emails,
935         socketNotifications: adminNotificationsServer2,
936         token: servers[1].accessToken
937       }
938
939       userBaseParams = {
940         server: servers[0],
941         emails,
942         socketNotifications: userNotifications,
943         token: userAccessToken
944       }
945
946       const resCustomConfig = await getCustomConfig(servers[0].url, servers[0].accessToken)
947       currentCustomConfig = resCustomConfig.body
948       const autoBlacklistTestsCustomConfig = immutableAssign(currentCustomConfig, {
949         autoBlacklist: {
950           videos: {
951             ofUsers: {
952               enabled: true
953             }
954           }
955         }
956       })
957       // enable transcoding otherwise own publish notification after transcoding not expected
958       autoBlacklistTestsCustomConfig.transcoding.enabled = true
959       await updateCustomConfig(servers[0].url, servers[0].accessToken, autoBlacklistTestsCustomConfig)
960
961       await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
962       await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
963
964     })
965
966     it('Should send notification to moderators on new video with auto-blacklist', async function () {
967       this.timeout(20000)
968
969       videoName = 'video with auto-blacklist ' + uuidv4()
970       const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
971       videoUUID = resVideo.body.video.uuid
972
973       await waitJobs(servers)
974       await checkVideoAutoBlacklistForModerators(adminBaseParamsServer1, videoUUID, videoName, 'presence')
975     })
976
977     it('Should not send video publish notification if auto-blacklisted', async function () {
978       await checkVideoIsPublished(userBaseParams, videoName, videoUUID, 'absence')
979     })
980
981     it('Should not send a local user subscription notification if auto-blacklisted', async function () {
982       await checkNewVideoFromSubscription(adminBaseParamsServer1, videoName, videoUUID, 'absence')
983     })
984
985     it('Should not send a remote user subscription notification if auto-blacklisted', async function () {
986       await checkNewVideoFromSubscription(adminBaseParamsServer2, videoName, videoUUID, 'absence')
987     })
988
989     it('Should send video published and unblacklist after video unblacklisted', async function () {
990       this.timeout(20000)
991
992       await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoUUID)
993
994       await waitJobs(servers)
995
996       // FIXME: Can't test as two notifications sent to same user and util only checks last one
997       // One notification might be better anyways
998       // await checkNewBlacklistOnMyVideo(userBaseParams, videoUUID, videoName, 'unblacklist')
999       // await checkVideoIsPublished(userBaseParams, videoName, videoUUID, 'presence')
1000     })
1001
1002     it('Should send a local user subscription notification after removed from blacklist', async function () {
1003       await checkNewVideoFromSubscription(adminBaseParamsServer1, videoName, videoUUID, 'presence')
1004     })
1005
1006     it('Should send a remote user subscription notification after removed from blacklist', async function () {
1007       await checkNewVideoFromSubscription(adminBaseParamsServer2, videoName, videoUUID, 'presence')
1008     })
1009
1010     it('Should send unblacklist but not published/subscription notes after unblacklisted if scheduled update pending', async function () {
1011       this.timeout(20000)
1012
1013       let updateAt = new Date(new Date().getTime() + 100000)
1014
1015       const name = 'video with auto-blacklist and future schedule ' + uuidv4()
1016
1017       const data = {
1018         name,
1019         privacy: VideoPrivacy.PRIVATE,
1020         scheduleUpdate: {
1021           updateAt: updateAt.toISOString(),
1022           privacy: VideoPrivacy.PUBLIC
1023         }
1024       }
1025
1026       const resVideo = await uploadVideo(servers[0].url, userAccessToken, data)
1027       const uuid = resVideo.body.video.uuid
1028
1029       await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
1030
1031       await waitJobs(servers)
1032       await checkNewBlacklistOnMyVideo(userBaseParams, uuid, name, 'unblacklist')
1033
1034       // FIXME: Can't test absence as two notifications sent to same user and util only checks last one
1035       // One notification might be better anyways
1036       // await checkVideoIsPublished(userBaseParams, name, uuid, 'absence')
1037
1038       await checkNewVideoFromSubscription(adminBaseParamsServer1, name, uuid, 'absence')
1039       await checkNewVideoFromSubscription(adminBaseParamsServer2, name, uuid, 'absence')
1040     })
1041
1042     it('Should not send publish/subscription notifications after scheduled update if video still auto-blacklisted', async function () {
1043       this.timeout(20000)
1044
1045       // In 2 seconds
1046       let updateAt = new Date(new Date().getTime() + 2000)
1047
1048       const name = 'video with schedule done and still auto-blacklisted ' + uuidv4()
1049
1050       const data = {
1051         name,
1052         privacy: VideoPrivacy.PRIVATE,
1053         scheduleUpdate: {
1054           updateAt: updateAt.toISOString(),
1055           privacy: VideoPrivacy.PUBLIC
1056         }
1057       }
1058
1059       const resVideo = await uploadVideo(servers[0].url, userAccessToken, data)
1060       const uuid = resVideo.body.video.uuid
1061
1062       await wait(6000)
1063       await checkVideoIsPublished(userBaseParams, name, uuid, 'absence')
1064       await checkNewVideoFromSubscription(adminBaseParamsServer1, name, uuid, 'absence')
1065       await checkNewVideoFromSubscription(adminBaseParamsServer2, name, uuid, 'absence')
1066     })
1067
1068     it('Should not send a notification to moderators on new video without auto-blacklist', async function () {
1069       this.timeout(20000)
1070
1071       const name = 'video without auto-blacklist ' + uuidv4()
1072
1073       // admin with blacklist right will not be auto-blacklisted
1074       const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name })
1075       const uuid = resVideo.body.video.uuid
1076
1077       await waitJobs(servers)
1078       await checkVideoAutoBlacklistForModerators(adminBaseParamsServer1, uuid, name, 'absence')
1079     })
1080
1081     after(async () => {
1082       await updateCustomConfig(servers[0].url, servers[0].accessToken, currentCustomConfig)
1083
1084       await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
1085       await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
1086     })
1087   })
1088
1089   describe('Mark as read', function () {
1090     it('Should mark as read some notifications', async function () {
1091       const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3)
1092       const ids = res.body.data.map(n => n.id)
1093
1094       await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids)
1095     })
1096
1097     it('Should have the notifications marked as read', async function () {
1098       const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10)
1099
1100       const notifications = res.body.data as UserNotification[]
1101       expect(notifications[ 0 ].read).to.be.false
1102       expect(notifications[ 1 ].read).to.be.false
1103       expect(notifications[ 2 ].read).to.be.true
1104       expect(notifications[ 3 ].read).to.be.true
1105       expect(notifications[ 4 ].read).to.be.true
1106       expect(notifications[ 5 ].read).to.be.false
1107     })
1108
1109     it('Should only list read notifications', async function () {
1110       const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false)
1111
1112       const notifications = res.body.data as UserNotification[]
1113       for (const notification of notifications) {
1114         expect(notification.read).to.be.true
1115       }
1116     })
1117
1118     it('Should only list unread notifications', async function () {
1119       const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
1120
1121       const notifications = res.body.data as UserNotification[]
1122       for (const notification of notifications) {
1123         expect(notification.read).to.be.false
1124       }
1125     })
1126
1127     it('Should mark as read all notifications', async function () {
1128       await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken)
1129
1130       const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
1131
1132       expect(res.body.total).to.equal(0)
1133       expect(res.body.data).to.have.lengthOf(0)
1134     })
1135   })
1136
1137   describe('Notification settings', function () {
1138     let baseParams: CheckerBaseParams
1139
1140     before(() => {
1141       baseParams = {
1142         server: servers[0],
1143         emails,
1144         socketNotifications: userNotifications,
1145         token: userAccessToken
1146       }
1147     })
1148
1149     it('Should not have notifications', async function () {
1150       this.timeout(20000)
1151
1152       await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1153         newVideoFromSubscription: UserNotificationSettingValue.NONE
1154       }))
1155
1156       {
1157         const res = await getMyUserInformation(servers[0].url, userAccessToken)
1158         const info = res.body as User
1159         expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
1160       }
1161
1162       const { name, uuid } = await uploadVideoByLocalAccount(servers)
1163
1164       const check = { web: true, mail: true }
1165       await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1166     })
1167
1168     it('Should only have web notifications', async function () {
1169       this.timeout(20000)
1170
1171       await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1172         newVideoFromSubscription: UserNotificationSettingValue.WEB
1173       }))
1174
1175       {
1176         const res = await getMyUserInformation(servers[0].url, userAccessToken)
1177         const info = res.body as User
1178         expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB)
1179       }
1180
1181       const { name, uuid } = await uploadVideoByLocalAccount(servers)
1182
1183       {
1184         const check = { mail: true, web: false }
1185         await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1186       }
1187
1188       {
1189         const check = { mail: false, web: true }
1190         await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
1191       }
1192     })
1193
1194     it('Should only have mail notifications', async function () {
1195       this.timeout(20000)
1196
1197       await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1198         newVideoFromSubscription: UserNotificationSettingValue.EMAIL
1199       }))
1200
1201       {
1202         const res = await getMyUserInformation(servers[0].url, userAccessToken)
1203         const info = res.body as User
1204         expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
1205       }
1206
1207       const { name, uuid } = await uploadVideoByLocalAccount(servers)
1208
1209       {
1210         const check = { mail: false, web: true }
1211         await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1212       }
1213
1214       {
1215         const check = { mail: true, web: false }
1216         await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
1217       }
1218     })
1219
1220     it('Should have email and web notifications', async function () {
1221       this.timeout(20000)
1222
1223       await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1224         newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1225       }))
1226
1227       {
1228         const res = await getMyUserInformation(servers[0].url, userAccessToken)
1229         const info = res.body as User
1230         expect(info.notificationSettings.newVideoFromSubscription).to.equal(
1231           UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1232         )
1233       }
1234
1235       const { name, uuid } = await uploadVideoByLocalAccount(servers)
1236
1237       await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
1238     })
1239   })
1240
1241   after(async function () {
1242     MockSmtpServer.Instance.kill()
1243
1244     killallServers(servers)
1245   })
1246 })