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