]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/check-params/video-imports.ts
Improve remote runner config UX
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / video-imports.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
5d08a6a7 2
c55e3d72 3import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, FIXTURE_URLS } from '@server/tests/shared'
bbd5aa7e 4import { buildAbsoluteFixturePath, omit } from '@shared/core-utils'
c55e3d72 5import { HttpStatusCode, VideoPrivacy } from '@shared/models'
5d08a6a7 6import {
7c3b7976 7 cleanupTests,
254d3579 8 createSingleServer,
5d08a6a7
C
9 makeGetRequest,
10 makePostBodyRequest,
11 makeUploadRequest,
254d3579 12 PeerTubeServer,
419b520c
C
13 setAccessTokensToServers,
14 setDefaultVideoChannel,
15 waitJobs
bf54587a 16} from '@shared/server-commands'
5d08a6a7
C
17
18describe('Test video imports API validator', function () {
19 const path = '/api/v1/videos/imports'
254d3579 20 let server: PeerTubeServer
5d08a6a7 21 let userAccessToken = ''
5d08a6a7 22 let channelId: number
5d08a6a7
C
23
24 // ---------------------------------------------------------------
25
26 before(async function () {
27 this.timeout(30000)
28
254d3579 29 server = await createSingleServer(1)
5d08a6a7
C
30
31 await setAccessTokensToServers([ server ])
419b520c 32 await setDefaultVideoChannel([ server ])
5d08a6a7
C
33
34 const username = 'user1'
35 const password = 'my super password'
ba2684ce 36 await server.users.create({ username, password })
89d241a7 37 userAccessToken = await server.login.getAccessToken({ username, password })
5d08a6a7
C
38
39 {
89d241a7 40 const { videoChannels } = await server.users.getMyInfo()
7926c5f9 41 channelId = videoChannels[0].id
5d08a6a7
C
42 }
43 })
44
45 describe('When listing my video imports', function () {
46 const myPath = '/api/v1/users/me/videos/imports'
47
48 it('Should fail with a bad start pagination', async function () {
49 await checkBadStartPagination(server.url, myPath, server.accessToken)
50 })
51
52 it('Should fail with a bad count pagination', async function () {
53 await checkBadCountPagination(server.url, myPath, server.accessToken)
54 })
55
56 it('Should fail with an incorrect sort', async function () {
57 await checkBadSortPagination(server.url, myPath, server.accessToken)
58 })
59
a3b472a1
C
60 it('Should fail with a bad videoChannelSyncId param', async function () {
61 await makeGetRequest({
62 url: server.url,
63 path: myPath,
64 query: { videoChannelSyncId: 'toto' },
65 token: server.accessToken
66 })
67 })
68
5d08a6a7 69 it('Should success with the correct parameters', async function () {
c0e8b12e 70 await makeGetRequest({ url: server.url, path: myPath, expectedStatus: HttpStatusCode.OK_200, token: server.accessToken })
5d08a6a7
C
71 })
72 })
73
74 describe('When adding a video import', function () {
75 let baseCorrectParams
76
77 before(function () {
78 baseCorrectParams = {
59bbcced 79 targetUrl: FIXTURE_URLS.goodVideo,
5d08a6a7
C
80 name: 'my super name',
81 category: 5,
82 licence: 1,
83 language: 'pt',
84 nsfw: false,
85 commentsEnabled: true,
7f2cfe3a 86 downloadEnabled: true,
5d08a6a7
C
87 waitTranscoding: true,
88 description: 'my super description',
89 support: 'my super support text',
90 tags: [ 'tag1', 'tag2' ],
91 privacy: VideoPrivacy.PUBLIC,
c8861d5d 92 channelId
5d08a6a7
C
93 }
94 })
95
96 it('Should fail with nothing', async function () {
97 const fields = {}
2a491182
F
98 await makePostBodyRequest({
99 url: server.url,
100 path,
101 token: server.accessToken,
102 fields,
103 expectedStatus: HttpStatusCode.BAD_REQUEST_400
104 })
5d08a6a7
C
105 })
106
590fb506 107 it('Should fail without a target url', async function () {
bbd5aa7e 108 const fields = omit(baseCorrectParams, [ 'targetUrl' ])
2d53be02
RK
109 await makePostBodyRequest({
110 url: server.url,
111 path,
112 token: server.accessToken,
113 fields,
c0e8b12e 114 expectedStatus: HttpStatusCode.BAD_REQUEST_400
2d53be02 115 })
590fb506
C
116 })
117
118 it('Should fail with a bad target url', async function () {
6c5065a0 119 const fields = { ...baseCorrectParams, targetUrl: 'htt://hello' }
590fb506
C
120
121 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
122 })
7b54a81c
C
123
124 it('Should fail with localhost', async function () {
125 const fields = { ...baseCorrectParams, targetUrl: 'http://localhost:8000' }
126
127 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
128 })
129
130 it('Should fail with a private IP target urls', async function () {
131 const targetUrls = [
132 'http://127.0.0.1:8000',
133 'http://127.0.0.1',
134 'http://127.0.0.1/hello',
135 'https://192.168.1.42',
f33e5159
C
136 'http://192.168.1.42',
137 'http://127.0.0.1.cpy.re'
7b54a81c
C
138 ]
139
140 for (const targetUrl of targetUrls) {
141 const fields = { ...baseCorrectParams, targetUrl }
142
143 await makePostBodyRequest({
144 url: server.url,
145 path,
146 token: server.accessToken,
147 fields,
148 expectedStatus: HttpStatusCode.FORBIDDEN_403
149 })
150 }
151 })
590fb506 152
5d08a6a7 153 it('Should fail with a long name', async function () {
6c5065a0 154 const fields = { ...baseCorrectParams, name: 'super'.repeat(65) }
5d08a6a7
C
155
156 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
157 })
158
159 it('Should fail with a bad category', async function () {
6c5065a0 160 const fields = { ...baseCorrectParams, category: 125 }
5d08a6a7
C
161
162 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
163 })
164
165 it('Should fail with a bad licence', async function () {
6c5065a0 166 const fields = { ...baseCorrectParams, licence: 125 }
5d08a6a7
C
167
168 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
169 })
170
171 it('Should fail with a bad language', async function () {
6c5065a0 172 const fields = { ...baseCorrectParams, language: 'a'.repeat(15) }
5d08a6a7
C
173
174 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
175 })
176
177 it('Should fail with a long description', async function () {
6c5065a0 178 const fields = { ...baseCorrectParams, description: 'super'.repeat(2500) }
5d08a6a7
C
179
180 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
181 })
182
183 it('Should fail with a long support text', async function () {
6c5065a0 184 const fields = { ...baseCorrectParams, support: 'super'.repeat(201) }
5d08a6a7
C
185
186 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
187 })
188
189 it('Should fail without a channel', async function () {
bbd5aa7e 190 const fields = omit(baseCorrectParams, [ 'channelId' ])
5d08a6a7
C
191
192 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
193 })
194
195 it('Should fail with a bad channel', async function () {
6c5065a0 196 const fields = { ...baseCorrectParams, channelId: 545454 }
5d08a6a7
C
197
198 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
199 })
200
201 it('Should fail with another user channel', async function () {
202 const user = {
203 username: 'fake',
204 password: 'fake_password'
205 }
89d241a7 206 await server.users.create({ username: user.username, password: user.password })
5d08a6a7 207
89d241a7
C
208 const accessTokenUser = await server.login.getAccessToken(user)
209 const { videoChannels } = await server.users.getMyInfo({ token: accessTokenUser })
7926c5f9 210 const customChannelId = videoChannels[0].id
5d08a6a7 211
6c5065a0 212 const fields = { ...baseCorrectParams, channelId: customChannelId }
5d08a6a7
C
213
214 await makePostBodyRequest({ url: server.url, path, token: userAccessToken, fields })
215 })
216
217 it('Should fail with too many tags', async function () {
6c5065a0 218 const fields = { ...baseCorrectParams, tags: [ 'tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' ] }
5d08a6a7
C
219
220 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
221 })
222
223 it('Should fail with a tag length too low', async function () {
6c5065a0 224 const fields = { ...baseCorrectParams, tags: [ 'tag1', 't' ] }
5d08a6a7
C
225
226 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
227 })
228
229 it('Should fail with a tag length too big', async function () {
6c5065a0 230 const fields = { ...baseCorrectParams, tags: [ 'tag1', 'my_super_tag_too_long_long_long_long_long_long' ] }
5d08a6a7
C
231
232 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
233 })
234
235 it('Should fail with an incorrect thumbnail file', async function () {
236 const fields = baseCorrectParams
237 const attaches = {
3d470a53 238 thumbnailfile: buildAbsoluteFixturePath('video_short.mp4')
5d08a6a7
C
239 }
240
241 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
242 })
243
244 it('Should fail with a big thumbnail file', async function () {
245 const fields = baseCorrectParams
246 const attaches = {
3d470a53 247 thumbnailfile: buildAbsoluteFixturePath('preview-big.png')
5d08a6a7
C
248 }
249
250 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
251 })
252
253 it('Should fail with an incorrect preview file', async function () {
254 const fields = baseCorrectParams
255 const attaches = {
3d470a53 256 previewfile: buildAbsoluteFixturePath('video_short.mp4')
5d08a6a7
C
257 }
258
259 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
260 })
261
262 it('Should fail with a big preview file', async function () {
263 const fields = baseCorrectParams
264 const attaches = {
3d470a53 265 previewfile: buildAbsoluteFixturePath('preview-big.png')
5d08a6a7
C
266 }
267
268 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
269 })
270
187501f8 271 it('Should fail with an invalid torrent file', async function () {
bbd5aa7e 272 const fields = omit(baseCorrectParams, [ 'targetUrl' ])
187501f8 273 const attaches = {
3d470a53 274 torrentfile: buildAbsoluteFixturePath('avatar-big.png')
187501f8
C
275 }
276
277 await makeUploadRequest({ url: server.url, path, token: server.accessToken, fields, attaches })
278 })
279
280 it('Should fail with an invalid magnet URI', async function () {
bbd5aa7e 281 let fields = omit(baseCorrectParams, [ 'targetUrl' ])
6c5065a0 282 fields = { ...fields, magnetUri: 'blabla' }
187501f8
C
283
284 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
285 })
286
5d08a6a7 287 it('Should succeed with the correct parameters', async function () {
8d57e728 288 this.timeout(120000)
5d08a6a7 289
b488ba1e
C
290 await makePostBodyRequest({
291 url: server.url,
292 path,
293 token: server.accessToken,
294 fields: baseCorrectParams,
c0e8b12e 295 expectedStatus: HttpStatusCode.OK_200
b488ba1e 296 })
5d08a6a7
C
297 })
298
187501f8 299 it('Should forbid to import http videos', async function () {
89d241a7 300 await server.config.updateCustomSubConfig({
65e6e260
C
301 newConfig: {
302 import: {
303 videos: {
304 http: {
305 enabled: false
306 },
307 torrent: {
308 enabled: true
309 }
590fb506
C
310 }
311 }
312 }
313 })
314
315 await makePostBodyRequest({
316 url: server.url,
317 path,
318 token: server.accessToken,
319 fields: baseCorrectParams,
c0e8b12e 320 expectedStatus: HttpStatusCode.CONFLICT_409
590fb506
C
321 })
322 })
187501f8
C
323
324 it('Should forbid to import torrent videos', async function () {
89d241a7 325 await server.config.updateCustomSubConfig({
65e6e260
C
326 newConfig: {
327 import: {
328 videos: {
329 http: {
330 enabled: true
331 },
332 torrent: {
333 enabled: false
334 }
187501f8
C
335 }
336 }
337 }
338 })
339
bbd5aa7e 340 let fields = omit(baseCorrectParams, [ 'targetUrl' ])
59bbcced 341 fields = { ...fields, magnetUri: FIXTURE_URLS.magnet }
187501f8 342
2d53be02
RK
343 await makePostBodyRequest({
344 url: server.url,
345 path,
346 token: server.accessToken,
347 fields,
c0e8b12e 348 expectedStatus: HttpStatusCode.CONFLICT_409
2d53be02 349 })
187501f8 350
bbd5aa7e 351 fields = omit(fields, [ 'magnetUri' ])
187501f8 352 const attaches = {
3d470a53 353 torrentfile: buildAbsoluteFixturePath('video-720p.torrent')
187501f8
C
354 }
355
2d53be02
RK
356 await makeUploadRequest({
357 url: server.url,
358 path,
359 token: server.accessToken,
360 fields,
361 attaches,
c0e8b12e 362 expectedStatus: HttpStatusCode.CONFLICT_409
2d53be02 363 })
187501f8 364 })
5d08a6a7
C
365 })
366
419b520c
C
367 describe('Deleting/cancelling a video import', function () {
368 let importId: number
369
370 async function importVideo () {
371 const attributes = { channelId: server.store.channel.id, targetUrl: FIXTURE_URLS.goodVideo }
372 const res = await server.imports.importVideo({ attributes })
373
374 return res.id
375 }
376
377 before(async function () {
378 importId = await importVideo()
379 })
380
381 it('Should fail with an invalid import id', async function () {
382 await server.imports.cancel({ importId: 'artyom' as any, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
383 await server.imports.delete({ importId: 'artyom' as any, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
384 })
385
386 it('Should fail with an unknown import id', async function () {
387 await server.imports.cancel({ importId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
388 await server.imports.delete({ importId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
389 })
390
391 it('Should fail without token', async function () {
392 await server.imports.cancel({ importId, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
393 await server.imports.delete({ importId, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
394 })
395
396 it('Should fail with another user token', async function () {
397 await server.imports.cancel({ importId, token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
398 await server.imports.delete({ importId, token: userAccessToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
399 })
400
401 it('Should fail to cancel non pending import', async function () {
402 this.timeout(60000)
403
404 await waitJobs([ server ])
405
406 await server.imports.cancel({ importId, expectedStatus: HttpStatusCode.CONFLICT_409 })
407 })
408
409 it('Should succeed to delete an import', async function () {
410 await server.imports.delete({ importId })
411 })
412
413 it('Should fail to delete a pending import', async function () {
414 await server.jobs.pauseJobQueue()
415
416 importId = await importVideo()
417
418 await server.imports.delete({ importId, expectedStatus: HttpStatusCode.CONFLICT_409 })
419 })
420
421 it('Should succeed to cancel an import', async function () {
422 importId = await importVideo()
423
424 await server.imports.cancel({ importId })
425 })
426 })
427
7c3b7976
C
428 after(async function () {
429 await cleanupTests([ server ])
5d08a6a7
C
430 })
431})