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