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