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 waitJobs(servers)
157 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
160 it('Should send a new video notification on a scheduled publication', async function () {
163 const videoNameId = 30
164 const videoName = 'local video ' + videoNameId
167 let updateAt = new Date(new Date().getTime() + 2000)
170 privacy: VideoPrivacy.PRIVATE,
172 updateAt: updateAt.toISOString(),
173 privacy: VideoPrivacy.PUBLIC
176 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
179 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
182 it('Should send a new video notification on a remote scheduled publication', async function () {
185 const videoNameId = 40
186 const videoName = 'remote video ' + videoNameId
189 let updateAt = new Date(new Date().getTime() + 2000)
192 privacy: VideoPrivacy.PRIVATE,
194 updateAt: updateAt.toISOString(),
195 privacy: VideoPrivacy.PUBLIC
198 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
199 await waitJobs(servers)
202 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
205 it('Should not send a notification before the video is published', async function () {
208 const videoNameId = 50
209 const videoName = 'local video ' + videoNameId
211 let updateAt = new Date(new Date().getTime() + 100000)
214 privacy: VideoPrivacy.PRIVATE,
216 updateAt: updateAt.toISOString(),
217 privacy: VideoPrivacy.PUBLIC
220 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
223 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
226 it('Should send a new video notification when a video becomes public', async function () {
229 const videoNameId = 60
230 const videoName = 'local video ' + videoNameId
232 const data = { privacy: VideoPrivacy.PRIVATE }
233 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
235 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
237 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
240 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
243 it('Should send a new video notification when a remote video becomes public', async function () {
246 const videoNameId = 70
247 const videoName = 'remote video ' + videoNameId
249 const data = { privacy: VideoPrivacy.PRIVATE }
250 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
251 await waitJobs(servers)
253 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
255 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
257 await waitJobs(servers)
258 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
261 it('Should not send a new video notification when a video becomes unlisted', async function () {
264 const videoNameId = 80
265 const videoName = 'local video ' + videoNameId
267 const data = { privacy: VideoPrivacy.PRIVATE }
268 const uuid = await uploadVideoByLocalAccount(servers, videoNameId, data)
270 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
272 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
275 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
278 const videoNameId = 90
279 const videoName = 'remote video ' + videoNameId
281 const data = { privacy: VideoPrivacy.PRIVATE }
282 const uuid = await uploadVideoByRemoteAccount(servers, videoNameId, data)
283 await waitJobs(servers)
285 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
287 await waitJobs(servers)
288 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'absence')
291 it('Should send a new video notification after a video import', async function () {
294 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
295 const channelId = resChannel.body.videoChannels[0].id
296 const videoName = 'local video 100'
301 privacy: VideoPrivacy.PUBLIC,
302 targetUrl: getYoutubeVideoUrl()
304 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
305 const uuid = res.body.video.uuid
307 await waitJobs(servers)
309 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
313 describe('Comment on my video notifications', function () {
314 let baseParams: CheckerBaseParams
320 socketNotifications: userNotifications,
321 token: userAccessToken
325 it('Should not send a new comment notification after a comment on another video', async function () {
328 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
329 const uuid = resVideo.body.video.uuid
331 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
332 const commentId = resComment.body.comment.id
335 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
338 it('Should not send a new comment notification if I comment my own video', async function () {
341 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
342 const uuid = resVideo.body.video.uuid
344 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
345 const commentId = resComment.body.comment.id
348 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
351 it('Should send a new comment notification after a local comment on my video', async function () {
354 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
355 const uuid = resVideo.body.video.uuid
357 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
358 const commentId = resComment.body.comment.id
361 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
364 it('Should send a new comment notification after a remote comment on my video', async function () {
367 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
368 const uuid = resVideo.body.video.uuid
370 await waitJobs(servers)
372 const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
373 const commentId = resComment.body.comment.id
375 await waitJobs(servers)
376 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
379 it('Should send a new comment notification after a local reply on my video', async function () {
382 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
383 const uuid = resVideo.body.video.uuid
385 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
386 const threadId = resThread.body.comment.id
388 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
389 const commentId = resComment.body.comment.id
392 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
395 it('Should send a new comment notification after a remote reply on my video', async function () {
398 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
399 const uuid = resVideo.body.video.uuid
400 await waitJobs(servers)
402 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
403 const threadId = resThread.body.comment.id
405 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
406 const commentId = resComment.body.comment.id
408 await waitJobs(servers)
409 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
413 describe('Video abuse for moderators notification' , function () {
414 let baseParams: CheckerBaseParams
420 socketNotifications: adminNotifications,
421 token: servers[0].accessToken
425 it('Should send a notification to moderators on local video abuse', async function () {
428 const videoName = 'local video 110'
430 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
431 const uuid = resVideo.body.video.uuid
433 await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
435 await waitJobs(servers)
436 await checkNewVideoAbuseForModerators(baseParams, uuid, videoName, 'presence')
439 it('Should send a notification to moderators on remote video abuse', async function () {
442 const videoName = 'remote video 120'
444 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
445 const uuid = resVideo.body.video.uuid
447 await waitJobs(servers)
449 await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
451 await waitJobs(servers)
452 await checkNewVideoAbuseForModerators(baseParams, uuid, videoName, 'presence')
456 describe('Video blacklist on my video', function () {
457 let baseParams: CheckerBaseParams
463 socketNotifications: userNotifications,
464 token: userAccessToken
468 it('Should send a notification to video owner on blacklist', async function () {
471 const videoName = 'local video 130'
473 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
474 const uuid = resVideo.body.video.uuid
476 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
478 await waitJobs(servers)
479 await checkNewBlacklistOnMyVideo(baseParams, uuid, videoName, 'blacklist')
482 it('Should send a notification to video owner on unblacklist', async function () {
485 const videoName = 'local video 130'
487 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: videoName })
488 const uuid = resVideo.body.video.uuid
490 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
492 await waitJobs(servers)
493 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
494 await waitJobs(servers)
497 await checkNewBlacklistOnMyVideo(baseParams, uuid, videoName, 'unblacklist')
501 describe('Mark as read', function () {
502 it('Should mark as read some notifications', async function () {
503 const res = await getUserNotifications(servers[0].url, userAccessToken, 2, 3)
504 const ids = res.body.data.map(n => n.id)
506 await markAsReadNotifications(servers[0].url, userAccessToken, ids)
509 it('Should have the notifications marked as read', async function () {
510 const res = await getUserNotifications(servers[0].url, userAccessToken, 0, 10)
512 const notifications = res.body.data as UserNotification[]
513 expect(notifications[0].read).to.be.false
514 expect(notifications[1].read).to.be.false
515 expect(notifications[2].read).to.be.true
516 expect(notifications[3].read).to.be.true
517 expect(notifications[4].read).to.be.true
518 expect(notifications[5].read).to.be.false
522 describe('Notification settings', function () {
523 const baseUpdateNotificationParams = {
524 newCommentOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
525 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
526 videoAbuseAsModerator: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL,
527 blacklistOnMyVideo: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL
529 let baseParams: CheckerBaseParams
535 socketNotifications: userNotifications,
536 token: userAccessToken
540 it('Should not have notifications', async function () {
541 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
542 newVideoFromSubscription: UserNotificationSettingValue.NONE
546 const res = await getMyUserInformation(servers[0].url, userAccessToken)
547 const info = res.body as User
548 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
551 const videoNameId = 42
552 const videoName = 'local video ' + videoNameId
553 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
555 const check = { web: true, mail: true }
556 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
559 it('Should only have web notifications', async function () {
560 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
561 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION
565 const res = await getMyUserInformation(servers[0].url, userAccessToken)
566 const info = res.body as User
567 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB_NOTIFICATION)
570 const videoNameId = 52
571 const videoName = 'local video ' + videoNameId
572 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
575 const check = { mail: true, web: false }
576 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
580 const check = { mail: false, web: true }
581 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'presence')
585 it('Should only have mail notifications', async function () {
586 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
587 newVideoFromSubscription: UserNotificationSettingValue.EMAIL
591 const res = await getMyUserInformation(servers[0].url, userAccessToken)
592 const info = res.body as User
593 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
596 const videoNameId = 62
597 const videoName = 'local video ' + videoNameId
598 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
601 const check = { mail: false, web: true }
602 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'absence')
606 const check = { mail: true, web: false }
607 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), videoName, uuid, 'presence')
611 it('Should have email and web notifications', async function () {
612 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(baseUpdateNotificationParams, {
613 newVideoFromSubscription: UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL
617 const res = await getMyUserInformation(servers[0].url, userAccessToken)
618 const info = res.body as User
619 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB_NOTIFICATION_AND_EMAIL)
622 const videoNameId = 72
623 const videoName = 'local video ' + videoNameId
624 const uuid = await uploadVideoByLocalAccount(servers, videoNameId)
626 await checkNewVideoFromSubscription(baseParams, videoName, uuid, 'presence')
630 after(async function () {
631 killallServers(servers)