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