1 /* tslint:disable:no-unused-expression */
3 import * as chai from 'chai'
10 flushAndRunMultipleServers,
14 getVideoCommentThreads,
15 getVideoThreadComments,
19 removeVideoFromBlacklist,
23 updateCustomSubConfig,
29 } from '../../../../shared/extra-utils'
30 import { ServerInfo, uploadVideo } from '../../../../shared/extra-utils/index'
31 import { setAccessTokensToServers } from '../../../../shared/extra-utils/users/login'
32 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
33 import { getUserNotificationSocket } from '../../../../shared/extra-utils/socket/socket-io'
35 checkAutoInstanceFollowing,
38 checkMyVideoImportIsFinished,
40 checkNewBlacklistOnMyVideo,
41 checkNewCommentOnMyVideo,
42 checkNewInstanceFollower,
43 checkNewVideoAbuseForModerators,
44 checkNewVideoFromSubscription,
46 checkVideoAutoBlacklistForModerators,
47 checkVideoIsPublished,
50 markAsReadAllNotifications,
51 markAsReadNotifications,
52 updateMyNotificationSettings
53 } from '../../../../shared/extra-utils/users/user-notifications'
57 UserNotificationSetting,
58 UserNotificationSettingValue,
60 } from '../../../../shared/models/users'
61 import { MockSmtpServer } from '../../../../shared/extra-utils/miscs/email'
62 import { addUserSubscription, removeUserSubscription } from '../../../../shared/extra-utils/users/user-subscriptions'
63 import { VideoPrivacy } from '../../../../shared/models/videos'
64 import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
65 import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/extra-utils/videos/video-comments'
66 import * as uuidv4 from 'uuid/v4'
67 import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/extra-utils/users/blocklist'
68 import { CustomConfig } from '../../../../shared/models/server'
69 import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
71 const expect = chai.expect
73 async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalParams: any = {}) {
74 const name = 'remote video ' + uuidv4()
76 const data = Object.assign({ name }, additionalParams)
77 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data)
79 await waitJobs(servers)
81 return { uuid: res.body.video.uuid, name }
84 async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParams: any = {}) {
85 const name = 'local video ' + uuidv4()
87 const data = Object.assign({ name }, additionalParams)
88 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data)
90 await waitJobs(servers)
92 return { uuid: res.body.video.uuid, name }
95 describe('Test users notifications', function () {
96 let servers: ServerInfo[] = []
97 let userAccessToken: string
98 let userNotifications: UserNotification[] = []
99 let adminNotifications: UserNotification[] = []
100 let adminNotificationsServer2: UserNotification[] = []
101 const emails: object[] = []
102 let channelId: number
104 const allNotificationSettings: UserNotificationSetting = {
105 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
106 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
107 videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
108 videoAutoBlacklistAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
109 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
110 myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
111 myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
112 commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
113 newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
114 newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
115 newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
116 autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
119 before(async function () {
122 const port = await MockSmtpServer.Instance.collectEmails(emails)
124 const overrideConfig = {
126 hostname: 'localhost',
130 servers = await flushAndRunMultipleServers(3, overrideConfig)
132 // Get the access tokens
133 await setAccessTokensToServers(servers)
135 // Server 1 and server 2 follow each other
136 await doubleFollow(servers[0], servers[1])
138 await waitJobs(servers)
142 password: 'super password'
145 url: servers[ 0 ].url,
146 accessToken: servers[ 0 ].accessToken,
147 username: user.username,
148 password: user.password,
149 videoQuota: 10 * 1000 * 1000
151 userAccessToken = await userLogin(servers[0], user)
153 await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings)
154 await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, allNotificationSettings)
155 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings)
158 const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken)
159 socket.on('new-notification', n => userNotifications.push(n))
162 const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken)
163 socket.on('new-notification', n => adminNotifications.push(n))
166 const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken)
167 socket.on('new-notification', n => adminNotificationsServer2.push(n))
171 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
172 channelId = resChannel.body.videoChannels[0].id
176 describe('New video from my subscription notification', function () {
177 let baseParams: CheckerBaseParams
183 socketNotifications: userNotifications,
184 token: userAccessToken
188 it('Should not send notifications if the user does not follow the video publisher', async function () {
191 await uploadVideoByLocalAccount(servers)
193 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
194 expect(notification).to.be.undefined
196 expect(emails).to.have.lengthOf(0)
197 expect(userNotifications).to.have.lengthOf(0)
200 it('Should send a new video notification if the user follows the local video publisher', async function () {
203 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:' + servers[0].port)
204 await waitJobs(servers)
206 const { name, uuid } = await uploadVideoByLocalAccount(servers)
207 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
210 it('Should send a new video notification from a remote account', async function () {
211 this.timeout(50000) // Server 2 has transcoding enabled
213 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:' + servers[1].port)
214 await waitJobs(servers)
216 const { name, uuid } = await uploadVideoByRemoteAccount(servers)
217 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
220 it('Should send a new video notification on a scheduled publication', async function () {
224 let updateAt = new Date(new Date().getTime() + 2000)
227 privacy: VideoPrivacy.PRIVATE,
229 updateAt: updateAt.toISOString(),
230 privacy: VideoPrivacy.PUBLIC
233 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
236 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
239 it('Should send a new video notification on a remote scheduled publication', async function () {
243 let updateAt = new Date(new Date().getTime() + 2000)
246 privacy: VideoPrivacy.PRIVATE,
248 updateAt: updateAt.toISOString(),
249 privacy: VideoPrivacy.PUBLIC
252 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
253 await waitJobs(servers)
256 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
259 it('Should not send a notification before the video is published', async function () {
262 let updateAt = new Date(new Date().getTime() + 1000000)
265 privacy: VideoPrivacy.PRIVATE,
267 updateAt: updateAt.toISOString(),
268 privacy: VideoPrivacy.PUBLIC
271 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
274 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
277 it('Should send a new video notification when a video becomes public', async function () {
280 const data = { privacy: VideoPrivacy.PRIVATE }
281 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
283 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
285 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
288 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
291 it('Should send a new video notification when a remote video becomes public', async function () {
294 const data = { privacy: VideoPrivacy.PRIVATE }
295 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
297 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
299 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
301 await waitJobs(servers)
302 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
305 it('Should not send a new video notification when a video becomes unlisted', async function () {
308 const data = { privacy: VideoPrivacy.PRIVATE }
309 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
311 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
313 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
316 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
319 const data = { privacy: VideoPrivacy.PRIVATE }
320 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
322 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
324 await waitJobs(servers)
325 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
328 it('Should send a new video notification after a video import', async function () {
331 const name = 'video import ' + uuidv4()
336 privacy: VideoPrivacy.PUBLIC,
337 targetUrl: getYoutubeVideoUrl()
339 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
340 const uuid = res.body.video.uuid
342 await waitJobs(servers)
344 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
348 describe('Comment on my video notifications', function () {
349 let baseParams: CheckerBaseParams
355 socketNotifications: userNotifications,
356 token: userAccessToken
360 it('Should not send a new comment notification after a comment on another video', async function () {
363 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
364 const uuid = resVideo.body.video.uuid
366 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
367 const commentId = resComment.body.comment.id
370 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
373 it('Should not send a new comment notification if I comment my own video', async function () {
376 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
377 const uuid = resVideo.body.video.uuid
379 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
380 const commentId = resComment.body.comment.id
383 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
386 it('Should not send a new comment notification if the account is muted', async function () {
389 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
391 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
392 const uuid = resVideo.body.video.uuid
394 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
395 const commentId = resComment.body.comment.id
398 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
400 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
403 it('Should send a new comment notification after a local comment on my video', async function () {
406 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
407 const uuid = resVideo.body.video.uuid
409 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
410 const commentId = resComment.body.comment.id
413 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
416 it('Should send a new comment notification after a remote comment on my video', async function () {
419 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
420 const uuid = resVideo.body.video.uuid
422 await waitJobs(servers)
424 await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
426 await waitJobs(servers)
428 const resComment = await getVideoCommentThreads(servers[0].url, uuid, 0, 5)
429 expect(resComment.body.data).to.have.lengthOf(1)
430 const commentId = resComment.body.data[0].id
432 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
435 it('Should send a new comment notification after a local reply on my video', async function () {
438 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
439 const uuid = resVideo.body.video.uuid
441 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
442 const threadId = resThread.body.comment.id
444 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
445 const commentId = resComment.body.comment.id
448 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
451 it('Should send a new comment notification after a remote reply on my video', async function () {
454 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
455 const uuid = resVideo.body.video.uuid
456 await waitJobs(servers)
459 const resThread = await addVideoCommentThread(servers[ 1 ].url, servers[ 1 ].accessToken, uuid, 'comment')
460 const threadId = resThread.body.comment.id
461 await addVideoCommentReply(servers[ 1 ].url, servers[ 1 ].accessToken, uuid, threadId, 'reply')
464 await waitJobs(servers)
466 const resThread = await getVideoCommentThreads(servers[0].url, uuid, 0, 5)
467 expect(resThread.body.data).to.have.lengthOf(1)
468 const threadId = resThread.body.data[0].id
470 const resComments = await getVideoThreadComments(servers[0].url, uuid, threadId)
471 const tree = resComments.body as VideoCommentThreadTree
473 expect(tree.children).to.have.lengthOf(1)
474 const commentId = tree.children[0].comment.id
476 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
480 describe('Mention notifications', function () {
481 let baseParams: CheckerBaseParams
487 socketNotifications: userNotifications,
488 token: userAccessToken
493 accessToken: servers[0].accessToken,
494 displayName: 'super root name'
499 accessToken: servers[1].accessToken,
500 displayName: 'super root 2 name'
504 it('Should not send a new mention comment notification if I mention the video owner', async function () {
507 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
508 const uuid = resVideo.body.video.uuid
510 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
511 const commentId = resComment.body.comment.id
514 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
517 it('Should not send a new mention comment notification if I mention myself', async function () {
520 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
521 const uuid = resVideo.body.video.uuid
523 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello')
524 const commentId = resComment.body.comment.id
527 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
530 it('Should not send a new mention notification if the account is muted', async function () {
533 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
535 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
536 const uuid = resVideo.body.video.uuid
538 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
539 const commentId = resComment.body.comment.id
542 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
544 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
547 it('Should not send a new mention notification if the remote account mention a local account', async function () {
550 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
551 const uuid = resVideo.body.video.uuid
553 await waitJobs(servers)
554 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, '@user_1 hello')
555 const threadId = resThread.body.comment.id
557 await waitJobs(servers)
558 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'absence')
561 it('Should send a new mention notification after local comments', async function () {
564 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
565 const uuid = resVideo.body.video.uuid
567 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1')
568 const threadId = resThread.body.comment.id
571 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence')
573 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1')
574 const commentId = resComment.body.comment.id
577 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence')
580 it('Should send a new mention notification after remote comments', async function () {
583 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
584 const uuid = resVideo.body.video.uuid
586 await waitJobs(servers)
588 const text1 = `hello @user_1@localhost:${servers[ 0 ].port} 1`
589 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, text1)
590 const server2ThreadId = resThread.body.comment.id
592 await waitJobs(servers)
594 const resThread2 = await getVideoCommentThreads(servers[0].url, uuid, 0, 5)
595 expect(resThread2.body.data).to.have.lengthOf(1)
596 const server1ThreadId = resThread2.body.data[0].id
597 await checkCommentMention(baseParams, uuid, server1ThreadId, server1ThreadId, 'super root 2 name', 'presence')
599 const text2 = `@user_1@localhost:${servers[ 0 ].port} hello 2 @root@localhost:${servers[ 0 ].port}`
600 await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, server2ThreadId, text2)
602 await waitJobs(servers)
604 const resComments = await getVideoThreadComments(servers[0].url, uuid, server1ThreadId)
605 const tree = resComments.body as VideoCommentThreadTree
607 expect(tree.children).to.have.lengthOf(1)
608 const commentId = tree.children[0].comment.id
610 await checkCommentMention(baseParams, uuid, commentId, server1ThreadId, 'super root 2 name', 'presence')
614 describe('Video abuse for moderators notification' , function () {
615 let baseParams: CheckerBaseParams
621 socketNotifications: adminNotifications,
622 token: servers[0].accessToken
626 it('Should send a notification to moderators on local video abuse', async function () {
629 const name = 'video for abuse ' + uuidv4()
630 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
631 const uuid = resVideo.body.video.uuid
633 await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
635 await waitJobs(servers)
636 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
639 it('Should send a notification to moderators on remote video abuse', async function () {
642 const name = 'video for abuse ' + uuidv4()
643 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
644 const uuid = resVideo.body.video.uuid
646 await waitJobs(servers)
648 await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
650 await waitJobs(servers)
651 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
655 describe('Video blacklist on my video', function () {
656 let baseParams: CheckerBaseParams
662 socketNotifications: userNotifications,
663 token: userAccessToken
667 it('Should send a notification to video owner on blacklist', async function () {
670 const name = 'video for abuse ' + uuidv4()
671 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
672 const uuid = resVideo.body.video.uuid
674 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
676 await waitJobs(servers)
677 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'blacklist')
680 it('Should send a notification to video owner on unblacklist', async function () {
683 const name = 'video for abuse ' + uuidv4()
684 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
685 const uuid = resVideo.body.video.uuid
687 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
689 await waitJobs(servers)
690 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
691 await waitJobs(servers)
694 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'unblacklist')
698 describe('My video is published', function () {
699 let baseParams: CheckerBaseParams
705 socketNotifications: adminNotificationsServer2,
706 token: servers[1].accessToken
710 it('Should not send a notification if transcoding is not enabled', async function () {
713 const { name, uuid } = await uploadVideoByLocalAccount(servers)
714 await waitJobs(servers)
716 await checkVideoIsPublished(baseParams, name, uuid, 'absence')
719 it('Should not send a notification if the wait transcoding is false', async function () {
722 await uploadVideoByRemoteAccount(servers, { waitTranscoding: false })
723 await waitJobs(servers)
725 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
727 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
731 it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
734 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
735 await waitJobs(servers)
737 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
740 it('Should send a notification with a transcoded video', async function () {
743 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true })
744 await waitJobs(servers)
746 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
749 it('Should send a notification when an imported video is transcoded', async function () {
752 const name = 'video import ' + uuidv4()
757 privacy: VideoPrivacy.PUBLIC,
758 targetUrl: getYoutubeVideoUrl(),
759 waitTranscoding: true
761 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
762 const uuid = res.body.video.uuid
764 await waitJobs(servers)
765 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
768 it('Should send a notification when the scheduled update has been proceeded', async function () {
772 let updateAt = new Date(new Date().getTime() + 2000)
775 privacy: VideoPrivacy.PRIVATE,
777 updateAt: updateAt.toISOString(),
778 privacy: VideoPrivacy.PUBLIC
781 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
784 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
787 it('Should not send a notification before the video is published', async function () {
790 let updateAt = new Date(new Date().getTime() + 1000000)
793 privacy: VideoPrivacy.PRIVATE,
795 updateAt: updateAt.toISOString(),
796 privacy: VideoPrivacy.PUBLIC
799 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
802 await checkVideoIsPublished(baseParams, name, uuid, 'absence')
806 describe('My video is imported', function () {
807 let baseParams: CheckerBaseParams
813 socketNotifications: adminNotifications,
814 token: servers[0].accessToken
818 it('Should send a notification when the video import failed', async function () {
821 const name = 'video import ' + uuidv4()
826 privacy: VideoPrivacy.PRIVATE,
827 targetUrl: getBadVideoUrl()
829 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
830 const uuid = res.body.video.uuid
832 await waitJobs(servers)
833 await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence')
836 it('Should send a notification when the video import succeeded', async function () {
839 const name = 'video import ' + uuidv4()
844 privacy: VideoPrivacy.PRIVATE,
845 targetUrl: getYoutubeVideoUrl()
847 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
848 const uuid = res.body.video.uuid
850 await waitJobs(servers)
851 await checkMyVideoImportIsFinished(baseParams, name, uuid, getYoutubeVideoUrl(), true, 'presence')
855 describe('New registration', function () {
856 let baseParams: CheckerBaseParams
862 socketNotifications: adminNotifications,
863 token: servers[0].accessToken
867 it('Should send a notification only to moderators when a user registers on the instance', async function () {
870 await registerUser(servers[0].url, 'user_45', 'password')
872 await waitJobs(servers)
874 await checkUserRegistered(baseParams, 'user_45', 'presence')
876 const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
877 await checkUserRegistered(immutableAssign(baseParams, userOverride), 'user_45', 'absence')
881 describe('New instance follows', function () {
882 const instanceIndexServer = new MockInstancesIndex()
887 indexUrl: 'http://localhost:42100',
893 let baseParams: CheckerBaseParams
899 socketNotifications: adminNotifications,
900 token: servers[0].accessToken
903 await instanceIndexServer.initialize()
904 instanceIndexServer.addInstance(servers[1].host)
907 it('Should send a notification only to admin when there is a new instance follower', async function () {
910 await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
912 await waitJobs(servers)
914 await checkNewInstanceFollower(baseParams, 'localhost:' + servers[2].port, 'presence')
916 const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
917 await checkNewInstanceFollower(immutableAssign(baseParams, userOverride), 'localhost:' + servers[2].port, 'absence')
920 it('Should send a notification on auto follow back', async function () {
923 await unfollow(servers[2].url, servers[2].accessToken, servers[0])
924 await waitJobs(servers)
929 autoFollowBack: { enabled: true }
933 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
935 await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
937 await waitJobs(servers)
939 const followerHost = servers[0].host
940 const followingHost = servers[2].host
941 await checkAutoInstanceFollowing(baseParams, followerHost, followingHost, 'presence')
943 const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
944 await checkAutoInstanceFollowing(immutableAssign(baseParams, userOverride), followerHost, followingHost, 'absence')
946 config.followings.instance.autoFollowBack.enabled = false
947 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
948 await unfollow(servers[0].url, servers[0].accessToken, servers[2])
949 await unfollow(servers[2].url, servers[2].accessToken, servers[0])
952 it('Should send a notification on auto instances index follow', async function () {
954 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
956 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
959 await waitJobs(servers)
961 const followerHost = servers[0].host
962 const followingHost = servers[1].host
963 await checkAutoInstanceFollowing(baseParams, followerHost, followingHost, 'presence')
965 config.followings.instance.autoFollowIndex.enabled = false
966 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, config)
967 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
971 describe('New actor follow', function () {
972 let baseParams: CheckerBaseParams
973 let myChannelName = 'super channel name'
974 let myUserName = 'super user name'
980 socketNotifications: userNotifications,
981 token: userAccessToken
986 accessToken: servers[0].accessToken,
987 displayName: 'super root name'
992 accessToken: userAccessToken,
993 displayName: myUserName
998 accessToken: servers[1].accessToken,
999 displayName: 'super root 2 name'
1002 await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName })
1005 it('Should notify when a local channel is following one of our channel', async function () {
1008 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1009 await waitJobs(servers)
1011 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence')
1013 await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1016 it('Should notify when a remote channel is following one of our channel', async function () {
1019 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1020 await waitJobs(servers)
1022 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence')
1024 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1027 it('Should notify when a local account is following one of our channel', async function () {
1030 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:' + servers[0].port)
1032 await waitJobs(servers)
1034 await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
1037 it('Should notify when a remote account is following one of our channel', async function () {
1040 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:' + servers[0].port)
1042 await waitJobs(servers)
1044 await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
1048 describe('Video-related notifications when video auto-blacklist is enabled', function () {
1049 let userBaseParams: CheckerBaseParams
1050 let adminBaseParamsServer1: CheckerBaseParams
1051 let adminBaseParamsServer2: CheckerBaseParams
1052 let videoUUID: string
1053 let videoName: string
1054 let currentCustomConfig: CustomConfig
1056 before(async () => {
1058 adminBaseParamsServer1 = {
1061 socketNotifications: adminNotifications,
1062 token: servers[0].accessToken
1065 adminBaseParamsServer2 = {
1068 socketNotifications: adminNotificationsServer2,
1069 token: servers[1].accessToken
1075 socketNotifications: userNotifications,
1076 token: userAccessToken
1079 const resCustomConfig = await getCustomConfig(servers[0].url, servers[0].accessToken)
1080 currentCustomConfig = resCustomConfig.body
1081 const autoBlacklistTestsCustomConfig = immutableAssign(currentCustomConfig, {
1090 // enable transcoding otherwise own publish notification after transcoding not expected
1091 autoBlacklistTestsCustomConfig.transcoding.enabled = true
1092 await updateCustomConfig(servers[0].url, servers[0].accessToken, autoBlacklistTestsCustomConfig)
1094 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1095 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1099 it('Should send notification to moderators on new video with auto-blacklist', async function () {
1102 videoName = 'video with auto-blacklist ' + uuidv4()
1103 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
1104 videoUUID = resVideo.body.video.uuid
1106 await waitJobs(servers)
1107 await checkVideoAutoBlacklistForModerators(adminBaseParamsServer1, videoUUID, videoName, 'presence')
1110 it('Should not send video publish notification if auto-blacklisted', async function () {
1111 await checkVideoIsPublished(userBaseParams, videoName, videoUUID, 'absence')
1114 it('Should not send a local user subscription notification if auto-blacklisted', async function () {
1115 await checkNewVideoFromSubscription(adminBaseParamsServer1, videoName, videoUUID, 'absence')
1118 it('Should not send a remote user subscription notification if auto-blacklisted', async function () {
1119 await checkNewVideoFromSubscription(adminBaseParamsServer2, videoName, videoUUID, 'absence')
1122 it('Should send video published and unblacklist after video unblacklisted', async function () {
1125 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoUUID)
1127 await waitJobs(servers)
1129 // FIXME: Can't test as two notifications sent to same user and util only checks last one
1130 // One notification might be better anyways
1131 // await checkNewBlacklistOnMyVideo(userBaseParams, videoUUID, videoName, 'unblacklist')
1132 // await checkVideoIsPublished(userBaseParams, videoName, videoUUID, 'presence')
1135 it('Should send a local user subscription notification after removed from blacklist', async function () {
1136 await checkNewVideoFromSubscription(adminBaseParamsServer1, videoName, videoUUID, 'presence')
1139 it('Should send a remote user subscription notification after removed from blacklist', async function () {
1140 await checkNewVideoFromSubscription(adminBaseParamsServer2, videoName, videoUUID, 'presence')
1143 it('Should send unblacklist but not published/subscription notes after unblacklisted if scheduled update pending', async function () {
1146 let updateAt = new Date(new Date().getTime() + 1000000)
1148 const name = 'video with auto-blacklist and future schedule ' + uuidv4()
1152 privacy: VideoPrivacy.PRIVATE,
1154 updateAt: updateAt.toISOString(),
1155 privacy: VideoPrivacy.PUBLIC
1159 const resVideo = await uploadVideo(servers[0].url, userAccessToken, data)
1160 const uuid = resVideo.body.video.uuid
1162 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
1164 await waitJobs(servers)
1165 await checkNewBlacklistOnMyVideo(userBaseParams, uuid, name, 'unblacklist')
1167 // FIXME: Can't test absence as two notifications sent to same user and util only checks last one
1168 // One notification might be better anyways
1169 // await checkVideoIsPublished(userBaseParams, name, uuid, 'absence')
1171 await checkNewVideoFromSubscription(adminBaseParamsServer1, name, uuid, 'absence')
1172 await checkNewVideoFromSubscription(adminBaseParamsServer2, name, uuid, 'absence')
1175 it('Should not send publish/subscription notifications after scheduled update if video still auto-blacklisted', async function () {
1179 let updateAt = new Date(new Date().getTime() + 2000)
1181 const name = 'video with schedule done and still auto-blacklisted ' + uuidv4()
1185 privacy: VideoPrivacy.PRIVATE,
1187 updateAt: updateAt.toISOString(),
1188 privacy: VideoPrivacy.PUBLIC
1192 const resVideo = await uploadVideo(servers[0].url, userAccessToken, data)
1193 const uuid = resVideo.body.video.uuid
1196 await checkVideoIsPublished(userBaseParams, name, uuid, 'absence')
1197 await checkNewVideoFromSubscription(adminBaseParamsServer1, name, uuid, 'absence')
1198 await checkNewVideoFromSubscription(adminBaseParamsServer2, name, uuid, 'absence')
1201 it('Should not send a notification to moderators on new video without auto-blacklist', async function () {
1204 const name = 'video without auto-blacklist ' + uuidv4()
1206 // admin with blacklist right will not be auto-blacklisted
1207 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name })
1208 const uuid = resVideo.body.video.uuid
1210 await waitJobs(servers)
1211 await checkVideoAutoBlacklistForModerators(adminBaseParamsServer1, uuid, name, 'absence')
1215 await updateCustomConfig(servers[0].url, servers[0].accessToken, currentCustomConfig)
1217 await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1218 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:' + servers[0].port)
1222 describe('Mark as read', function () {
1223 it('Should mark as read some notifications', async function () {
1224 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3)
1225 const ids = res.body.data.map(n => n.id)
1227 await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids)
1230 it('Should have the notifications marked as read', async function () {
1231 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10)
1233 const notifications = res.body.data as UserNotification[]
1234 expect(notifications[ 0 ].read).to.be.false
1235 expect(notifications[ 1 ].read).to.be.false
1236 expect(notifications[ 2 ].read).to.be.true
1237 expect(notifications[ 3 ].read).to.be.true
1238 expect(notifications[ 4 ].read).to.be.true
1239 expect(notifications[ 5 ].read).to.be.false
1242 it('Should only list read notifications', async function () {
1243 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false)
1245 const notifications = res.body.data as UserNotification[]
1246 for (const notification of notifications) {
1247 expect(notification.read).to.be.true
1251 it('Should only list unread notifications', async function () {
1252 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
1254 const notifications = res.body.data as UserNotification[]
1255 for (const notification of notifications) {
1256 expect(notification.read).to.be.false
1260 it('Should mark as read all notifications', async function () {
1261 await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken)
1263 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
1265 expect(res.body.total).to.equal(0)
1266 expect(res.body.data).to.have.lengthOf(0)
1270 describe('Notification settings', function () {
1271 let baseParams: CheckerBaseParams
1277 socketNotifications: userNotifications,
1278 token: userAccessToken
1282 it('Should not have notifications', async function () {
1285 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1286 newVideoFromSubscription: UserNotificationSettingValue.NONE
1290 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1291 const info = res.body as User
1292 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
1295 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1297 const check = { web: true, mail: true }
1298 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1301 it('Should only have web notifications', async function () {
1304 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1305 newVideoFromSubscription: UserNotificationSettingValue.WEB
1309 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1310 const info = res.body as User
1311 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB)
1314 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1317 const check = { mail: true, web: false }
1318 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1322 const check = { mail: false, web: true }
1323 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
1327 it('Should only have mail notifications', async function () {
1330 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1331 newVideoFromSubscription: UserNotificationSettingValue.EMAIL
1335 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1336 const info = res.body as User
1337 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
1340 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1343 const check = { mail: false, web: true }
1344 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
1348 const check = { mail: true, web: false }
1349 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
1353 it('Should have email and web notifications', async function () {
1356 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
1357 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1361 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1362 const info = res.body as User
1363 expect(info.notificationSettings.newVideoFromSubscription).to.equal(
1364 UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1368 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1370 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
1374 after(async function () {
1375 MockSmtpServer.Instance.kill()
1377 await cleanupTests(servers)