]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/check-params/video-playlists.ts
Correctly fix octet stream fallback for video ext
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / video-playlists.ts
1 /* tslint:disable:no-unused-expression */
2
3 import 'mocha'
4 import {
5 addVideoInPlaylist,
6 cleanupTests,
7 createVideoPlaylist,
8 deleteVideoPlaylist,
9 flushAndRunServer,
10 generateUserAccessToken,
11 getAccountPlaylistsListWithToken,
12 getVideoPlaylist,
13 immutableAssign,
14 makeGetRequest,
15 removeVideoFromPlaylist,
16 reorderVideosPlaylist,
17 ServerInfo,
18 setAccessTokensToServers,
19 setDefaultVideoChannel,
20 updateVideoPlaylist,
21 updateVideoPlaylistElement,
22 uploadVideoAndGetId
23 } from '../../../../shared/extra-utils'
24 import {
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'
31
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
38 let videoId: number
39 let videoId2: number
40 let playlistElementId: number
41
42 // ---------------------------------------------------------------
43
44 before(async function () {
45 this.timeout(30000)
46
47 server = await flushAndRunServer(1)
48
49 await setAccessTokensToServers([ server ])
50 await setDefaultVideoChannel([ server ])
51
52 userAccessToken = await generateUserAccessToken(server, 'user1')
53 videoId = (await uploadVideoAndGetId({ server, videoName: 'video 1' })).id
54 videoId2 = (await uploadVideoAndGetId({ server, videoName: 'video 2' })).id
55
56 {
57 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
58 watchLaterPlaylistId = res.body.data[0].id
59 }
60
61 {
62 const res = await createVideoPlaylist({
63 url: server.url,
64 token: server.accessToken,
65 playlistAttrs: {
66 displayName: 'super playlist',
67 privacy: VideoPlaylistPrivacy.PUBLIC,
68 videoChannelId: server.videoChannel.id
69 }
70 })
71 playlistUUID = res.body.videoPlaylist.uuid
72 }
73
74 {
75 const res = await createVideoPlaylist({
76 url: server.url,
77 token: server.accessToken,
78 playlistAttrs: {
79 displayName: 'private',
80 privacy: VideoPlaylistPrivacy.PRIVATE
81 }
82 })
83 privatePlaylistUUID = res.body.videoPlaylist.uuid
84 }
85 })
86
87 describe('When listing playlists', function () {
88 const globalPath = '/api/v1/video-playlists'
89 const accountPath = '/api/v1/accounts/root/video-playlists'
90 const videoChannelPath = '/api/v1/video-channels/root_channel/video-playlists'
91
92 it('Should fail with a bad start pagination', async function () {
93 await checkBadStartPagination(server.url, globalPath, server.accessToken)
94 await checkBadStartPagination(server.url, accountPath, server.accessToken)
95 await checkBadStartPagination(server.url, videoChannelPath, server.accessToken)
96 })
97
98 it('Should fail with a bad count pagination', async function () {
99 await checkBadCountPagination(server.url, globalPath, server.accessToken)
100 await checkBadCountPagination(server.url, accountPath, server.accessToken)
101 await checkBadCountPagination(server.url, videoChannelPath, server.accessToken)
102 })
103
104 it('Should fail with an incorrect sort', async function () {
105 await checkBadSortPagination(server.url, globalPath, server.accessToken)
106 await checkBadSortPagination(server.url, accountPath, server.accessToken)
107 await checkBadSortPagination(server.url, videoChannelPath, server.accessToken)
108 })
109
110 it('Should fail with a bad playlist type', async function () {
111 await makeGetRequest({ url: server.url, path: globalPath, query: { playlistType: 3 } })
112 await makeGetRequest({ url: server.url, path: accountPath, query: { playlistType: 3 } })
113 await makeGetRequest({ url: server.url, path: videoChannelPath, query: { playlistType: 3 } })
114 })
115
116 it('Should fail with a bad account parameter', async function () {
117 const accountPath = '/api/v1/accounts/root2/video-playlists'
118
119 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 404, token: server.accessToken })
120 })
121
122 it('Should fail with a bad video channel parameter', async function () {
123 const accountPath = '/api/v1/video-channels/bad_channel/video-playlists'
124
125 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 404, token: server.accessToken })
126 })
127
128 it('Should success with the correct parameters', async function () {
129 await makeGetRequest({ url: server.url, path: globalPath, statusCodeExpected: 200, token: server.accessToken })
130 await makeGetRequest({ url: server.url, path: accountPath, statusCodeExpected: 200, token: server.accessToken })
131 await makeGetRequest({ url: server.url, path: videoChannelPath, statusCodeExpected: 200, token: server.accessToken })
132 })
133 })
134
135 describe('When listing videos of a playlist', function () {
136 const path = '/api/v1/video-playlists/'
137
138 it('Should fail with a bad start pagination', async function () {
139 await checkBadStartPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
140 })
141
142 it('Should fail with a bad count pagination', async function () {
143 await checkBadCountPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
144 })
145
146 it('Should success with the correct parameters', async function () {
147 await makeGetRequest({ url: server.url, path: path + playlistUUID + '/videos', statusCodeExpected: 200 })
148 })
149 })
150
151 describe('When getting a video playlist', function () {
152 it('Should fail with a bad id or uuid', async function () {
153 await getVideoPlaylist(server.url, 'toto', 400)
154 })
155
156 it('Should fail with an unknown playlist', async function () {
157 await getVideoPlaylist(server.url, 42, 404)
158 })
159
160 it('Should fail to get an unlisted playlist with the number id', async function () {
161 const res = await createVideoPlaylist({
162 url: server.url,
163 token: server.accessToken,
164 playlistAttrs: {
165 displayName: 'super playlist',
166 privacy: VideoPlaylistPrivacy.UNLISTED
167 }
168 })
169 const playlist = res.body.videoPlaylist
170
171 await getVideoPlaylist(server.url, playlist.id, 404)
172 await getVideoPlaylist(server.url, playlist.uuid, 200)
173 })
174
175 it('Should succeed with the correct params', async function () {
176 await getVideoPlaylist(server.url, playlistUUID, 200)
177 })
178 })
179
180 describe('When creating/updating a video playlist', function () {
181 const getBase = (playlistAttrs: any = {}, wrapper: any = {}) => {
182 return Object.assign({
183 expectedStatus: 400,
184 url: server.url,
185 token: server.accessToken,
186 playlistAttrs: Object.assign({
187 displayName: 'display name',
188 privacy: VideoPlaylistPrivacy.UNLISTED,
189 thumbnailfile: 'thumbnail.jpg',
190 videoChannelId: server.videoChannel.id
191 }, playlistAttrs)
192 }, wrapper)
193 }
194 const getUpdate = (params: any, playlistId: number | string) => {
195 return immutableAssign(params, { playlistId: playlistId })
196 }
197
198 it('Should fail with an unauthenticated user', async function () {
199 const params = getBase({}, { token: null, expectedStatus: 401 })
200
201 await createVideoPlaylist(params)
202 await updateVideoPlaylist(getUpdate(params, playlistUUID))
203 })
204
205 it('Should fail without displayName', async function () {
206 const params = getBase({ displayName: undefined })
207
208 await createVideoPlaylist(params)
209 })
210
211 it('Should fail with an incorrect display name', async function () {
212 const params = getBase({ displayName: 's'.repeat(300) })
213
214 await createVideoPlaylist(params)
215 await updateVideoPlaylist(getUpdate(params, playlistUUID))
216 })
217
218 it('Should fail with an incorrect description', async function () {
219 const params = getBase({ description: 't' })
220
221 await createVideoPlaylist(params)
222 await updateVideoPlaylist(getUpdate(params, playlistUUID))
223 })
224
225 it('Should fail with an incorrect privacy', async function () {
226 const params = getBase({ privacy: 45 })
227
228 await createVideoPlaylist(params)
229 await updateVideoPlaylist(getUpdate(params, playlistUUID))
230 })
231
232 it('Should fail with an unknown video channel id', async function () {
233 const params = getBase({ videoChannelId: 42 }, { expectedStatus: 404 })
234
235 await createVideoPlaylist(params)
236 await updateVideoPlaylist(getUpdate(params, playlistUUID))
237 })
238
239 it('Should fail with an incorrect thumbnail file', async function () {
240 const params = getBase({ thumbnailfile: 'avatar.png' })
241
242 await createVideoPlaylist(params)
243 await updateVideoPlaylist(getUpdate(params, playlistUUID))
244 })
245
246 it('Should fail to set "public" a playlist not assigned to a channel', async function () {
247 const params = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: undefined })
248 const params2 = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: 'null' })
249 const params3 = getBase({ privacy: undefined, videoChannelId: 'null' })
250
251 await createVideoPlaylist(params)
252 await createVideoPlaylist(params2)
253 await updateVideoPlaylist(getUpdate(params, privatePlaylistUUID))
254 await updateVideoPlaylist(getUpdate(params2, playlistUUID))
255 await updateVideoPlaylist(getUpdate(params3, playlistUUID))
256 })
257
258 it('Should fail with an unknown playlist to update', async function () {
259 await updateVideoPlaylist(getUpdate(
260 getBase({}, { expectedStatus: 404 }),
261 42
262 ))
263 })
264
265 it('Should fail to update a playlist of another user', async function () {
266 await updateVideoPlaylist(getUpdate(
267 getBase({}, { token: userAccessToken, expectedStatus: 403 }),
268 playlistUUID
269 ))
270 })
271
272 it('Should fail to update the watch later playlist', async function () {
273 await updateVideoPlaylist(getUpdate(
274 getBase({}, { expectedStatus: 400 }),
275 watchLaterPlaylistId
276 ))
277 })
278
279 it('Should succeed with the correct params', async function () {
280 {
281 const params = getBase({}, { expectedStatus: 200 })
282 await createVideoPlaylist(params)
283 }
284
285 {
286 const params = getBase({}, { expectedStatus: 204 })
287 await updateVideoPlaylist(getUpdate(params, playlistUUID))
288 }
289 })
290 })
291
292 describe('When adding an element in a playlist', function () {
293 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
294 return Object.assign({
295 expectedStatus: 400,
296 url: server.url,
297 token: server.accessToken,
298 playlistId: playlistUUID,
299 elementAttrs: Object.assign({
300 videoId,
301 startTimestamp: 2,
302 stopTimestamp: 3
303 }, elementAttrs)
304 }, wrapper)
305 }
306
307 it('Should fail with an unauthenticated user', async function () {
308 const params = getBase({}, { token: null, expectedStatus: 401 })
309 await addVideoInPlaylist(params)
310 })
311
312 it('Should fail with the playlist of another user', async function () {
313 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
314 await addVideoInPlaylist(params)
315 })
316
317 it('Should fail with an unknown or incorrect playlist id', async function () {
318 {
319 const params = getBase({}, { playlistId: 'toto' })
320 await addVideoInPlaylist(params)
321 }
322
323 {
324 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
325 await addVideoInPlaylist(params)
326 }
327 })
328
329 it('Should fail with an unknown or incorrect video id', async function () {
330 const params = getBase({ videoId: 42 }, { expectedStatus: 404 })
331 await addVideoInPlaylist(params)
332 })
333
334 it('Should fail with a bad start/stop timestamp', async function () {
335 {
336 const params = getBase({ startTimestamp: -42 })
337 await addVideoInPlaylist(params)
338 }
339
340 {
341 const params = getBase({ stopTimestamp: 'toto' as any })
342 await addVideoInPlaylist(params)
343 }
344 })
345
346 it('Succeed with the correct params', async function () {
347 const params = getBase({}, { expectedStatus: 200 })
348 const res = await addVideoInPlaylist(params)
349 playlistElementId = res.body.videoPlaylistElement.id
350 })
351
352 it('Should fail if the video was already added in the playlist', async function () {
353 const params = getBase({}, { expectedStatus: 409 })
354 await addVideoInPlaylist(params)
355 })
356 })
357
358 describe('When updating an element in a playlist', function () {
359 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
360 return Object.assign({
361 url: server.url,
362 token: server.accessToken,
363 elementAttrs: Object.assign({
364 startTimestamp: 1,
365 stopTimestamp: 2
366 }, elementAttrs),
367 playlistElementId,
368 playlistId: playlistUUID,
369 expectedStatus: 400
370 }, wrapper)
371 }
372
373 it('Should fail with an unauthenticated user', async function () {
374 const params = getBase({}, { token: null, expectedStatus: 401 })
375 await updateVideoPlaylistElement(params)
376 })
377
378 it('Should fail with the playlist of another user', async function () {
379 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
380 await updateVideoPlaylistElement(params)
381 })
382
383 it('Should fail with an unknown or incorrect playlist id', async function () {
384 {
385 const params = getBase({}, { playlistId: 'toto' })
386 await updateVideoPlaylistElement(params)
387 }
388
389 {
390 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
391 await updateVideoPlaylistElement(params)
392 }
393 })
394
395 it('Should fail with an unknown or incorrect playlistElement id', async function () {
396 {
397 const params = getBase({}, { playlistElementId: 'toto' })
398 await updateVideoPlaylistElement(params)
399 }
400
401 {
402 const params = getBase({}, { playlistElementId: 42, expectedStatus: 404 })
403 await updateVideoPlaylistElement(params)
404 }
405 })
406
407 it('Should fail with a bad start/stop timestamp', async function () {
408 {
409 const params = getBase({ startTimestamp: 'toto' as any })
410 await updateVideoPlaylistElement(params)
411 }
412
413 {
414 const params = getBase({ stopTimestamp: -42 })
415 await updateVideoPlaylistElement(params)
416 }
417 })
418
419 it('Should fail with an unknown element', async function () {
420 const params = getBase({}, { playlistElementId: 888, expectedStatus: 404 })
421 await updateVideoPlaylistElement(params)
422 })
423
424 it('Succeed with the correct params', async function () {
425 const params = getBase({}, { expectedStatus: 204 })
426 await updateVideoPlaylistElement(params)
427 })
428 })
429
430 describe('When reordering elements of a playlist', function () {
431 let videoId3: number
432 let videoId4: number
433
434 const getBase = (elementAttrs: any = {}, wrapper: any = {}) => {
435 return Object.assign({
436 url: server.url,
437 token: server.accessToken,
438 playlistId: playlistUUID,
439 elementAttrs: Object.assign({
440 startPosition: 1,
441 insertAfterPosition: 2,
442 reorderLength: 3
443 }, elementAttrs),
444 expectedStatus: 400
445 }, wrapper)
446 }
447
448 before(async function () {
449 videoId3 = (await uploadVideoAndGetId({ server, videoName: 'video 3' })).id
450 videoId4 = (await uploadVideoAndGetId({ server, videoName: 'video 4' })).id
451
452 for (let id of [ videoId3, videoId4 ]) {
453 await addVideoInPlaylist({
454 url: server.url,
455 token: server.accessToken,
456 playlistId: playlistUUID,
457 elementAttrs: { videoId: id }
458 })
459 }
460 })
461
462 it('Should fail with an unauthenticated user', async function () {
463 const params = getBase({}, { token: null, expectedStatus: 401 })
464 await reorderVideosPlaylist(params)
465 })
466
467 it('Should fail with the playlist of another user', async function () {
468 const params = getBase({}, { token: userAccessToken, expectedStatus: 403 })
469 await reorderVideosPlaylist(params)
470 })
471
472 it('Should fail with an invalid playlist', async function () {
473 {
474 const params = getBase({}, { playlistId: 'toto' })
475 await reorderVideosPlaylist(params)
476 }
477
478 {
479 const params = getBase({}, { playlistId: 42, expectedStatus: 404 })
480 await reorderVideosPlaylist(params)
481 }
482 })
483
484 it('Should fail with an invalid start position', async function () {
485 {
486 const params = getBase({ startPosition: -1 })
487 await reorderVideosPlaylist(params)
488 }
489
490 {
491 const params = getBase({ startPosition: 'toto' as any })
492 await reorderVideosPlaylist(params)
493 }
494
495 {
496 const params = getBase({ startPosition: 42 })
497 await reorderVideosPlaylist(params)
498 }
499 })
500
501 it('Should fail with an invalid insert after position', async function () {
502 {
503 const params = getBase({ insertAfterPosition: 'toto' as any })
504 await reorderVideosPlaylist(params)
505 }
506
507 {
508 const params = getBase({ insertAfterPosition: -2 })
509 await reorderVideosPlaylist(params)
510 }
511
512 {
513 const params = getBase({ insertAfterPosition: 42 })
514 await reorderVideosPlaylist(params)
515 }
516 })
517
518 it('Should fail with an invalid reorder length', async function () {
519 {
520 const params = getBase({ reorderLength: 'toto' as any })
521 await reorderVideosPlaylist(params)
522 }
523
524 {
525 const params = getBase({ reorderLength: -2 })
526 await reorderVideosPlaylist(params)
527 }
528
529 {
530 const params = getBase({ reorderLength: 42 })
531 await reorderVideosPlaylist(params)
532 }
533 })
534
535 it('Succeed with the correct params', async function () {
536 const params = getBase({}, { expectedStatus: 204 })
537 await reorderVideosPlaylist(params)
538 })
539 })
540
541 describe('When checking exists in playlist endpoint', function () {
542 const path = '/api/v1/users/me/video-playlists/videos-exist'
543
544 it('Should fail with an unauthenticated user', async function () {
545 await makeGetRequest({
546 url: server.url,
547 path,
548 query: { videoIds: [ 1, 2 ] },
549 statusCodeExpected: 401
550 })
551 })
552
553 it('Should fail with invalid video ids', async function () {
554 await makeGetRequest({
555 url: server.url,
556 token: server.accessToken,
557 path,
558 query: { videoIds: 'toto' }
559 })
560
561 await makeGetRequest({
562 url: server.url,
563 token: server.accessToken,
564 path,
565 query: { videoIds: [ 'toto' ] }
566 })
567
568 await makeGetRequest({
569 url: server.url,
570 token: server.accessToken,
571 path,
572 query: { videoIds: [ 1, 'toto' ] }
573 })
574 })
575
576 it('Should succeed with the correct params', async function () {
577 await makeGetRequest({
578 url: server.url,
579 token: server.accessToken,
580 path,
581 query: { videoIds: [ 1, 2 ] },
582 statusCodeExpected: 200
583 })
584 })
585 })
586
587 describe('When deleting an element in a playlist', function () {
588 const getBase = (wrapper: any = {}) => {
589 return Object.assign({
590 url: server.url,
591 token: server.accessToken,
592 playlistElementId,
593 playlistId: playlistUUID,
594 expectedStatus: 400
595 }, wrapper)
596 }
597
598 it('Should fail with an unauthenticated user', async function () {
599 const params = getBase({ token: null, expectedStatus: 401 })
600 await removeVideoFromPlaylist(params)
601 })
602
603 it('Should fail with the playlist of another user', async function () {
604 const params = getBase({ token: userAccessToken, expectedStatus: 403 })
605 await removeVideoFromPlaylist(params)
606 })
607
608 it('Should fail with an unknown or incorrect playlist id', async function () {
609 {
610 const params = getBase({ playlistId: 'toto' })
611 await removeVideoFromPlaylist(params)
612 }
613
614 {
615 const params = getBase({ playlistId: 42, expectedStatus: 404 })
616 await removeVideoFromPlaylist(params)
617 }
618 })
619
620 it('Should fail with an unknown or incorrect video id', async function () {
621 {
622 const params = getBase({ playlistElementId: 'toto' })
623 await removeVideoFromPlaylist(params)
624 }
625
626 {
627 const params = getBase({ playlistElementId: 42, expectedStatus: 404 })
628 await removeVideoFromPlaylist(params)
629 }
630 })
631
632 it('Should fail with an unknown element', async function () {
633 const params = getBase({ playlistElementId: 888, expectedStatus: 404 })
634 await removeVideoFromPlaylist(params)
635 })
636
637 it('Succeed with the correct params', async function () {
638 const params = getBase({ expectedStatus: 204 })
639 await removeVideoFromPlaylist(params)
640 })
641 })
642
643 describe('When deleting a playlist', function () {
644 it('Should fail with an unknown playlist', async function () {
645 await deleteVideoPlaylist(server.url, server.accessToken, 42, 404)
646 })
647
648 it('Should fail with a playlist of another user', async function () {
649 await deleteVideoPlaylist(server.url, userAccessToken, playlistUUID, 403)
650 })
651
652 it('Should fail with the watch later playlist', async function () {
653 await deleteVideoPlaylist(server.url, server.accessToken, watchLaterPlaylistId, 400)
654 })
655
656 it('Should succeed with the correct params', async function () {
657 await deleteVideoPlaylist(server.url, server.accessToken, playlistUUID)
658 })
659 })
660
661 after(async function () {
662 await cleanupTests([ server ])
663 })
664 })