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