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