]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/extra-utils/videos/videos.ts
Move markdown icon on right and correct colors
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / videos / videos.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */
a20399c9
C
2
3import { expect } from 'chai'
df0b219d 4import { pathExists, readdir, readFile } from 'fs-extra'
fdbda9e3 5import * as parseTorrent from 'parse-torrent'
1d791a26 6import { extname, join } from 'path'
c5d31dba 7import * as request from 'supertest'
8eb07b01
C
8import { v4 as uuidv4 } from 'uuid'
9import validator from 'validator'
10import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants'
11import { VideoDetails, VideoPrivacy } from '../../models/videos'
ac81d1a0
C
12import {
13 buildAbsoluteFixturePath,
8eb07b01
C
14 buildServerDirectory,
15 dateIsValid,
62689b94 16 immutableAssign,
ac81d1a0 17 root,
8eb07b01
C
18 testImage,
19 webtorrentAdd
20} from '../miscs/miscs'
21import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests'
22import { waitJobs } from '../server/jobs'
23import { ServerInfo } from '../server/servers'
24import { getMyUserInformation } from '../users/users'
0e1dc3e7 25
8f0bc73d
C
26loadLanguages()
27
0e1dc3e7
C
28type VideoAttributes = {
29 name?: string
30 category?: number
31 licence?: number
9d3ef9fe 32 language?: string
0e1dc3e7 33 nsfw?: boolean
47564bbe 34 commentsEnabled?: boolean
7f2cfe3a 35 downloadEnabled?: boolean
2186386c 36 waitTranscoding?: boolean
0e1dc3e7 37 description?: string
7519127b 38 originallyPublishedAt?: string
0e1dc3e7 39 tags?: string[]
5f04dd2f 40 channelId?: number
11474c3c 41 privacy?: VideoPrivacy
0e1dc3e7 42 fixture?: string
ac81d1a0
C
43 thumbnailfile?: string
44 previewfile?: string
2baea0c7
C
45 scheduleUpdate?: {
46 updateAt: string
47 privacy?: VideoPrivacy
48 }
0e1dc3e7
C
49}
50
51function getVideoCategories (url: string) {
52 const path = '/api/v1/videos/categories'
53
eec63bbc
C
54 return makeGetRequest({
55 url,
59651eee
C
56 path,
57 statusCodeExpected: 200
eec63bbc 58 })
0e1dc3e7
C
59}
60
61function getVideoLicences (url: string) {
62 const path = '/api/v1/videos/licences'
63
eec63bbc
C
64 return makeGetRequest({
65 url,
59651eee
C
66 path,
67 statusCodeExpected: 200
eec63bbc 68 })
0e1dc3e7
C
69}
70
71function getVideoLanguages (url: string) {
72 const path = '/api/v1/videos/languages'
73
eec63bbc
C
74 return makeGetRequest({
75 url,
59651eee
C
76 path,
77 statusCodeExpected: 200
eec63bbc 78 })
0e1dc3e7
C
79}
80
11474c3c
C
81function getVideoPrivacies (url: string) {
82 const path = '/api/v1/videos/privacies'
83
eec63bbc
C
84 return makeGetRequest({
85 url,
59651eee
C
86 path,
87 statusCodeExpected: 200
eec63bbc 88 })
11474c3c
C
89}
90
11474c3c 91function getVideo (url: string, id: number | string, expectedStatus = 200) {
0e1dc3e7
C
92 const path = '/api/v1/videos/' + id
93
94 return request(url)
95 .get(path)
96 .set('Accept', 'application/json')
11474c3c
C
97 .expect(expectedStatus)
98}
99
696d83fd
C
100async function getVideoIdFromUUID (url: string, uuid: string) {
101 const res = await getVideo(url, uuid)
102
103 return res.body.id
104}
105
8319d6ae
RK
106function getVideoFileMetadataUrl (url: string) {
107 return request(url)
108 .get('/')
109 .set('Accept', 'application/json')
110 .expect(200)
111 .expect('Content-Type', /json/)
112}
113
490b595a 114function viewVideo (url: string, id: number | string, expectedStatus = 204, xForwardedFor?: string) {
1f3e9fec
C
115 const path = '/api/v1/videos/' + id + '/views'
116
490b595a 117 const req = request(url)
1f3e9fec
C
118 .post(path)
119 .set('Accept', 'application/json')
490b595a
C
120
121 if (xForwardedFor) {
122 req.set('X-Forwarded-For', xForwardedFor)
123 }
124
125 return req.expect(expectedStatus)
1f3e9fec
C
126}
127
11474c3c
C
128function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) {
129 const path = '/api/v1/videos/' + id
130
131 return request(url)
132 .get(path)
133 .set('Authorization', 'Bearer ' + token)
134 .set('Accept', 'application/json')
135 .expect(expectedStatus)
0e1dc3e7
C
136}
137
9567011b
C
138function getVideoDescription (url: string, descriptionPath: string) {
139 return request(url)
140 .get(descriptionPath)
141 .set('Accept', 'application/json')
142 .expect(200)
143 .expect('Content-Type', /json/)
144}
145
0e1dc3e7
C
146function getVideosList (url: string) {
147 const path = '/api/v1/videos'
148
149 return request(url)
150 .get(path)
151 .query({ sort: 'name' })
152 .set('Accept', 'application/json')
153 .expect(200)
154 .expect('Content-Type', /json/)
155}
156
d525fc39 157function getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) {
0883b324
C
158 const path = '/api/v1/videos'
159
160 return request(url)
161 .get(path)
162 .set('Authorization', 'Bearer ' + token)
d525fc39 163 .query(immutableAssign(query, { sort: 'name' }))
0883b324
C
164 .set('Accept', 'application/json')
165 .expect(200)
166 .expect('Content-Type', /json/)
167}
168
066e94c5
C
169function getLocalVideos (url: string) {
170 const path = '/api/v1/videos'
171
172 return request(url)
173 .get(path)
174 .query({ sort: 'name', filter: 'local' })
175 .set('Accept', 'application/json')
176 .expect(200)
177 .expect('Content-Type', /json/)
178}
179
cca1e13b 180function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string, search?: string) {
11474c3c
C
181 const path = '/api/v1/users/me/videos'
182
183 const req = request(url)
184 .get(path)
185 .query({ start: start })
186 .query({ count: count })
cca1e13b 187 .query({ search: search })
11474c3c
C
188
189 if (sort) req.query({ sort })
190
191 return req.set('Accept', 'application/json')
192 .set('Authorization', 'Bearer ' + accessToken)
193 .expect(200)
194 .expect('Content-Type', /json/)
195}
196
d525fc39
C
197function getAccountVideos (
198 url: string,
199 accessToken: string,
200 accountName: string,
201 start: number,
202 count: number,
203 sort?: string,
204 query: { nsfw?: boolean } = {}
205) {
ad9e39fb 206 const path = '/api/v1/accounts/' + accountName + '/videos'
6b738c7a
C
207
208 return makeGetRequest({
209 url,
210 path,
d525fc39 211 query: immutableAssign(query, {
6b738c7a
C
212 start,
213 count,
214 sort
d525fc39 215 }),
6b738c7a
C
216 token: accessToken,
217 statusCodeExpected: 200
218 })
219}
220
221function getVideoChannelVideos (
222 url: string,
223 accessToken: string,
8a19bee1 224 videoChannelName: string,
6b738c7a
C
225 start: number,
226 count: number,
d525fc39
C
227 sort?: string,
228 query: { nsfw?: boolean } = {}
6b738c7a 229) {
8a19bee1 230 const path = '/api/v1/video-channels/' + videoChannelName + '/videos'
6b738c7a
C
231
232 return makeGetRequest({
233 url,
234 path,
d525fc39 235 query: immutableAssign(query, {
6b738c7a
C
236 start,
237 count,
238 sort
d525fc39 239 }),
6b738c7a
C
240 token: accessToken,
241 statusCodeExpected: 200
242 })
243}
244
418d092a
C
245function getPlaylistVideos (
246 url: string,
247 accessToken: string,
248 playlistId: number | string,
249 start: number,
250 count: number,
251 query: { nsfw?: boolean } = {}
252) {
253 const path = '/api/v1/video-playlists/' + playlistId + '/videos'
254
255 return makeGetRequest({
256 url,
257 path,
258 query: immutableAssign(query, {
259 start,
260 count
261 }),
262 token: accessToken,
263 statusCodeExpected: 200
264 })
265}
266
fe987656 267function getVideosListPagination (url: string, start: number, count: number, sort?: string, skipCount?: boolean) {
0e1dc3e7
C
268 const path = '/api/v1/videos'
269
270 const req = request(url)
271 .get(path)
272 .query({ start: start })
273 .query({ count: count })
274
275 if (sort) req.query({ sort })
fe987656 276 if (skipCount) req.query({ skipCount })
0e1dc3e7
C
277
278 return req.set('Accept', 'application/json')
279 .expect(200)
280 .expect('Content-Type', /json/)
281}
282
283function getVideosListSort (url: string, sort: string) {
284 const path = '/api/v1/videos'
285
286 return request(url)
287 .get(path)
288 .query({ sort: sort })
289 .set('Accept', 'application/json')
290 .expect(200)
291 .expect('Content-Type', /json/)
292}
293
d525fc39 294function getVideosWithFilters (url: string, query: { tagsAllOf: string[], categoryOneOf: number[] | number }) {
0e1dc3e7
C
295 const path = '/api/v1/videos'
296
297 return request(url)
57c36b27 298 .get(path)
d525fc39 299 .query(query)
f3aaa9a9 300 .set('Accept', 'application/json')
d525fc39 301 .expect(200)
f3aaa9a9 302 .expect('Content-Type', /json/)
0e1dc3e7
C
303}
304
d525fc39 305function removeVideo (url: string, token: string, id: number | string, expectedStatus = 204) {
0883b324 306 const path = '/api/v1/videos'
0e1dc3e7
C
307
308 return request(url)
d525fc39 309 .delete(path + '/' + id)
0e1dc3e7 310 .set('Accept', 'application/json')
d525fc39
C
311 .set('Authorization', 'Bearer ' + token)
312 .expect(expectedStatus)
0e1dc3e7
C
313}
314
25378bc8
C
315async function checkVideoFilesWereRemoved (
316 videoUUID: string,
317 serverNumber: number,
09209296
C
318 directories = [
319 'redundancy',
320 'videos',
321 'thumbnails',
322 'torrents',
323 'previews',
324 'captions',
325 join('playlists', 'hls'),
326 join('redundancy', 'hls')
327 ]
25378bc8 328) {
25378bc8 329 for (const directory of directories) {
e2600d8b 330 const directoryPath = buildServerDirectory(serverNumber, directory)
f05a1c30 331
df0b219d
C
332 const directoryExists = await pathExists(directoryPath)
333 if (directoryExists === false) continue
f05a1c30 334
62689b94 335 const files = await readdir(directoryPath)
f05a1c30
C
336 for (const file of files) {
337 expect(file).to.not.contain(videoUUID)
338 }
339 }
340}
341
e11f68a3 342async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) {
e95561cd 343 const path = '/api/v1/videos/upload'
5f04dd2f
C
344 let defaultChannelId = '1'
345
346 try {
347 const res = await getMyUserInformation(url, accessToken)
348 defaultChannelId = res.body.videoChannels[0].id
349 } catch (e) { /* empty */ }
0e1dc3e7 350
ac81d1a0
C
351 // Override default attributes
352 const attributes = Object.assign({
0e1dc3e7
C
353 name: 'my super video',
354 category: 5,
355 licence: 4,
9d3ef9fe 356 language: 'zh',
5f04dd2f 357 channelId: defaultChannelId,
0e1dc3e7 358 nsfw: true,
2186386c 359 waitTranscoding: false,
0e1dc3e7 360 description: 'my super description',
2422c46b 361 support: 'my super support text',
0e1dc3e7 362 tags: [ 'tag' ],
11474c3c 363 privacy: VideoPrivacy.PUBLIC,
47564bbe 364 commentsEnabled: true,
7f2cfe3a 365 downloadEnabled: true,
0e1dc3e7 366 fixture: 'video_short.webm'
ac81d1a0 367 }, videoAttributesArg)
0e1dc3e7
C
368
369 const req = request(url)
370 .post(path)
371 .set('Accept', 'application/json')
372 .set('Authorization', 'Bearer ' + accessToken)
373 .field('name', attributes.name)
0e1dc3e7 374 .field('nsfw', JSON.stringify(attributes.nsfw))
47564bbe 375 .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
7f2cfe3a 376 .field('downloadEnabled', JSON.stringify(attributes.downloadEnabled))
2186386c 377 .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
11474c3c 378 .field('privacy', attributes.privacy.toString())
5f04dd2f 379 .field('channelId', attributes.channelId)
0e1dc3e7 380
fc8c024a
C
381 if (attributes.support !== undefined) {
382 req.field('support', attributes.support)
383 }
384
a87d467a
C
385 if (attributes.description !== undefined) {
386 req.field('description', attributes.description)
387 }
8df87ce7
C
388 if (attributes.language !== undefined) {
389 req.field('language', attributes.language.toString())
390 }
a7fea183
C
391 if (attributes.category !== undefined) {
392 req.field('category', attributes.category.toString())
393 }
394 if (attributes.licence !== undefined) {
395 req.field('licence', attributes.licence.toString())
396 }
8df87ce7 397
970ceac0
C
398 const tags = attributes.tags || []
399 for (let i = 0; i < tags.length; i++) {
2422c46b
C
400 req.field('tags[' + i + ']', attributes.tags[i])
401 }
402
ac81d1a0
C
403 if (attributes.thumbnailfile !== undefined) {
404 req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
405 }
406 if (attributes.previewfile !== undefined) {
407 req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
0e1dc3e7
C
408 }
409
2baea0c7
C
410 if (attributes.scheduleUpdate) {
411 req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt)
412
413 if (attributes.scheduleUpdate.privacy) {
414 req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy)
415 }
416 }
417
84929846
AM
418 if (attributes.originallyPublishedAt !== undefined) {
419 req.field('originallyPublishedAt', attributes.originallyPublishedAt)
420 }
421
ac81d1a0 422 return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
0e1dc3e7
C
423 .expect(specialStatus)
424}
425
ac81d1a0 426function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, statusCodeExpected = 204) {
0e1dc3e7
C
427 const path = '/api/v1/videos/' + id
428 const body = {}
429
430 if (attributes.name) body['name'] = attributes.name
431 if (attributes.category) body['category'] = attributes.category
432 if (attributes.licence) body['licence'] = attributes.licence
433 if (attributes.language) body['language'] = attributes.language
47564bbe
C
434 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
435 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
7f2cfe3a 436 if (attributes.downloadEnabled !== undefined) body['downloadEnabled'] = JSON.stringify(attributes.downloadEnabled)
7519127b 437 if (attributes.originallyPublishedAt !== undefined) body['originallyPublishedAt'] = attributes.originallyPublishedAt
0e1dc3e7
C
438 if (attributes.description) body['description'] = attributes.description
439 if (attributes.tags) body['tags'] = attributes.tags
11474c3c 440 if (attributes.privacy) body['privacy'] = attributes.privacy
0f320037 441 if (attributes.channelId) body['channelId'] = attributes.channelId
2baea0c7 442 if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate
0e1dc3e7 443
ac81d1a0
C
444 // Upload request
445 if (attributes.thumbnailfile || attributes.previewfile) {
446 const attaches: any = {}
447 if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile
448 if (attributes.previewfile) attaches.previewfile = attributes.previewfile
449
450 return makeUploadRequest({
451 url,
452 method: 'PUT',
453 path,
454 token: accessToken,
455 fields: body,
456 attaches,
457 statusCodeExpected
458 })
459 }
460
461 return makePutBodyRequest({
462 url,
463 path,
464 fields: body,
465 token: accessToken,
466 statusCodeExpected
467 })
0e1dc3e7
C
468}
469
470function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) {
471 const path = '/api/v1/videos/' + id + '/rate'
472
473 return request(url)
474 .put(path)
475 .set('Accept', 'application/json')
476 .set('Authorization', 'Bearer ' + accessToken)
477 .send({ rating })
478 .expect(specialStatus)
479}
480
14d3270f 481function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
fdbda9e3 482 return new Promise<any>((res, rej) => {
14d3270f 483 const torrentName = videoUUID + '-' + resolution + '.torrent'
ffc65cbd 484 const torrentPath = join(root(), 'test' + server.internalServerNumber, 'torrents', torrentName)
fdbda9e3
C
485 readFile(torrentPath, (err, data) => {
486 if (err) return rej(err)
487
488 return res(parseTorrent(data))
489 })
490 })
491}
492
a20399c9
C
493async function completeVideoCheck (
494 url: string,
495 video: any,
496 attributes: {
497 name: string
498 category: number
499 licence: number
9d3ef9fe 500 language: string
a20399c9 501 nsfw: boolean
47564bbe 502 commentsEnabled: boolean
7f2cfe3a 503 downloadEnabled: boolean
a20399c9 504 description: string
53a61317 505 publishedAt?: string
2422c46b 506 support: string
a1587156 507 originallyPublishedAt?: string
b64c950a
C
508 account: {
509 name: string
510 host: string
511 }
f6eebcb3
C
512 isLocal: boolean
513 tags: string[]
514 privacy: number
515 likes?: number
516 dislikes?: number
517 duration: number
a20399c9 518 channel: {
f6eebcb3
C
519 displayName: string
520 name: string
b1f5b93e 521 description
a20399c9
C
522 isLocal: boolean
523 }
f6eebcb3 524 fixture: string
a20399c9
C
525 files: {
526 resolution: number
527 size: number
a1587156 528 }[]
ac81d1a0
C
529 thumbnailfile?: string
530 previewfile?: string
a20399c9
C
531 }
532) {
b1f5b93e
C
533 if (!attributes.likes) attributes.likes = 0
534 if (!attributes.dislikes) attributes.dislikes = 0
535
a20399c9 536 expect(video.name).to.equal(attributes.name)
09700934 537 expect(video.category.id).to.equal(attributes.category)
9d3ef9fe 538 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
09700934 539 expect(video.licence.id).to.equal(attributes.licence)
9d3ef9fe 540 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
09700934 541 expect(video.language.id).to.equal(attributes.language)
9d3ef9fe 542 expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
2243730c
C
543 expect(video.privacy.id).to.deep.equal(attributes.privacy)
544 expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
a20399c9
C
545 expect(video.nsfw).to.equal(attributes.nsfw)
546 expect(video.description).to.equal(attributes.description)
03e12d7c 547 expect(video.account.id).to.be.a('number')
b64c950a
C
548 expect(video.account.host).to.equal(attributes.account.host)
549 expect(video.account.name).to.equal(attributes.account.name)
f6eebcb3
C
550 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
551 expect(video.channel.name).to.equal(attributes.channel.name)
b1f5b93e
C
552 expect(video.likes).to.equal(attributes.likes)
553 expect(video.dislikes).to.equal(attributes.dislikes)
a20399c9 554 expect(video.isLocal).to.equal(attributes.isLocal)
b1f5b93e 555 expect(video.duration).to.equal(attributes.duration)
a20399c9 556 expect(dateIsValid(video.createdAt)).to.be.true
c49db162 557 expect(dateIsValid(video.publishedAt)).to.be.true
a20399c9
C
558 expect(dateIsValid(video.updatedAt)).to.be.true
559
53a61317 560 if (attributes.publishedAt) {
53a61317
C
561 expect(video.publishedAt).to.equal(attributes.publishedAt)
562 }
563
7519127b
C
564 if (attributes.originallyPublishedAt) {
565 expect(video.originallyPublishedAt).to.equal(attributes.originallyPublishedAt)
566 } else {
567 expect(video.originallyPublishedAt).to.be.null
568 }
569
66b16caf 570 const res = await getVideo(url, video.uuid)
0f320037 571 const videoDetails: VideoDetails = res.body
a20399c9
C
572
573 expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
574 expect(videoDetails.tags).to.deep.equal(attributes.tags)
19a3b914
C
575 expect(videoDetails.account.name).to.equal(attributes.account.name)
576 expect(videoDetails.account.host).to.equal(attributes.account.host)
f6eebcb3
C
577 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
578 expect(video.channel.name).to.equal(attributes.channel.name)
0f320037 579 expect(videoDetails.channel.host).to.equal(attributes.account.host)
a20399c9 580 expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
0f320037
C
581 expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
582 expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
583 expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
7f2cfe3a 584 expect(videoDetails.downloadEnabled).to.equal(attributes.downloadEnabled)
a20399c9
C
585
586 for (const attributeFile of attributes.files) {
5d00a3d7 587 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
a20399c9
C
588 expect(file).not.to.be.undefined
589
b1f5b93e 590 let extension = extname(attributes.fixture)
48f07b4a
C
591 // Transcoding enabled: extension will always be .mp4
592 if (attributes.files.length > 1) extension = '.mp4'
b1f5b93e 593
a20399c9 594 expect(file.magnetUri).to.have.lengthOf.above(2)
5d00a3d7
C
595 expect(file.torrentUrl).to.equal(`http://${attributes.account.host}/static/torrents/${videoDetails.uuid}-${file.resolution.id}.torrent`)
596 expect(file.fileUrl).to.equal(`http://${attributes.account.host}/static/webseed/${videoDetails.uuid}-${file.resolution.id}${extension}`)
09700934
C
597 expect(file.resolution.id).to.equal(attributeFile.resolution)
598 expect(file.resolution.label).to.equal(attributeFile.resolution + 'p')
b1f5b93e
C
599
600 const minSize = attributeFile.size - ((10 * attributeFile.size) / 100)
601 const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100)
a1587156
C
602 expect(
603 file.size,
604 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')'
605 ).to.be.above(minSize).and.below(maxSize)
a20399c9 606
d7a25329 607 const torrent = await webtorrentAdd(file.magnetUri, true)
a20399c9
C
608 expect(torrent.files).to.be.an('array')
609 expect(torrent.files.length).to.equal(1)
610 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
611 }
44d4ee4f
C
612
613 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
614
615 if (attributes.previewfile) {
616 await testImage(url, attributes.previewfile, videoDetails.previewPath)
617 }
a20399c9
C
618}
619
df0b219d
C
620async function videoUUIDToId (url: string, id: number | string) {
621 if (validator.isUUID('' + id) === false) return id
622
623 const res = await getVideo(url, id)
624 return res.body.id
625}
626
b764380a 627async function uploadVideoAndGetId (options: {
a1587156
C
628 server: ServerInfo
629 videoName: string
630 nsfw?: boolean
631 privacy?: VideoPrivacy
b764380a
C
632 token?: string
633}) {
df0b219d
C
634 const videoAttrs: any = { name: options.videoName }
635 if (options.nsfw) videoAttrs.nsfw = options.nsfw
b764380a 636 if (options.privacy) videoAttrs.privacy = options.privacy
df0b219d 637
df0b219d
C
638 const res = await uploadVideo(options.server.url, options.token || options.server.accessToken, videoAttrs)
639
640 return { id: res.body.video.id, uuid: res.body.video.uuid }
641}
642
b764380a
C
643async function getLocalIdByUUID (url: string, uuid: string) {
644 const res = await getVideo(url, uuid)
645
646 return res.body.id
647}
648
8eb07b01
C
649// serverNumber starts from 1
650async function uploadRandomVideoOnServers (servers: ServerInfo[], serverNumber: number, additionalParams: any = {}) {
651 const server = servers.find(s => s.serverNumber === serverNumber)
652 const res = await uploadRandomVideo(server, false, additionalParams)
653
654 await waitJobs(servers)
655
656 return res
657}
658
659async function uploadRandomVideo (server: ServerInfo, wait = true, additionalParams: any = {}) {
660 const prefixName = additionalParams.prefixName || ''
661 const name = prefixName + uuidv4()
662
663 const data = Object.assign({ name }, additionalParams)
664 const res = await uploadVideo(server.url, server.accessToken, data)
665
666 if (wait) await waitJobs([ server ])
667
668 return { uuid: res.body.video.uuid, name }
669}
670
0e1dc3e7
C
671// ---------------------------------------------------------------------------
672
673export {
9567011b 674 getVideoDescription,
0e1dc3e7 675 getVideoCategories,
8eb07b01 676 uploadRandomVideo,
0e1dc3e7 677 getVideoLicences,
df0b219d 678 videoUUIDToId,
11474c3c 679 getVideoPrivacies,
0e1dc3e7 680 getVideoLanguages,
11474c3c 681 getMyVideos,
6b738c7a
C
682 getAccountVideos,
683 getVideoChannelVideos,
0e1dc3e7 684 getVideo,
8319d6ae 685 getVideoFileMetadataUrl,
11474c3c 686 getVideoWithToken,
0e1dc3e7
C
687 getVideosList,
688 getVideosListPagination,
689 getVideosListSort,
690 removeVideo,
0883b324 691 getVideosListWithToken,
0e1dc3e7 692 uploadVideo,
d525fc39 693 getVideosWithFilters,
8eb07b01 694 uploadRandomVideoOnServers,
0e1dc3e7 695 updateVideo,
fdbda9e3 696 rateVideo,
1f3e9fec 697 viewVideo,
a20399c9 698 parseTorrentVideo,
066e94c5 699 getLocalVideos,
f05a1c30 700 completeVideoCheck,
418d092a 701 checkVideoFilesWereRemoved,
df0b219d 702 getPlaylistVideos,
b764380a 703 uploadVideoAndGetId,
696d83fd
C
704 getLocalIdByUUID,
705 getVideoIdFromUUID
0e1dc3e7 706}