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