]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - shared/extra-utils/users/user-notifications.ts
Merge branch 'release/2.3.0' into develop
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / users / user-notifications.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import { expect } from 'chai'
4 import { inspect } from 'util'
5 import { UserNotification, UserNotificationSetting, UserNotificationSettingValue, UserNotificationType } from '../../models/users'
6 import { MockSmtpServer } from '../miscs/email'
7 import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
8 import { doubleFollow } from '../server/follows'
9 import { flushAndRunMultipleServers, ServerInfo } from '../server/servers'
10 import { getUserNotificationSocket } from '../socket/socket-io'
11 import { setAccessTokensToServers, userLogin } from './login'
12 import { createUser, getMyUserInformation } from './users'
13
14 function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) {
15 const path = '/api/v1/users/me/notification-settings'
16
17 return makePutBodyRequest({
18 url,
19 path,
20 token,
21 fields: settings,
22 statusCodeExpected
23 })
24 }
25
26 async function getUserNotifications (
27 url: string,
28 token: string,
29 start: number,
30 count: number,
31 unread?: boolean,
32 sort = '-createdAt',
33 statusCodeExpected = 200
34 ) {
35 const path = '/api/v1/users/me/notifications'
36
37 return makeGetRequest({
38 url,
39 path,
40 token,
41 query: {
42 start,
43 count,
44 sort,
45 unread
46 },
47 statusCodeExpected
48 })
49 }
50
51 function markAsReadNotifications (url: string, token: string, ids: number[], statusCodeExpected = 204) {
52 const path = '/api/v1/users/me/notifications/read'
53
54 return makePostBodyRequest({
55 url,
56 path,
57 token,
58 fields: { ids },
59 statusCodeExpected
60 })
61 }
62
63 function markAsReadAllNotifications (url: string, token: string, statusCodeExpected = 204) {
64 const path = '/api/v1/users/me/notifications/read-all'
65
66 return makePostBodyRequest({
67 url,
68 path,
69 token,
70 statusCodeExpected
71 })
72 }
73
74 async function getLastNotification (serverUrl: string, accessToken: string) {
75 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, undefined, '-createdAt')
76
77 if (res.body.total === 0) return undefined
78
79 return res.body.data[0] as UserNotification
80 }
81
82 type CheckerBaseParams = {
83 server: ServerInfo
84 emails: any[]
85 socketNotifications: UserNotification[]
86 token: string
87 check?: { web: boolean, mail: boolean }
88 }
89
90 type CheckerType = 'presence' | 'absence'
91
92 async function checkNotification (
93 base: CheckerBaseParams,
94 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
95 emailNotificationFinder: (email: object) => boolean,
96 checkType: CheckerType
97 ) {
98 const check = base.check || { web: true, mail: true }
99
100 if (check.web) {
101 const notification = await getLastNotification(base.server.url, base.token)
102
103 if (notification || checkType !== 'absence') {
104 notificationChecker(notification, checkType)
105 }
106
107 const socketNotification = base.socketNotifications.find(n => {
108 try {
109 notificationChecker(n, 'presence')
110 return true
111 } catch {
112 return false
113 }
114 })
115
116 if (checkType === 'presence') {
117 const obj = inspect(base.socketNotifications, { depth: 5 })
118 expect(socketNotification, 'The socket notification is absent when it should be present. ' + obj).to.not.be.undefined
119 } else {
120 const obj = inspect(socketNotification, { depth: 5 })
121 expect(socketNotification, 'The socket notification is present when it should not be present. ' + obj).to.be.undefined
122 }
123 }
124
125 if (check.mail) {
126 // Last email
127 const email = base.emails
128 .slice()
129 .reverse()
130 .find(e => emailNotificationFinder(e))
131
132 if (checkType === 'presence') {
133 const emails = base.emails.map(e => e.text)
134 expect(email, 'The email is absent when is should be present. ' + inspect(emails)).to.not.be.undefined
135 } else {
136 expect(email, 'The email is present when is should not be present. ' + inspect(email)).to.be.undefined
137 }
138 }
139 }
140
141 function checkVideo (video: any, videoName?: string, videoUUID?: string) {
142 if (videoName) {
143 expect(video.name).to.be.a('string')
144 expect(video.name).to.not.be.empty
145 expect(video.name).to.equal(videoName)
146 }
147
148 if (videoUUID) {
149 expect(video.uuid).to.be.a('string')
150 expect(video.uuid).to.not.be.empty
151 expect(video.uuid).to.equal(videoUUID)
152 }
153
154 expect(video.id).to.be.a('number')
155 }
156
157 function checkActor (actor: any) {
158 expect(actor.displayName).to.be.a('string')
159 expect(actor.displayName).to.not.be.empty
160 expect(actor.host).to.not.be.undefined
161 }
162
163 function checkComment (comment: any, commentId: number, threadId: number) {
164 expect(comment.id).to.equal(commentId)
165 expect(comment.threadId).to.equal(threadId)
166 }
167
168 async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
169 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
170
171 function notificationChecker (notification: UserNotification, type: CheckerType) {
172 if (type === 'presence') {
173 expect(notification).to.not.be.undefined
174 expect(notification.type).to.equal(notificationType)
175
176 checkVideo(notification.video, videoName, videoUUID)
177 checkActor(notification.video.channel)
178 } else {
179 expect(notification).to.satisfy((n: UserNotification) => {
180 return n === undefined || n.type !== UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION || n.video.name !== videoName
181 })
182 }
183 }
184
185 function emailNotificationFinder (email: object) {
186 const text = email['text']
187 return text.indexOf(videoUUID) !== -1 && text.indexOf('Your subscription') !== -1
188 }
189
190 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
191 }
192
193 async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
194 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
195
196 function notificationChecker (notification: UserNotification, type: CheckerType) {
197 if (type === 'presence') {
198 expect(notification).to.not.be.undefined
199 expect(notification.type).to.equal(notificationType)
200
201 checkVideo(notification.video, videoName, videoUUID)
202 checkActor(notification.video.channel)
203 } else {
204 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
205 }
206 }
207
208 function emailNotificationFinder (email: object) {
209 const text: string = email['text']
210 return text.includes(videoUUID) && text.includes('Your video')
211 }
212
213 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
214 }
215
216 async function checkMyVideoImportIsFinished (
217 base: CheckerBaseParams,
218 videoName: string,
219 videoUUID: string,
220 url: string,
221 success: boolean,
222 type: CheckerType
223 ) {
224 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
225
226 function notificationChecker (notification: UserNotification, type: CheckerType) {
227 if (type === 'presence') {
228 expect(notification).to.not.be.undefined
229 expect(notification.type).to.equal(notificationType)
230
231 expect(notification.videoImport.targetUrl).to.equal(url)
232
233 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID)
234 } else {
235 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
236 }
237 }
238
239 function emailNotificationFinder (email: object) {
240 const text: string = email['text']
241 const toFind = success ? ' finished' : ' error'
242
243 return text.includes(url) && text.includes(toFind)
244 }
245
246 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
247 }
248
249 async function checkUserRegistered (base: CheckerBaseParams, username: string, type: CheckerType) {
250 const notificationType = UserNotificationType.NEW_USER_REGISTRATION
251
252 function notificationChecker (notification: UserNotification, type: CheckerType) {
253 if (type === 'presence') {
254 expect(notification).to.not.be.undefined
255 expect(notification.type).to.equal(notificationType)
256
257 checkActor(notification.account)
258 expect(notification.account.name).to.equal(username)
259 } else {
260 expect(notification).to.satisfy(n => n.type !== notificationType || n.account.name !== username)
261 }
262 }
263
264 function emailNotificationFinder (email: object) {
265 const text: string = email['text']
266
267 return text.includes(' registered.') && text.includes(username)
268 }
269
270 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
271 }
272
273 async function checkNewActorFollow (
274 base: CheckerBaseParams,
275 followType: 'channel' | 'account',
276 followerName: string,
277 followerDisplayName: string,
278 followingDisplayName: string,
279 type: CheckerType
280 ) {
281 const notificationType = UserNotificationType.NEW_FOLLOW
282
283 function notificationChecker (notification: UserNotification, type: CheckerType) {
284 if (type === 'presence') {
285 expect(notification).to.not.be.undefined
286 expect(notification.type).to.equal(notificationType)
287
288 checkActor(notification.actorFollow.follower)
289 expect(notification.actorFollow.follower.displayName).to.equal(followerDisplayName)
290 expect(notification.actorFollow.follower.name).to.equal(followerName)
291 expect(notification.actorFollow.follower.host).to.not.be.undefined
292
293 const following = notification.actorFollow.following
294 expect(following.displayName).to.equal(followingDisplayName)
295 expect(following.type).to.equal(followType)
296 } else {
297 expect(notification).to.satisfy(n => {
298 return n.type !== notificationType ||
299 (n.actorFollow.follower.name !== followerName && n.actorFollow.following !== followingDisplayName)
300 })
301 }
302 }
303
304 function emailNotificationFinder (email: object) {
305 const text: string = email['text']
306
307 return text.includes(followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
308 }
309
310 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
311 }
312
313 async function checkNewInstanceFollower (base: CheckerBaseParams, followerHost: string, type: CheckerType) {
314 const notificationType = UserNotificationType.NEW_INSTANCE_FOLLOWER
315
316 function notificationChecker (notification: UserNotification, type: CheckerType) {
317 if (type === 'presence') {
318 expect(notification).to.not.be.undefined
319 expect(notification.type).to.equal(notificationType)
320
321 checkActor(notification.actorFollow.follower)
322 expect(notification.actorFollow.follower.name).to.equal('peertube')
323 expect(notification.actorFollow.follower.host).to.equal(followerHost)
324
325 expect(notification.actorFollow.following.name).to.equal('peertube')
326 } else {
327 expect(notification).to.satisfy(n => {
328 return n.type !== notificationType || n.actorFollow.follower.host !== followerHost
329 })
330 }
331 }
332
333 function emailNotificationFinder (email: object) {
334 const text: string = email['text']
335
336 return text.includes('instance has a new follower') && text.includes(followerHost)
337 }
338
339 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
340 }
341
342 async function checkAutoInstanceFollowing (base: CheckerBaseParams, followerHost: string, followingHost: string, type: CheckerType) {
343 const notificationType = UserNotificationType.AUTO_INSTANCE_FOLLOWING
344
345 function notificationChecker (notification: UserNotification, type: CheckerType) {
346 if (type === 'presence') {
347 expect(notification).to.not.be.undefined
348 expect(notification.type).to.equal(notificationType)
349
350 const following = notification.actorFollow.following
351 checkActor(following)
352 expect(following.name).to.equal('peertube')
353 expect(following.host).to.equal(followingHost)
354
355 expect(notification.actorFollow.follower.name).to.equal('peertube')
356 expect(notification.actorFollow.follower.host).to.equal(followerHost)
357 } else {
358 expect(notification).to.satisfy(n => {
359 return n.type !== notificationType || n.actorFollow.following.host !== followingHost
360 })
361 }
362 }
363
364 function emailNotificationFinder (email: object) {
365 const text: string = email['text']
366
367 return text.includes(' automatically followed a new instance') && text.includes(followingHost)
368 }
369
370 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
371 }
372
373 async function checkCommentMention (
374 base: CheckerBaseParams,
375 uuid: string,
376 commentId: number,
377 threadId: number,
378 byAccountDisplayName: string,
379 type: CheckerType
380 ) {
381 const notificationType = UserNotificationType.COMMENT_MENTION
382
383 function notificationChecker (notification: UserNotification, type: CheckerType) {
384 if (type === 'presence') {
385 expect(notification).to.not.be.undefined
386 expect(notification.type).to.equal(notificationType)
387
388 checkComment(notification.comment, commentId, threadId)
389 checkActor(notification.comment.account)
390 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName)
391
392 checkVideo(notification.comment.video, undefined, uuid)
393 } else {
394 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId)
395 }
396 }
397
398 function emailNotificationFinder (email: object) {
399 const text: string = email['text']
400
401 return text.includes(' mentioned ') && text.includes(uuid) && text.includes(byAccountDisplayName)
402 }
403
404 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
405 }
406
407 let lastEmailCount = 0
408
409 async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) {
410 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
411
412 function notificationChecker (notification: UserNotification, type: CheckerType) {
413 if (type === 'presence') {
414 expect(notification).to.not.be.undefined
415 expect(notification.type).to.equal(notificationType)
416
417 checkComment(notification.comment, commentId, threadId)
418 checkActor(notification.comment.account)
419 checkVideo(notification.comment.video, undefined, uuid)
420 } else {
421 expect(notification).to.satisfy((n: UserNotification) => {
422 return n === undefined || n.comment === undefined || n.comment.id !== commentId
423 })
424 }
425 }
426
427 const commentUrl = `http://localhost:${base.server.port}/videos/watch/${uuid};threadId=${threadId}`
428
429 function emailNotificationFinder (email: object) {
430 return email['text'].indexOf(commentUrl) !== -1
431 }
432
433 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
434
435 if (type === 'presence') {
436 // We cannot detect email duplicates, so check we received another email
437 expect(base.emails).to.have.length.above(lastEmailCount)
438 lastEmailCount = base.emails.length
439 }
440 }
441
442 async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
443 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
444
445 function notificationChecker (notification: UserNotification, type: CheckerType) {
446 if (type === 'presence') {
447 expect(notification).to.not.be.undefined
448 expect(notification.type).to.equal(notificationType)
449
450 expect(notification.abuse.id).to.be.a('number')
451 checkVideo(notification.abuse.video, videoName, videoUUID)
452 } else {
453 expect(notification).to.satisfy((n: UserNotification) => {
454 return n === undefined || n.abuse === undefined || n.abuse.video.uuid !== videoUUID
455 })
456 }
457 }
458
459 function emailNotificationFinder (email: object) {
460 const text = email['text']
461 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
462 }
463
464 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
465 }
466
467 async function checkNewCommentAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
468 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
469
470 function notificationChecker (notification: UserNotification, type: CheckerType) {
471 if (type === 'presence') {
472 expect(notification).to.not.be.undefined
473 expect(notification.type).to.equal(notificationType)
474
475 expect(notification.abuse.id).to.be.a('number')
476 checkVideo(notification.abuse.comment.video, videoName, videoUUID)
477 } else {
478 expect(notification).to.satisfy((n: UserNotification) => {
479 return n === undefined || n.abuse === undefined || n.abuse.comment.video.uuid !== videoUUID
480 })
481 }
482 }
483
484 function emailNotificationFinder (email: object) {
485 const text = email['text']
486 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
487 }
488
489 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
490 }
491
492 async function checkNewAccountAbuseForModerators (base: CheckerBaseParams, displayName: string, type: CheckerType) {
493 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
494
495 function notificationChecker (notification: UserNotification, type: CheckerType) {
496 if (type === 'presence') {
497 expect(notification).to.not.be.undefined
498 expect(notification.type).to.equal(notificationType)
499
500 expect(notification.abuse.id).to.be.a('number')
501 expect(notification.abuse.account.displayName).to.equal(displayName)
502 } else {
503 expect(notification).to.satisfy((n: UserNotification) => {
504 return n === undefined || n.abuse === undefined || n.abuse.account.displayName !== displayName
505 })
506 }
507 }
508
509 function emailNotificationFinder (email: object) {
510 const text = email['text']
511 return text.indexOf(displayName) !== -1 && text.indexOf('abuse') !== -1
512 }
513
514 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
515 }
516
517 async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
518 const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS
519
520 function notificationChecker (notification: UserNotification, type: CheckerType) {
521 if (type === 'presence') {
522 expect(notification).to.not.be.undefined
523 expect(notification.type).to.equal(notificationType)
524
525 expect(notification.videoBlacklist.video.id).to.be.a('number')
526 checkVideo(notification.videoBlacklist.video, videoName, videoUUID)
527 } else {
528 expect(notification).to.satisfy((n: UserNotification) => {
529 return n === undefined || n.video === undefined || n.video.uuid !== videoUUID
530 })
531 }
532 }
533
534 function emailNotificationFinder (email: object) {
535 const text = email['text']
536 return text.indexOf(videoUUID) !== -1 && email['text'].indexOf('video-auto-blacklist/list') !== -1
537 }
538
539 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
540 }
541
542 async function checkNewBlacklistOnMyVideo (
543 base: CheckerBaseParams,
544 videoUUID: string,
545 videoName: string,
546 blacklistType: 'blacklist' | 'unblacklist'
547 ) {
548 const notificationType = blacklistType === 'blacklist'
549 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
550 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
551
552 function notificationChecker (notification: UserNotification) {
553 expect(notification).to.not.be.undefined
554 expect(notification.type).to.equal(notificationType)
555
556 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
557
558 checkVideo(video, videoName, videoUUID)
559 }
560
561 function emailNotificationFinder (email: object) {
562 const text = email['text']
563 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
564 }
565
566 await checkNotification(base, notificationChecker, emailNotificationFinder, 'presence')
567 }
568
569 function getAllNotificationsSettings () {
570 return {
571 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
572 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
573 abuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
574 videoAutoBlacklistAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
575 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
576 myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
577 myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
578 commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
579 newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
580 newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
581 newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
582 autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
583 } as UserNotificationSetting
584 }
585
586 async function prepareNotificationsTest (serversCount = 3) {
587 const userNotifications: UserNotification[] = []
588 const adminNotifications: UserNotification[] = []
589 const adminNotificationsServer2: UserNotification[] = []
590 const emails: object[] = []
591
592 const port = await MockSmtpServer.Instance.collectEmails(emails)
593
594 const overrideConfig = {
595 smtp: {
596 hostname: 'localhost',
597 port
598 },
599 signup: {
600 limit: 20
601 }
602 }
603 const servers = await flushAndRunMultipleServers(serversCount, overrideConfig)
604
605 await setAccessTokensToServers(servers)
606
607 if (serversCount > 1) {
608 await doubleFollow(servers[0], servers[1])
609 }
610
611 const user = {
612 username: 'user_1',
613 password: 'super password'
614 }
615 await createUser({
616 url: servers[0].url,
617 accessToken: servers[0].accessToken,
618 username: user.username,
619 password: user.password,
620 videoQuota: 10 * 1000 * 1000
621 })
622 const userAccessToken = await userLogin(servers[0], user)
623
624 await updateMyNotificationSettings(servers[0].url, userAccessToken, getAllNotificationsSettings())
625 await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, getAllNotificationsSettings())
626
627 if (serversCount > 1) {
628 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, getAllNotificationsSettings())
629 }
630
631 {
632 const socket = getUserNotificationSocket(servers[0].url, userAccessToken)
633 socket.on('new-notification', n => userNotifications.push(n))
634 }
635 {
636 const socket = getUserNotificationSocket(servers[0].url, servers[0].accessToken)
637 socket.on('new-notification', n => adminNotifications.push(n))
638 }
639
640 if (serversCount > 1) {
641 const socket = getUserNotificationSocket(servers[1].url, servers[1].accessToken)
642 socket.on('new-notification', n => adminNotificationsServer2.push(n))
643 }
644
645 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
646 const channelId = resChannel.body.videoChannels[0].id
647
648 return {
649 userNotifications,
650 adminNotifications,
651 adminNotificationsServer2,
652 userAccessToken,
653 emails,
654 servers,
655 channelId
656 }
657 }
658
659 // ---------------------------------------------------------------------------
660
661 export {
662 CheckerBaseParams,
663 CheckerType,
664 getAllNotificationsSettings,
665 checkNotification,
666 markAsReadAllNotifications,
667 checkMyVideoImportIsFinished,
668 checkUserRegistered,
669 checkAutoInstanceFollowing,
670 checkVideoIsPublished,
671 checkNewVideoFromSubscription,
672 checkNewActorFollow,
673 checkNewCommentOnMyVideo,
674 checkNewBlacklistOnMyVideo,
675 checkCommentMention,
676 updateMyNotificationSettings,
677 checkNewVideoAbuseForModerators,
678 checkVideoAutoBlacklistForModerators,
679 getUserNotifications,
680 markAsReadNotifications,
681 getLastNotification,
682 checkNewInstanceFollower,
683 prepareNotificationsTest,
684 checkNewCommentAbuseForModerators,
685 checkNewAccountAbuseForModerators
686 }