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