]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/video-playlists.ts
Use test wrapper exit function
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-playlists.ts
1 /* tslint:disable:no-unused-expression */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import {
6 addVideoChannel,
7 addVideoInPlaylist,
8 checkPlaylistFilesWereRemoved, cleanupTests,
9 createUser,
10 createVideoPlaylist,
11 deleteVideoChannel,
12 deleteVideoPlaylist,
13 doubleFollow, doVideosExistInMyPlaylist,
14 flushAndRunMultipleServers,
15 flushTests,
16 getAccountPlaylistsList,
17 getAccountPlaylistsListWithToken, getMyUserInformation,
18 getPlaylistVideos,
19 getVideoChannelPlaylistsList,
20 getVideoPlaylist,
21 getVideoPlaylistPrivacies,
22 getVideoPlaylistsList,
23 getVideoPlaylistWithToken,
24 killallServers,
25 removeUser,
26 removeVideoFromPlaylist,
27 reorderVideosPlaylist,
28 ServerInfo,
29 setAccessTokensToServers,
30 setDefaultVideoChannel,
31 testImage,
32 unfollow,
33 updateVideoPlaylist,
34 updateVideoPlaylistElement,
35 uploadVideo,
36 uploadVideoAndGetId,
37 userLogin,
38 waitJobs
39 } from '../../../../shared/extra-utils'
40 import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
41 import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
42 import { Video } from '../../../../shared/models/videos'
43 import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
44 import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model'
45 import { User } from '../../../../shared/models/users'
46
47 const expect = chai.expect
48
49 describe('Test video playlists', function () {
50 let servers: ServerInfo[] = []
51
52 let playlistServer2Id1: number
53 let playlistServer2Id2: number
54 let playlistServer2UUID2: number
55
56 let playlistServer1Id: number
57 let playlistServer1UUID: string
58
59 let nsfwVideoServer1: number
60
61 before(async function () {
62 this.timeout(120000)
63
64 servers = await flushAndRunMultipleServers(3, { transcoding: { enabled: false } })
65
66 // Get the access tokens
67 await setAccessTokensToServers(servers)
68 await setDefaultVideoChannel(servers)
69
70 // Server 1 and server 2 follow each other
71 await doubleFollow(servers[0], servers[1])
72 // Server 1 and server 3 follow each other
73 await doubleFollow(servers[0], servers[2])
74
75 {
76 const serverPromises: Promise<any>[][] = []
77
78 for (const server of servers) {
79 const videoPromises: Promise<any>[] = []
80
81 for (let i = 0; i < 7; i++) {
82 videoPromises.push(
83 uploadVideo(server.url, server.accessToken, { name: `video ${i} server ${server.serverNumber}`, nsfw: false })
84 .then(res => res.body.video)
85 )
86 }
87
88 serverPromises.push(videoPromises)
89 }
90
91 servers[0].videos = await Promise.all(serverPromises[0])
92 servers[1].videos = await Promise.all(serverPromises[1])
93 servers[2].videos = await Promise.all(serverPromises[2])
94 }
95
96 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'NSFW video', nsfw: true })).id
97
98 await waitJobs(servers)
99 })
100
101 it('Should list video playlist privacies', async function () {
102 const res = await getVideoPlaylistPrivacies(servers[0].url)
103
104 const privacies = res.body
105 expect(Object.keys(privacies)).to.have.length.at.least(3)
106
107 expect(privacies[3]).to.equal('Private')
108 })
109
110 it('Should list watch later playlist', async function () {
111 const url = servers[ 0 ].url
112 const accessToken = servers[ 0 ].accessToken
113
114 {
115 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
116
117 expect(res.body.total).to.equal(1)
118 expect(res.body.data).to.have.lengthOf(1)
119
120 const playlist: VideoPlaylist = res.body.data[ 0 ]
121 expect(playlist.displayName).to.equal('Watch later')
122 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER)
123 expect(playlist.type.label).to.equal('Watch later')
124 }
125
126 {
127 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.REGULAR)
128
129 expect(res.body.total).to.equal(0)
130 expect(res.body.data).to.have.lengthOf(0)
131 }
132
133 {
134 const res = await getAccountPlaylistsList(url, 'root', 0, 5)
135 expect(res.body.total).to.equal(0)
136 expect(res.body.data).to.have.lengthOf(0)
137 }
138 })
139
140 it('Should create a playlist on server 1 and have the playlist on server 2 and 3', async function () {
141 this.timeout(30000)
142
143 await createVideoPlaylist({
144 url: servers[0].url,
145 token: servers[0].accessToken,
146 playlistAttrs: {
147 displayName: 'my super playlist',
148 privacy: VideoPlaylistPrivacy.PUBLIC,
149 description: 'my super description',
150 thumbnailfile: 'thumbnail.jpg',
151 videoChannelId: servers[0].videoChannel.id
152 }
153 })
154
155 await waitJobs(servers)
156
157 for (const server of servers) {
158 const res = await getVideoPlaylistsList(server.url, 0, 5)
159 expect(res.body.total).to.equal(1)
160 expect(res.body.data).to.have.lengthOf(1)
161
162 const playlistFromList = res.body.data[0] as VideoPlaylist
163
164 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
165 const playlistFromGet = res2.body
166
167 for (const playlist of [ playlistFromGet, playlistFromList ]) {
168 expect(playlist.id).to.be.a('number')
169 expect(playlist.uuid).to.be.a('string')
170
171 expect(playlist.isLocal).to.equal(server.serverNumber === 1)
172
173 expect(playlist.displayName).to.equal('my super playlist')
174 expect(playlist.description).to.equal('my super description')
175 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
176 expect(playlist.privacy.label).to.equal('Public')
177 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
178 expect(playlist.type.label).to.equal('Regular')
179
180 expect(playlist.videosLength).to.equal(0)
181
182 expect(playlist.ownerAccount.name).to.equal('root')
183 expect(playlist.ownerAccount.displayName).to.equal('root')
184 expect(playlist.videoChannel.name).to.equal('root_channel')
185 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
186 }
187 }
188 })
189
190 it('Should create a playlist on server 2 and have the playlist on server 1 but not on server 3', async function () {
191 this.timeout(30000)
192
193 {
194 const res = await createVideoPlaylist({
195 url: servers[1].url,
196 token: servers[1].accessToken,
197 playlistAttrs: {
198 displayName: 'playlist 2',
199 privacy: VideoPlaylistPrivacy.PUBLIC,
200 videoChannelId: servers[1].videoChannel.id
201 }
202 })
203 playlistServer2Id1 = res.body.videoPlaylist.id
204 }
205
206 {
207 const res = await createVideoPlaylist({
208 url: servers[ 1 ].url,
209 token: servers[ 1 ].accessToken,
210 playlistAttrs: {
211 displayName: 'playlist 3',
212 privacy: VideoPlaylistPrivacy.PUBLIC,
213 thumbnailfile: 'thumbnail.jpg',
214 videoChannelId: servers[1].videoChannel.id
215 }
216 })
217
218 playlistServer2Id2 = res.body.videoPlaylist.id
219 playlistServer2UUID2 = res.body.videoPlaylist.uuid
220 }
221
222 for (let id of [ playlistServer2Id1, playlistServer2Id2 ]) {
223 await addVideoInPlaylist({
224 url: servers[ 1 ].url,
225 token: servers[ 1 ].accessToken,
226 playlistId: id,
227 elementAttrs: { videoId: servers[ 1 ].videos[ 0 ].id, startTimestamp: 1, stopTimestamp: 2 }
228 })
229 await addVideoInPlaylist({
230 url: servers[ 1 ].url,
231 token: servers[ 1 ].accessToken,
232 playlistId: id,
233 elementAttrs: { videoId: servers[ 1 ].videos[ 1 ].id }
234 })
235 }
236
237 await waitJobs(servers)
238
239 for (const server of [ servers[0], servers[1] ]) {
240 const res = await getVideoPlaylistsList(server.url, 0, 5)
241
242 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
243 expect(playlist2).to.not.be.undefined
244 await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath)
245
246 const playlist3 = res.body.data.find(p => p.displayName === 'playlist 3')
247 expect(playlist3).to.not.be.undefined
248 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath)
249 }
250
251 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
252 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined
253 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined
254 })
255
256 it('Should have the playlist on server 3 after a new follow', async function () {
257 this.timeout(30000)
258
259 // Server 2 and server 3 follow each other
260 await doubleFollow(servers[1], servers[2])
261
262 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
263
264 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
265 expect(playlist2).to.not.be.undefined
266 await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath)
267
268 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined
269 })
270
271 it('Should correctly list the playlists', async function () {
272 this.timeout(30000)
273
274 {
275 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, 'createdAt')
276
277 expect(res.body.total).to.equal(3)
278
279 const data: VideoPlaylist[] = res.body.data
280 expect(data).to.have.lengthOf(2)
281 expect(data[ 0 ].displayName).to.equal('playlist 2')
282 expect(data[ 1 ].displayName).to.equal('playlist 3')
283 }
284
285 {
286 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, '-createdAt')
287
288 expect(res.body.total).to.equal(3)
289
290 const data: VideoPlaylist[] = res.body.data
291 expect(data).to.have.lengthOf(2)
292 expect(data[ 0 ].displayName).to.equal('playlist 2')
293 expect(data[ 1 ].displayName).to.equal('my super playlist')
294 }
295 })
296
297 it('Should list video channel playlists', async function () {
298 this.timeout(30000)
299
300 {
301 const res = await getVideoChannelPlaylistsList(servers[ 0 ].url, 'root_channel', 0, 2, '-createdAt')
302
303 expect(res.body.total).to.equal(1)
304
305 const data: VideoPlaylist[] = res.body.data
306 expect(data).to.have.lengthOf(1)
307 expect(data[ 0 ].displayName).to.equal('my super playlist')
308 }
309 })
310
311 it('Should list account playlists', async function () {
312 this.timeout(30000)
313
314 {
315 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, '-createdAt')
316
317 expect(res.body.total).to.equal(2)
318
319 const data: VideoPlaylist[] = res.body.data
320 expect(data).to.have.lengthOf(1)
321 expect(data[ 0 ].displayName).to.equal('playlist 2')
322 }
323
324 {
325 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, 'createdAt')
326
327 expect(res.body.total).to.equal(2)
328
329 const data: VideoPlaylist[] = res.body.data
330 expect(data).to.have.lengthOf(1)
331 expect(data[ 0 ].displayName).to.equal('playlist 3')
332 }
333 })
334
335 it('Should not list unlisted or private playlists', async function () {
336 this.timeout(30000)
337
338 await createVideoPlaylist({
339 url: servers[ 1 ].url,
340 token: servers[ 1 ].accessToken,
341 playlistAttrs: {
342 displayName: 'playlist unlisted',
343 privacy: VideoPlaylistPrivacy.UNLISTED
344 }
345 })
346
347 await createVideoPlaylist({
348 url: servers[ 1 ].url,
349 token: servers[ 1 ].accessToken,
350 playlistAttrs: {
351 displayName: 'playlist private',
352 privacy: VideoPlaylistPrivacy.PRIVATE
353 }
354 })
355
356 await waitJobs(servers)
357
358 for (const server of servers) {
359 const results = [
360 await getAccountPlaylistsList(server.url, 'root@localhost:9002', 0, 5, '-createdAt'),
361 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt')
362 ]
363
364 expect(results[0].body.total).to.equal(2)
365 expect(results[1].body.total).to.equal(3)
366
367 for (const res of results) {
368 const data: VideoPlaylist[] = res.body.data
369 expect(data).to.have.lengthOf(2)
370 expect(data[ 0 ].displayName).to.equal('playlist 3')
371 expect(data[ 1 ].displayName).to.equal('playlist 2')
372 }
373 }
374 })
375
376 it('Should update a playlist', async function () {
377 this.timeout(30000)
378
379 await updateVideoPlaylist({
380 url: servers[1].url,
381 token: servers[1].accessToken,
382 playlistAttrs: {
383 displayName: 'playlist 3 updated',
384 description: 'description updated',
385 privacy: VideoPlaylistPrivacy.UNLISTED,
386 thumbnailfile: 'thumbnail.jpg',
387 videoChannelId: servers[1].videoChannel.id
388 },
389 playlistId: playlistServer2Id2
390 })
391
392 await waitJobs(servers)
393
394 for (const server of servers) {
395 const res = await getVideoPlaylist(server.url, playlistServer2UUID2)
396 const playlist: VideoPlaylist = res.body
397
398 expect(playlist.displayName).to.equal('playlist 3 updated')
399 expect(playlist.description).to.equal('description updated')
400
401 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.UNLISTED)
402 expect(playlist.privacy.label).to.equal('Unlisted')
403
404 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
405 expect(playlist.type.label).to.equal('Regular')
406
407 expect(playlist.videosLength).to.equal(2)
408
409 expect(playlist.ownerAccount.name).to.equal('root')
410 expect(playlist.ownerAccount.displayName).to.equal('root')
411 expect(playlist.videoChannel.name).to.equal('root_channel')
412 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
413 }
414 })
415
416 it('Should create a playlist containing different startTimestamp/endTimestamp videos', async function () {
417 this.timeout(30000)
418
419 const addVideo = (elementAttrs: any) => {
420 return addVideoInPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: playlistServer1Id, elementAttrs })
421 }
422
423 const res = await createVideoPlaylist({
424 url: servers[ 0 ].url,
425 token: servers[ 0 ].accessToken,
426 playlistAttrs: {
427 displayName: 'playlist 4',
428 privacy: VideoPlaylistPrivacy.PUBLIC,
429 videoChannelId: servers[0].videoChannel.id
430 }
431 })
432
433 playlistServer1Id = res.body.videoPlaylist.id
434 playlistServer1UUID = res.body.videoPlaylist.uuid
435
436 await addVideo({ videoId: servers[0].videos[0].uuid, startTimestamp: 15, stopTimestamp: 28 })
437 await addVideo({ videoId: servers[2].videos[1].uuid, startTimestamp: 35 })
438 await addVideo({ videoId: servers[2].videos[2].uuid })
439 await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 })
440 await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 })
441 await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 })
442
443 await waitJobs(servers)
444 })
445
446 it('Should correctly list playlist videos', async function () {
447 this.timeout(30000)
448
449 for (const server of servers) {
450 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
451
452 expect(res.body.total).to.equal(6)
453
454 const videos: Video[] = res.body.data
455 expect(videos).to.have.lengthOf(6)
456
457 expect(videos[0].name).to.equal('video 0 server 1')
458 expect(videos[0].playlistElement.position).to.equal(1)
459 expect(videos[0].playlistElement.startTimestamp).to.equal(15)
460 expect(videos[0].playlistElement.stopTimestamp).to.equal(28)
461
462 expect(videos[1].name).to.equal('video 1 server 3')
463 expect(videos[1].playlistElement.position).to.equal(2)
464 expect(videos[1].playlistElement.startTimestamp).to.equal(35)
465 expect(videos[1].playlistElement.stopTimestamp).to.be.null
466
467 expect(videos[2].name).to.equal('video 2 server 3')
468 expect(videos[2].playlistElement.position).to.equal(3)
469 expect(videos[2].playlistElement.startTimestamp).to.be.null
470 expect(videos[2].playlistElement.stopTimestamp).to.be.null
471
472 expect(videos[3].name).to.equal('video 3 server 1')
473 expect(videos[3].playlistElement.position).to.equal(4)
474 expect(videos[3].playlistElement.startTimestamp).to.be.null
475 expect(videos[3].playlistElement.stopTimestamp).to.equal(35)
476
477 expect(videos[4].name).to.equal('video 4 server 1')
478 expect(videos[4].playlistElement.position).to.equal(5)
479 expect(videos[4].playlistElement.startTimestamp).to.equal(45)
480 expect(videos[4].playlistElement.stopTimestamp).to.equal(60)
481
482 expect(videos[5].name).to.equal('NSFW video')
483 expect(videos[5].playlistElement.position).to.equal(6)
484 expect(videos[5].playlistElement.startTimestamp).to.equal(5)
485 expect(videos[5].playlistElement.stopTimestamp).to.be.null
486
487 const res2 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10, { nsfw: false })
488 expect(res2.body.total).to.equal(5)
489 expect(res2.body.data.find(v => v.name === 'NSFW video')).to.be.undefined
490
491 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2)
492 expect(res3.body.data).to.have.lengthOf(2)
493 }
494 })
495
496 it('Should reorder the playlist', async function () {
497 this.timeout(30000)
498
499 {
500 await reorderVideosPlaylist({
501 url: servers[ 0 ].url,
502 token: servers[ 0 ].accessToken,
503 playlistId: playlistServer1Id,
504 elementAttrs: {
505 startPosition: 2,
506 insertAfterPosition: 3
507 }
508 })
509
510 await waitJobs(servers)
511
512 for (const server of servers) {
513 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
514 const names = res.body.data.map(v => v.name)
515
516 expect(names).to.deep.equal([
517 'video 0 server 1',
518 'video 2 server 3',
519 'video 1 server 3',
520 'video 3 server 1',
521 'video 4 server 1',
522 'NSFW video'
523 ])
524 }
525 }
526
527 {
528 await reorderVideosPlaylist({
529 url: servers[0].url,
530 token: servers[0].accessToken,
531 playlistId: playlistServer1Id,
532 elementAttrs: {
533 startPosition: 1,
534 reorderLength: 3,
535 insertAfterPosition: 4
536 }
537 })
538
539 await waitJobs(servers)
540
541 for (const server of servers) {
542 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
543 const names = res.body.data.map(v => v.name)
544
545 expect(names).to.deep.equal([
546 'video 3 server 1',
547 'video 0 server 1',
548 'video 2 server 3',
549 'video 1 server 3',
550 'video 4 server 1',
551 'NSFW video'
552 ])
553 }
554 }
555
556 {
557 await reorderVideosPlaylist({
558 url: servers[0].url,
559 token: servers[0].accessToken,
560 playlistId: playlistServer1Id,
561 elementAttrs: {
562 startPosition: 6,
563 insertAfterPosition: 3
564 }
565 })
566
567 await waitJobs(servers)
568
569 for (const server of servers) {
570 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
571 const videos: Video[] = res.body.data
572
573 const names = videos.map(v => v.name)
574
575 expect(names).to.deep.equal([
576 'video 3 server 1',
577 'video 0 server 1',
578 'video 2 server 3',
579 'NSFW video',
580 'video 1 server 3',
581 'video 4 server 1'
582 ])
583
584 for (let i = 1; i <= videos.length; i++) {
585 expect(videos[i - 1].playlistElement.position).to.equal(i)
586 }
587 }
588 }
589 })
590
591 it('Should update startTimestamp/endTimestamp of some elements', async function () {
592 this.timeout(30000)
593
594 await updateVideoPlaylistElement({
595 url: servers[0].url,
596 token: servers[0].accessToken,
597 playlistId: playlistServer1Id,
598 videoId: servers[0].videos[3].uuid,
599 elementAttrs: {
600 startTimestamp: 1
601 }
602 })
603
604 await updateVideoPlaylistElement({
605 url: servers[0].url,
606 token: servers[0].accessToken,
607 playlistId: playlistServer1Id,
608 videoId: servers[0].videos[4].uuid,
609 elementAttrs: {
610 stopTimestamp: null
611 }
612 })
613
614 await waitJobs(servers)
615
616 for (const server of servers) {
617 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
618 const videos: Video[] = res.body.data
619
620 expect(videos[0].name).to.equal('video 3 server 1')
621 expect(videos[0].playlistElement.position).to.equal(1)
622 expect(videos[0].playlistElement.startTimestamp).to.equal(1)
623 expect(videos[0].playlistElement.stopTimestamp).to.equal(35)
624
625 expect(videos[5].name).to.equal('video 4 server 1')
626 expect(videos[5].playlistElement.position).to.equal(6)
627 expect(videos[5].playlistElement.startTimestamp).to.equal(45)
628 expect(videos[5].playlistElement.stopTimestamp).to.be.null
629 }
630 })
631
632 it('Should check videos existence in my playlist', async function () {
633 const videoIds = [
634 servers[0].videos[0].id,
635 42000,
636 servers[0].videos[3].id,
637 43000,
638 servers[0].videos[4].id
639 ]
640 const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds)
641 const obj = res.body as VideoExistInPlaylist
642
643 {
644 const elem = obj[servers[0].videos[0].id]
645 expect(elem).to.have.lengthOf(1)
646 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
647 expect(elem[ 0 ].startTimestamp).to.equal(15)
648 expect(elem[ 0 ].stopTimestamp).to.equal(28)
649 }
650
651 {
652 const elem = obj[servers[0].videos[3].id]
653 expect(elem).to.have.lengthOf(1)
654 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
655 expect(elem[ 0 ].startTimestamp).to.equal(1)
656 expect(elem[ 0 ].stopTimestamp).to.equal(35)
657 }
658
659 {
660 const elem = obj[servers[0].videos[4].id]
661 expect(elem).to.have.lengthOf(1)
662 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
663 expect(elem[ 0 ].startTimestamp).to.equal(45)
664 expect(elem[ 0 ].stopTimestamp).to.equal(null)
665 }
666
667 expect(obj[42000]).to.have.lengthOf(0)
668 expect(obj[43000]).to.have.lengthOf(0)
669 })
670
671 it('Should automatically update updatedAt field of playlists', async function () {
672 const server = servers[1]
673 const videoId = servers[1].videos[5].id
674
675 async function getPlaylistNames () {
676 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt')
677
678 return (res.body.data as VideoPlaylist[]).map(p => p.displayName)
679 }
680
681 const elementAttrs = { videoId }
682 await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, elementAttrs })
683 await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, elementAttrs })
684
685 const names1 = await getPlaylistNames()
686 expect(names1[0]).to.equal('playlist 3 updated')
687 expect(names1[1]).to.equal('playlist 2')
688
689 await removeVideoFromPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, videoId })
690
691 const names2 = await getPlaylistNames()
692 expect(names2[0]).to.equal('playlist 2')
693 expect(names2[1]).to.equal('playlist 3 updated')
694
695 await removeVideoFromPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, videoId })
696
697 const names3 = await getPlaylistNames()
698 expect(names3[0]).to.equal('playlist 3 updated')
699 expect(names3[1]).to.equal('playlist 2')
700 })
701
702 it('Should delete some elements', async function () {
703 this.timeout(30000)
704
705 await removeVideoFromPlaylist({
706 url: servers[0].url,
707 token: servers[0].accessToken,
708 playlistId: playlistServer1Id,
709 videoId: servers[0].videos[3].uuid
710 })
711
712 await removeVideoFromPlaylist({
713 url: servers[0].url,
714 token: servers[0].accessToken,
715 playlistId: playlistServer1Id,
716 videoId: nsfwVideoServer1
717 })
718
719 await waitJobs(servers)
720
721 for (const server of servers) {
722 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
723
724 expect(res.body.total).to.equal(4)
725
726 const videos: Video[] = res.body.data
727 expect(videos).to.have.lengthOf(4)
728
729 expect(videos[ 0 ].name).to.equal('video 0 server 1')
730 expect(videos[ 0 ].playlistElement.position).to.equal(1)
731
732 expect(videos[ 1 ].name).to.equal('video 2 server 3')
733 expect(videos[ 1 ].playlistElement.position).to.equal(2)
734
735 expect(videos[ 2 ].name).to.equal('video 1 server 3')
736 expect(videos[ 2 ].playlistElement.position).to.equal(3)
737
738 expect(videos[ 3 ].name).to.equal('video 4 server 1')
739 expect(videos[ 3 ].playlistElement.position).to.equal(4)
740 }
741 })
742
743 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () {
744 this.timeout(30000)
745
746 await deleteVideoPlaylist(servers[0].url, servers[0].accessToken, playlistServer1Id)
747
748 await waitJobs(servers)
749
750 for (const server of servers) {
751 await getVideoPlaylist(server.url, playlistServer1UUID, 404)
752 }
753 })
754
755 it('Should have deleted the thumbnail on server 1, 2 and 3', async function () {
756 this.timeout(30000)
757
758 for (const server of servers) {
759 await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.serverNumber)
760 }
761 })
762
763 it('Should unfollow servers 1 and 2 and hide their playlists', async function () {
764 this.timeout(30000)
765
766 const finder = data => data.find(p => p.displayName === 'my super playlist')
767
768 {
769 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
770 expect(res.body.total).to.equal(2)
771 expect(finder(res.body.data)).to.not.be.undefined
772 }
773
774 await unfollow(servers[2].url, servers[2].accessToken, servers[0])
775
776 {
777 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
778 expect(res.body.total).to.equal(1)
779
780 expect(finder(res.body.data)).to.be.undefined
781 }
782 })
783
784 it('Should delete a channel and put the associated playlist in private mode', async function () {
785 this.timeout(30000)
786
787 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' })
788 const videoChannelId = res.body.videoChannel.id
789
790 const res2 = await createVideoPlaylist({
791 url: servers[0].url,
792 token: servers[0].accessToken,
793 playlistAttrs: {
794 displayName: 'channel playlist',
795 privacy: VideoPlaylistPrivacy.PUBLIC,
796 videoChannelId
797 }
798 })
799 const videoPlaylistUUID = res2.body.videoPlaylist.uuid
800
801 await waitJobs(servers)
802
803 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'super_channel')
804
805 await waitJobs(servers)
806
807 const res3 = await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistUUID)
808 expect(res3.body.displayName).to.equal('channel playlist')
809 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
810
811 await getVideoPlaylist(servers[1].url, videoPlaylistUUID, 404)
812 })
813
814 it('Should delete an account and delete its playlists', async function () {
815 this.timeout(30000)
816
817 const user = { username: 'user_1', password: 'password' }
818 const res = await createUser({
819 url: servers[ 0 ].url,
820 accessToken: servers[ 0 ].accessToken,
821 username: user.username,
822 password: user.password
823 })
824
825 const userId = res.body.user.id
826 const userAccessToken = await userLogin(servers[0], user)
827
828 const resChannel = await getMyUserInformation(servers[0].url, userAccessToken)
829 const userChannel = (resChannel.body as User).videoChannels[0]
830
831 await createVideoPlaylist({
832 url: servers[0].url,
833 token: userAccessToken,
834 playlistAttrs: {
835 displayName: 'playlist to be deleted',
836 privacy: VideoPlaylistPrivacy.PUBLIC,
837 videoChannelId: userChannel.id
838 }
839 })
840
841 await waitJobs(servers)
842
843 const finder = data => data.find(p => p.displayName === 'playlist to be deleted')
844
845 {
846 for (const server of [ servers[0], servers[1] ]) {
847 const res = await getVideoPlaylistsList(server.url, 0, 15)
848 expect(finder(res.body.data)).to.not.be.undefined
849 }
850 }
851
852 await removeUser(servers[0].url, userId, servers[0].accessToken)
853 await waitJobs(servers)
854
855 {
856 for (const server of [ servers[0], servers[1] ]) {
857 const res = await getVideoPlaylistsList(server.url, 0, 15)
858 expect(finder(res.body.data)).to.be.undefined
859 }
860 }
861 })
862
863 after(async function () {
864 await cleanupTests(servers)
865 })
866 })