1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
10 generateUserAccessToken,
11 getAccountPlaylistsListWithToken,
15 removeVideoFromPlaylist,
16 reorderVideosPlaylist,
18 setAccessTokensToServers,
19 setDefaultVideoChannel,
21 updateVideoPlaylistElement,
23 } from '../../../../shared/extra-utils'
25 checkBadCountPagination,
26 checkBadSortPagination,
27 checkBadStartPagination
28 } from '../../../../shared/extra-utils/requests/check-api-params'
29 import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
30 import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
32 describe('Test video playlists API validator', function () {
33 let server: ServerInfo
34 let userAccessToken: string
35 let playlistUUID: string
36 let privatePlaylistUUID: string
37 let watchLaterPlaylistId: number
39 // eslint-disable-next-line @typescript-eslint/no-unused-vars
41 let playlistElementId: number
43 // ---------------------------------------------------------------
45 before(async function () {
48 server = await flushAndRunServer(1)
50 await setAccessTokensToServers([ server ])
51 await setDefaultVideoChannel([ server ])
53 userAccessToken = await generateUserAccessToken(server, 'user1')
54 videoId = (await uploadVideoAndGetId({ server, videoName: 'video 1' })).id
55 videoId2 = (await uploadVideoAndGetId({ server, videoName: 'video 2' })).id
58 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
59 watchLaterPlaylistId = res.body.data[0].id
63 const res = await createVideoPlaylist({
65 token: server.accessToken,
67 displayName: 'super playlist',
68 privacy: VideoPlaylistPrivacy.PUBLIC,
69 videoChannelId: server.videoChannel.id
72 playlistUUID = res.body.videoPlaylist.uuid
76 const res = await createVideoPlaylist({
78 token: server.accessToken,
80 displayName: 'private',
81 privacy: VideoPlaylistPrivacy.PRIVATE
84 privatePlaylistUUID = res.body.videoPlaylist.uuid
88 describe('When listing playlists', function () {
89 const globalPath = '/api/v1/video-playlists'
90 const accountPath = '/api/v1/accounts/root/video-playlists'
91 const videoChannelPath = '/api/v1/video-channels/root_channel/video-playlists'
93 it('Should fail with a bad start pagination', async function () {
94 await checkBadStartPagination(server.url, globalPath, server.accessToken)
95 await checkBadStartPagination(server.url, accountPath, server.accessToken)
96 await checkBadStartPagination(server.url, videoChannelPath, server.accessToken)
99 it('Should fail with a bad count pagination', async function () {
100 await checkBadCountPagination(server.url, globalPath, server.accessToken)
101 await checkBadCountPagination(server.url, accountPath, server.accessToken)
102 await checkBadCountPagination(server.url, videoChannelPath, server.accessToken)
105 it('Should fail with an incorrect sort', async function () {
106 await checkBadSortPagination(server.url, globalPath, server.accessToken)
107 await checkBadSortPagination(server.url, accountPath, server.accessToken)
108 await checkBadSortPagination(server.url, videoChannelPath, server.accessToken)
111 it('Should fail with a bad playlist type', async function () {
112 await makeGetRequest({ url: server.url, path: globalPath, query: { playlistType: 3 } })
113 await makeGetRequest({ url: server.url, path: accountPath, query: { playlistType: 3 } })
114 await makeGetRequest({ url: server.url, path: videoChannelPath, query: { playlistType: 3 } })
117 it('Should fail with a bad account parameter', async function () {
118 const accountPath = '/api/v1/accounts/root2/video-playlists'
120 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 404, token: server.accessToken })
123 it('Should fail with a bad video channel parameter', async function () {
124 const accountPath = '/api/v1/video-channels/bad_channel/video-playlists'
126 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 404, token: server.accessToken })
129 it('Should success with the correct parameters', async function () {
130 await makeGetRequest({ url: server.url, path: globalPath, statusCodeExpected: 200, token: server.accessToken })
131 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 200, token: server.accessToken })
132 await makeGetRequest({ url: server.url, path: videoChannelPath, statusCodeExpected: 200, token: server.accessToken })
136 describe('When listing videos of a playlist', function () {
137 const path = '/api/v1/video-playlists/'
139 it('Should fail with a bad start pagination', async function () {
140 await checkBadStartPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
143 it('Should fail with a bad count pagination', async function () {
144 await checkBadCountPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
147 it('Should success with the correct parameters', async function () {
148 await makeGetRequest({ url: server.url, path: path + playlistUUID + '/videos', statusCodeExpected: 200 })
152 describe('When getting a video playlist', function () {
153 it('Should fail with a bad id or uuid', async function () {
154 await getVideoPlaylist(server.url, 'toto', 400)
157 it('Should fail with an unknown playlist', async function () {
158 await getVideoPlaylist(server.url, 42, 404)
161 it('Should fail to get an unlisted playlist with the number id', async function () {
162 const res = await createVideoPlaylist({
164 token: server.accessToken,
166 displayName: 'super playlist',
167 privacy: VideoPlaylistPrivacy.UNLISTED
170 const playlist = res.body.videoPlaylist
172 await getVideoPlaylist(server.url, playlist.id, 404)
173 await getVideoPlaylist(server.url, playlist.uuid, 200)
176 it('Should succeed with the correct params', async function () {
177 await getVideoPlaylist(server.url, playlistUUID, 200)
181 describe('When creating/updating a video playlist', function () {
182 const getBase = (playlistAttrs: any = {}, wrapper: any = {}) => {
183 return Object.assign({
186 token: server.accessToken,
187 playlistAttrs: Object.assign({
188 displayName: 'display name',
189 privacy: VideoPlaylistPrivacy.UNLISTED,
190 thumbnailfile: 'thumbnail.jpg',
191 videoChannelId: server.videoChannel.id
195 const getUpdate = (params: any, playlistId: number | string) => {
196 return immutableAssign(params, { playlistId: playlistId })
199 it('Should fail with an unauthenticated user', async function () {
200 const params = getBase({}, { token: null, expectedStatus: 401 })
202 await createVideoPlaylist(params)
203 await updateVideoPlaylist(getUpdate(params, playlistUUID))
206 it('Should fail without displayName', async function () {
207 const params = getBase({ displayName: undefined })
209 await createVideoPlaylist(params)
212 it('Should fail with an incorrect display name', async function () {
213 const params = getBase({ displayName: 's'.repeat(300) })
215 await createVideoPlaylist(params)
216 await updateVideoPlaylist(getUpdate(params, playlistUUID))
219 it('Should fail with an incorrect description', async function () {
220 const params = getBase({ description: 't' })
222 await createVideoPlaylist(params)
223 await updateVideoPlaylist(getUpdate(params, playlistUUID))
226 it('Should fail with an incorrect privacy', async function () {
227 const params = getBase({ privacy: 45 })
229 await createVideoPlaylist(params)
230 await updateVideoPlaylist(getUpdate(params, playlistUUID))
233 it('Should fail with an unknown video channel id', async function () {
234 const params = getBase({ videoChannelId: 42 }, { expectedStatus: 404 })
236 await createVideoPlaylist(params)
237 await updateVideoPlaylist(getUpdate(params, playlistUUID))
240 it('Should fail with an incorrect thumbnail file', async function () {
241 const params = getBase({ thumbnailfile: 'avatar.png' })
243 await createVideoPlaylist(params)
244 await updateVideoPlaylist(getUpdate(params, playlistUUID))
247 it('Should fail to set "public" a playlist not assigned to a channel', async function () {
248 const params = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: undefined })
249 const params2 = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: 'null' })
250 const params3 = getBase({ privacy: undefined, videoChannelId: 'null' })
252 await createVideoPlaylist(params)
253 await createVideoPlaylist(params2)
254 await updateVideoPlaylist(getUpdate(params, privatePlaylistUUID))
255 await updateVideoPlaylist(getUpdate(params2, playlistUUID))
256 await updateVideoPlaylist(getUpdate(params3, playlistUUID))
259 it('Should fail with an unknown playlist to update', async function () {
260 await updateVideoPlaylist(getUpdate(
261 getBase({}, { expectedStatus: 404 }),
266 it('Should fail to update a playlist of another user', async function () {
267 await updateVideoPlaylist(getUpdate(
268 getBase({}, { token: userAccessToken, expectedStatus: 403 }),
273 it('Should fail to update the watch later playlist', async function () {
274 await updateVideoPlaylist(getUpdate(
275 getBase({}, { expectedStatus: 400 }),
280 it('Should succeed with the correct params', async function () {
282 const params = getBase({}, { expectedStatus: 200 })
283 await createVideoPlaylist(params)
287 const params = getBase({}, { expectedStatus: 204 })
288 await updateVideoPlaylist(getUpdate(params, playlistUUID))
293 describe('When adding an element in a playlist', function () {
294 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
295 return Object.assign({
298 token: server.accessToken,
299 playlistId: playlistUUID,
300 elementAttrs: Object.assign({
308 it('Should fail with an unauthenticated user', async function () {
309 const params = getBase({}, { token: null, expectedStatus: 401 })
310 await addVideoInPlaylist(params)
313 it('Should fail with the playlist of another user', async function () {
314 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
315 await addVideoInPlaylist(params)
318 it('Should fail with an unknown or incorrect playlist id', async function () {
320 const params = getBase({}, { playlistId: 'toto' })
321 await addVideoInPlaylist(params)
325 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
326 await addVideoInPlaylist(params)
330 it('Should fail with an unknown or incorrect video id', async function () {
331 const params = getBase({ videoId: 42 }, { expectedStatus: 404 })
332 await addVideoInPlaylist(params)
335 it('Should fail with a bad start/stop timestamp', async function () {
337 const params = getBase({ startTimestamp: -42 })
338 await addVideoInPlaylist(params)
342 const params = getBase({ stopTimestamp: 'toto' as any })
343 await addVideoInPlaylist(params)
347 it('Succeed with the correct params', async function () {
348 const params = getBase({}, { expectedStatus: 200 })
349 const res = await addVideoInPlaylist(params)
350 playlistElementId = res.body.videoPlaylistElement.id
353 it('Should fail if the video was already added in the playlist', async function () {
354 const params = getBase({}, { expectedStatus: 409 })
355 await addVideoInPlaylist(params)
359 describe('When updating an element in a playlist', function () {
360 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
361 return Object.assign({
363 token: server.accessToken,
364 elementAttrs: Object.assign({
369 playlistId: playlistUUID,
374 it('Should fail with an unauthenticated user', async function () {
375 const params = getBase({}, { token: null, expectedStatus: 401 })
376 await updateVideoPlaylistElement(params)
379 it('Should fail with the playlist of another user', async function () {
380 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
381 await updateVideoPlaylistElement(params)
384 it('Should fail with an unknown or incorrect playlist id', async function () {
386 const params = getBase({}, { playlistId: 'toto' })
387 await updateVideoPlaylistElement(params)
391 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
392 await updateVideoPlaylistElement(params)
396 it('Should fail with an unknown or incorrect playlistElement id', async function () {
398 const params = getBase({}, { playlistElementId: 'toto' })
399 await updateVideoPlaylistElement(params)
403 const params = getBase({}, { playlistElementId: 42, expectedStatus: 404 })
404 await updateVideoPlaylistElement(params)
408 it('Should fail with a bad start/stop timestamp', async function () {
410 const params = getBase({ startTimestamp: 'toto' as any })
411 await updateVideoPlaylistElement(params)
415 const params = getBase({ stopTimestamp: -42 })
416 await updateVideoPlaylistElement(params)
420 it('Should fail with an unknown element', async function () {
421 const params = getBase({}, { playlistElementId: 888, expectedStatus: 404 })
422 await updateVideoPlaylistElement(params)
425 it('Succeed with the correct params', async function () {
426 const params = getBase({}, { expectedStatus: 204 })
427 await updateVideoPlaylistElement(params)
431 describe('When reordering elements of a playlist', function () {
435 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
436 return Object.assign({
438 token: server.accessToken,
439 playlistId: playlistUUID,
440 elementAttrs: Object.assign({
442 insertAfterPosition: 2,
449 before(async function () {
450 videoId3 = (await uploadVideoAndGetId({ server, videoName: 'video 3' })).id
451 videoId4 = (await uploadVideoAndGetId({ server, videoName: 'video 4' })).id
453 for (const id of [ videoId3, videoId4 ]) {
454 await addVideoInPlaylist({
456 token: server.accessToken,
457 playlistId: playlistUUID,
458 elementAttrs: { videoId: id }
463 it('Should fail with an unauthenticated user', async function () {
464 const params = getBase({}, { token: null, expectedStatus: 401 })
465 await reorderVideosPlaylist(params)
468 it('Should fail with the playlist of another user', async function () {
469 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
470 await reorderVideosPlaylist(params)
473 it('Should fail with an invalid playlist', async function () {
475 const params = getBase({}, { playlistId: 'toto' })
476 await reorderVideosPlaylist(params)
480 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
481 await reorderVideosPlaylist(params)
485 it('Should fail with an invalid start position', async function () {
487 const params = getBase({ startPosition: -1 })
488 await reorderVideosPlaylist(params)
492 const params = getBase({ startPosition: 'toto' as any })
493 await reorderVideosPlaylist(params)
497 const params = getBase({ startPosition: 42 })
498 await reorderVideosPlaylist(params)
502 it('Should fail with an invalid insert after position', async function () {
504 const params = getBase({ insertAfterPosition: 'toto' as any })
505 await reorderVideosPlaylist(params)
509 const params = getBase({ insertAfterPosition: -2 })
510 await reorderVideosPlaylist(params)
514 const params = getBase({ insertAfterPosition: 42 })
515 await reorderVideosPlaylist(params)
519 it('Should fail with an invalid reorder length', async function () {
521 const params = getBase({ reorderLength: 'toto' as any })
522 await reorderVideosPlaylist(params)
526 const params = getBase({ reorderLength: -2 })
527 await reorderVideosPlaylist(params)
531 const params = getBase({ reorderLength: 42 })
532 await reorderVideosPlaylist(params)
536 it('Succeed with the correct params', async function () {
537 const params = getBase({}, { expectedStatus: 204 })
538 await reorderVideosPlaylist(params)
542 describe('When checking exists in playlist endpoint', function () {
543 const path = '/api/v1/users/me/video-playlists/videos-exist'
545 it('Should fail with an unauthenticated user', async function () {
546 await makeGetRequest({
549 query: { videoIds: [ 1, 2 ] },
550 statusCodeExpected: 401
554 it('Should fail with invalid video ids', async function () {
555 await makeGetRequest({
557 token: server.accessToken,
559 query: { videoIds: 'toto' }
562 await makeGetRequest({
564 token: server.accessToken,
566 query: { videoIds: [ 'toto' ] }
569 await makeGetRequest({
571 token: server.accessToken,
573 query: { videoIds: [ 1, 'toto' ] }
577 it('Should succeed with the correct params', async function () {
578 await makeGetRequest({
580 token: server.accessToken,
582 query: { videoIds: [ 1, 2 ] },
583 statusCodeExpected: 200
588 describe('When deleting an element in a playlist', function () {
589 const getBase = (wrapper: any = {}) => {
590 return Object.assign({
592 token: server.accessToken,
594 playlistId: playlistUUID,
599 it('Should fail with an unauthenticated user', async function () {
600 const params = getBase({ token: null, expectedStatus: 401 })
601 await removeVideoFromPlaylist(params)
604 it('Should fail with the playlist of another user', async function () {
605 const params = getBase({ token: userAccessToken, expectedStatus: 403 })
606 await removeVideoFromPlaylist(params)
609 it('Should fail with an unknown or incorrect playlist id', async function () {
611 const params = getBase({ playlistId: 'toto' })
612 await removeVideoFromPlaylist(params)
616 const params = getBase({ playlistId: 42, expectedStatus: 404 })
617 await removeVideoFromPlaylist(params)
621 it('Should fail with an unknown or incorrect video id', async function () {
623 const params = getBase({ playlistElementId: 'toto' })
624 await removeVideoFromPlaylist(params)
628 const params = getBase({ playlistElementId: 42, expectedStatus: 404 })
629 await removeVideoFromPlaylist(params)
633 it('Should fail with an unknown element', async function () {
634 const params = getBase({ playlistElementId: 888, expectedStatus: 404 })
635 await removeVideoFromPlaylist(params)
638 it('Succeed with the correct params', async function () {
639 const params = getBase({ expectedStatus: 204 })
640 await removeVideoFromPlaylist(params)
644 describe('When deleting a playlist', function () {
645 it('Should fail with an unknown playlist', async function () {
646 await deleteVideoPlaylist(server.url, server.accessToken, 42, 404)
649 it('Should fail with a playlist of another user', async function () {
650 await deleteVideoPlaylist(server.url, userAccessToken, playlistUUID, 403)
653 it('Should fail with the watch later playlist', async function () {
654 await deleteVideoPlaylist(server.url, server.accessToken, watchLaterPlaylistId, 400)
657 it('Should succeed with the correct params', async function () {
658 await deleteVideoPlaylist(server.url, server.accessToken, playlistUUID)
662 after(async function () {
663 await cleanupTests([ server ])