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