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