]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/videos/video-playlists.ts
Specify if we want to fallback to the server token
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-playlists.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
418d092a 2
418d092a 3import 'mocha'
59fd824c 4import * as chai from 'chai'
c3d29f69 5import { HttpStatusCode } from '@shared/core-utils'
418d092a
C
6import {
7 addVideoChannel,
df0b219d 8 addVideoInPlaylist,
bfbd9128 9 addVideoToBlacklist,
8519cc92
C
10 checkPlaylistFilesWereRemoved,
11 cleanupTests,
418d092a 12 createUser,
df0b219d
C
13 createVideoPlaylist,
14 deleteVideoChannel,
15 deleteVideoPlaylist,
8519cc92
C
16 doubleFollow,
17 doVideosExistInMyPlaylist,
418d092a 18 flushAndRunMultipleServers,
bfbd9128
C
19 generateUserAccessToken,
20 getAccessToken,
df0b219d 21 getAccountPlaylistsList,
8519cc92
C
22 getAccountPlaylistsListWithToken,
23 getMyUserInformation,
df0b219d
C
24 getPlaylistVideos,
25 getVideoChannelPlaylistsList,
26 getVideoPlaylist,
d4c9f45b 27 getVideoPlaylistPrivacies,
df0b219d
C
28 getVideoPlaylistsList,
29 getVideoPlaylistWithToken,
df0b219d 30 removeUser,
bfbd9128 31 removeVideoFromBlacklist,
df0b219d
C
32 removeVideoFromPlaylist,
33 reorderVideosPlaylist,
418d092a
C
34 ServerInfo,
35 setAccessTokensToServers,
df0b219d 36 setDefaultVideoChannel,
418d092a 37 testImage,
bfbd9128 38 updateVideo,
df0b219d
C
39 updateVideoPlaylist,
40 updateVideoPlaylistElement,
418d092a 41 uploadVideo,
df0b219d 42 uploadVideoAndGetId,
418d092a 43 userLogin,
7f88a58e 44 wait,
bfbd9128 45 waitJobs
c3d29f69 46} from '@shared/extra-utils'
bfbd9128 47import {
c3d29f69
C
48 User,
49 VideoExistInPlaylist,
50 VideoPlaylist,
51 VideoPlaylistCreateResult,
52 VideoPlaylistElement,
53 VideoPlaylistElementType,
54 VideoPlaylistPrivacy,
55 VideoPlaylistType,
56 VideoPrivacy
57} from '@shared/models'
418d092a
C
58
59const expect = chai.expect
60
bfbd9128
C
61async function checkPlaylistElementType (
62 servers: ServerInfo[],
63 playlistId: string,
64 type: VideoPlaylistElementType,
65 position: number,
66 name: string,
67 total: number
68) {
69 for (const server of servers) {
70 const res = await getPlaylistVideos(server.url, server.accessToken, playlistId, 0, 10)
71 expect(res.body.total).to.equal(total)
72
73 const videoElement: VideoPlaylistElement = res.body.data.find((e: VideoPlaylistElement) => e.position === position)
74 expect(videoElement.type).to.equal(type, 'On server ' + server.url)
75
76 if (type === VideoPlaylistElementType.REGULAR) {
77 expect(videoElement.video).to.not.be.null
78 expect(videoElement.video.name).to.equal(name)
79 } else {
80 expect(videoElement.video).to.be.null
81 }
82 }
83}
84
418d092a
C
85describe('Test video playlists', function () {
86 let servers: ServerInfo[] = []
87
df0b219d
C
88 let playlistServer2Id1: number
89 let playlistServer2Id2: number
90 let playlistServer2UUID2: number
91
92 let playlistServer1Id: number
93 let playlistServer1UUID: string
bfbd9128
C
94 let playlistServer1UUID2: string
95
96 let playlistElementServer1Video4: number
97 let playlistElementServer1Video5: number
98 let playlistElementNSFW: number
df0b219d
C
99
100 let nsfwVideoServer1: number
101
bfbd9128
C
102 let userAccessTokenServer1: string
103
418d092a
C
104 before(async function () {
105 this.timeout(120000)
106
df0b219d 107 servers = await flushAndRunMultipleServers(3, { transcoding: { enabled: false } })
418d092a
C
108
109 // Get the access tokens
110 await setAccessTokensToServers(servers)
df0b219d 111 await setDefaultVideoChannel(servers)
418d092a
C
112
113 // Server 1 and server 2 follow each other
114 await doubleFollow(servers[0], servers[1])
115 // Server 1 and server 3 follow each other
116 await doubleFollow(servers[0], servers[2])
df0b219d
C
117
118 {
59fd824c
C
119 servers[0].videos = []
120 servers[1].videos = []
121 servers[2].videos = []
df0b219d
C
122
123 for (const server of servers) {
df0b219d 124 for (let i = 0; i < 7; i++) {
59fd824c
C
125 const name = `video ${i} server ${server.serverNumber}`
126 const resVideo = await uploadVideo(server.url, server.accessToken, { name, nsfw: false })
df0b219d 127
59fd824c
C
128 server.videos.push(resVideo.body.video)
129 }
df0b219d 130 }
df0b219d
C
131 }
132
a1587156 133 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'NSFW video', nsfw: true })).id
df0b219d 134
bfbd9128
C
135 {
136 await createUser({
a1587156
C
137 url: servers[0].url,
138 accessToken: servers[0].accessToken,
bfbd9128
C
139 username: 'user1',
140 password: 'password'
141 })
142 userAccessTokenServer1 = await getAccessToken(servers[0].url, 'user1', 'password')
143 }
144
df0b219d 145 await waitJobs(servers)
418d092a
C
146 })
147
bfbd9128
C
148 describe('Get default playlists', function () {
149 it('Should list video playlist privacies', async function () {
a1587156 150 const res = await getVideoPlaylistPrivacies(servers[0].url)
d4c9f45b 151
bfbd9128
C
152 const privacies = res.body
153 expect(Object.keys(privacies)).to.have.length.at.least(3)
d4c9f45b 154
a1587156 155 expect(privacies[3]).to.equal('Private')
bfbd9128 156 })
d4c9f45b 157
bfbd9128 158 it('Should list watch later playlist', async function () {
a1587156
C
159 const url = servers[0].url
160 const accessToken = servers[0].accessToken
df0b219d 161
bfbd9128
C
162 {
163 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
164
165 expect(res.body.total).to.equal(1)
166 expect(res.body.data).to.have.lengthOf(1)
167
a1587156 168 const playlist: VideoPlaylist = res.body.data[0]
bfbd9128
C
169 expect(playlist.displayName).to.equal('Watch later')
170 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER)
171 expect(playlist.type.label).to.equal('Watch later')
172 }
173
174 {
175 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.REGULAR)
176
177 expect(res.body.total).to.equal(0)
178 expect(res.body.data).to.have.lengthOf(0)
179 }
180
181 {
182 const res = await getAccountPlaylistsList(url, 'root', 0, 5)
183 expect(res.body.total).to.equal(0)
184 expect(res.body.data).to.have.lengthOf(0)
185 }
186 })
187
188 it('Should get private playlist for a classic user', async function () {
a1587156 189 const token = await generateUserAccessToken(servers[0], 'toto')
bfbd9128 190
a1587156 191 const res = await getAccountPlaylistsListWithToken(servers[0].url, token, 'toto', 0, 5)
df0b219d
C
192
193 expect(res.body.total).to.equal(1)
194 expect(res.body.data).to.have.lengthOf(1)
418d092a 195
a1587156
C
196 const playlistId = res.body.data[0].id
197 await getPlaylistVideos(servers[0].url, token, playlistId, 0, 5)
bfbd9128
C
198 })
199 })
df0b219d 200
bfbd9128 201 describe('Create and federate playlists', function () {
df0b219d 202
bfbd9128
C
203 it('Should create a playlist on server 1 and have the playlist on server 2 and 3', async function () {
204 this.timeout(30000)
df0b219d 205
bfbd9128 206 await createVideoPlaylist({
a1587156
C
207 url: servers[0].url,
208 token: servers[0].accessToken,
bfbd9128
C
209 playlistAttrs: {
210 displayName: 'my super playlist',
211 privacy: VideoPlaylistPrivacy.PUBLIC,
212 description: 'my super description',
213 thumbnailfile: 'thumbnail.jpg',
a1587156 214 videoChannelId: servers[0].videoChannel.id
bfbd9128
C
215 }
216 })
217
218 await waitJobs(servers)
7f88a58e
C
219 // Processing a playlist by the receiver could be long
220 await wait(3000)
bfbd9128
C
221
222 for (const server of servers) {
223 const res = await getVideoPlaylistsList(server.url, 0, 5)
224 expect(res.body.total).to.equal(1)
225 expect(res.body.data).to.have.lengthOf(1)
226
a1587156 227 const playlistFromList = res.body.data[0] as VideoPlaylist
bfbd9128
C
228
229 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
951b582f 230 const playlistFromGet = res2.body as VideoPlaylist
bfbd9128
C
231
232 for (const playlist of [ playlistFromGet, playlistFromList ]) {
233 expect(playlist.id).to.be.a('number')
234 expect(playlist.uuid).to.be.a('string')
235
236 expect(playlist.isLocal).to.equal(server.serverNumber === 1)
237
238 expect(playlist.displayName).to.equal('my super playlist')
239 expect(playlist.description).to.equal('my super description')
240 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
241 expect(playlist.privacy.label).to.equal('Public')
242 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
243 expect(playlist.type.label).to.equal('Regular')
951b582f 244 expect(playlist.embedPath).to.equal('/video-playlists/embed/' + playlist.uuid)
bfbd9128
C
245
246 expect(playlist.videosLength).to.equal(0)
df0b219d 247
bfbd9128
C
248 expect(playlist.ownerAccount.name).to.equal('root')
249 expect(playlist.ownerAccount.displayName).to.equal('root')
250 expect(playlist.videoChannel.name).to.equal('root_channel')
251 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
252 }
253 }
254 })
4d09cfba 255
bfbd9128
C
256 it('Should create a playlist on server 2 and have the playlist on server 1 but not on server 3', async function () {
257 this.timeout(30000)
258
259 {
260 const res = await createVideoPlaylist({
a1587156
C
261 url: servers[1].url,
262 token: servers[1].accessToken,
bfbd9128
C
263 playlistAttrs: {
264 displayName: 'playlist 2',
265 privacy: VideoPlaylistPrivacy.PUBLIC,
a1587156 266 videoChannelId: servers[1].videoChannel.id
bfbd9128
C
267 }
268 })
269 playlistServer2Id1 = res.body.videoPlaylist.id
270 }
4d09cfba 271
bfbd9128
C
272 {
273 const res = await createVideoPlaylist({
a1587156
C
274 url: servers[1].url,
275 token: servers[1].accessToken,
bfbd9128
C
276 playlistAttrs: {
277 displayName: 'playlist 3',
278 privacy: VideoPlaylistPrivacy.PUBLIC,
279 thumbnailfile: 'thumbnail.jpg',
a1587156 280 videoChannelId: servers[1].videoChannel.id
bfbd9128
C
281 }
282 })
283
284 playlistServer2Id2 = res.body.videoPlaylist.id
285 playlistServer2UUID2 = res.body.videoPlaylist.uuid
286 }
287
a1587156 288 for (const id of [ playlistServer2Id1, playlistServer2Id2 ]) {
bfbd9128 289 await addVideoInPlaylist({
a1587156
C
290 url: servers[1].url,
291 token: servers[1].accessToken,
bfbd9128 292 playlistId: id,
a1587156 293 elementAttrs: { videoId: servers[1].videos[0].id, startTimestamp: 1, stopTimestamp: 2 }
bfbd9128
C
294 })
295 await addVideoInPlaylist({
a1587156
C
296 url: servers[1].url,
297 token: servers[1].accessToken,
bfbd9128 298 playlistId: id,
a1587156 299 elementAttrs: { videoId: servers[1].videos[1].id }
bfbd9128
C
300 })
301 }
302
303 await waitJobs(servers)
7f88a58e 304 await wait(3000)
bfbd9128 305
a1587156 306 for (const server of [ servers[0], servers[1] ]) {
bfbd9128
C
307 const res = await getVideoPlaylistsList(server.url, 0, 5)
308
309 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
310 expect(playlist2).to.not.be.undefined
311 await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath)
312
313 const playlist3 = res.body.data.find(p => p.displayName === 'playlist 3')
314 expect(playlist3).to.not.be.undefined
315 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath)
316 }
4d09cfba 317
a1587156 318 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
bfbd9128
C
319 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined
320 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined
321 })
322
323 it('Should have the playlist on server 3 after a new follow', async function () {
324 this.timeout(30000)
325
326 // Server 2 and server 3 follow each other
a1587156 327 await doubleFollow(servers[1], servers[2])
bfbd9128 328
a1587156 329 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
bfbd9128
C
330
331 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
332 expect(playlist2).to.not.be.undefined
a1587156 333 await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath)
bfbd9128
C
334
335 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined
336 })
4d09cfba
C
337 })
338
bfbd9128 339 describe('List playlists', function () {
65af03a2 340
bfbd9128
C
341 it('Should correctly list the playlists', async function () {
342 this.timeout(30000)
343
344 {
a1587156 345 const res = await getVideoPlaylistsList(servers[2].url, 1, 2, 'createdAt')
df0b219d 346
bfbd9128
C
347 expect(res.body.total).to.equal(3)
348
349 const data: VideoPlaylist[] = res.body.data
350 expect(data).to.have.lengthOf(2)
a1587156
C
351 expect(data[0].displayName).to.equal('playlist 2')
352 expect(data[1].displayName).to.equal('playlist 3')
bfbd9128
C
353 }
354
355 {
a1587156 356 const res = await getVideoPlaylistsList(servers[2].url, 1, 2, '-createdAt')
bfbd9128
C
357
358 expect(res.body.total).to.equal(3)
359
360 const data: VideoPlaylist[] = res.body.data
361 expect(data).to.have.lengthOf(2)
a1587156
C
362 expect(data[0].displayName).to.equal('playlist 2')
363 expect(data[1].displayName).to.equal('my super playlist')
df0b219d
C
364 }
365 })
366
bfbd9128
C
367 it('Should list video channel playlists', async function () {
368 this.timeout(30000)
df0b219d 369
bfbd9128 370 {
a1587156 371 const res = await getVideoChannelPlaylistsList(servers[0].url, 'root_channel', 0, 2, '-createdAt')
df0b219d 372
bfbd9128 373 expect(res.body.total).to.equal(1)
df0b219d 374
bfbd9128
C
375 const data: VideoPlaylist[] = res.body.data
376 expect(data).to.have.lengthOf(1)
a1587156 377 expect(data[0].displayName).to.equal('my super playlist')
bfbd9128
C
378 }
379 })
df0b219d 380
bfbd9128
C
381 it('Should list account playlists', async function () {
382 this.timeout(30000)
df0b219d 383
bfbd9128 384 {
a1587156 385 const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, '-createdAt')
df0b219d 386
bfbd9128
C
387 expect(res.body.total).to.equal(2)
388
389 const data: VideoPlaylist[] = res.body.data
390 expect(data).to.have.lengthOf(1)
a1587156 391 expect(data[0].displayName).to.equal('playlist 2')
bfbd9128 392 }
df0b219d 393
bfbd9128 394 {
a1587156 395 const res = await getAccountPlaylistsList(servers[1].url, 'root', 1, 2, 'createdAt')
df0b219d 396
bfbd9128
C
397 expect(res.body.total).to.equal(2)
398
399 const data: VideoPlaylist[] = res.body.data
400 expect(data).to.have.lengthOf(1)
a1587156 401 expect(data[0].displayName).to.equal('playlist 3')
df0b219d 402 }
822c7e61
C
403
404 {
a1587156 405 const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '3')
822c7e61
C
406
407 expect(res.body.total).to.equal(1)
408
409 const data: VideoPlaylist[] = res.body.data
410 expect(data).to.have.lengthOf(1)
a1587156 411 expect(data[0].displayName).to.equal('playlist 3')
822c7e61
C
412 }
413
414 {
a1587156 415 const res = await getAccountPlaylistsList(servers[1].url, 'root', 0, 10, 'createdAt', '4')
822c7e61
C
416
417 expect(res.body.total).to.equal(0)
418
419 const data: VideoPlaylist[] = res.body.data
420 expect(data).to.have.lengthOf(0)
421 }
bfbd9128 422 })
d4a8e7a6 423 })
418d092a 424
d4a8e7a6
C
425 describe('Playlist rights', function () {
426 let unlistedPlaylist: VideoPlaylistCreateResult
427 let privatePlaylist: VideoPlaylistCreateResult
428
429 before(async function () {
bfbd9128 430 this.timeout(30000)
df0b219d 431
d4a8e7a6
C
432 {
433 const res = await createVideoPlaylist({
434 url: servers[1].url,
435 token: servers[1].accessToken,
436 playlistAttrs: {
437 displayName: 'playlist unlisted',
438 privacy: VideoPlaylistPrivacy.UNLISTED,
439 videoChannelId: servers[1].videoChannel.id
440 }
441 })
442 unlistedPlaylist = res.body.videoPlaylist
443 }
df0b219d 444
d4a8e7a6
C
445 {
446 const res = await createVideoPlaylist({
447 url: servers[1].url,
448 token: servers[1].accessToken,
449 playlistAttrs: {
450 displayName: 'playlist private',
451 privacy: VideoPlaylistPrivacy.PRIVATE
452 }
453 })
454 privatePlaylist = res.body.videoPlaylist
455 }
df0b219d 456
bfbd9128 457 await waitJobs(servers)
7f88a58e 458 await wait(3000)
d4a8e7a6 459 })
df0b219d 460
d4a8e7a6 461 it('Should not list unlisted or private playlists', async function () {
bfbd9128
C
462 for (const server of servers) {
463 const results = [
a1587156 464 await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[1].port, 0, 5, '-createdAt'),
bfbd9128
C
465 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt')
466 ]
467
a1587156
C
468 expect(results[0].body.total).to.equal(2)
469 expect(results[1].body.total).to.equal(3)
bfbd9128
C
470
471 for (const res of results) {
472 const data: VideoPlaylist[] = res.body.data
473 expect(data).to.have.lengthOf(2)
a1587156
C
474 expect(data[0].displayName).to.equal('playlist 3')
475 expect(data[1].displayName).to.equal('playlist 2')
bfbd9128
C
476 }
477 }
478 })
d4a8e7a6
C
479
480 it('Should not get unlisted playlist using only the id', async function () {
481 await getVideoPlaylist(servers[1].url, unlistedPlaylist.id, 404)
482 })
483
484 it('Should get unlisted plyaylist using uuid or shortUUID', async function () {
485 await getVideoPlaylist(servers[1].url, unlistedPlaylist.uuid)
486 await getVideoPlaylist(servers[1].url, unlistedPlaylist.shortUUID)
487 })
488
489 it('Should not get private playlist without token', async function () {
490 for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) {
491 await getVideoPlaylist(servers[1].url, id, 401)
492 }
493 })
494
495 it('Should get private playlist with a token', async function () {
496 for (const id of [ privatePlaylist.id, privatePlaylist.uuid, privatePlaylist.shortUUID ]) {
497 await getVideoPlaylistWithToken(servers[1].url, servers[1].accessToken, id)
498 }
499 })
bfbd9128 500 })
df0b219d 501
bfbd9128 502 describe('Update playlists', function () {
df0b219d 503
bfbd9128
C
504 it('Should update a playlist', async function () {
505 this.timeout(30000)
df0b219d 506
bfbd9128
C
507 await updateVideoPlaylist({
508 url: servers[1].url,
509 token: servers[1].accessToken,
510 playlistAttrs: {
511 displayName: 'playlist 3 updated',
512 description: 'description updated',
513 privacy: VideoPlaylistPrivacy.UNLISTED,
514 thumbnailfile: 'thumbnail.jpg',
515 videoChannelId: servers[1].videoChannel.id
516 },
517 playlistId: playlistServer2Id2
518 })
df0b219d 519
bfbd9128 520 await waitJobs(servers)
df0b219d 521
bfbd9128
C
522 for (const server of servers) {
523 const res = await getVideoPlaylist(server.url, playlistServer2UUID2)
524 const playlist: VideoPlaylist = res.body
418d092a 525
bfbd9128
C
526 expect(playlist.displayName).to.equal('playlist 3 updated')
527 expect(playlist.description).to.equal('description updated')
df0b219d 528
bfbd9128
C
529 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.UNLISTED)
530 expect(playlist.privacy.label).to.equal('Unlisted')
df0b219d 531
bfbd9128
C
532 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
533 expect(playlist.type.label).to.equal('Regular')
df0b219d 534
bfbd9128 535 expect(playlist.videosLength).to.equal(2)
df0b219d 536
bfbd9128
C
537 expect(playlist.ownerAccount.name).to.equal('root')
538 expect(playlist.ownerAccount.displayName).to.equal('root')
539 expect(playlist.videoChannel.name).to.equal('root_channel')
540 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
541 }
542 })
418d092a
C
543 })
544
bfbd9128 545 describe('Element timestamps', function () {
df0b219d 546
bfbd9128
C
547 it('Should create a playlist containing different startTimestamp/endTimestamp videos', async function () {
548 this.timeout(30000)
df0b219d 549
bfbd9128 550 const addVideo = (elementAttrs: any) => {
a1587156 551 return addVideoInPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: playlistServer1Id, elementAttrs })
bfbd9128 552 }
df0b219d 553
bfbd9128 554 const res = await createVideoPlaylist({
a1587156
C
555 url: servers[0].url,
556 token: servers[0].accessToken,
bfbd9128
C
557 playlistAttrs: {
558 displayName: 'playlist 4',
559 privacy: VideoPlaylistPrivacy.PUBLIC,
a1587156 560 videoChannelId: servers[0].videoChannel.id
bfbd9128
C
561 }
562 })
df0b219d 563
bfbd9128
C
564 playlistServer1Id = res.body.videoPlaylist.id
565 playlistServer1UUID = res.body.videoPlaylist.uuid
df0b219d 566
a1587156
C
567 await addVideo({ videoId: servers[0].videos[0].uuid, startTimestamp: 15, stopTimestamp: 28 })
568 await addVideo({ videoId: servers[2].videos[1].uuid, startTimestamp: 35 })
569 await addVideo({ videoId: servers[2].videos[2].uuid })
bfbd9128 570 {
a1587156 571 const res = await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 })
bfbd9128
C
572 playlistElementServer1Video4 = res.body.videoPlaylistElement.id
573 }
df0b219d 574
bfbd9128 575 {
a1587156 576 const res = await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 })
bfbd9128
C
577 playlistElementServer1Video5 = res.body.videoPlaylistElement.id
578 }
418d092a 579
bfbd9128
C
580 {
581 const res = await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 })
582 playlistElementNSFW = res.body.videoPlaylistElement.id
37190663
C
583
584 await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 4 })
585 await addVideo({ videoId: nsfwVideoServer1 })
bfbd9128 586 }
df0b219d 587
bfbd9128
C
588 await waitJobs(servers)
589 })
df0b219d 590
bfbd9128
C
591 it('Should correctly list playlist videos', async function () {
592 this.timeout(30000)
df0b219d 593
bfbd9128
C
594 for (const server of servers) {
595 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
418d092a 596
37190663 597 expect(res.body.total).to.equal(8)
df0b219d 598
bfbd9128 599 const videoElements: VideoPlaylistElement[] = res.body.data
37190663 600 expect(videoElements).to.have.lengthOf(8)
df0b219d 601
a1587156
C
602 expect(videoElements[0].video.name).to.equal('video 0 server 1')
603 expect(videoElements[0].position).to.equal(1)
604 expect(videoElements[0].startTimestamp).to.equal(15)
605 expect(videoElements[0].stopTimestamp).to.equal(28)
df0b219d 606
a1587156
C
607 expect(videoElements[1].video.name).to.equal('video 1 server 3')
608 expect(videoElements[1].position).to.equal(2)
609 expect(videoElements[1].startTimestamp).to.equal(35)
610 expect(videoElements[1].stopTimestamp).to.be.null
df0b219d 611
a1587156
C
612 expect(videoElements[2].video.name).to.equal('video 2 server 3')
613 expect(videoElements[2].position).to.equal(3)
614 expect(videoElements[2].startTimestamp).to.be.null
615 expect(videoElements[2].stopTimestamp).to.be.null
df0b219d 616
a1587156
C
617 expect(videoElements[3].video.name).to.equal('video 3 server 1')
618 expect(videoElements[3].position).to.equal(4)
619 expect(videoElements[3].startTimestamp).to.be.null
620 expect(videoElements[3].stopTimestamp).to.equal(35)
df0b219d 621
a1587156
C
622 expect(videoElements[4].video.name).to.equal('video 4 server 1')
623 expect(videoElements[4].position).to.equal(5)
624 expect(videoElements[4].startTimestamp).to.equal(45)
625 expect(videoElements[4].stopTimestamp).to.equal(60)
418d092a 626
a1587156
C
627 expect(videoElements[5].video.name).to.equal('NSFW video')
628 expect(videoElements[5].position).to.equal(6)
629 expect(videoElements[5].startTimestamp).to.equal(5)
630 expect(videoElements[5].stopTimestamp).to.be.null
df0b219d 631
37190663
C
632 expect(videoElements[6].video.name).to.equal('NSFW video')
633 expect(videoElements[6].position).to.equal(7)
634 expect(videoElements[6].startTimestamp).to.equal(4)
635 expect(videoElements[6].stopTimestamp).to.be.null
636
637 expect(videoElements[7].video.name).to.equal('NSFW video')
638 expect(videoElements[7].position).to.equal(8)
639 expect(videoElements[7].startTimestamp).to.be.null
640 expect(videoElements[7].stopTimestamp).to.be.null
641
bfbd9128
C
642 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2)
643 expect(res3.body.data).to.have.lengthOf(2)
df0b219d
C
644 }
645 })
bfbd9128 646 })
df0b219d 647
bfbd9128
C
648 describe('Element type', function () {
649 let groupUser1: ServerInfo[]
650 let groupWithoutToken1: ServerInfo[]
651 let group1: ServerInfo[]
652 let group2: ServerInfo[]
df0b219d 653
bfbd9128
C
654 let video1: string
655 let video2: string
656 let video3: string
df0b219d 657
bfbd9128 658 before(async function () {
19149d45 659 this.timeout(60000)
df0b219d 660
a1587156
C
661 groupUser1 = [ Object.assign({}, servers[0], { accessToken: userAccessTokenServer1 }) ]
662 groupWithoutToken1 = [ Object.assign({}, servers[0], { accessToken: undefined }) ]
663 group1 = [ servers[0] ]
664 group2 = [ servers[1], servers[2] ]
df0b219d 665
bfbd9128 666 const res = await createVideoPlaylist({
a1587156 667 url: servers[0].url,
bfbd9128
C
668 token: userAccessTokenServer1,
669 playlistAttrs: {
670 displayName: 'playlist 56',
671 privacy: VideoPlaylistPrivacy.PUBLIC,
a1587156 672 videoChannelId: servers[0].videoChannel.id
bfbd9128
C
673 }
674 })
418d092a 675
bfbd9128
C
676 const playlistServer1Id2 = res.body.videoPlaylist.id
677 playlistServer1UUID2 = res.body.videoPlaylist.uuid
df0b219d 678
bfbd9128 679 const addVideo = (elementAttrs: any) => {
a1587156 680 return addVideoInPlaylist({ url: servers[0].url, token: userAccessTokenServer1, playlistId: playlistServer1Id2, elementAttrs })
bfbd9128 681 }
df0b219d 682
bfbd9128
C
683 video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userAccessTokenServer1 })).uuid
684 video2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 90' })).uuid
685 video3 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 91', nsfw: true })).uuid
df0b219d 686
19149d45
C
687 await waitJobs(servers)
688
bfbd9128
C
689 await addVideo({ videoId: video1, startTimestamp: 15, stopTimestamp: 28 })
690 await addVideo({ videoId: video2, startTimestamp: 35 })
691 await addVideo({ videoId: video3 })
df0b219d 692
bfbd9128
C
693 await waitJobs(servers)
694 })
df0b219d 695
bfbd9128
C
696 it('Should update the element type if the video is private', async function () {
697 this.timeout(20000)
df0b219d 698
bfbd9128
C
699 const name = 'video 89'
700 const position = 1
df0b219d 701
bfbd9128 702 {
a1587156 703 await updateVideo(servers[0].url, servers[0].accessToken, video1, { privacy: VideoPrivacy.PRIVATE })
bfbd9128 704 await waitJobs(servers)
418d092a 705
bfbd9128
C
706 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
707 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.PRIVATE, position, name, 3)
708 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.PRIVATE, position, name, 3)
709 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
710 }
df0b219d 711
bfbd9128 712 {
a1587156 713 await updateVideo(servers[0].url, servers[0].accessToken, video1, { privacy: VideoPrivacy.PUBLIC })
bfbd9128 714 await waitJobs(servers)
418d092a 715
bfbd9128
C
716 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
717 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
718 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
719 // We deleted the video, so even if we recreated it, the old entry is still deleted
720 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
df0b219d
C
721 }
722 })
723
bfbd9128
C
724 it('Should update the element type if the video is blacklisted', async function () {
725 this.timeout(20000)
df0b219d 726
bfbd9128
C
727 const name = 'video 89'
728 const position = 1
df0b219d 729
bfbd9128 730 {
a1587156 731 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, video1, 'reason', true)
bfbd9128 732 await waitJobs(servers)
418d092a 733
bfbd9128
C
734 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
735 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
736 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
737 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
738 }
df0b219d 739
bfbd9128 740 {
a1587156 741 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, video1)
bfbd9128 742 await waitJobs(servers)
df0b219d 743
bfbd9128
C
744 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
745 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
746 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
747 // We deleted the video (because unfederated), so even if we recreated it, the old entry is still deleted
748 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
749 }
750 })
df0b219d 751
bfbd9128
C
752 it('Should update the element type if the account or server of the video is blocked', async function () {
753 this.timeout(90000)
df0b219d 754
5f8bd4cb
C
755 const command = servers[0].blocklistCommand
756
bfbd9128
C
757 const name = 'video 90'
758 const position = 2
df0b219d 759
bfbd9128 760 {
5f8bd4cb 761 await command.addToMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port })
bfbd9128 762 await waitJobs(servers)
df0b219d 763
bfbd9128
C
764 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
765 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 766
5f8bd4cb 767 await command.removeFromMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port })
bfbd9128 768 await waitJobs(servers)
df0b219d 769
bfbd9128
C
770 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
771 }
df0b219d 772
bfbd9128 773 {
5f8bd4cb 774 await command.addToMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port })
bfbd9128 775 await waitJobs(servers)
df0b219d 776
bfbd9128
C
777 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
778 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 779
5f8bd4cb 780 await command.removeFromMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port })
bfbd9128 781 await waitJobs(servers)
418d092a 782
bfbd9128
C
783 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
784 }
df0b219d 785
bfbd9128 786 {
5f8bd4cb 787 await command.addToServerBlocklist({ account: 'root@localhost:' + servers[1].port })
bfbd9128 788 await waitJobs(servers)
df0b219d 789
bfbd9128
C
790 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
791 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 792
5f8bd4cb 793 await command.removeFromServerBlocklist({ account: 'root@localhost:' + servers[1].port })
bfbd9128 794 await waitJobs(servers)
df0b219d 795
bfbd9128 796 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 797 }
df0b219d 798
bfbd9128 799 {
5f8bd4cb 800 await command.addToServerBlocklist({ server: 'localhost:' + servers[1].port })
bfbd9128 801 await waitJobs(servers)
df0b219d 802
bfbd9128
C
803 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
804 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 805
5f8bd4cb 806 await command.removeFromServerBlocklist({ server: 'localhost:' + servers[1].port })
bfbd9128 807 await waitJobs(servers)
df0b219d 808
bfbd9128 809 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
df0b219d 810 }
bfbd9128 811 })
df0b219d 812
bfbd9128
C
813 it('Should hide the video if it is NSFW', async function () {
814 const res = await getPlaylistVideos(servers[0].url, userAccessTokenServer1, playlistServer1UUID2, 0, 10, { nsfw: false })
815 expect(res.body.total).to.equal(3)
df0b219d 816
bfbd9128
C
817 const elements: VideoPlaylistElement[] = res.body.data
818 const element = elements.find(e => e.position === 3)
df0b219d 819
bfbd9128
C
820 expect(element).to.exist
821 expect(element.video).to.be.null
822 expect(element.type).to.equal(VideoPlaylistElementType.UNAVAILABLE)
823 })
df0b219d 824
bfbd9128 825 })
df0b219d 826
bfbd9128
C
827 describe('Managing playlist elements', function () {
828
829 it('Should reorder the playlist', async function () {
830 this.timeout(30000)
831
832 {
833 await reorderVideosPlaylist({
a1587156
C
834 url: servers[0].url,
835 token: servers[0].accessToken,
bfbd9128
C
836 playlistId: playlistServer1Id,
837 elementAttrs: {
838 startPosition: 2,
839 insertAfterPosition: 3
840 }
841 })
842
843 await waitJobs(servers)
844
845 for (const server of servers) {
846 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
847 const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
848
849 expect(names).to.deep.equal([
850 'video 0 server 1',
851 'video 2 server 3',
852 'video 1 server 3',
853 'video 3 server 1',
854 'video 4 server 1',
37190663
C
855 'NSFW video',
856 'NSFW video',
bfbd9128
C
857 'NSFW video'
858 ])
df0b219d
C
859 }
860 }
df0b219d 861
bfbd9128
C
862 {
863 await reorderVideosPlaylist({
a1587156
C
864 url: servers[0].url,
865 token: servers[0].accessToken,
bfbd9128
C
866 playlistId: playlistServer1Id,
867 elementAttrs: {
868 startPosition: 1,
869 reorderLength: 3,
870 insertAfterPosition: 4
871 }
872 })
873
874 await waitJobs(servers)
875
876 for (const server of servers) {
877 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
878 const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
879
880 expect(names).to.deep.equal([
881 'video 3 server 1',
882 'video 0 server 1',
883 'video 2 server 3',
884 'video 1 server 3',
885 'video 4 server 1',
37190663
C
886 'NSFW video',
887 'NSFW video',
bfbd9128
C
888 'NSFW video'
889 ])
890 }
df0b219d 891 }
df0b219d 892
bfbd9128
C
893 {
894 await reorderVideosPlaylist({
a1587156
C
895 url: servers[0].url,
896 token: servers[0].accessToken,
bfbd9128
C
897 playlistId: playlistServer1Id,
898 elementAttrs: {
899 startPosition: 6,
900 insertAfterPosition: 3
901 }
902 })
903
904 await waitJobs(servers)
905
906 for (const server of servers) {
907 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
908 const elements: VideoPlaylistElement[] = res.body.data
909 const names = elements.map(v => v.video.name)
910
911 expect(names).to.deep.equal([
912 'video 3 server 1',
913 'video 0 server 1',
914 'video 2 server 3',
915 'NSFW video',
916 'video 1 server 3',
37190663
C
917 'video 4 server 1',
918 'NSFW video',
919 'NSFW video'
bfbd9128
C
920 ])
921
922 for (let i = 1; i <= elements.length; i++) {
a1587156 923 expect(elements[i - 1].position).to.equal(i)
bfbd9128
C
924 }
925 }
df0b219d
C
926 }
927 })
928
bfbd9128
C
929 it('Should update startTimestamp/endTimestamp of some elements', async function () {
930 this.timeout(30000)
931
932 await updateVideoPlaylistElement({
a1587156
C
933 url: servers[0].url,
934 token: servers[0].accessToken,
bfbd9128
C
935 playlistId: playlistServer1Id,
936 playlistElementId: playlistElementServer1Video4,
937 elementAttrs: {
938 startTimestamp: 1
939 }
940 })
df0b219d 941
bfbd9128 942 await updateVideoPlaylistElement({
a1587156
C
943 url: servers[0].url,
944 token: servers[0].accessToken,
bfbd9128
C
945 playlistId: playlistServer1Id,
946 playlistElementId: playlistElementServer1Video5,
947 elementAttrs: {
948 stopTimestamp: null
949 }
950 })
df0b219d 951
bfbd9128 952 await waitJobs(servers)
df0b219d 953
bfbd9128
C
954 for (const server of servers) {
955 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
956 const elements: VideoPlaylistElement[] = res.body.data
418d092a 957
a1587156
C
958 expect(elements[0].video.name).to.equal('video 3 server 1')
959 expect(elements[0].position).to.equal(1)
960 expect(elements[0].startTimestamp).to.equal(1)
961 expect(elements[0].stopTimestamp).to.equal(35)
0b16f5f2 962
a1587156
C
963 expect(elements[5].video.name).to.equal('video 4 server 1')
964 expect(elements[5].position).to.equal(6)
965 expect(elements[5].startTimestamp).to.equal(45)
966 expect(elements[5].stopTimestamp).to.be.null
bfbd9128
C
967 }
968 })
0b16f5f2 969
bfbd9128
C
970 it('Should check videos existence in my playlist', async function () {
971 const videoIds = [
a1587156 972 servers[0].videos[0].id,
bfbd9128 973 42000,
a1587156 974 servers[0].videos[3].id,
bfbd9128 975 43000,
a1587156 976 servers[0].videos[4].id
bfbd9128 977 ]
a1587156 978 const res = await doVideosExistInMyPlaylist(servers[0].url, servers[0].accessToken, videoIds)
bfbd9128
C
979 const obj = res.body as VideoExistInPlaylist
980
981 {
a1587156 982 const elem = obj[servers[0].videos[0].id]
bfbd9128 983 expect(elem).to.have.lengthOf(1)
a1587156
C
984 expect(elem[0].playlistElementId).to.exist
985 expect(elem[0].playlistId).to.equal(playlistServer1Id)
986 expect(elem[0].startTimestamp).to.equal(15)
987 expect(elem[0].stopTimestamp).to.equal(28)
bfbd9128 988 }
0b16f5f2 989
bfbd9128 990 {
a1587156 991 const elem = obj[servers[0].videos[3].id]
bfbd9128 992 expect(elem).to.have.lengthOf(1)
a1587156
C
993 expect(elem[0].playlistElementId).to.equal(playlistElementServer1Video4)
994 expect(elem[0].playlistId).to.equal(playlistServer1Id)
995 expect(elem[0].startTimestamp).to.equal(1)
996 expect(elem[0].stopTimestamp).to.equal(35)
bfbd9128 997 }
0b16f5f2 998
bfbd9128 999 {
a1587156 1000 const elem = obj[servers[0].videos[4].id]
bfbd9128 1001 expect(elem).to.have.lengthOf(1)
a1587156
C
1002 expect(elem[0].playlistId).to.equal(playlistServer1Id)
1003 expect(elem[0].startTimestamp).to.equal(45)
1004 expect(elem[0].stopTimestamp).to.equal(null)
bfbd9128 1005 }
0b16f5f2 1006
a1587156
C
1007 expect(obj[42000]).to.have.lengthOf(0)
1008 expect(obj[43000]).to.have.lengthOf(0)
bfbd9128 1009 })
2a10aab3 1010
bfbd9128 1011 it('Should automatically update updatedAt field of playlists', async function () {
a1587156
C
1012 const server = servers[1]
1013 const videoId = servers[1].videos[5].id
2a10aab3 1014
bfbd9128
C
1015 async function getPlaylistNames () {
1016 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt')
2a10aab3 1017
bfbd9128
C
1018 return (res.body.data as VideoPlaylist[]).map(p => p.displayName)
1019 }
2a10aab3 1020
bfbd9128
C
1021 const elementAttrs = { videoId }
1022 const res1 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, elementAttrs })
1023 const res2 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, elementAttrs })
2a10aab3 1024
bfbd9128
C
1025 const element1 = res1.body.videoPlaylistElement.id
1026 const element2 = res2.body.videoPlaylistElement.id
2a10aab3 1027
bfbd9128 1028 const names1 = await getPlaylistNames()
a1587156
C
1029 expect(names1[0]).to.equal('playlist 3 updated')
1030 expect(names1[1]).to.equal('playlist 2')
2a10aab3 1031
bfbd9128
C
1032 await removeVideoFromPlaylist({
1033 url: server.url,
1034 token: server.accessToken,
1035 playlistId: playlistServer2Id1,
1036 playlistElementId: element1
1037 })
2a10aab3 1038
bfbd9128 1039 const names2 = await getPlaylistNames()
a1587156
C
1040 expect(names2[0]).to.equal('playlist 2')
1041 expect(names2[1]).to.equal('playlist 3 updated')
2a10aab3 1042
bfbd9128
C
1043 await removeVideoFromPlaylist({
1044 url: server.url,
1045 token: server.accessToken,
1046 playlistId: playlistServer2Id2,
1047 playlistElementId: element2
1048 })
df0b219d 1049
bfbd9128 1050 const names3 = await getPlaylistNames()
a1587156
C
1051 expect(names3[0]).to.equal('playlist 3 updated')
1052 expect(names3[1]).to.equal('playlist 2')
df0b219d
C
1053 })
1054
bfbd9128
C
1055 it('Should delete some elements', async function () {
1056 this.timeout(30000)
df0b219d 1057
bfbd9128 1058 await removeVideoFromPlaylist({
a1587156
C
1059 url: servers[0].url,
1060 token: servers[0].accessToken,
bfbd9128
C
1061 playlistId: playlistServer1Id,
1062 playlistElementId: playlistElementServer1Video4
1063 })
df0b219d 1064
bfbd9128 1065 await removeVideoFromPlaylist({
a1587156
C
1066 url: servers[0].url,
1067 token: servers[0].accessToken,
bfbd9128
C
1068 playlistId: playlistServer1Id,
1069 playlistElementId: playlistElementNSFW
1070 })
df0b219d 1071
bfbd9128 1072 await waitJobs(servers)
df0b219d 1073
bfbd9128
C
1074 for (const server of servers) {
1075 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
418d092a 1076
37190663 1077 expect(res.body.total).to.equal(6)
df0b219d 1078
bfbd9128 1079 const elements: VideoPlaylistElement[] = res.body.data
37190663 1080 expect(elements).to.have.lengthOf(6)
df0b219d 1081
a1587156
C
1082 expect(elements[0].video.name).to.equal('video 0 server 1')
1083 expect(elements[0].position).to.equal(1)
df0b219d 1084
a1587156
C
1085 expect(elements[1].video.name).to.equal('video 2 server 3')
1086 expect(elements[1].position).to.equal(2)
418d092a 1087
a1587156
C
1088 expect(elements[2].video.name).to.equal('video 1 server 3')
1089 expect(elements[2].position).to.equal(3)
1b319b7a 1090
a1587156
C
1091 expect(elements[3].video.name).to.equal('video 4 server 1')
1092 expect(elements[3].position).to.equal(4)
37190663
C
1093
1094 expect(elements[4].video.name).to.equal('NSFW video')
1095 expect(elements[4].position).to.equal(5)
1096
1097 expect(elements[5].video.name).to.equal('NSFW video')
1098 expect(elements[5].position).to.equal(6)
1b319b7a
C
1099 }
1100 })
1b319b7a 1101
bfbd9128
C
1102 it('Should be able to create a public playlist, and set it to private', async function () {
1103 this.timeout(30000)
1b319b7a 1104
bfbd9128 1105 const res = await createVideoPlaylist({
a1587156
C
1106 url: servers[0].url,
1107 token: servers[0].accessToken,
bfbd9128
C
1108 playlistAttrs: {
1109 displayName: 'my super public playlist',
1110 privacy: VideoPlaylistPrivacy.PUBLIC,
a1587156 1111 videoChannelId: servers[0].videoChannel.id
bfbd9128
C
1112 }
1113 })
1114 const videoPlaylistIds = res.body.videoPlaylist
1b319b7a 1115
bfbd9128 1116 await waitJobs(servers)
1b319b7a 1117
bfbd9128 1118 for (const server of servers) {
f2eb23cd 1119 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.OK_200)
bfbd9128 1120 }
1b319b7a 1121
bfbd9128 1122 const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE }
a1587156 1123 await updateVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs })
1b319b7a 1124
bfbd9128 1125 await waitJobs(servers)
1b319b7a 1126
a1587156 1127 for (const server of [ servers[1], servers[2] ]) {
f2eb23cd 1128 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, HttpStatusCode.NOT_FOUND_404)
bfbd9128 1129 }
f2eb23cd 1130 await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, HttpStatusCode.UNAUTHORIZED_401)
418d092a 1131
f2eb23cd 1132 await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, HttpStatusCode.OK_200)
bfbd9128
C
1133 })
1134 })
df0b219d 1135
bfbd9128 1136 describe('Playlist deletion', function () {
df0b219d 1137
bfbd9128
C
1138 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () {
1139 this.timeout(30000)
418d092a 1140
a1587156 1141 await deleteVideoPlaylist(servers[0].url, servers[0].accessToken, playlistServer1Id)
418d092a 1142
bfbd9128 1143 await waitJobs(servers)
418d092a 1144
bfbd9128 1145 for (const server of servers) {
f2eb23cd 1146 await getVideoPlaylist(server.url, playlistServer1UUID, HttpStatusCode.NOT_FOUND_404)
bfbd9128
C
1147 }
1148 })
418d092a 1149
bfbd9128
C
1150 it('Should have deleted the thumbnail on server 1, 2 and 3', async function () {
1151 this.timeout(30000)
df0b219d 1152
bfbd9128
C
1153 for (const server of servers) {
1154 await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.internalServerNumber)
1155 }
1156 })
df0b219d 1157
bfbd9128
C
1158 it('Should unfollow servers 1 and 2 and hide their playlists', async function () {
1159 this.timeout(30000)
df0b219d 1160
bfbd9128 1161 const finder = data => data.find(p => p.displayName === 'my super playlist')
df0b219d 1162
bfbd9128 1163 {
a1587156 1164 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
bfbd9128
C
1165 expect(res.body.total).to.equal(3)
1166 expect(finder(res.body.data)).to.not.be.undefined
1167 }
418d092a 1168
c3d29f69 1169 await servers[2].followsCommand.unfollow({ target: servers[0] })
df0b219d 1170
bfbd9128 1171 {
a1587156 1172 const res = await getVideoPlaylistsList(servers[2].url, 0, 5)
bfbd9128 1173 expect(res.body.total).to.equal(1)
418d092a 1174
bfbd9128 1175 expect(finder(res.body.data)).to.be.undefined
df0b219d
C
1176 }
1177 })
df0b219d 1178
bfbd9128
C
1179 it('Should delete a channel and put the associated playlist in private mode', async function () {
1180 this.timeout(30000)
df0b219d 1181
a1587156 1182 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' })
bfbd9128 1183 const videoChannelId = res.body.videoChannel.id
df0b219d 1184
bfbd9128 1185 const res2 = await createVideoPlaylist({
a1587156
C
1186 url: servers[0].url,
1187 token: servers[0].accessToken,
bfbd9128
C
1188 playlistAttrs: {
1189 displayName: 'channel playlist',
1190 privacy: VideoPlaylistPrivacy.PUBLIC,
1191 videoChannelId
1192 }
1193 })
1194 const videoPlaylistUUID = res2.body.videoPlaylist.uuid
1195
1196 await waitJobs(servers)
df0b219d 1197
a1587156 1198 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'super_channel')
df0b219d 1199
bfbd9128 1200 await waitJobs(servers)
418d092a 1201
a1587156 1202 const res3 = await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistUUID)
bfbd9128
C
1203 expect(res3.body.displayName).to.equal('channel playlist')
1204 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
df0b219d 1205
f2eb23cd 1206 await getVideoPlaylist(servers[1].url, videoPlaylistUUID, HttpStatusCode.NOT_FOUND_404)
1eddc9a7 1207 })
df0b219d 1208
bfbd9128
C
1209 it('Should delete an account and delete its playlists', async function () {
1210 this.timeout(30000)
418d092a 1211
bfbd9128
C
1212 const user = { username: 'user_1', password: 'password' }
1213 const res = await createUser({
a1587156
C
1214 url: servers[0].url,
1215 accessToken: servers[0].accessToken,
bfbd9128
C
1216 username: user.username,
1217 password: user.password
1218 })
397d78fb 1219
bfbd9128 1220 const userId = res.body.user.id
a1587156 1221 const userAccessToken = await userLogin(servers[0], user)
df0b219d 1222
a1587156
C
1223 const resChannel = await getMyUserInformation(servers[0].url, userAccessToken)
1224 const userChannel = (resChannel.body as User).videoChannels[0]
df0b219d 1225
bfbd9128 1226 await createVideoPlaylist({
a1587156 1227 url: servers[0].url,
bfbd9128
C
1228 token: userAccessToken,
1229 playlistAttrs: {
1230 displayName: 'playlist to be deleted',
1231 privacy: VideoPlaylistPrivacy.PUBLIC,
1232 videoChannelId: userChannel.id
1233 }
1234 })
df0b219d 1235
bfbd9128
C
1236 await waitJobs(servers)
1237
1238 const finder = data => data.find(p => p.displayName === 'playlist to be deleted')
1239
1240 {
a1587156 1241 for (const server of [ servers[0], servers[1] ]) {
bfbd9128
C
1242 const res = await getVideoPlaylistsList(server.url, 0, 15)
1243 expect(finder(res.body.data)).to.not.be.undefined
1244 }
df0b219d 1245 }
df0b219d 1246
a1587156 1247 await removeUser(servers[0].url, userId, servers[0].accessToken)
bfbd9128 1248 await waitJobs(servers)
df0b219d 1249
bfbd9128 1250 {
a1587156 1251 for (const server of [ servers[0], servers[1] ]) {
bfbd9128
C
1252 const res = await getVideoPlaylistsList(server.url, 0, 15)
1253 expect(finder(res.body.data)).to.be.undefined
1254 }
df0b219d 1255 }
bfbd9128 1256 })
418d092a
C
1257 })
1258
7c3b7976
C
1259 after(async function () {
1260 await cleanupTests(servers)
418d092a
C
1261 })
1262})