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