diff options
Diffstat (limited to 'server/tests/shared/notifications.ts')
-rw-r--r-- | server/tests/shared/notifications.ts | 889 |
1 files changed, 0 insertions, 889 deletions
diff --git a/server/tests/shared/notifications.ts b/server/tests/shared/notifications.ts deleted file mode 100644 index 6c0688d5a..000000000 --- a/server/tests/shared/notifications.ts +++ /dev/null | |||
@@ -1,889 +0,0 @@ | |||
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 | } | ||