1 /* tslint:disable:no-unused-expression */
3 import * as chai from 'chai'
9 flushAndRunMultipleServers,
13 removeVideoFromBlacklist,
18 } from '../../../../shared/utils'
19 import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
20 import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
21 import { waitJobs } from '../../../../shared/utils/server/jobs'
22 import { getUserNotificationSocket } from '../../../../shared/utils/socket/socket-io'
25 checkNewBlacklistOnMyVideo,
26 checkNewCommentOnMyVideo,
27 checkNewVideoAbuseForModerators,
28 checkNewVideoFromSubscription,
31 markAsReadNotifications,
32 updateMyNotificationSettings
33 } from '../../../../shared/utils/users/user-notifications'
34 import { User, UserNotification, UserNotificationSettingValue } from '../../../../shared/models/users'
35 import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
36 import { addUserSubscription } from '../../../../shared/utils/users/user-subscriptions'
37 import { VideoPrivacy } from '../../../../shared/models/videos'
38 import { getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
39 import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
41 const expect = chai.expect
43 async function uploadVideoByRemoteAccount (servers: ServerInfo[], videoNameId: number, additionalParams: any = {}) {
44 const data = Object.assign({ name: 'remote video ' + videoNameId }, additionalParams)
45 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data)
47 await waitJobs(servers)
49 return res.body.video.uuid
52 async function uploadVideoByLocalAccount (servers: ServerInfo[], videoNameId: number, additionalParams: any = {}) {
53 const data = Object.assign({ name: 'local video ' + videoNameId }, additionalParams)
54 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data)
56 await waitJobs(servers)
58 return res.body.video.uuid
61 describe('Test users notifications', function () {
62 let servers: ServerInfo[] = []
63 let userAccessToken: string
64 let userNotifications: UserNotification[] = []
65 let adminNotifications: UserNotification[] = []
66 const emails: object[] = []
68 before(async function () {
71 await MockSmtpServer.Instance.collectEmails(emails)
75 const overrideConfig = {
80 servers = await flushAndRunMultipleServers(2, overrideConfig)
82 // Get the access tokens
83 await setAccessTokensToServers(servers)
85 // Server 1 and server 2 follow each other
86 await doubleFollow(servers[0], servers[1])
88 await waitJobs(servers)
92 password: 'super password'
94 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000)
95 userAccessToken = await userLogin(servers[0], user)
97 await updateMyNotificationSettings(servers[0].url, userAccessToken, {
98 newCommentOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
99 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
100 blacklistOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
101 videoAbuseAsModerator: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL
105 const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken)
106 socket.on('new-notification', n => userNotifications.push(n))
109 const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken)
110 socket.on('new-notification', n => adminNotifications.push(n))
114 describe('New video from my subscription notification', function () {
115 let baseParams: CheckerBaseParams
121 socketNotifications: userNotifications,
122 token: userAccessToken
126 it('Should not send notifications if the user does not follow the video publisher', async function () {
127 await uploadVideoByLocalAccount(servers, 1)
129 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
130 expect(notification).to.be.undefined
132 expect(emails).to.have.lengthOf(0)
133 expect(userNotifications).to.have.lengthOf(0)
136 it('Should send a new video notification if the user follows the local video publisher', async function () {
137 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9001')
139 const videoNameId = 10
140 const videoName = 'local video ' + videoNameId
142 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
143 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
146 it('Should send a new video notification from a remote account', async function () {
147 this.timeout(50000) // Server 2 has transcoding enabled
149 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9002')
151 const videoNameId = 20
152 const videoName = 'remote video ' + videoNameId
154 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId)
155 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
158 it('Should send a new video notification on a scheduled publication', async function () {
161 const videoNameId = 30
162 const videoName = 'local video ' + videoNameId
165 let updateAt = new Date(new Date().getTime() + 2000)
168 privacy: VideoPrivacy.PRIVATE,
170 updateAt: updateAt.toISOString(),
171 privacy: VideoPrivacy.PUBLIC
174 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
177 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
180 it('Should send a new video notification on a remote scheduled publication', async function () {
183 const videoNameId = 40
184 const videoName = 'remote video ' + videoNameId
187 let updateAt = new Date(new Date().getTime() + 2000)
190 privacy: VideoPrivacy.PRIVATE,
192 updateAt: updateAt.toISOString(),
193 privacy: VideoPrivacy.PUBLIC
196 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
199 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
202 it('Should not send a notification before the video is published', async function () {
205 const videoNameId = 50
206 const videoName = 'local video ' + videoNameId
208 let updateAt = new Date(new Date().getTime() + 100000)
211 privacy: VideoPrivacy.PRIVATE,
213 updateAt: updateAt.toISOString(),
214 privacy: VideoPrivacy.PUBLIC
217 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
220 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
223 it('Should send a new video notification when a video becomes public', async function () {
226 const videoNameId = 60
227 const videoName = 'local video ' + videoNameId
229 const data = { privacy: VideoPrivacy.PRIVATE }
230 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
232 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
234 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
237 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
240 it('Should send a new video notification when a remote video becomes public', async function () {
243 const videoNameId = 70
244 const videoName = 'remote video ' + videoNameId
246 const data = { privacy: VideoPrivacy.PRIVATE }
247 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
249 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
251 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
253 await waitJobs(servers)
254 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
257 it('Should not send a new video notification when a video becomes unlisted', async function () {
260 const videoNameId = 80
261 const videoName = 'local video ' + videoNameId
263 const data = { privacy: VideoPrivacy.PRIVATE }
264 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
266 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
268 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
271 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
274 const videoNameId = 90
275 const videoName = 'remote video ' + videoNameId
277 const data = { privacy: VideoPrivacy.PRIVATE }
278 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
280 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
282 await waitJobs(servers)
283 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
286 it('Should send a new video notification after a video import', async function () {
289 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
290 const channelId = resChannel.body.videoChannels[0].id
291 const videoName = 'local video 100'
296 privacy: VideoPrivacy.PUBLIC,
297 targetUrl: getYoutubeVideoUrl()
299 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
300 const uuid = res.body.video.uuid
302 await waitJobs(servers)
304 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
308 describe('Comment on my video notifications', function () {
309 let baseParams: CheckerBaseParams
315 socketNotifications: userNotifications,
316 token: userAccessToken
320 it('Should not send a new comment notification after a comment on another video', async function () {
323 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
324 const uuid = resVideo.body.video.uuid
326 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
327 const commentId = resComment.body.comment.id
330 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
333 it('Should not send a new comment notification if I comment my own video', async function () {
336 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
337 const uuid = resVideo.body.video.uuid
339 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
340 const commentId = resComment.body.comment.id
343 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
346 it('Should send a new comment notification after a local comment on my video', async function () {
349 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
350 const uuid = resVideo.body.video.uuid
352 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
353 const commentId = resComment.body.comment.id
356 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
359 it('Should send a new comment notification after a remote comment on my video', async function () {
362 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
363 const uuid = resVideo.body.video.uuid
365 await waitJobs(servers)
367 const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
368 const commentId = resComment.body.comment.id
370 await waitJobs(servers)
371 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
374 it('Should send a new comment notification after a local reply on my video', async function () {
377 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
378 const uuid = resVideo.body.video.uuid
380 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
381 const threadId = resThread.body.comment.id
383 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
384 const commentId = resComment.body.comment.id
387 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
390 it('Should send a new comment notification after a remote reply on my video', async function () {
393 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
394 const uuid = resVideo.body.video.uuid
395 await waitJobs(servers)
397 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
398 const threadId = resThread.body.comment.id
400 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
401 const commentId = resComment.body.comment.id
403 await waitJobs(servers)
404 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
408 describe('Video abuse for moderators notification' , function () {
409 let baseParams: CheckerBaseParams
415 socketNotifications: adminNotifications,
416 token: servers[0].accessToken
420 it('Should send a notification to moderators on local video abuse', async function () {
423 const videoName = 'local video 110'
425 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
426 const uuid = resVideo.body.video.uuid
428 await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
430 await waitJobs(servers)
431 await checkNewVideoAbuseForModerators(baseParams, uuid, videoName, 'presence')
434 it('Should send a notification to moderators on remote video abuse', async function () {
437 const videoName = 'remote video 120'
439 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
440 const uuid = resVideo.body.video.uuid
442 await waitJobs(servers)
444 await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
446 await waitJobs(servers)
447 await checkNewVideoAbuseForModerators(baseParams, uuid, videoName, 'presence')
451 describe('Video blacklist on my video', function () {
452 let baseParams: CheckerBaseParams
458 socketNotifications: userNotifications,
459 token: userAccessToken
463 it('Should send a notification to video owner on blacklist', async function () {
466 const videoName = 'local video 130'
468 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
469 const uuid = resVideo.body.video.uuid
471 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
473 await waitJobs(servers)
474 await checkNewBlacklistOnMyVideo(baseParams, uuid, videoName, 'blacklist')
477 it('Should send a notification to video owner on unblacklist', async function () {
480 const videoName = 'local video 130'
482 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
483 const uuid = resVideo.body.video.uuid
485 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
487 await waitJobs(servers)
488 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
489 await waitJobs(servers)
492 await checkNewBlacklistOnMyVideo(baseParams, uuid, videoName, 'unblacklist')
496 describe('Mark as read', function () {
497 it('Should mark as read some notifications', async function () {
498 const res = await getUserNotifications(servers[0].url, userAccessToken, 2, 3)
499 const ids = res.body.data.map(n => n.id)
501 await markAsReadNotifications(servers[0].url, userAccessToken, ids)
504 it('Should have the notifications marked as read', async function () {
505 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10)
507 const notifications = res.body.data as UserNotification[]
508 expect(notifications[0].read).to.be.false
509 expect(notifications[1].read).to.be.false
510 expect(notifications[2].read).to.be.true
511 expect(notifications[3].read).to.be.true
512 expect(notifications[4].read).to.be.true
513 expect(notifications[5].read).to.be.false
517 describe('Notification settings', function () {
518 const baseUpdateNotificationParams = {
519 newCommentOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
520 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
521 videoAbuseAsModerator: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
522 blacklistOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL
524 let baseParams: CheckerBaseParams
530 socketNotifications: userNotifications,
531 token: userAccessToken
535 it('Should not have notifications', async function () {
536 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
537 newVideoFromSubscription: UserNotificationSettingValue.NONE
541 const res = await getMyUserInformation(servers[0].url, userAccessToken)
542 const info = res.body as User
543 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
546 const videoNameId = 42
547 const videoName = 'local video ' + videoNameId
548 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
550 const check = { web: true, mail: true }
551 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
554 it('Should only have web notifications', async function () {
555 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
556 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION
560 const res = await getMyUserInformation(servers[0].url, userAccessToken)
561 const info = res.body as User
562 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB_NOTIFICATION)
565 const videoNameId = 52
566 const videoName = 'local video ' + videoNameId
567 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
570 const check = { mail: true, web: false }
571 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
575 const check = { mail: false, web: true }
576 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'presence')
580 it('Should only have mail notifications', async function () {
581 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
582 newVideoFromSubscription: UserNotificationSettingValue.EMAIL
586 const res = await getMyUserInformation(servers[0].url, userAccessToken)
587 const info = res.body as User
588 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
591 const videoNameId = 62
592 const videoName = 'local video ' + videoNameId
593 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
596 const check = { mail: false, web: true }
597 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
601 const check = { mail: true, web: false }
602 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'presence')
606 it('Should have email and web notifications', async function () {
607 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
608 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL
612 const res = await getMyUserInformation(servers[0].url, userAccessToken)
613 const info = res.body as User
614 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL)
617 const videoNameId = 72
618 const videoName = 'local video ' + videoNameId
619 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
621 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
625 after(async function () {
626 killallServers(servers)