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