aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/extra-utils/users/notifications.ts483
-rw-r--r--shared/models/search/videos-search-query.model.ts2
-rw-r--r--shared/models/users/user-notification.model.ts7
3 files changed, 283 insertions, 209 deletions
diff --git a/shared/extra-utils/users/notifications.ts b/shared/extra-utils/users/notifications.ts
index 4c42fad3e..7db4bfd3f 100644
--- a/shared/extra-utils/users/notifications.ts
+++ b/shared/extra-utils/users/notifications.ts
@@ -10,6 +10,16 @@ import { doubleFollow } from '../server/follows'
10import { createMultipleServers } from '../server/servers' 10import { createMultipleServers } from '../server/servers'
11import { setAccessTokensToServers } from './login' 11import { setAccessTokensToServers } from './login'
12 12
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
13function getAllNotificationsSettings (): UserNotificationSetting { 23function getAllNotificationsSettings (): UserNotificationSetting {
14 return { 24 return {
15 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 25 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
@@ -31,101 +41,20 @@ function getAllNotificationsSettings (): UserNotificationSetting {
31 } 41 }
32} 42}
33 43
34type CheckerBaseParams = { 44async function checkNewVideoFromSubscription (options: CheckerBaseParams & {
35 server: PeerTubeServer 45 videoName: string
36 emails: any[] 46 shortUUID: string
37 socketNotifications: UserNotification[]
38 token: string
39 check?: { web: boolean, mail: boolean }
40}
41
42type CheckerType = 'presence' | 'absence'
43
44async function checkNotification (
45 base: CheckerBaseParams,
46 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
47 emailNotificationFinder: (email: object) => boolean,
48 checkType: CheckerType 47 checkType: CheckerType
49) { 48}) {
50 const check = base.check || { web: true, mail: true } 49 const { videoName, shortUUID } = options
51
52 if (check.web) {
53 const notification = await base.server.notifications.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
93function 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
109function 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
115function checkComment (comment: any, commentId: number, threadId: number) {
116 expect(comment.id).to.equal(commentId)
117 expect(comment.threadId).to.equal(threadId)
118}
119
120async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
121 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION 50 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
122 51
123 function notificationChecker (notification: UserNotification, type: CheckerType) { 52 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
124 if (type === 'presence') { 53 if (checkType === 'presence') {
125 expect(notification).to.not.be.undefined 54 expect(notification).to.not.be.undefined
126 expect(notification.type).to.equal(notificationType) 55 expect(notification.type).to.equal(notificationType)
127 56
128 checkVideo(notification.video, videoName, videoUUID) 57 checkVideo(notification.video, videoName, shortUUID)
129 checkActor(notification.video.channel) 58 checkActor(notification.video.channel)
130 } else { 59 } else {
131 expect(notification).to.satisfy((n: UserNotification) => { 60 expect(notification).to.satisfy((n: UserNotification) => {
@@ -136,21 +65,26 @@ async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName
136 65
137 function emailNotificationFinder (email: object) { 66 function emailNotificationFinder (email: object) {
138 const text = email['text'] 67 const text = email['text']
139 return text.indexOf(videoUUID) !== -1 && text.indexOf('Your subscription') !== -1 68 return text.indexOf(shortUUID) !== -1 && text.indexOf('Your subscription') !== -1
140 } 69 }
141 70
142 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 71 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
143} 72}
144 73
145async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) { 74async function checkVideoIsPublished (options: CheckerBaseParams & {
75 videoName: string
76 shortUUID: string
77 checkType: CheckerType
78}) {
79 const { videoName, shortUUID } = options
146 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED 80 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
147 81
148 function notificationChecker (notification: UserNotification, type: CheckerType) { 82 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
149 if (type === 'presence') { 83 if (checkType === 'presence') {
150 expect(notification).to.not.be.undefined 84 expect(notification).to.not.be.undefined
151 expect(notification.type).to.equal(notificationType) 85 expect(notification.type).to.equal(notificationType)
152 86
153 checkVideo(notification.video, videoName, videoUUID) 87 checkVideo(notification.video, videoName, shortUUID)
154 checkActor(notification.video.channel) 88 checkActor(notification.video.channel)
155 } else { 89 } else {
156 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName) 90 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
@@ -159,30 +93,31 @@ async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string
159 93
160 function emailNotificationFinder (email: object) { 94 function emailNotificationFinder (email: object) {
161 const text: string = email['text'] 95 const text: string = email['text']
162 return text.includes(videoUUID) && text.includes('Your video') 96 return text.includes(shortUUID) && text.includes('Your video')
163 } 97 }
164 98
165 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 99 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
166} 100}
167 101
168async function checkMyVideoImportIsFinished ( 102async function checkMyVideoImportIsFinished (options: CheckerBaseParams & {
169 base: CheckerBaseParams, 103 videoName: string
170 videoName: string, 104 shortUUID: string
171 videoUUID: string, 105 url: string
172 url: string, 106 success: boolean
173 success: boolean, 107 checkType: CheckerType
174 type: CheckerType 108}) {
175) { 109 const { videoName, shortUUID, url, success } = options
110
176 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR 111 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
177 112
178 function notificationChecker (notification: UserNotification, type: CheckerType) { 113 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
179 if (type === 'presence') { 114 if (checkType === 'presence') {
180 expect(notification).to.not.be.undefined 115 expect(notification).to.not.be.undefined
181 expect(notification.type).to.equal(notificationType) 116 expect(notification.type).to.equal(notificationType)
182 117
183 expect(notification.videoImport.targetUrl).to.equal(url) 118 expect(notification.videoImport.targetUrl).to.equal(url)
184 119
185 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID) 120 if (success) checkVideo(notification.videoImport.video, videoName, shortUUID)
186 } else { 121 } else {
187 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url) 122 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
188 } 123 }
@@ -195,14 +130,18 @@ async function checkMyVideoImportIsFinished (
195 return text.includes(url) && text.includes(toFind) 130 return text.includes(url) && text.includes(toFind)
196 } 131 }
197 132
198 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 133 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
199} 134}
200 135
201async function checkUserRegistered (base: CheckerBaseParams, username: string, type: CheckerType) { 136async function checkUserRegistered (options: CheckerBaseParams & {
137 username: string
138 checkType: CheckerType
139}) {
140 const { username } = options
202 const notificationType = UserNotificationType.NEW_USER_REGISTRATION 141 const notificationType = UserNotificationType.NEW_USER_REGISTRATION
203 142
204 function notificationChecker (notification: UserNotification, type: CheckerType) { 143 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
205 if (type === 'presence') { 144 if (checkType === 'presence') {
206 expect(notification).to.not.be.undefined 145 expect(notification).to.not.be.undefined
207 expect(notification.type).to.equal(notificationType) 146 expect(notification.type).to.equal(notificationType)
208 147
@@ -219,21 +158,21 @@ async function checkUserRegistered (base: CheckerBaseParams, username: string, t
219 return text.includes(' registered.') && text.includes(username) 158 return text.includes(' registered.') && text.includes(username)
220 } 159 }
221 160
222 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 161 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
223} 162}
224 163
225async function checkNewActorFollow ( 164async function checkNewActorFollow (options: CheckerBaseParams & {
226 base: CheckerBaseParams, 165 followType: 'channel' | 'account'
227 followType: 'channel' | 'account', 166 followerName: string
228 followerName: string, 167 followerDisplayName: string
229 followerDisplayName: string, 168 followingDisplayName: string
230 followingDisplayName: string, 169 checkType: CheckerType
231 type: CheckerType 170}) {
232) { 171 const { followType, followerName, followerDisplayName, followingDisplayName } = options
233 const notificationType = UserNotificationType.NEW_FOLLOW 172 const notificationType = UserNotificationType.NEW_FOLLOW
234 173
235 function notificationChecker (notification: UserNotification, type: CheckerType) { 174 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
236 if (type === 'presence') { 175 if (checkType === 'presence') {
237 expect(notification).to.not.be.undefined 176 expect(notification).to.not.be.undefined
238 expect(notification.type).to.equal(notificationType) 177 expect(notification.type).to.equal(notificationType)
239 178
@@ -259,14 +198,18 @@ async function checkNewActorFollow (
259 return text.includes(followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName) 198 return text.includes(followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
260 } 199 }
261 200
262 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 201 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
263} 202}
264 203
265async function checkNewInstanceFollower (base: CheckerBaseParams, followerHost: string, type: CheckerType) { 204async function checkNewInstanceFollower (options: CheckerBaseParams & {
205 followerHost: string
206 checkType: CheckerType
207}) {
208 const { followerHost } = options
266 const notificationType = UserNotificationType.NEW_INSTANCE_FOLLOWER 209 const notificationType = UserNotificationType.NEW_INSTANCE_FOLLOWER
267 210
268 function notificationChecker (notification: UserNotification, type: CheckerType) { 211 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
269 if (type === 'presence') { 212 if (checkType === 'presence') {
270 expect(notification).to.not.be.undefined 213 expect(notification).to.not.be.undefined
271 expect(notification.type).to.equal(notificationType) 214 expect(notification.type).to.equal(notificationType)
272 215
@@ -288,14 +231,19 @@ async function checkNewInstanceFollower (base: CheckerBaseParams, followerHost:
288 return text.includes('instance has a new follower') && text.includes(followerHost) 231 return text.includes('instance has a new follower') && text.includes(followerHost)
289 } 232 }
290 233
291 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 234 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
292} 235}
293 236
294async function checkAutoInstanceFollowing (base: CheckerBaseParams, followerHost: string, followingHost: string, type: CheckerType) { 237async function checkAutoInstanceFollowing (options: CheckerBaseParams & {
238 followerHost: string
239 followingHost: string
240 checkType: CheckerType
241}) {
242 const { followerHost, followingHost } = options
295 const notificationType = UserNotificationType.AUTO_INSTANCE_FOLLOWING 243 const notificationType = UserNotificationType.AUTO_INSTANCE_FOLLOWING
296 244
297 function notificationChecker (notification: UserNotification, type: CheckerType) { 245 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
298 if (type === 'presence') { 246 if (checkType === 'presence') {
299 expect(notification).to.not.be.undefined 247 expect(notification).to.not.be.undefined
300 expect(notification.type).to.equal(notificationType) 248 expect(notification.type).to.equal(notificationType)
301 249
@@ -319,21 +267,21 @@ async function checkAutoInstanceFollowing (base: CheckerBaseParams, followerHost
319 return text.includes(' automatically followed a new instance') && text.includes(followingHost) 267 return text.includes(' automatically followed a new instance') && text.includes(followingHost)
320 } 268 }
321 269
322 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 270 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
323} 271}
324 272
325async function checkCommentMention ( 273async function checkCommentMention (options: CheckerBaseParams & {
326 base: CheckerBaseParams, 274 shortUUID: string
327 uuid: string, 275 commentId: number
328 commentId: number, 276 threadId: number
329 threadId: number, 277 byAccountDisplayName: string
330 byAccountDisplayName: string, 278 checkType: CheckerType
331 type: CheckerType 279}) {
332) { 280 const { shortUUID, commentId, threadId, byAccountDisplayName } = options
333 const notificationType = UserNotificationType.COMMENT_MENTION 281 const notificationType = UserNotificationType.COMMENT_MENTION
334 282
335 function notificationChecker (notification: UserNotification, type: CheckerType) { 283 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
336 if (type === 'presence') { 284 if (checkType === 'presence') {
337 expect(notification).to.not.be.undefined 285 expect(notification).to.not.be.undefined
338 expect(notification.type).to.equal(notificationType) 286 expect(notification.type).to.equal(notificationType)
339 287
@@ -341,7 +289,7 @@ async function checkCommentMention (
341 checkActor(notification.comment.account) 289 checkActor(notification.comment.account)
342 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName) 290 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName)
343 291
344 checkVideo(notification.comment.video, undefined, uuid) 292 checkVideo(notification.comment.video, undefined, shortUUID)
345 } else { 293 } else {
346 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId) 294 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId)
347 } 295 }
@@ -350,25 +298,31 @@ async function checkCommentMention (
350 function emailNotificationFinder (email: object) { 298 function emailNotificationFinder (email: object) {
351 const text: string = email['text'] 299 const text: string = email['text']
352 300
353 return text.includes(' mentioned ') && text.includes(uuid) && text.includes(byAccountDisplayName) 301 return text.includes(' mentioned ') && text.includes(shortUUID) && text.includes(byAccountDisplayName)
354 } 302 }
355 303
356 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 304 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
357} 305}
358 306
359let lastEmailCount = 0 307let lastEmailCount = 0
360 308
361async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) { 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
362 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO 316 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
363 317
364 function notificationChecker (notification: UserNotification, type: CheckerType) { 318 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
365 if (type === 'presence') { 319 if (checkType === 'presence') {
366 expect(notification).to.not.be.undefined 320 expect(notification).to.not.be.undefined
367 expect(notification.type).to.equal(notificationType) 321 expect(notification.type).to.equal(notificationType)
368 322
369 checkComment(notification.comment, commentId, threadId) 323 checkComment(notification.comment, commentId, threadId)
370 checkActor(notification.comment.account) 324 checkActor(notification.comment.account)
371 checkVideo(notification.comment.video, undefined, uuid) 325 checkVideo(notification.comment.video, undefined, shortUUID)
372 } else { 326 } else {
373 expect(notification).to.satisfy((n: UserNotification) => { 327 expect(notification).to.satisfy((n: UserNotification) => {
374 return n === undefined || n.comment === undefined || n.comment.id !== commentId 328 return n === undefined || n.comment === undefined || n.comment.id !== commentId
@@ -376,51 +330,62 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
376 } 330 }
377 } 331 }
378 332
379 const commentUrl = `http://localhost:${base.server.port}/w/${uuid};threadId=${threadId}` 333 const commentUrl = `http://localhost:${server.port}/w/${shortUUID};threadId=${threadId}`
380 334
381 function emailNotificationFinder (email: object) { 335 function emailNotificationFinder (email: object) {
382 return email['text'].indexOf(commentUrl) !== -1 336 return email['text'].indexOf(commentUrl) !== -1
383 } 337 }
384 338
385 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 339 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
386 340
387 if (type === 'presence') { 341 if (checkType === 'presence') {
388 // We cannot detect email duplicates, so check we received another email 342 // We cannot detect email duplicates, so check we received another email
389 expect(base.emails).to.have.length.above(lastEmailCount) 343 expect(emails).to.have.length.above(lastEmailCount)
390 lastEmailCount = base.emails.length 344 lastEmailCount = emails.length
391 } 345 }
392} 346}
393 347
394async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) { 348async function checkNewVideoAbuseForModerators (options: CheckerBaseParams & {
349 shortUUID: string
350 videoName: string
351 checkType: CheckerType
352}) {
353 const { shortUUID, videoName } = options
395 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS 354 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
396 355
397 function notificationChecker (notification: UserNotification, type: CheckerType) { 356 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
398 if (type === 'presence') { 357 if (checkType === 'presence') {
399 expect(notification).to.not.be.undefined 358 expect(notification).to.not.be.undefined
400 expect(notification.type).to.equal(notificationType) 359 expect(notification.type).to.equal(notificationType)
401 360
402 expect(notification.abuse.id).to.be.a('number') 361 expect(notification.abuse.id).to.be.a('number')
403 checkVideo(notification.abuse.video, videoName, videoUUID) 362 checkVideo(notification.abuse.video, videoName, shortUUID)
404 } else { 363 } else {
405 expect(notification).to.satisfy((n: UserNotification) => { 364 expect(notification).to.satisfy((n: UserNotification) => {
406 return n === undefined || n.abuse === undefined || n.abuse.video.uuid !== videoUUID 365 return n === undefined || n.abuse === undefined || n.abuse.video.shortUUID !== shortUUID
407 }) 366 })
408 } 367 }
409 } 368 }
410 369
411 function emailNotificationFinder (email: object) { 370 function emailNotificationFinder (email: object) {
412 const text = email['text'] 371 const text = email['text']
413 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1 372 return text.indexOf(shortUUID) !== -1 && text.indexOf('abuse') !== -1
414 } 373 }
415 374
416 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 375 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
417} 376}
418 377
419async function checkNewAbuseMessage (base: CheckerBaseParams, abuseId: number, message: string, toEmail: string, type: CheckerType) { 378async function checkNewAbuseMessage (options: CheckerBaseParams & {
379 abuseId: number
380 message: string
381 toEmail: string
382 checkType: CheckerType
383}) {
384 const { abuseId, message, toEmail } = options
420 const notificationType = UserNotificationType.ABUSE_NEW_MESSAGE 385 const notificationType = UserNotificationType.ABUSE_NEW_MESSAGE
421 386
422 function notificationChecker (notification: UserNotification, type: CheckerType) { 387 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
423 if (type === 'presence') { 388 if (checkType === 'presence') {
424 expect(notification).to.not.be.undefined 389 expect(notification).to.not.be.undefined
425 expect(notification.type).to.equal(notificationType) 390 expect(notification.type).to.equal(notificationType)
426 391
@@ -439,14 +404,19 @@ async function checkNewAbuseMessage (base: CheckerBaseParams, abuseId: number, m
439 return text.indexOf(message) !== -1 && to.length !== 0 404 return text.indexOf(message) !== -1 && to.length !== 0
440 } 405 }
441 406
442 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 407 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
443} 408}
444 409
445async function checkAbuseStateChange (base: CheckerBaseParams, abuseId: number, state: AbuseState, type: CheckerType) { 410async function checkAbuseStateChange (options: CheckerBaseParams & {
411 abuseId: number
412 state: AbuseState
413 checkType: CheckerType
414}) {
415 const { abuseId, state } = options
446 const notificationType = UserNotificationType.ABUSE_STATE_CHANGE 416 const notificationType = UserNotificationType.ABUSE_STATE_CHANGE
447 417
448 function notificationChecker (notification: UserNotification, type: CheckerType) { 418 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
449 if (type === 'presence') { 419 if (checkType === 'presence') {
450 expect(notification).to.not.be.undefined 420 expect(notification).to.not.be.undefined
451 expect(notification.type).to.equal(notificationType) 421 expect(notification.type).to.equal(notificationType)
452 422
@@ -469,39 +439,48 @@ async function checkAbuseStateChange (base: CheckerBaseParams, abuseId: number,
469 return text.indexOf(contains) !== -1 439 return text.indexOf(contains) !== -1
470 } 440 }
471 441
472 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 442 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
473} 443}
474 444
475async function checkNewCommentAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) { 445async function checkNewCommentAbuseForModerators (options: CheckerBaseParams & {
446 shortUUID: string
447 videoName: string
448 checkType: CheckerType
449}) {
450 const { shortUUID, videoName } = options
476 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS 451 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
477 452
478 function notificationChecker (notification: UserNotification, type: CheckerType) { 453 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
479 if (type === 'presence') { 454 if (checkType === 'presence') {
480 expect(notification).to.not.be.undefined 455 expect(notification).to.not.be.undefined
481 expect(notification.type).to.equal(notificationType) 456 expect(notification.type).to.equal(notificationType)
482 457
483 expect(notification.abuse.id).to.be.a('number') 458 expect(notification.abuse.id).to.be.a('number')
484 checkVideo(notification.abuse.comment.video, videoName, videoUUID) 459 checkVideo(notification.abuse.comment.video, videoName, shortUUID)
485 } else { 460 } else {
486 expect(notification).to.satisfy((n: UserNotification) => { 461 expect(notification).to.satisfy((n: UserNotification) => {
487 return n === undefined || n.abuse === undefined || n.abuse.comment.video.uuid !== videoUUID 462 return n === undefined || n.abuse === undefined || n.abuse.comment.video.shortUUID !== shortUUID
488 }) 463 })
489 } 464 }
490 } 465 }
491 466
492 function emailNotificationFinder (email: object) { 467 function emailNotificationFinder (email: object) {
493 const text = email['text'] 468 const text = email['text']
494 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1 469 return text.indexOf(shortUUID) !== -1 && text.indexOf('abuse') !== -1
495 } 470 }
496 471
497 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 472 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
498} 473}
499 474
500async function checkNewAccountAbuseForModerators (base: CheckerBaseParams, displayName: string, type: CheckerType) { 475async function checkNewAccountAbuseForModerators (options: CheckerBaseParams & {
476 displayName: string
477 checkType: CheckerType
478}) {
479 const { displayName } = options
501 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS 480 const notificationType = UserNotificationType.NEW_ABUSE_FOR_MODERATORS
502 481
503 function notificationChecker (notification: UserNotification, type: CheckerType) { 482 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
504 if (type === 'presence') { 483 if (checkType === 'presence') {
505 expect(notification).to.not.be.undefined 484 expect(notification).to.not.be.undefined
506 expect(notification.type).to.equal(notificationType) 485 expect(notification.type).to.equal(notificationType)
507 486
@@ -519,40 +498,45 @@ async function checkNewAccountAbuseForModerators (base: CheckerBaseParams, displ
519 return text.indexOf(displayName) !== -1 && text.indexOf('abuse') !== -1 498 return text.indexOf(displayName) !== -1 && text.indexOf('abuse') !== -1
520 } 499 }
521 500
522 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 501 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
523} 502}
524 503
525async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) { 504async function checkVideoAutoBlacklistForModerators (options: CheckerBaseParams & {
505 shortUUID: string
506 videoName: string
507 checkType: CheckerType
508}) {
509 const { shortUUID, videoName } = options
526 const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS 510 const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS
527 511
528 function notificationChecker (notification: UserNotification, type: CheckerType) { 512 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
529 if (type === 'presence') { 513 if (checkType === 'presence') {
530 expect(notification).to.not.be.undefined 514 expect(notification).to.not.be.undefined
531 expect(notification.type).to.equal(notificationType) 515 expect(notification.type).to.equal(notificationType)
532 516
533 expect(notification.videoBlacklist.video.id).to.be.a('number') 517 expect(notification.videoBlacklist.video.id).to.be.a('number')
534 checkVideo(notification.videoBlacklist.video, videoName, videoUUID) 518 checkVideo(notification.videoBlacklist.video, videoName, shortUUID)
535 } else { 519 } else {
536 expect(notification).to.satisfy((n: UserNotification) => { 520 expect(notification).to.satisfy((n: UserNotification) => {
537 return n === undefined || n.video === undefined || n.video.uuid !== videoUUID 521 return n === undefined || n.video === undefined || n.video.shortUUID !== shortUUID
538 }) 522 })
539 } 523 }
540 } 524 }
541 525
542 function emailNotificationFinder (email: object) { 526 function emailNotificationFinder (email: object) {
543 const text = email['text'] 527 const text = email['text']
544 return text.indexOf(videoUUID) !== -1 && email['text'].indexOf('video-auto-blacklist/list') !== -1 528 return text.indexOf(shortUUID) !== -1 && email['text'].indexOf('video-auto-blacklist/list') !== -1
545 } 529 }
546 530
547 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 531 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
548} 532}
549 533
550async function checkNewBlacklistOnMyVideo ( 534async function checkNewBlacklistOnMyVideo (options: CheckerBaseParams & {
551 base: CheckerBaseParams, 535 shortUUID: string
552 videoUUID: string, 536 videoName: string
553 videoName: string,
554 blacklistType: 'blacklist' | 'unblacklist' 537 blacklistType: 'blacklist' | 'unblacklist'
555) { 538}) {
539 const { videoName, shortUUID, blacklistType } = options
556 const notificationType = blacklistType === 'blacklist' 540 const notificationType = blacklistType === 'blacklist'
557 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO 541 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
558 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO 542 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
@@ -563,22 +547,30 @@ async function checkNewBlacklistOnMyVideo (
563 547
564 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video 548 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
565 549
566 checkVideo(video, videoName, videoUUID) 550 checkVideo(video, videoName, shortUUID)
567 } 551 }
568 552
569 function emailNotificationFinder (email: object) { 553 function emailNotificationFinder (email: object) {
570 const text = email['text'] 554 const text = email['text']
571 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1 555 const blacklistText = blacklistType === 'blacklist'
556 ? 'blacklisted'
557 : 'unblacklisted'
558
559 return text.includes(shortUUID) && text.includes(blacklistText)
572 } 560 }
573 561
574 await checkNotification(base, notificationChecker, emailNotificationFinder, 'presence') 562 await checkNotification({ ...options, notificationChecker, emailNotificationFinder, checkType: 'presence' })
575} 563}
576 564
577async function checkNewPeerTubeVersion (base: CheckerBaseParams, latestVersion: string, type: CheckerType) { 565async function checkNewPeerTubeVersion (options: CheckerBaseParams & {
566 latestVersion: string
567 checkType: CheckerType
568}) {
569 const { latestVersion } = options
578 const notificationType = UserNotificationType.NEW_PEERTUBE_VERSION 570 const notificationType = UserNotificationType.NEW_PEERTUBE_VERSION
579 571
580 function notificationChecker (notification: UserNotification, type: CheckerType) { 572 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
581 if (type === 'presence') { 573 if (checkType === 'presence') {
582 expect(notification).to.not.be.undefined 574 expect(notification).to.not.be.undefined
583 expect(notification.type).to.equal(notificationType) 575 expect(notification.type).to.equal(notificationType)
584 576
@@ -597,14 +589,19 @@ async function checkNewPeerTubeVersion (base: CheckerBaseParams, latestVersion:
597 return text.includes(latestVersion) 589 return text.includes(latestVersion)
598 } 590 }
599 591
600 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 592 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
601} 593}
602 594
603async function checkNewPluginVersion (base: CheckerBaseParams, pluginType: PluginType, pluginName: string, type: CheckerType) { 595async function checkNewPluginVersion (options: CheckerBaseParams & {
596 pluginType: PluginType
597 pluginName: string
598 checkType: CheckerType
599}) {
600 const { pluginName, pluginType } = options
604 const notificationType = UserNotificationType.NEW_PLUGIN_VERSION 601 const notificationType = UserNotificationType.NEW_PLUGIN_VERSION
605 602
606 function notificationChecker (notification: UserNotification, type: CheckerType) { 603 function notificationChecker (notification: UserNotification, checkType: CheckerType) {
607 if (type === 'presence') { 604 if (checkType === 'presence') {
608 expect(notification).to.not.be.undefined 605 expect(notification).to.not.be.undefined
609 expect(notification.type).to.equal(notificationType) 606 expect(notification.type).to.equal(notificationType)
610 607
@@ -623,7 +620,7 @@ async function checkNewPluginVersion (base: CheckerBaseParams, pluginType: Plugi
623 return text.includes(pluginName) 620 return text.includes(pluginName)
624 } 621 }
625 622
626 await checkNotification(base, notificationChecker, emailNotificationFinder, type) 623 await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
627} 624}
628 625
629async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: any = {}) { 626async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: any = {}) {
@@ -697,7 +694,6 @@ export {
697 694
698 CheckerBaseParams, 695 CheckerBaseParams,
699 CheckerType, 696 CheckerType,
700 checkNotification,
701 checkMyVideoImportIsFinished, 697 checkMyVideoImportIsFinished,
702 checkUserRegistered, 698 checkUserRegistered,
703 checkAutoInstanceFollowing, 699 checkAutoInstanceFollowing,
@@ -718,3 +714,82 @@ export {
718 checkNewPeerTubeVersion, 714 checkNewPeerTubeVersion,
719 checkNewPluginVersion 715 checkNewPluginVersion
720} 716}
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) {
730 const notification = await server.notifications.getLastest({ token: token })
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}
diff --git a/shared/models/search/videos-search-query.model.ts b/shared/models/search/videos-search-query.model.ts
index 406f6cab2..a568c960e 100644
--- a/shared/models/search/videos-search-query.model.ts
+++ b/shared/models/search/videos-search-query.model.ts
@@ -4,6 +4,8 @@ import { VideosCommonQuery } from './videos-common-query.model'
4export interface VideosSearchQuery extends SearchTargetQuery, VideosCommonQuery { 4export interface VideosSearchQuery extends SearchTargetQuery, VideosCommonQuery {
5 search?: string 5 search?: string
6 6
7 host?: string
8
7 startDate?: string // ISO 8601 9 startDate?: string // ISO 8601
8 endDate?: string // ISO 8601 10 endDate?: string // ISO 8601
9 11
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts
index 8b33e3fbd..5820589fe 100644
--- a/shared/models/users/user-notification.model.ts
+++ b/shared/models/users/user-notification.model.ts
@@ -36,6 +36,7 @@ export const enum UserNotificationType {
36export interface VideoInfo { 36export interface VideoInfo {
37 id: number 37 id: number
38 uuid: string 38 uuid: string
39 shortUUID: string
39 name: string 40 name: string
40} 41}
41 42
@@ -82,11 +83,7 @@ export interface UserNotification {
82 comment?: { 83 comment?: {
83 threadId: number 84 threadId: number
84 85
85 video: { 86 video: VideoInfo
86 id: number
87 uuid: string
88 name: string
89 }
90 } 87 }
91 88
92 account?: ActorInfo 89 account?: ActorInfo