]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/shared/notifications.ts
Remove low timeouts
[github/Chocobozzz/PeerTube.git] / server / tests / shared / 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 {
6 AbuseState,
7 PluginType,
8 UserNotification,
9 UserNotificationSetting,
10 UserNotificationSettingValue,
11 UserNotificationType
12 } from '@shared/models'
13 import {
14 ConfigCommand,
15 createMultipleServers,
16 doubleFollow,
17 PeerTubeServer,
18 setAccessTokensToServers,
19 setDefaultAccountAvatar,
20 setDefaultChannelAvatar,
21 setDefaultVideoChannel
22 } from '@shared/server-commands'
23 import { MockSmtpServer } from './mock-servers'
24
25 type CheckerBaseParams = {
26 server: PeerTubeServer
27 emails: any[]
28 socketNotifications: UserNotification[]
29 token: string
30 check?: { web: boolean, mail: boolean }
31 }
32
33 type CheckerType = 'presence' | 'absence'
34
35 function getAllNotificationsSettings (): UserNotificationSetting {
36 return {
37 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
38 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
39 abuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
40 videoAutoBlacklistAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
41 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
42 myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
43 myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
44 commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
45 newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
46 newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
47 newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
48 abuseNewMessage: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
49 abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
50 autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
51 newPeerTubeVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
52 myVideoStudioEditionFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
53 newPluginVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
54 }
55 }
56
57 async function checkNewVideoFromSubscription (options: CheckerBaseParams & {
58 videoName: string
59 shortUUID: string
60 checkType: CheckerType
61 }) {
62 const { videoName, shortUUID } = options
63 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
64
65 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
66 if (checkType === 'presence') {
67 expect(notification).to.not.be.undefined
68 expect(notification.type).to.equal(notificationType)
69
70 checkVideo(notification.video, videoName, shortUUID)
71 checkActor(notification.video.channel)
72 } else {
73 expect(notification).to.satisfy((n: UserNotification) => {
74 return n === undefined || n.type !== UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION || n.video.name !== videoName
75 })
76 }
77 }
78
79 function emailNotificationFinder (email: object) {
80 const text = email['text']
81 return text.indexOf(shortUUID) !== -1 && text.indexOf('Your subscription') !== -1
82 }
83
84 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
85 }
86
87 async function checkVideoIsPublished (options: CheckerBaseParams & {
88 videoName: string
89 shortUUID: string
90 checkType: CheckerType
91 }) {
92 const { videoName, shortUUID } = options
93 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
94
95 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
96 if (checkType === 'presence') {
97 expect(notification).to.not.be.undefined
98 expect(notification.type).to.equal(notificationType)
99
100 checkVideo(notification.video, videoName, shortUUID)
101 checkActor(notification.video.channel)
102 } else {
103 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
104 }
105 }
106
107 function emailNotificationFinder (email: object) {
108 const text: string = email['text']
109 return text.includes(shortUUID) && text.includes('Your video')
110 }
111
112 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
113 }
114
115 async function checkVideoStudioEditionIsFinished (options: CheckerBaseParams & {
116 videoName: string
117 shortUUID: string
118 checkType: CheckerType
119 }) {
120 const { videoName, shortUUID } = options
121 const notificationType = UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED
122
123 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
124 if (checkType === 'presence') {
125 expect(notification).to.not.be.undefined
126 expect(notification.type).to.equal(notificationType)
127
128 checkVideo(notification.video, videoName, shortUUID)
129 checkActor(notification.video.channel)
130 } else {
131 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
132 }
133 }
134
135 function emailNotificationFinder (email: object) {
136 const text: string = email['text']
137 return text.includes(shortUUID) && text.includes('Edition of your video')
138 }
139
140 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
141 }
142
143 async function checkMyVideoImportIsFinished (options: CheckerBaseParams & {
144 videoName: string
145 shortUUID: string
146 url: string
147 success: boolean
148 checkType: CheckerType
149 }) {
150 const { videoName, shortUUID, url, success } = options
151
152 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
153
154 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
155 if (checkType === 'presence') {
156 expect(notification).to.not.be.undefined
157 expect(notification.type).to.equal(notificationType)
158
159 expect(notification.videoImport.targetUrl).to.equal(url)
160
161 if (success) checkVideo(notification.videoImport.video, videoName, shortUUID)
162 } else {
163 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
164 }
165 }
166
167 function emailNotificationFinder (email: object) {
168 const text: string = email['text']
169 const toFind = success ? ' finished' : ' error'
170
171 return text.includes(url) && text.includes(toFind)
172 }
173
174 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
175 }
176
177 // ---------------------------------------------------------------------------
178
179 async function checkUserRegistered (options: CheckerBaseParams & {
180 username: string
181 checkType: CheckerType
182 }) {
183 const { username } = options
184 const notificationType = UserNotificationType.NEW_USER_REGISTRATION
185
186 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
187 if (checkType === 'presence') {
188 expect(notification).to.not.be.undefined
189 expect(notification.type).to.equal(notificationType)
190
191 checkActor(notification.account, { withAvatar: false })
192 expect(notification.account.name).to.equal(username)
193 } else {
194 expect(notification).to.satisfy(n => n.type !== notificationType || n.account.name !== username)
195 }
196 }
197
198 function emailNotificationFinder (email: object) {
199 const text: string = email['text']
200
201 return text.includes(' registered.') && text.includes(username)
202 }
203
204 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
205 }
206
207 async function checkRegistrationRequest (options: CheckerBaseParams & {
208 username: string
209 registrationReason: string
210 checkType: CheckerType
211 }) {
212 const { username, registrationReason } = options
213 const notificationType = UserNotificationType.NEW_USER_REGISTRATION_REQUEST
214
215 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
216 if (checkType === 'presence') {
217 expect(notification).to.not.be.undefined
218 expect(notification.type).to.equal(notificationType)
219
220 expect(notification.registration.username).to.equal(username)
221 } else {
222 expect(notification).to.satisfy(n => n.type !== notificationType || n.registration.username !== username)
223 }
224 }
225
226 function emailNotificationFinder (email: object) {
227 const text: string = email['text']
228
229 return text.includes(' wants to register ') && text.includes(username) && text.includes(registrationReason)
230 }
231
232 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
233 }
234
235 // ---------------------------------------------------------------------------
236
237 async function checkNewActorFollow (options: CheckerBaseParams & {
238 followType: 'channel' | 'account'
239 followerName: string
240 followerDisplayName: string
241 followingDisplayName: string
242 checkType: CheckerType
243 }) {
244 const { followType, followerName, followerDisplayName, followingDisplayName } = options
245 const notificationType = UserNotificationType.NEW_FOLLOW
246
247 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
248 if (checkType === 'presence') {
249 expect(notification).to.not.be.undefined
250 expect(notification.type).to.equal(notificationType)
251
252 checkActor(notification.actorFollow.follower)
253 expect(notification.actorFollow.follower.displayName).to.equal(followerDisplayName)
254 expect(notification.actorFollow.follower.name).to.equal(followerName)
255 expect(notification.actorFollow.follower.host).to.not.be.undefined
256
257 const following = notification.actorFollow.following
258 expect(following.displayName).to.equal(followingDisplayName)
259 expect(following.type).to.equal(followType)
260 } else {
261 expect(notification).to.satisfy(n => {
262 return n.type !== notificationType ||
263 (n.actorFollow.follower.name !== followerName && n.actorFollow.following !== followingDisplayName)
264 })
265 }
266 }
267
268 function emailNotificationFinder (email: object) {
269 const text: string = email['text']
270
271 return text.includes(followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
272 }
273
274 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
275 }
276
277 async function checkNewInstanceFollower (options: CheckerBaseParams & {
278 followerHost: string
279 checkType: CheckerType
280 }) {
281 const { followerHost } = options
282 const notificationType = UserNotificationType.NEW_INSTANCE_FOLLOWER
283
284 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
285 if (checkType === 'presence') {
286 expect(notification).to.not.be.undefined
287 expect(notification.type).to.equal(notificationType)
288
289 checkActor(notification.actorFollow.follower, { withAvatar: false })
290 expect(notification.actorFollow.follower.name).to.equal('peertube')
291 expect(notification.actorFollow.follower.host).to.equal(followerHost)
292
293 expect(notification.actorFollow.following.name).to.equal('peertube')
294 } else {
295 expect(notification).to.satisfy(n => {
296 return n.type !== notificationType || n.actorFollow.follower.host !== followerHost
297 })
298 }
299 }
300
301 function emailNotificationFinder (email: object) {
302 const text: string = email['text']
303
304 return text.includes('instance has a new follower') && text.includes(followerHost)
305 }
306
307 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
308 }
309
310 async function checkAutoInstanceFollowing (options: CheckerBaseParams & {
311 followerHost: string
312 followingHost: string
313 checkType: CheckerType
314 }) {
315 const { followerHost, followingHost } = options
316 const notificationType = UserNotificationType.AUTO_INSTANCE_FOLLOWING
317
318 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
319 if (checkType === 'presence') {
320 expect(notification).to.not.be.undefined
321 expect(notification.type).to.equal(notificationType)
322
323 const following = notification.actorFollow.following
324
325 checkActor(following, { withAvatar: false })
326 expect(following.name).to.equal('peertube')
327 expect(following.host).to.equal(followingHost)
328
329 expect(notification.actorFollow.follower.name).to.equal('peertube')
330 expect(notification.actorFollow.follower.host).to.equal(followerHost)
331 } else {
332 expect(notification).to.satisfy(n => {
333 return n.type !== notificationType || n.actorFollow.following.host !== followingHost
334 })
335 }
336 }
337
338 function emailNotificationFinder (email: object) {
339 const text: string = email['text']
340
341 return text.includes(' automatically followed a new instance') && text.includes(followingHost)
342 }
343
344 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
345 }
346
347 async function checkCommentMention (options: CheckerBaseParams & {
348 shortUUID: string
349 commentId: number
350 threadId: number
351 byAccountDisplayName: string
352 checkType: CheckerType
353 }) {
354 const { shortUUID, commentId, threadId, byAccountDisplayName } = options
355 const notificationType = UserNotificationType.COMMENT_MENTION
356
357 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
358 if (checkType === 'presence') {
359 expect(notification).to.not.be.undefined
360 expect(notification.type).to.equal(notificationType)
361
362 checkComment(notification.comment, commentId, threadId)
363 checkActor(notification.comment.account)
364 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName)
365
366 checkVideo(notification.comment.video, undefined, shortUUID)
367 } else {
368 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId)
369 }
370 }
371
372 function emailNotificationFinder (email: object) {
373 const text: string = email['text']
374
375 return text.includes(' mentioned ') && text.includes(shortUUID) && text.includes(byAccountDisplayName)
376 }
377
378 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
379 }
380
381 let lastEmailCount = 0
382
383 async function checkNewCommentOnMyVideo (options: CheckerBaseParams & {
384 shortUUID: string
385 commentId: number
386 threadId: number
387 checkType: CheckerType
388 }) {
389 const { server, shortUUID, commentId, threadId, checkType, emails } = options
390 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
391
392 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
393 if (checkType === 'presence') {
394 expect(notification).to.not.be.undefined
395 expect(notification.type).to.equal(notificationType)
396
397 checkComment(notification.comment, commentId, threadId)
398 checkActor(notification.comment.account)
399 checkVideo(notification.comment.video, undefined, shortUUID)
400 } else {
401 expect(notification).to.satisfy((n: UserNotification) => {
402 return n === undefined || n.comment === undefined || n.comment.id !== commentId
403 })
404 }
405 }
406
407 const commentUrl = `${server.url}/w/${shortUUID};threadId=${threadId}`
408
409 function emailNotificationFinder (email: object) {
410 return email['text'].indexOf(commentUrl) !== -1
411 }
412
413 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
414
415 if (checkType === 'presence') {
416 // We cannot detect email duplicates, so check we received another email
417 expect(emails).to.have.length.above(lastEmailCount)
418 lastEmailCount = emails.length
419 }
420 }
421
422 async function checkNewVideoAbuseForModerators (options: CheckerBaseParams & {
423 shortUUID: string
424 videoName: string
425 checkType: CheckerType
426 }) {
427 const { shortUUID, videoName } = options
428 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
429
430 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
431 if (checkType === 'presence') {
432 expect(notification).to.not.be.undefined
433 expect(notification.type).to.equal(notificationType)
434
435 expect(notification.abuse.id).to.be.a('number')
436 checkVideo(notification.abuse.video, videoName, shortUUID)
437 } else {
438 expect(notification).to.satisfy((n: UserNotification) => {
439 return n === undefined || n.abuse === undefined || n.abuse.video.shortUUID !== shortUUID
440 })
441 }
442 }
443
444 function emailNotificationFinder (email: object) {
445 const text = email['text']
446 return text.indexOf(shortUUID) !== -1 && text.indexOf('abuse') !== -1
447 }
448
449 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
450 }
451
452 async function checkNewAbuseMessage (options: CheckerBaseParams & {
453 abuseId: number
454 message: string
455 toEmail: string
456 checkType: CheckerType
457 }) {
458 const { abuseId, message, toEmail } = options
459 const notificationType = UserNotificationType.ABUSE_NEW_MESSAGE
460
461 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
462 if (checkType === 'presence') {
463 expect(notification).to.not.be.undefined
464 expect(notification.type).to.equal(notificationType)
465
466 expect(notification.abuse.id).to.equal(abuseId)
467 } else {
468 expect(notification).to.satisfy((n: UserNotification) => {
469 return n === undefined || n.type !== notificationType || n.abuse === undefined || n.abuse.id !== abuseId
470 })
471 }
472 }
473
474 function emailNotificationFinder (email: object) {
475 const text = email['text']
476 const to = email['to'].filter(t => t.address === toEmail)
477
478 return text.indexOf(message) !== -1 && to.length !== 0
479 }
480
481 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
482 }
483
484 async function checkAbuseStateChange (options: CheckerBaseParams & {
485 abuseId: number
486 state: AbuseState
487 checkType: CheckerType
488 }) {
489 const { abuseId, state } = options
490 const notificationType = UserNotificationType.ABUSE_STATE_CHANGE
491
492 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
493 if (checkType === 'presence') {
494 expect(notification).to.not.be.undefined
495 expect(notification.type).to.equal(notificationType)
496
497 expect(notification.abuse.id).to.equal(abuseId)
498 expect(notification.abuse.state).to.equal(state)
499 } else {
500 expect(notification).to.satisfy((n: UserNotification) => {
501 return n === undefined || n.abuse === undefined || n.abuse.id !== abuseId
502 })
503 }
504 }
505
506 function emailNotificationFinder (email: object) {
507 const text = email['text']
508
509 const contains = state === AbuseState.ACCEPTED
510 ? ' accepted'
511 : ' rejected'
512
513 return text.indexOf(contains) !== -1
514 }
515
516 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
517 }
518
519 async function checkNewCommentAbuseForModerators (options: CheckerBaseParams & {
520 shortUUID: string
521 videoName: string
522 checkType: CheckerType
523 }) {
524 const { shortUUID, videoName } = options
525 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
526
527 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
528 if (checkType === 'presence') {
529 expect(notification).to.not.be.undefined
530 expect(notification.type).to.equal(notificationType)
531
532 expect(notification.abuse.id).to.be.a('number')
533 checkVideo(notification.abuse.comment.video, videoName, shortUUID)
534 } else {
535 expect(notification).to.satisfy((n: UserNotification) => {
536 return n === undefined || n.abuse === undefined || n.abuse.comment.video.shortUUID !== shortUUID
537 })
538 }
539 }
540
541 function emailNotificationFinder (email: object) {
542 const text = email['text']
543 return text.indexOf(shortUUID) !== -1 && text.indexOf('abuse') !== -1
544 }
545
546 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
547 }
548
549 async function checkNewAccountAbuseForModerators (options: CheckerBaseParams & {
550 displayName: string
551 checkType: CheckerType
552 }) {
553 const { displayName } = options
554 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
555
556 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
557 if (checkType === 'presence') {
558 expect(notification).to.not.be.undefined
559 expect(notification.type).to.equal(notificationType)
560
561 expect(notification.abuse.id).to.be.a('number')
562 expect(notification.abuse.account.displayName).to.equal(displayName)
563 } else {
564 expect(notification).to.satisfy((n: UserNotification) => {
565 return n === undefined || n.abuse === undefined || n.abuse.account.displayName !== displayName
566 })
567 }
568 }
569
570 function emailNotificationFinder (email: object) {
571 const text = email['text']
572 return text.indexOf(displayName) !== -1 && text.indexOf('abuse') !== -1
573 }
574
575 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
576 }
577
578 async function checkVideoAutoBlacklistForModerators (options: CheckerBaseParams & {
579 shortUUID: string
580 videoName: string
581 checkType: CheckerType
582 }) {
583 const { shortUUID, videoName } = options
584 const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS
585
586 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
587 if (checkType === 'presence') {
588 expect(notification).to.not.be.undefined
589 expect(notification.type).to.equal(notificationType)
590
591 expect(notification.videoBlacklist.video.id).to.be.a('number')
592 checkVideo(notification.videoBlacklist.video, videoName, shortUUID)
593 } else {
594 expect(notification).to.satisfy((n: UserNotification) => {
595 return n === undefined || n.video === undefined || n.video.shortUUID !== shortUUID
596 })
597 }
598 }
599
600 function emailNotificationFinder (email: object) {
601 const text = email['text']
602 return text.indexOf(shortUUID) !== -1 && email['text'].indexOf('video-auto-blacklist/list') !== -1
603 }
604
605 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
606 }
607
608 async function checkNewBlacklistOnMyVideo (options: CheckerBaseParams & {
609 shortUUID: string
610 videoName: string
611 blacklistType: 'blacklist' | 'unblacklist'
612 }) {
613 const { videoName, shortUUID, blacklistType } = options
614 const notificationType = blacklistType === 'blacklist'
615 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
616 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
617
618 function notificationChecker (notification: UserNotification) {
619 expect(notification).to.not.be.undefined
620 expect(notification.type).to.equal(notificationType)
621
622 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
623
624 checkVideo(video, videoName, shortUUID)
625 }
626
627 function emailNotificationFinder (email: object) {
628 const text = email['text']
629 const blacklistText = blacklistType === 'blacklist'
630 ? 'blacklisted'
631 : 'unblacklisted'
632
633 return text.includes(shortUUID) && text.includes(blacklistText)
634 }
635
636 await checkNotification({ ...options, notificationChecker, emailNotificationFinder, checkType: 'presence' })
637 }
638
639 async function checkNewPeerTubeVersion (options: CheckerBaseParams & {
640 latestVersion: string
641 checkType: CheckerType
642 }) {
643 const { latestVersion } = options
644 const notificationType = UserNotificationType.NEW_PEERTUBE_VERSION
645
646 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
647 if (checkType === 'presence') {
648 expect(notification).to.not.be.undefined
649 expect(notification.type).to.equal(notificationType)
650
651 expect(notification.peertube).to.exist
652 expect(notification.peertube.latestVersion).to.equal(latestVersion)
653 } else {
654 expect(notification).to.satisfy((n: UserNotification) => {
655 return n === undefined || n.peertube === undefined || n.peertube.latestVersion !== latestVersion
656 })
657 }
658 }
659
660 function emailNotificationFinder (email: object) {
661 const text = email['text']
662
663 return text.includes(latestVersion)
664 }
665
666 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
667 }
668
669 async function checkNewPluginVersion (options: CheckerBaseParams & {
670 pluginType: PluginType
671 pluginName: string
672 checkType: CheckerType
673 }) {
674 const { pluginName, pluginType } = options
675 const notificationType = UserNotificationType.NEW_PLUGIN_VERSION
676
677 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
678 if (checkType === 'presence') {
679 expect(notification).to.not.be.undefined
680 expect(notification.type).to.equal(notificationType)
681
682 expect(notification.plugin.name).to.equal(pluginName)
683 expect(notification.plugin.type).to.equal(pluginType)
684 } else {
685 expect(notification).to.satisfy((n: UserNotification) => {
686 return n === undefined || n.plugin === undefined || n.plugin.name !== pluginName
687 })
688 }
689 }
690
691 function emailNotificationFinder (email: object) {
692 const text = email['text']
693
694 return text.includes(pluginName)
695 }
696
697 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
698 }
699
700 async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: any = {}) {
701 const userNotifications: UserNotification[] = []
702 const adminNotifications: UserNotification[] = []
703 const adminNotificationsServer2: UserNotification[] = []
704 const emails: object[] = []
705
706 const port = await MockSmtpServer.Instance.collectEmails(emails)
707
708 const overrideConfig = {
709 ...ConfigCommand.getEmailOverrideConfig(port),
710
711 signup: {
712 limit: 20
713 }
714 }
715 const servers = await createMultipleServers(serversCount, Object.assign(overrideConfig, overrideConfigArg))
716
717 await setAccessTokensToServers(servers)
718 await setDefaultVideoChannel(servers)
719 await setDefaultChannelAvatar(servers)
720 await setDefaultAccountAvatar(servers)
721
722 if (servers[1]) {
723 await servers[1].config.enableStudio()
724 await servers[1].config.enableLive({ allowReplay: true, transcoding: false })
725 }
726
727 if (serversCount > 1) {
728 await doubleFollow(servers[0], servers[1])
729 }
730
731 const user = { username: 'user_1', password: 'super password' }
732 await servers[0].users.create({ ...user, videoQuota: 10 * 1000 * 1000 })
733 const userAccessToken = await servers[0].login.getAccessToken(user)
734
735 await servers[0].notifications.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() })
736 await servers[0].users.updateMyAvatar({ token: userAccessToken, fixture: 'avatar.png' })
737 await servers[0].channels.updateImage({ channelName: 'user_1_channel', token: userAccessToken, fixture: 'avatar.png', type: 'avatar' })
738
739 await servers[0].notifications.updateMySettings({ settings: getAllNotificationsSettings() })
740
741 if (serversCount > 1) {
742 await servers[1].notifications.updateMySettings({ settings: getAllNotificationsSettings() })
743 }
744
745 {
746 const socket = servers[0].socketIO.getUserNotificationSocket({ token: userAccessToken })
747 socket.on('new-notification', n => userNotifications.push(n))
748 }
749 {
750 const socket = servers[0].socketIO.getUserNotificationSocket()
751 socket.on('new-notification', n => adminNotifications.push(n))
752 }
753
754 if (serversCount > 1) {
755 const socket = servers[1].socketIO.getUserNotificationSocket()
756 socket.on('new-notification', n => adminNotificationsServer2.push(n))
757 }
758
759 const { videoChannels } = await servers[0].users.getMyInfo()
760 const channelId = videoChannels[0].id
761
762 return {
763 userNotifications,
764 adminNotifications,
765 adminNotificationsServer2,
766 userAccessToken,
767 emails,
768 servers,
769 channelId,
770 baseOverrideConfig: overrideConfig
771 }
772 }
773
774 // ---------------------------------------------------------------------------
775
776 export {
777 getAllNotificationsSettings,
778
779 CheckerBaseParams,
780 CheckerType,
781 checkMyVideoImportIsFinished,
782 checkUserRegistered,
783 checkAutoInstanceFollowing,
784 checkVideoIsPublished,
785 checkNewVideoFromSubscription,
786 checkNewActorFollow,
787 checkNewCommentOnMyVideo,
788 checkNewBlacklistOnMyVideo,
789 checkCommentMention,
790 checkNewVideoAbuseForModerators,
791 checkVideoAutoBlacklistForModerators,
792 checkNewAbuseMessage,
793 checkAbuseStateChange,
794 checkNewInstanceFollower,
795 prepareNotificationsTest,
796 checkNewCommentAbuseForModerators,
797 checkNewAccountAbuseForModerators,
798 checkNewPeerTubeVersion,
799 checkNewPluginVersion,
800 checkVideoStudioEditionIsFinished,
801 checkRegistrationRequest
802 }
803
804 // ---------------------------------------------------------------------------
805
806 async function checkNotification (options: CheckerBaseParams & {
807 notificationChecker: (notification: UserNotification, checkType: CheckerType) => void
808 emailNotificationFinder: (email: object) => boolean
809 checkType: CheckerType
810 }) {
811 const { server, token, checkType, notificationChecker, emailNotificationFinder, socketNotifications, emails } = options
812
813 const check = options.check || { web: true, mail: true }
814
815 if (check.web) {
816 const notification = await server.notifications.getLatest({ token })
817
818 if (notification || checkType !== 'absence') {
819 notificationChecker(notification, checkType)
820 }
821
822 const socketNotification = socketNotifications.find(n => {
823 try {
824 notificationChecker(n, 'presence')
825 return true
826 } catch {
827 return false
828 }
829 })
830
831 if (checkType === 'presence') {
832 const obj = inspect(socketNotifications, { depth: 5 })
833 expect(socketNotification, 'The socket notification is absent when it should be present. ' + obj).to.not.be.undefined
834 } else {
835 const obj = inspect(socketNotification, { depth: 5 })
836 expect(socketNotification, 'The socket notification is present when it should not be present. ' + obj).to.be.undefined
837 }
838 }
839
840 if (check.mail) {
841 // Last email
842 const email = emails
843 .slice()
844 .reverse()
845 .find(e => emailNotificationFinder(e))
846
847 if (checkType === 'presence') {
848 const texts = emails.map(e => e.text)
849 expect(email, 'The email is absent when is should be present. ' + inspect(texts)).to.not.be.undefined
850 } else {
851 expect(email, 'The email is present when is should not be present. ' + inspect(email)).to.be.undefined
852 }
853 }
854 }
855
856 function checkVideo (video: any, videoName?: string, shortUUID?: string) {
857 if (videoName) {
858 expect(video.name).to.be.a('string')
859 expect(video.name).to.not.be.empty
860 expect(video.name).to.equal(videoName)
861 }
862
863 if (shortUUID) {
864 expect(video.shortUUID).to.be.a('string')
865 expect(video.shortUUID).to.not.be.empty
866 expect(video.shortUUID).to.equal(shortUUID)
867 }
868
869 expect(video.id).to.be.a('number')
870 }
871
872 function checkActor (actor: any, options: { withAvatar?: boolean } = {}) {
873 const { withAvatar = true } = options
874
875 expect(actor.displayName).to.be.a('string')
876 expect(actor.displayName).to.not.be.empty
877 expect(actor.host).to.not.be.undefined
878
879 if (withAvatar) {
880 expect(actor.avatars).to.be.an('array')
881 expect(actor.avatars).to.have.lengthOf(2)
882 expect(actor.avatars[0].path).to.exist.and.not.empty
883 }
884 }
885
886 function checkComment (comment: any, commentId: number, threadId: number) {
887 expect(comment.id).to.equal(commentId)
888 expect(comment.threadId).to.equal(threadId)
889 }