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