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