]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - shared/utils/users/user-notifications.ts
Add import finished and video published notifs
[github/Chocobozzz/PeerTube.git] / shared / utils / users / user-notifications.ts
1 /* tslint:disable:no-unused-expression */
2
3 import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
4 import { UserNotification, UserNotificationSetting, UserNotificationType } from '../../models/users'
5 import { ServerInfo } from '..'
6 import { expect } from 'chai'
7 import { inspect } from 'util'
8
9 function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) {
10 const path = '/api/v1/users/me/notification-settings'
11
12 return makePutBodyRequest({
13 url,
14 path,
15 token,
16 fields: settings,
17 statusCodeExpected
18 })
19 }
20
21 function getUserNotifications (
22 url: string,
23 token: string,
24 start: number,
25 count: number,
26 unread?: boolean,
27 sort = '-createdAt',
28 statusCodeExpected = 200
29 ) {
30 const path = '/api/v1/users/me/notifications'
31
32 return makeGetRequest({
33 url,
34 path,
35 token,
36 query: {
37 start,
38 count,
39 sort,
40 unread
41 },
42 statusCodeExpected
43 })
44 }
45
46 function markAsReadNotifications (url: string, token: string, ids: number[], statusCodeExpected = 204) {
47 const path = '/api/v1/users/me/notifications/read'
48
49 return makePostBodyRequest({
50 url,
51 path,
52 token,
53 fields: { ids },
54 statusCodeExpected
55 })
56 }
57
58 async function getLastNotification (serverUrl: string, accessToken: string) {
59 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, undefined, '-createdAt')
60
61 if (res.body.total === 0) return undefined
62
63 return res.body.data[0] as UserNotification
64 }
65
66 type CheckerBaseParams = {
67 server: ServerInfo
68 emails: object[]
69 socketNotifications: UserNotification[]
70 token: string,
71 check?: { web: boolean, mail: boolean }
72 }
73
74 type CheckerType = 'presence' | 'absence'
75
76 async function checkNotification (
77 base: CheckerBaseParams,
78 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
79 emailNotificationFinder: (email: object) => boolean,
80 checkType: CheckerType
81 ) {
82 const check = base.check || { web: true, mail: true }
83
84 if (check.web) {
85 const notification = await getLastNotification(base.server.url, base.token)
86
87 if (notification || checkType !== 'absence') {
88 notificationChecker(notification, checkType)
89 }
90
91 const socketNotification = base.socketNotifications.find(n => {
92 try {
93 notificationChecker(n, 'presence')
94 return true
95 } catch {
96 return false
97 }
98 })
99
100 if (checkType === 'presence') {
101 expect(socketNotification, 'The socket notification is absent. ' + inspect(base.socketNotifications)).to.not.be.undefined
102 } else {
103 expect(socketNotification, 'The socket notification is present. ' + inspect(socketNotification)).to.be.undefined
104 }
105 }
106
107 if (check.mail) {
108 // Last email
109 const email = base.emails
110 .slice()
111 .reverse()
112 .find(e => emailNotificationFinder(e))
113
114 if (checkType === 'presence') {
115 expect(email, 'The email is absent. ' + inspect(base.emails)).to.not.be.undefined
116 } else {
117 expect(email, 'The email is present. ' + inspect(email)).to.be.undefined
118 }
119 }
120 }
121
122 function checkVideo (video: any, videoName?: string, videoUUID?: string) {
123 expect(video.name).to.be.a('string')
124 expect(video.name).to.not.be.empty
125 if (videoName) expect(video.name).to.equal(videoName)
126
127 expect(video.uuid).to.be.a('string')
128 expect(video.uuid).to.not.be.empty
129 if (videoUUID) expect(video.uuid).to.equal(videoUUID)
130
131 expect(video.id).to.be.a('number')
132 }
133
134 function checkActor (channel: any) {
135 expect(channel.id).to.be.a('number')
136 expect(channel.displayName).to.be.a('string')
137 expect(channel.displayName).to.not.be.empty
138 }
139
140 function checkComment (comment: any, commentId: number, threadId: number) {
141 expect(comment.id).to.equal(commentId)
142 expect(comment.threadId).to.equal(threadId)
143 }
144
145 async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
146 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
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 emailFinder (email: object) {
161 return email[ 'text' ].indexOf(videoUUID) !== -1
162 }
163
164 await checkNotification(base, notificationChecker, emailFinder, type)
165 }
166
167 async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
168 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
169
170 function notificationChecker (notification: UserNotification, type: CheckerType) {
171 if (type === 'presence') {
172 expect(notification).to.not.be.undefined
173 expect(notification.type).to.equal(notificationType)
174
175 checkVideo(notification.video, videoName, videoUUID)
176 checkActor(notification.video.channel)
177 } else {
178 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
179 }
180 }
181
182 function emailFinder (email: object) {
183 const text: string = email[ 'text' ]
184 return text.includes(videoUUID) && text.includes('Your video')
185 }
186
187 await checkNotification(base, notificationChecker, emailFinder, type)
188 }
189
190 async function checkMyVideoImportIsFinished (
191 base: CheckerBaseParams,
192 videoName: string,
193 videoUUID: string,
194 url: string,
195 success: boolean,
196 type: CheckerType
197 ) {
198 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
199
200 function notificationChecker (notification: UserNotification, type: CheckerType) {
201 if (type === 'presence') {
202 expect(notification).to.not.be.undefined
203 expect(notification.type).to.equal(notificationType)
204
205 expect(notification.videoImport.targetUrl).to.equal(url)
206
207 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID)
208 } else {
209 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
210 }
211 }
212
213 function emailFinder (email: object) {
214 const text: string = email[ 'text' ]
215 const toFind = success ? ' finished' : ' error'
216
217 return text.includes(url) && text.includes(toFind)
218 }
219
220 await checkNotification(base, notificationChecker, emailFinder, type)
221 }
222
223 let lastEmailCount = 0
224 async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) {
225 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
226
227 function notificationChecker (notification: UserNotification, type: CheckerType) {
228 if (type === 'presence') {
229 expect(notification).to.not.be.undefined
230 expect(notification.type).to.equal(notificationType)
231
232 checkComment(notification.comment, commentId, threadId)
233 checkActor(notification.comment.account)
234 checkVideo(notification.comment.video, undefined, uuid)
235 } else {
236 expect(notification).to.satisfy((n: UserNotification) => {
237 return n === undefined || n.comment === undefined || n.comment.id !== commentId
238 })
239 }
240 }
241
242 const commentUrl = `http://localhost:9001/videos/watch/${uuid};threadId=${threadId}`
243 function emailFinder (email: object) {
244 return email[ 'text' ].indexOf(commentUrl) !== -1
245 }
246
247 await checkNotification(base, notificationChecker, emailFinder, type)
248
249 if (type === 'presence') {
250 // We cannot detect email duplicates, so check we received another email
251 expect(base.emails).to.have.length.above(lastEmailCount)
252 lastEmailCount = base.emails.length
253 }
254 }
255
256 async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
257 const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS
258
259 function notificationChecker (notification: UserNotification, type: CheckerType) {
260 if (type === 'presence') {
261 expect(notification).to.not.be.undefined
262 expect(notification.type).to.equal(notificationType)
263
264 expect(notification.videoAbuse.id).to.be.a('number')
265 checkVideo(notification.videoAbuse.video, videoName, videoUUID)
266 } else {
267 expect(notification).to.satisfy((n: UserNotification) => {
268 return n === undefined || n.videoAbuse === undefined || n.videoAbuse.video.uuid !== videoUUID
269 })
270 }
271 }
272
273 function emailFinder (email: object) {
274 const text = email[ 'text' ]
275 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
276 }
277
278 await checkNotification(base, notificationChecker, emailFinder, type)
279 }
280
281 async function checkNewBlacklistOnMyVideo (
282 base: CheckerBaseParams,
283 videoUUID: string,
284 videoName: string,
285 blacklistType: 'blacklist' | 'unblacklist'
286 ) {
287 const notificationType = blacklistType === 'blacklist'
288 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
289 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
290
291 function notificationChecker (notification: UserNotification) {
292 expect(notification).to.not.be.undefined
293 expect(notification.type).to.equal(notificationType)
294
295 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
296
297 checkVideo(video, videoName, videoUUID)
298 }
299
300 function emailFinder (email: object) {
301 const text = email[ 'text' ]
302 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
303 }
304
305 await checkNotification(base, notificationChecker, emailFinder, 'presence')
306 }
307
308 // ---------------------------------------------------------------------------
309
310 export {
311 CheckerBaseParams,
312 CheckerType,
313 checkNotification,
314 checkMyVideoImportIsFinished,
315 checkVideoIsPublished,
316 checkNewVideoFromSubscription,
317 checkNewCommentOnMyVideo,
318 checkNewBlacklistOnMyVideo,
319 updateMyNotificationSettings,
320 checkNewVideoAbuseForModerators,
321 getUserNotifications,
322 markAsReadNotifications,
323 getLastNotification
324 }