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