diff options
Diffstat (limited to 'server/tests/api/users/user-notifications.ts')
-rw-r--r-- | server/tests/api/users/user-notifications.ts | 1053 |
1 files changed, 1053 insertions, 0 deletions
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts new file mode 100644 index 000000000..69e51677e --- /dev/null +++ b/server/tests/api/users/user-notifications.ts | |||
@@ -0,0 +1,1053 @@ | |||
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 | } from '../../../../shared/utils' | ||
22 | import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index' | ||
23 | import { setAccessTokensToServers } from '../../../../shared/utils/users/login' | ||
24 | import { waitJobs } from '../../../../shared/utils/server/jobs' | ||
25 | import { getUserNotificationSocket } from '../../../../shared/utils/socket/socket-io' | ||
26 | import { | ||
27 | checkCommentMention, | ||
28 | CheckerBaseParams, | ||
29 | checkMyVideoImportIsFinished, | ||
30 | checkNewActorFollow, | ||
31 | checkNewBlacklistOnMyVideo, | ||
32 | checkNewCommentOnMyVideo, | ||
33 | checkNewVideoAbuseForModerators, | ||
34 | checkNewVideoFromSubscription, | ||
35 | checkUserRegistered, | ||
36 | checkVideoIsPublished, | ||
37 | getLastNotification, | ||
38 | getUserNotifications, | ||
39 | markAsReadNotifications, | ||
40 | updateMyNotificationSettings, | ||
41 | markAsReadAllNotifications | ||
42 | } from '../../../../shared/utils/users/user-notifications' | ||
43 | import { | ||
44 | User, | ||
45 | UserNotification, | ||
46 | UserNotificationSetting, | ||
47 | UserNotificationSettingValue, | ||
48 | UserNotificationType | ||
49 | } from '../../../../shared/models/users' | ||
50 | import { MockSmtpServer } from '../../../../shared/utils/miscs/email' | ||
51 | import { addUserSubscription, removeUserSubscription } from '../../../../shared/utils/users/user-subscriptions' | ||
52 | import { VideoPrivacy } from '../../../../shared/models/videos' | ||
53 | import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports' | ||
54 | import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/utils/videos/video-comments' | ||
55 | import * as uuidv4 from 'uuid/v4' | ||
56 | import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/utils/users/blocklist' | ||
57 | |||
58 | const expect = chai.expect | ||
59 | |||
60 | async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalParams: any = {}) { | ||
61 | const name = 'remote video ' + uuidv4() | ||
62 | |||
63 | const data = Object.assign({ name }, additionalParams) | ||
64 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data) | ||
65 | |||
66 | await waitJobs(servers) | ||
67 | |||
68 | return { uuid: res.body.video.uuid, name } | ||
69 | } | ||
70 | |||
71 | async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParams: any = {}) { | ||
72 | const name = 'local video ' + uuidv4() | ||
73 | |||
74 | const data = Object.assign({ name }, additionalParams) | ||
75 | const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data) | ||
76 | |||
77 | await waitJobs(servers) | ||
78 | |||
79 | return { uuid: res.body.video.uuid, name } | ||
80 | } | ||
81 | |||
82 | describe('Test users notifications', function () { | ||
83 | let servers: ServerInfo[] = [] | ||
84 | let userAccessToken: string | ||
85 | let userNotifications: UserNotification[] = [] | ||
86 | let adminNotifications: UserNotification[] = [] | ||
87 | let adminNotificationsServer2: UserNotification[] = [] | ||
88 | const emails: object[] = [] | ||
89 | let channelId: number | ||
90 | |||
91 | const allNotificationSettings: UserNotificationSetting = { | ||
92 | newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
93 | newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
94 | videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
95 | blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
96 | myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
97 | myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
98 | commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
99 | newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, | ||
100 | newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | ||
101 | } | ||
102 | |||
103 | before(async function () { | ||
104 | this.timeout(120000) | ||
105 | |||
106 | await MockSmtpServer.Instance.collectEmails(emails) | ||
107 | |||
108 | await flushTests() | ||
109 | |||
110 | const overrideConfig = { | ||
111 | smtp: { | ||
112 | hostname: 'localhost' | ||
113 | } | ||
114 | } | ||
115 | servers = await flushAndRunMultipleServers(2, overrideConfig) | ||
116 | |||
117 | // Get the access tokens | ||
118 | await setAccessTokensToServers(servers) | ||
119 | |||
120 | // Server 1 and server 2 follow each other | ||
121 | await doubleFollow(servers[0], servers[1]) | ||
122 | |||
123 | await waitJobs(servers) | ||
124 | |||
125 | const user = { | ||
126 | username: 'user_1', | ||
127 | password: 'super password' | ||
128 | } | ||
129 | await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000) | ||
130 | userAccessToken = await userLogin(servers[0], user) | ||
131 | |||
132 | await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings) | ||
133 | await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, allNotificationSettings) | ||
134 | await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings) | ||
135 | |||
136 | { | ||
137 | const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken) | ||
138 | socket.on('new-notification', n => userNotifications.push(n)) | ||
139 | } | ||
140 | { | ||
141 | const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken) | ||
142 | socket.on('new-notification', n => adminNotifications.push(n)) | ||
143 | } | ||
144 | { | ||
145 | const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken) | ||
146 | socket.on('new-notification', n => adminNotificationsServer2.push(n)) | ||
147 | } | ||
148 | |||
149 | { | ||
150 | const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken) | ||
151 | channelId = resChannel.body.videoChannels[0].id | ||
152 | } | ||
153 | }) | ||
154 | |||
155 | describe('New video from my subscription notification', function () { | ||
156 | let baseParams: CheckerBaseParams | ||
157 | |||
158 | before(() => { | ||
159 | baseParams = { | ||
160 | server: servers[0], | ||
161 | emails, | ||
162 | socketNotifications: userNotifications, | ||
163 | token: userAccessToken | ||
164 | } | ||
165 | }) | ||
166 | |||
167 | it('Should not send notifications if the user does not follow the video publisher', async function () { | ||
168 | this.timeout(10000) | ||
169 | |||
170 | await uploadVideoByLocalAccount(servers) | ||
171 | |||
172 | const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) | ||
173 | expect(notification).to.be.undefined | ||
174 | |||
175 | expect(emails).to.have.lengthOf(0) | ||
176 | expect(userNotifications).to.have.lengthOf(0) | ||
177 | }) | ||
178 | |||
179 | it('Should send a new video notification if the user follows the local video publisher', async function () { | ||
180 | this.timeout(15000) | ||
181 | |||
182 | await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9001') | ||
183 | await waitJobs(servers) | ||
184 | |||
185 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
186 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
187 | }) | ||
188 | |||
189 | it('Should send a new video notification from a remote account', async function () { | ||
190 | this.timeout(50000) // Server 2 has transcoding enabled | ||
191 | |||
192 | await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9002') | ||
193 | await waitJobs(servers) | ||
194 | |||
195 | const { name, uuid } = await uploadVideoByRemoteAccount(servers) | ||
196 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
197 | }) | ||
198 | |||
199 | it('Should send a new video notification on a scheduled publication', async function () { | ||
200 | this.timeout(20000) | ||
201 | |||
202 | // In 2 seconds | ||
203 | let updateAt = new Date(new Date().getTime() + 2000) | ||
204 | |||
205 | const data = { | ||
206 | privacy: VideoPrivacy.PRIVATE, | ||
207 | scheduleUpdate: { | ||
208 | updateAt: updateAt.toISOString(), | ||
209 | privacy: VideoPrivacy.PUBLIC | ||
210 | } | ||
211 | } | ||
212 | const { name, uuid } = await uploadVideoByLocalAccount(servers, data) | ||
213 | |||
214 | await wait(6000) | ||
215 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
216 | }) | ||
217 | |||
218 | it('Should send a new video notification on a remote scheduled publication', async function () { | ||
219 | this.timeout(20000) | ||
220 | |||
221 | // In 2 seconds | ||
222 | let updateAt = new Date(new Date().getTime() + 2000) | ||
223 | |||
224 | const data = { | ||
225 | privacy: VideoPrivacy.PRIVATE, | ||
226 | scheduleUpdate: { | ||
227 | updateAt: updateAt.toISOString(), | ||
228 | privacy: VideoPrivacy.PUBLIC | ||
229 | } | ||
230 | } | ||
231 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
232 | await waitJobs(servers) | ||
233 | |||
234 | await wait(6000) | ||
235 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
236 | }) | ||
237 | |||
238 | it('Should not send a notification before the video is published', async function () { | ||
239 | this.timeout(20000) | ||
240 | |||
241 | let updateAt = new Date(new Date().getTime() + 100000) | ||
242 | |||
243 | const data = { | ||
244 | privacy: VideoPrivacy.PRIVATE, | ||
245 | scheduleUpdate: { | ||
246 | updateAt: updateAt.toISOString(), | ||
247 | privacy: VideoPrivacy.PUBLIC | ||
248 | } | ||
249 | } | ||
250 | const { name, uuid } = await uploadVideoByLocalAccount(servers, data) | ||
251 | |||
252 | await wait(6000) | ||
253 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence') | ||
254 | }) | ||
255 | |||
256 | it('Should send a new video notification when a video becomes public', async function () { | ||
257 | this.timeout(10000) | ||
258 | |||
259 | const data = { privacy: VideoPrivacy.PRIVATE } | ||
260 | const { name, uuid } = await uploadVideoByLocalAccount(servers, data) | ||
261 | |||
262 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence') | ||
263 | |||
264 | await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC }) | ||
265 | |||
266 | await wait(500) | ||
267 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
268 | }) | ||
269 | |||
270 | it('Should send a new video notification when a remote video becomes public', async function () { | ||
271 | this.timeout(20000) | ||
272 | |||
273 | const data = { privacy: VideoPrivacy.PRIVATE } | ||
274 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
275 | |||
276 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence') | ||
277 | |||
278 | await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC }) | ||
279 | |||
280 | await waitJobs(servers) | ||
281 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
282 | }) | ||
283 | |||
284 | it('Should not send a new video notification when a video becomes unlisted', async function () { | ||
285 | this.timeout(20000) | ||
286 | |||
287 | const data = { privacy: VideoPrivacy.PRIVATE } | ||
288 | const { name, uuid } = await uploadVideoByLocalAccount(servers, data) | ||
289 | |||
290 | await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED }) | ||
291 | |||
292 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence') | ||
293 | }) | ||
294 | |||
295 | it('Should not send a new video notification when a remote video becomes unlisted', async function () { | ||
296 | this.timeout(20000) | ||
297 | |||
298 | const data = { privacy: VideoPrivacy.PRIVATE } | ||
299 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
300 | |||
301 | await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED }) | ||
302 | |||
303 | await waitJobs(servers) | ||
304 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence') | ||
305 | }) | ||
306 | |||
307 | it('Should send a new video notification after a video import', async function () { | ||
308 | this.timeout(30000) | ||
309 | |||
310 | const name = 'video import ' + uuidv4() | ||
311 | |||
312 | const attributes = { | ||
313 | name, | ||
314 | channelId, | ||
315 | privacy: VideoPrivacy.PUBLIC, | ||
316 | targetUrl: getYoutubeVideoUrl() | ||
317 | } | ||
318 | const res = await importVideo(servers[0].url, servers[0].accessToken, attributes) | ||
319 | const uuid = res.body.video.uuid | ||
320 | |||
321 | await waitJobs(servers) | ||
322 | |||
323 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
324 | }) | ||
325 | }) | ||
326 | |||
327 | describe('Comment on my video notifications', function () { | ||
328 | let baseParams: CheckerBaseParams | ||
329 | |||
330 | before(() => { | ||
331 | baseParams = { | ||
332 | server: servers[0], | ||
333 | emails, | ||
334 | socketNotifications: userNotifications, | ||
335 | token: userAccessToken | ||
336 | } | ||
337 | }) | ||
338 | |||
339 | it('Should not send a new comment notification after a comment on another video', async function () { | ||
340 | this.timeout(10000) | ||
341 | |||
342 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
343 | const uuid = resVideo.body.video.uuid | ||
344 | |||
345 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') | ||
346 | const commentId = resComment.body.comment.id | ||
347 | |||
348 | await wait(500) | ||
349 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') | ||
350 | }) | ||
351 | |||
352 | it('Should not send a new comment notification if I comment my own video', async function () { | ||
353 | this.timeout(10000) | ||
354 | |||
355 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
356 | const uuid = resVideo.body.video.uuid | ||
357 | |||
358 | const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment') | ||
359 | const commentId = resComment.body.comment.id | ||
360 | |||
361 | await wait(500) | ||
362 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') | ||
363 | }) | ||
364 | |||
365 | it('Should not send a new comment notification if the account is muted', async function () { | ||
366 | this.timeout(10000) | ||
367 | |||
368 | await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') | ||
369 | |||
370 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
371 | const uuid = resVideo.body.video.uuid | ||
372 | |||
373 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') | ||
374 | const commentId = resComment.body.comment.id | ||
375 | |||
376 | await wait(500) | ||
377 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence') | ||
378 | |||
379 | await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') | ||
380 | }) | ||
381 | |||
382 | it('Should send a new comment notification after a local comment on my video', async function () { | ||
383 | this.timeout(10000) | ||
384 | |||
385 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
386 | const uuid = resVideo.body.video.uuid | ||
387 | |||
388 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') | ||
389 | const commentId = resComment.body.comment.id | ||
390 | |||
391 | await wait(500) | ||
392 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence') | ||
393 | }) | ||
394 | |||
395 | it('Should send a new comment notification after a remote comment on my video', async function () { | ||
396 | this.timeout(10000) | ||
397 | |||
398 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
399 | const uuid = resVideo.body.video.uuid | ||
400 | |||
401 | await waitJobs(servers) | ||
402 | |||
403 | const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment') | ||
404 | const commentId = resComment.body.comment.id | ||
405 | |||
406 | await waitJobs(servers) | ||
407 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence') | ||
408 | }) | ||
409 | |||
410 | it('Should send a new comment notification after a local reply on my video', async function () { | ||
411 | this.timeout(10000) | ||
412 | |||
413 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
414 | const uuid = resVideo.body.video.uuid | ||
415 | |||
416 | const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment') | ||
417 | const threadId = resThread.body.comment.id | ||
418 | |||
419 | const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply') | ||
420 | const commentId = resComment.body.comment.id | ||
421 | |||
422 | await wait(500) | ||
423 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence') | ||
424 | }) | ||
425 | |||
426 | it('Should send a new comment notification after a remote reply on my video', async function () { | ||
427 | this.timeout(10000) | ||
428 | |||
429 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
430 | const uuid = resVideo.body.video.uuid | ||
431 | await waitJobs(servers) | ||
432 | |||
433 | const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment') | ||
434 | const threadId = resThread.body.comment.id | ||
435 | |||
436 | const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply') | ||
437 | const commentId = resComment.body.comment.id | ||
438 | |||
439 | await waitJobs(servers) | ||
440 | await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence') | ||
441 | }) | ||
442 | }) | ||
443 | |||
444 | describe('Mention notifications', function () { | ||
445 | let baseParams: CheckerBaseParams | ||
446 | |||
447 | before(async () => { | ||
448 | baseParams = { | ||
449 | server: servers[0], | ||
450 | emails, | ||
451 | socketNotifications: userNotifications, | ||
452 | token: userAccessToken | ||
453 | } | ||
454 | |||
455 | await updateMyUser({ | ||
456 | url: servers[0].url, | ||
457 | accessToken: servers[0].accessToken, | ||
458 | displayName: 'super root name' | ||
459 | }) | ||
460 | |||
461 | await updateMyUser({ | ||
462 | url: servers[1].url, | ||
463 | accessToken: servers[1].accessToken, | ||
464 | displayName: 'super root 2 name' | ||
465 | }) | ||
466 | }) | ||
467 | |||
468 | it('Should not send a new mention comment notification if I mention the video owner', async function () { | ||
469 | this.timeout(10000) | ||
470 | |||
471 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' }) | ||
472 | const uuid = resVideo.body.video.uuid | ||
473 | |||
474 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello') | ||
475 | const commentId = resComment.body.comment.id | ||
476 | |||
477 | await wait(500) | ||
478 | await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') | ||
479 | }) | ||
480 | |||
481 | it('Should not send a new mention comment notification if I mention myself', async function () { | ||
482 | this.timeout(10000) | ||
483 | |||
484 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
485 | const uuid = resVideo.body.video.uuid | ||
486 | |||
487 | const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello') | ||
488 | const commentId = resComment.body.comment.id | ||
489 | |||
490 | await wait(500) | ||
491 | await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') | ||
492 | }) | ||
493 | |||
494 | it('Should not send a new mention notification if the account is muted', async function () { | ||
495 | this.timeout(10000) | ||
496 | |||
497 | await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') | ||
498 | |||
499 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
500 | const uuid = resVideo.body.video.uuid | ||
501 | |||
502 | const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello') | ||
503 | const commentId = resComment.body.comment.id | ||
504 | |||
505 | await wait(500) | ||
506 | await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence') | ||
507 | |||
508 | await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') | ||
509 | }) | ||
510 | |||
511 | it('Should send a new mention notification after local comments', async function () { | ||
512 | this.timeout(10000) | ||
513 | |||
514 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
515 | const uuid = resVideo.body.video.uuid | ||
516 | |||
517 | const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1') | ||
518 | const threadId = resThread.body.comment.id | ||
519 | |||
520 | await wait(500) | ||
521 | await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence') | ||
522 | |||
523 | const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1') | ||
524 | const commentId = resComment.body.comment.id | ||
525 | |||
526 | await wait(500) | ||
527 | await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence') | ||
528 | }) | ||
529 | |||
530 | it('Should send a new mention notification after remote comments', async function () { | ||
531 | this.timeout(20000) | ||
532 | |||
533 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
534 | const uuid = resVideo.body.video.uuid | ||
535 | |||
536 | await waitJobs(servers) | ||
537 | const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'hello @user_1@localhost:9001 1') | ||
538 | const threadId = resThread.body.comment.id | ||
539 | |||
540 | await waitJobs(servers) | ||
541 | await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'presence') | ||
542 | |||
543 | const text = '@user_1@localhost:9001 hello 2 @root@localhost:9001' | ||
544 | const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, text) | ||
545 | const commentId = resComment.body.comment.id | ||
546 | |||
547 | await waitJobs(servers) | ||
548 | await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root 2 name', 'presence') | ||
549 | }) | ||
550 | }) | ||
551 | |||
552 | describe('Video abuse for moderators notification' , function () { | ||
553 | let baseParams: CheckerBaseParams | ||
554 | |||
555 | before(() => { | ||
556 | baseParams = { | ||
557 | server: servers[0], | ||
558 | emails, | ||
559 | socketNotifications: adminNotifications, | ||
560 | token: servers[0].accessToken | ||
561 | } | ||
562 | }) | ||
563 | |||
564 | it('Should send a notification to moderators on local video abuse', async function () { | ||
565 | this.timeout(10000) | ||
566 | |||
567 | const name = 'video for abuse ' + uuidv4() | ||
568 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) | ||
569 | const uuid = resVideo.body.video.uuid | ||
570 | |||
571 | await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason') | ||
572 | |||
573 | await waitJobs(servers) | ||
574 | await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence') | ||
575 | }) | ||
576 | |||
577 | it('Should send a notification to moderators on remote video abuse', async function () { | ||
578 | this.timeout(10000) | ||
579 | |||
580 | const name = 'video for abuse ' + uuidv4() | ||
581 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) | ||
582 | const uuid = resVideo.body.video.uuid | ||
583 | |||
584 | await waitJobs(servers) | ||
585 | |||
586 | await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason') | ||
587 | |||
588 | await waitJobs(servers) | ||
589 | await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence') | ||
590 | }) | ||
591 | }) | ||
592 | |||
593 | describe('Video blacklist on my video', function () { | ||
594 | let baseParams: CheckerBaseParams | ||
595 | |||
596 | before(() => { | ||
597 | baseParams = { | ||
598 | server: servers[0], | ||
599 | emails, | ||
600 | socketNotifications: userNotifications, | ||
601 | token: userAccessToken | ||
602 | } | ||
603 | }) | ||
604 | |||
605 | it('Should send a notification to video owner on blacklist', async function () { | ||
606 | this.timeout(10000) | ||
607 | |||
608 | const name = 'video for abuse ' + uuidv4() | ||
609 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) | ||
610 | const uuid = resVideo.body.video.uuid | ||
611 | |||
612 | await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid) | ||
613 | |||
614 | await waitJobs(servers) | ||
615 | await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'blacklist') | ||
616 | }) | ||
617 | |||
618 | it('Should send a notification to video owner on unblacklist', async function () { | ||
619 | this.timeout(10000) | ||
620 | |||
621 | const name = 'video for abuse ' + uuidv4() | ||
622 | const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name }) | ||
623 | const uuid = resVideo.body.video.uuid | ||
624 | |||
625 | await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid) | ||
626 | |||
627 | await waitJobs(servers) | ||
628 | await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid) | ||
629 | await waitJobs(servers) | ||
630 | |||
631 | await wait(500) | ||
632 | await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'unblacklist') | ||
633 | }) | ||
634 | }) | ||
635 | |||
636 | describe('My video is published', function () { | ||
637 | let baseParams: CheckerBaseParams | ||
638 | |||
639 | before(() => { | ||
640 | baseParams = { | ||
641 | server: servers[1], | ||
642 | emails, | ||
643 | socketNotifications: adminNotificationsServer2, | ||
644 | token: servers[1].accessToken | ||
645 | } | ||
646 | }) | ||
647 | |||
648 | it('Should not send a notification if transcoding is not enabled', async function () { | ||
649 | this.timeout(10000) | ||
650 | |||
651 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
652 | await waitJobs(servers) | ||
653 | |||
654 | await checkVideoIsPublished(baseParams, name, uuid, 'absence') | ||
655 | }) | ||
656 | |||
657 | it('Should not send a notification if the wait transcoding is false', async function () { | ||
658 | this.timeout(50000) | ||
659 | |||
660 | await uploadVideoByRemoteAccount(servers, { waitTranscoding: false }) | ||
661 | await waitJobs(servers) | ||
662 | |||
663 | const notification = await getLastNotification(servers[ 0 ].url, userAccessToken) | ||
664 | if (notification) { | ||
665 | expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED) | ||
666 | } | ||
667 | }) | ||
668 | |||
669 | it('Should send a notification even if the video is not transcoded in other resolutions', async function () { | ||
670 | this.timeout(50000) | ||
671 | |||
672 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true, fixture: 'video_short_240p.mp4' }) | ||
673 | await waitJobs(servers) | ||
674 | |||
675 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') | ||
676 | }) | ||
677 | |||
678 | it('Should send a notification with a transcoded video', async function () { | ||
679 | this.timeout(50000) | ||
680 | |||
681 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true }) | ||
682 | await waitJobs(servers) | ||
683 | |||
684 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') | ||
685 | }) | ||
686 | |||
687 | it('Should send a notification when an imported video is transcoded', async function () { | ||
688 | this.timeout(50000) | ||
689 | |||
690 | const name = 'video import ' + uuidv4() | ||
691 | |||
692 | const attributes = { | ||
693 | name, | ||
694 | channelId, | ||
695 | privacy: VideoPrivacy.PUBLIC, | ||
696 | targetUrl: getYoutubeVideoUrl(), | ||
697 | waitTranscoding: true | ||
698 | } | ||
699 | const res = await importVideo(servers[1].url, servers[1].accessToken, attributes) | ||
700 | const uuid = res.body.video.uuid | ||
701 | |||
702 | await waitJobs(servers) | ||
703 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') | ||
704 | }) | ||
705 | |||
706 | it('Should send a notification when the scheduled update has been proceeded', async function () { | ||
707 | this.timeout(70000) | ||
708 | |||
709 | // In 2 seconds | ||
710 | let updateAt = new Date(new Date().getTime() + 2000) | ||
711 | |||
712 | const data = { | ||
713 | privacy: VideoPrivacy.PRIVATE, | ||
714 | scheduleUpdate: { | ||
715 | updateAt: updateAt.toISOString(), | ||
716 | privacy: VideoPrivacy.PUBLIC | ||
717 | } | ||
718 | } | ||
719 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
720 | |||
721 | await wait(6000) | ||
722 | await checkVideoIsPublished(baseParams, name, uuid, 'presence') | ||
723 | }) | ||
724 | |||
725 | it('Should not send a notification before the video is published', async function () { | ||
726 | this.timeout(20000) | ||
727 | |||
728 | let updateAt = new Date(new Date().getTime() + 100000) | ||
729 | |||
730 | const data = { | ||
731 | privacy: VideoPrivacy.PRIVATE, | ||
732 | scheduleUpdate: { | ||
733 | updateAt: updateAt.toISOString(), | ||
734 | privacy: VideoPrivacy.PUBLIC | ||
735 | } | ||
736 | } | ||
737 | const { name, uuid } = await uploadVideoByRemoteAccount(servers, data) | ||
738 | |||
739 | await wait(6000) | ||
740 | await checkVideoIsPublished(baseParams, name, uuid, 'absence') | ||
741 | }) | ||
742 | }) | ||
743 | |||
744 | describe('My video is imported', function () { | ||
745 | let baseParams: CheckerBaseParams | ||
746 | |||
747 | before(() => { | ||
748 | baseParams = { | ||
749 | server: servers[0], | ||
750 | emails, | ||
751 | socketNotifications: adminNotifications, | ||
752 | token: servers[0].accessToken | ||
753 | } | ||
754 | }) | ||
755 | |||
756 | it('Should send a notification when the video import failed', async function () { | ||
757 | this.timeout(70000) | ||
758 | |||
759 | const name = 'video import ' + uuidv4() | ||
760 | |||
761 | const attributes = { | ||
762 | name, | ||
763 | channelId, | ||
764 | privacy: VideoPrivacy.PRIVATE, | ||
765 | targetUrl: getBadVideoUrl() | ||
766 | } | ||
767 | const res = await importVideo(servers[0].url, servers[0].accessToken, attributes) | ||
768 | const uuid = res.body.video.uuid | ||
769 | |||
770 | await waitJobs(servers) | ||
771 | await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence') | ||
772 | }) | ||
773 | |||
774 | it('Should send a notification when the video import succeeded', async function () { | ||
775 | this.timeout(70000) | ||
776 | |||
777 | const name = 'video import ' + uuidv4() | ||
778 | |||
779 | const attributes = { | ||
780 | name, | ||
781 | channelId, | ||
782 | privacy: VideoPrivacy.PRIVATE, | ||
783 | targetUrl: getYoutubeVideoUrl() | ||
784 | } | ||
785 | const res = await importVideo(servers[0].url, servers[0].accessToken, attributes) | ||
786 | const uuid = res.body.video.uuid | ||
787 | |||
788 | await waitJobs(servers) | ||
789 | await checkMyVideoImportIsFinished(baseParams, name, uuid, getYoutubeVideoUrl(), true, 'presence') | ||
790 | }) | ||
791 | }) | ||
792 | |||
793 | describe('New registration', function () { | ||
794 | let baseParams: CheckerBaseParams | ||
795 | |||
796 | before(() => { | ||
797 | baseParams = { | ||
798 | server: servers[0], | ||
799 | emails, | ||
800 | socketNotifications: adminNotifications, | ||
801 | token: servers[0].accessToken | ||
802 | } | ||
803 | }) | ||
804 | |||
805 | it('Should send a notification only to moderators when a user registers on the instance', async function () { | ||
806 | this.timeout(10000) | ||
807 | |||
808 | await registerUser(servers[0].url, 'user_45', 'password') | ||
809 | |||
810 | await waitJobs(servers) | ||
811 | |||
812 | await checkUserRegistered(baseParams, 'user_45', 'presence') | ||
813 | |||
814 | const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } } | ||
815 | await checkUserRegistered(immutableAssign(baseParams, userOverride), 'user_45', 'absence') | ||
816 | }) | ||
817 | }) | ||
818 | |||
819 | describe('New actor follow', function () { | ||
820 | let baseParams: CheckerBaseParams | ||
821 | let myChannelName = 'super channel name' | ||
822 | let myUserName = 'super user name' | ||
823 | |||
824 | before(async () => { | ||
825 | baseParams = { | ||
826 | server: servers[0], | ||
827 | emails, | ||
828 | socketNotifications: userNotifications, | ||
829 | token: userAccessToken | ||
830 | } | ||
831 | |||
832 | await updateMyUser({ | ||
833 | url: servers[0].url, | ||
834 | accessToken: servers[0].accessToken, | ||
835 | displayName: 'super root name' | ||
836 | }) | ||
837 | |||
838 | await updateMyUser({ | ||
839 | url: servers[0].url, | ||
840 | accessToken: userAccessToken, | ||
841 | displayName: myUserName | ||
842 | }) | ||
843 | |||
844 | await updateMyUser({ | ||
845 | url: servers[1].url, | ||
846 | accessToken: servers[1].accessToken, | ||
847 | displayName: 'super root 2 name' | ||
848 | }) | ||
849 | |||
850 | await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName }) | ||
851 | }) | ||
852 | |||
853 | it('Should notify when a local channel is following one of our channel', async function () { | ||
854 | this.timeout(10000) | ||
855 | |||
856 | await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001') | ||
857 | await waitJobs(servers) | ||
858 | |||
859 | await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence') | ||
860 | |||
861 | await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001') | ||
862 | }) | ||
863 | |||
864 | it('Should notify when a remote channel is following one of our channel', async function () { | ||
865 | this.timeout(10000) | ||
866 | |||
867 | await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001') | ||
868 | await waitJobs(servers) | ||
869 | |||
870 | await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence') | ||
871 | |||
872 | await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001') | ||
873 | }) | ||
874 | |||
875 | it('Should notify when a local account is following one of our channel', async function () { | ||
876 | this.timeout(10000) | ||
877 | |||
878 | await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001') | ||
879 | |||
880 | await waitJobs(servers) | ||
881 | |||
882 | await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence') | ||
883 | }) | ||
884 | |||
885 | it('Should notify when a remote account is following one of our channel', async function () { | ||
886 | this.timeout(10000) | ||
887 | |||
888 | await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001') | ||
889 | |||
890 | await waitJobs(servers) | ||
891 | |||
892 | await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence') | ||
893 | }) | ||
894 | }) | ||
895 | |||
896 | describe('Mark as read', function () { | ||
897 | it('Should mark as read some notifications', async function () { | ||
898 | const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3) | ||
899 | const ids = res.body.data.map(n => n.id) | ||
900 | |||
901 | await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids) | ||
902 | }) | ||
903 | |||
904 | it('Should have the notifications marked as read', async function () { | ||
905 | const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10) | ||
906 | |||
907 | const notifications = res.body.data as UserNotification[] | ||
908 | expect(notifications[ 0 ].read).to.be.false | ||
909 | expect(notifications[ 1 ].read).to.be.false | ||
910 | expect(notifications[ 2 ].read).to.be.true | ||
911 | expect(notifications[ 3 ].read).to.be.true | ||
912 | expect(notifications[ 4 ].read).to.be.true | ||
913 | expect(notifications[ 5 ].read).to.be.false | ||
914 | }) | ||
915 | |||
916 | it('Should only list read notifications', async function () { | ||
917 | const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false) | ||
918 | |||
919 | const notifications = res.body.data as UserNotification[] | ||
920 | for (const notification of notifications) { | ||
921 | expect(notification.read).to.be.true | ||
922 | } | ||
923 | }) | ||
924 | |||
925 | it('Should only list unread notifications', async function () { | ||
926 | const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true) | ||
927 | |||
928 | const notifications = res.body.data as UserNotification[] | ||
929 | for (const notification of notifications) { | ||
930 | expect(notification.read).to.be.false | ||
931 | } | ||
932 | }) | ||
933 | |||
934 | it('Should mark as read all notifications', async function () { | ||
935 | await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken) | ||
936 | |||
937 | const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true) | ||
938 | |||
939 | expect(res.body.total).to.equal(0) | ||
940 | expect(res.body.data).to.have.lengthOf(0) | ||
941 | }) | ||
942 | }) | ||
943 | |||
944 | describe('Notification settings', function () { | ||
945 | let baseParams: CheckerBaseParams | ||
946 | |||
947 | before(() => { | ||
948 | baseParams = { | ||
949 | server: servers[0], | ||
950 | emails, | ||
951 | socketNotifications: userNotifications, | ||
952 | token: userAccessToken | ||
953 | } | ||
954 | }) | ||
955 | |||
956 | it('Should not have notifications', async function () { | ||
957 | this.timeout(10000) | ||
958 | |||
959 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | ||
960 | newVideoFromSubscription: UserNotificationSettingValue.NONE | ||
961 | })) | ||
962 | |||
963 | { | ||
964 | const res = await getMyUserInformation(servers[0].url, userAccessToken) | ||
965 | const info = res.body as User | ||
966 | expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE) | ||
967 | } | ||
968 | |||
969 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
970 | |||
971 | const check = { web: true, mail: true } | ||
972 | await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence') | ||
973 | }) | ||
974 | |||
975 | it('Should only have web notifications', async function () { | ||
976 | this.timeout(10000) | ||
977 | |||
978 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | ||
979 | newVideoFromSubscription: UserNotificationSettingValue.WEB | ||
980 | })) | ||
981 | |||
982 | { | ||
983 | const res = await getMyUserInformation(servers[0].url, userAccessToken) | ||
984 | const info = res.body as User | ||
985 | expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB) | ||
986 | } | ||
987 | |||
988 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
989 | |||
990 | { | ||
991 | const check = { mail: true, web: false } | ||
992 | await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence') | ||
993 | } | ||
994 | |||
995 | { | ||
996 | const check = { mail: false, web: true } | ||
997 | await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence') | ||
998 | } | ||
999 | }) | ||
1000 | |||
1001 | it('Should only have mail notifications', async function () { | ||
1002 | this.timeout(10000) | ||
1003 | |||
1004 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | ||
1005 | newVideoFromSubscription: UserNotificationSettingValue.EMAIL | ||
1006 | })) | ||
1007 | |||
1008 | { | ||
1009 | const res = await getMyUserInformation(servers[0].url, userAccessToken) | ||
1010 | const info = res.body as User | ||
1011 | expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL) | ||
1012 | } | ||
1013 | |||
1014 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
1015 | |||
1016 | { | ||
1017 | const check = { mail: false, web: true } | ||
1018 | await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence') | ||
1019 | } | ||
1020 | |||
1021 | { | ||
1022 | const check = { mail: true, web: false } | ||
1023 | await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence') | ||
1024 | } | ||
1025 | }) | ||
1026 | |||
1027 | it('Should have email and web notifications', async function () { | ||
1028 | this.timeout(10000) | ||
1029 | |||
1030 | await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, { | ||
1031 | newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | ||
1032 | })) | ||
1033 | |||
1034 | { | ||
1035 | const res = await getMyUserInformation(servers[0].url, userAccessToken) | ||
1036 | const info = res.body as User | ||
1037 | expect(info.notificationSettings.newVideoFromSubscription).to.equal( | ||
1038 | UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL | ||
1039 | ) | ||
1040 | } | ||
1041 | |||
1042 | const { name, uuid } = await uploadVideoByLocalAccount(servers) | ||
1043 | |||
1044 | await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence') | ||
1045 | }) | ||
1046 | }) | ||
1047 | |||
1048 | after(async function () { | ||
1049 | MockSmtpServer.Instance.kill() | ||
1050 | |||
1051 | killallServers(servers) | ||
1052 | }) | ||
1053 | }) | ||