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