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