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