]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/notifications/user-notifications.ts
bb3024617fa27e1e2fd037fe8fbcdd42d5b44a4c
[github/Chocobozzz/PeerTube.git] / server / tests / api / notifications / user-notifications.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import {
6 CheckerBaseParams,
7 checkMyVideoImportIsFinished,
8 checkNewActorFollow,
9 checkNewVideoFromSubscription,
10 checkVideoIsPublished,
11 FIXTURE_URLS,
12 MockSmtpServer,
13 prepareNotificationsTest,
14 uploadRandomVideoOnServers
15 } from '@server/tests/shared'
16 import { buildUUID, wait } from '@shared/core-utils'
17 import { UserNotification, UserNotificationType, VideoPrivacy } from '@shared/models'
18 import { cleanupTests, PeerTubeServer, waitJobs } from '@shared/server-commands'
19
20 const expect = chai.expect
21
22 describe('Test user notifications', function () {
23 let servers: PeerTubeServer[] = []
24 let userAccessToken: string
25 let userNotifications: UserNotification[] = []
26 let adminNotifications: UserNotification[] = []
27 let adminNotificationsServer2: UserNotification[] = []
28 let emails: object[] = []
29 let channelId: number
30
31 before(async function () {
32 this.timeout(120000)
33
34 const res = await prepareNotificationsTest(3)
35 emails = res.emails
36 userAccessToken = res.userAccessToken
37 servers = res.servers
38 userNotifications = res.userNotifications
39 adminNotifications = res.adminNotifications
40 adminNotificationsServer2 = res.adminNotificationsServer2
41 channelId = res.channelId
42 })
43
44 describe('New video from my subscription notification', function () {
45 let baseParams: CheckerBaseParams
46
47 before(() => {
48 baseParams = {
49 server: servers[0],
50 emails,
51 socketNotifications: userNotifications,
52 token: userAccessToken
53 }
54 })
55
56 it('Should not send notifications if the user does not follow the video publisher', async function () {
57 this.timeout(50000)
58
59 await uploadRandomVideoOnServers(servers, 1)
60
61 const notification = await servers[0].notifications.getLatest({ token: userAccessToken })
62 expect(notification).to.be.undefined
63
64 expect(emails).to.have.lengthOf(0)
65 expect(userNotifications).to.have.lengthOf(0)
66 })
67
68 it('Should send a new video notification if the user follows the local video publisher', async function () {
69 this.timeout(15000)
70
71 await servers[0].subscriptions.add({ token: userAccessToken, targetUri: 'root_channel@localhost:' + servers[0].port })
72 await waitJobs(servers)
73
74 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 1)
75 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
76 })
77
78 it('Should send a new video notification from a remote account', async function () {
79 this.timeout(150000) // Server 2 has transcoding enabled
80
81 await servers[0].subscriptions.add({ token: userAccessToken, targetUri: 'root_channel@localhost:' + servers[1].port })
82 await waitJobs(servers)
83
84 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2)
85 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
86 })
87
88 it('Should send a new video notification on a scheduled publication', async function () {
89 this.timeout(50000)
90
91 // In 2 seconds
92 const updateAt = new Date(new Date().getTime() + 2000)
93
94 const data = {
95 privacy: VideoPrivacy.PRIVATE,
96 scheduleUpdate: {
97 updateAt: updateAt.toISOString(),
98 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
99 }
100 }
101 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 1, data)
102
103 await wait(6000)
104 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
105 })
106
107 it('Should send a new video notification on a remote scheduled publication', async function () {
108 this.timeout(100000)
109
110 // In 2 seconds
111 const updateAt = new Date(new Date().getTime() + 2000)
112
113 const data = {
114 privacy: VideoPrivacy.PRIVATE,
115 scheduleUpdate: {
116 updateAt: updateAt.toISOString(),
117 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
118 }
119 }
120 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
121 await waitJobs(servers)
122
123 await wait(6000)
124 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
125 })
126
127 it('Should not send a notification before the video is published', async function () {
128 this.timeout(50000)
129
130 const updateAt = new Date(new Date().getTime() + 1000000)
131
132 const data = {
133 privacy: VideoPrivacy.PRIVATE,
134 scheduleUpdate: {
135 updateAt: updateAt.toISOString(),
136 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
137 }
138 }
139 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 1, data)
140
141 await wait(6000)
142 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
143 })
144
145 it('Should send a new video notification when a video becomes public', async function () {
146 this.timeout(50000)
147
148 const data = { privacy: VideoPrivacy.PRIVATE }
149 const { name, uuid, shortUUID } = await uploadRandomVideoOnServers(servers, 1, data)
150
151 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
152
153 await servers[0].videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.PUBLIC } })
154
155 await waitJobs(servers)
156 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
157 })
158
159 it('Should send a new video notification when a remote video becomes public', async function () {
160 this.timeout(50000)
161
162 const data = { privacy: VideoPrivacy.PRIVATE }
163 const { name, uuid, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
164
165 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
166
167 await servers[1].videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.PUBLIC } })
168
169 await waitJobs(servers)
170 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
171 })
172
173 it('Should not send a new video notification when a video becomes unlisted', async function () {
174 this.timeout(50000)
175
176 const data = { privacy: VideoPrivacy.PRIVATE }
177 const { name, uuid, shortUUID } = await uploadRandomVideoOnServers(servers, 1, data)
178
179 await servers[0].videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.UNLISTED } })
180
181 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
182 })
183
184 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
185 this.timeout(50000)
186
187 const data = { privacy: VideoPrivacy.PRIVATE }
188 const { name, uuid, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
189
190 await servers[1].videos.update({ id: uuid, attributes: { privacy: VideoPrivacy.UNLISTED } })
191
192 await waitJobs(servers)
193 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
194 })
195
196 it('Should send a new video notification after a video import', async function () {
197 this.timeout(100000)
198
199 const name = 'video import ' + buildUUID()
200
201 const attributes = {
202 name,
203 channelId,
204 privacy: VideoPrivacy.PUBLIC,
205 targetUrl: FIXTURE_URLS.goodVideo
206 }
207 const { video } = await servers[0].imports.importVideo({ attributes })
208
209 await waitJobs(servers)
210
211 await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
212 })
213 })
214
215 describe('My video is published', function () {
216 let baseParams: CheckerBaseParams
217
218 before(() => {
219 baseParams = {
220 server: servers[1],
221 emails,
222 socketNotifications: adminNotificationsServer2,
223 token: servers[1].accessToken
224 }
225 })
226
227 it('Should not send a notification if transcoding is not enabled', async function () {
228 this.timeout(50000)
229
230 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 1)
231 await waitJobs(servers)
232
233 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
234 })
235
236 it('Should not send a notification if the wait transcoding is false', async function () {
237 this.timeout(100_000)
238
239 await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: false })
240 await waitJobs(servers)
241
242 const notification = await servers[0].notifications.getLatest({ token: userAccessToken })
243 if (notification) {
244 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
245 }
246 })
247
248 it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
249 this.timeout(50000)
250
251 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
252 await waitJobs(servers)
253
254 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
255 })
256
257 it('Should send a notification with a transcoded video', async function () {
258 this.timeout(50000)
259
260 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true })
261 await waitJobs(servers)
262
263 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
264 })
265
266 it('Should send a notification when an imported video is transcoded', async function () {
267 this.timeout(120000)
268
269 const name = 'video import ' + buildUUID()
270
271 const attributes = {
272 name,
273 channelId,
274 privacy: VideoPrivacy.PUBLIC,
275 targetUrl: FIXTURE_URLS.goodVideo,
276 waitTranscoding: true
277 }
278 const { video } = await servers[1].imports.importVideo({ attributes })
279
280 await waitJobs(servers)
281 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
282 })
283
284 it('Should send a notification when the scheduled update has been proceeded', async function () {
285 this.timeout(70000)
286
287 // In 2 seconds
288 const updateAt = new Date(new Date().getTime() + 2000)
289
290 const data = {
291 privacy: VideoPrivacy.PRIVATE,
292 scheduleUpdate: {
293 updateAt: updateAt.toISOString(),
294 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
295 }
296 }
297 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
298
299 await wait(6000)
300 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
301 })
302
303 it('Should not send a notification before the video is published', async function () {
304 this.timeout(50000)
305
306 const updateAt = new Date(new Date().getTime() + 1000000)
307
308 const data = {
309 privacy: VideoPrivacy.PRIVATE,
310 scheduleUpdate: {
311 updateAt: updateAt.toISOString(),
312 privacy: VideoPrivacy.PUBLIC as VideoPrivacy.PUBLIC
313 }
314 }
315 const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
316
317 await wait(6000)
318 await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
319 })
320 })
321
322 describe('My video is imported', function () {
323 let baseParams: CheckerBaseParams
324
325 before(() => {
326 baseParams = {
327 server: servers[0],
328 emails,
329 socketNotifications: adminNotifications,
330 token: servers[0].accessToken
331 }
332 })
333
334 it('Should send a notification when the video import failed', async function () {
335 this.timeout(70000)
336
337 const name = 'video import ' + buildUUID()
338
339 const attributes = {
340 name,
341 channelId,
342 privacy: VideoPrivacy.PRIVATE,
343 targetUrl: FIXTURE_URLS.badVideo
344 }
345 const { video: { shortUUID } } = await servers[0].imports.importVideo({ attributes })
346
347 await waitJobs(servers)
348
349 const url = FIXTURE_URLS.badVideo
350 await checkMyVideoImportIsFinished({ ...baseParams, videoName: name, shortUUID, url, success: false, checkType: 'presence' })
351 })
352
353 it('Should send a notification when the video import succeeded', async function () {
354 this.timeout(70000)
355
356 const name = 'video import ' + buildUUID()
357
358 const attributes = {
359 name,
360 channelId,
361 privacy: VideoPrivacy.PRIVATE,
362 targetUrl: FIXTURE_URLS.goodVideo
363 }
364 const { video: { shortUUID } } = await servers[0].imports.importVideo({ attributes })
365
366 await waitJobs(servers)
367
368 const url = FIXTURE_URLS.goodVideo
369 await checkMyVideoImportIsFinished({ ...baseParams, videoName: name, shortUUID, url, success: true, checkType: 'presence' })
370 })
371 })
372
373 describe('New actor follow', function () {
374 let baseParams: CheckerBaseParams
375 const myChannelName = 'super channel name'
376 const myUserName = 'super user name'
377
378 before(async () => {
379 baseParams = {
380 server: servers[0],
381 emails,
382 socketNotifications: userNotifications,
383 token: userAccessToken
384 }
385
386 await servers[0].users.updateMe({ displayName: 'super root name' })
387
388 await servers[0].users.updateMe({
389 token: userAccessToken,
390 displayName: myUserName
391 })
392
393 await servers[1].users.updateMe({ displayName: 'super root 2 name' })
394
395 await servers[0].channels.update({
396 token: userAccessToken,
397 channelName: 'user_1_channel',
398 attributes: { displayName: myChannelName }
399 })
400 })
401
402 it('Should notify when a local channel is following one of our channel', async function () {
403 this.timeout(50000)
404
405 await servers[0].subscriptions.add({ targetUri: 'user_1_channel@localhost:' + servers[0].port })
406 await waitJobs(servers)
407
408 await checkNewActorFollow({
409 ...baseParams,
410 followType: 'channel',
411 followerName: 'root',
412 followerDisplayName: 'super root name',
413 followingDisplayName: myChannelName,
414 checkType: 'presence'
415 })
416
417 await servers[0].subscriptions.remove({ uri: 'user_1_channel@localhost:' + servers[0].port })
418 })
419
420 it('Should notify when a remote channel is following one of our channel', async function () {
421 this.timeout(50000)
422
423 await servers[1].subscriptions.add({ targetUri: 'user_1_channel@localhost:' + servers[0].port })
424 await waitJobs(servers)
425
426 await checkNewActorFollow({
427 ...baseParams,
428 followType: 'channel',
429 followerName: 'root',
430 followerDisplayName: 'super root 2 name',
431 followingDisplayName: myChannelName,
432 checkType: 'presence'
433 })
434
435 await servers[1].subscriptions.remove({ uri: 'user_1_channel@localhost:' + servers[0].port })
436 })
437
438 // PeerTube does not support accout -> account follows
439 // it('Should notify when a local account is following one of our channel', async function () {
440 // this.timeout(50000)
441 //
442 // await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:' + servers[0].port)
443 //
444 // await waitJobs(servers)
445 //
446 // await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
447 // })
448
449 // it('Should notify when a remote account is following one of our channel', async function () {
450 // this.timeout(50000)
451 //
452 // await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:' + servers[0].port)
453 //
454 // await waitJobs(servers)
455 //
456 // await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
457 // })
458 })
459
460 after(async function () {
461 MockSmtpServer.Instance.kill()
462
463 await cleanupTests(servers)
464 })
465 })