]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/extra-utils/miscs/miscs.ts
Don't rely on youtube for tests
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / miscs / miscs.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
9ee83eb9 2
7b0956ec 3import * as chai from 'chai'
2284f202 4import { basename, dirname, isAbsolute, join, resolve } from 'path'
9ee83eb9 5import * as request from 'supertest'
0e1dc3e7 6import * as WebTorrent from 'webtorrent'
2284f202 7import { ensureDir, pathExists, readFile } from 'fs-extra'
74cd011b 8import * as ffmpeg from 'fluent-ffmpeg'
0e1dc3e7 9
7b0956ec 10const expect = chai.expect
8d2be0ed 11let webtorrent: WebTorrent.Instance
0e1dc3e7 12
a1587156 13function immutableAssign<T, U> (target: T, source: U) {
26d21b78
C
14 return Object.assign<{}, T, U>({}, target, source)
15}
16
a1587156 17// Default interval -> 5 minutes
b1f5b93e 18function dateIsValid (dateString: string, interval = 300000) {
0e1dc3e7
C
19 const dateToCheck = new Date(dateString)
20 const now = new Date()
21
22 return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval
23}
24
25function wait (milliseconds: number) {
26 return new Promise(resolve => setTimeout(resolve, milliseconds))
27}
28
29function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
8d2be0ed
C
30 const WebTorrent = require('webtorrent')
31
32 if (!webtorrent) webtorrent = new WebTorrent()
0e1dc3e7
C
33 if (refreshWebTorrent === true) webtorrent = new WebTorrent()
34
35 return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
36}
37
f05a1c30 38function root () {
94565d52 39 // We are in /miscs
1a12f66d
C
40 let root = join(__dirname, '..', '..', '..')
41
42 if (basename(root) === 'dist') root = resolve(root, '..')
43
44 return root
f05a1c30
C
45}
46
e2600d8b
C
47function buildServerDirectory (internalServerNumber: number, directory: string) {
48 return join(root(), 'test' + internalServerNumber, directory)
49}
50
9ee83eb9 51async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
288178bf
C
52 const res = await request(url)
53 .get(imagePath)
54 .expect(200)
55
56 const body = res.body
57
2a8c5d0a 58 const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension))
e6dfa586
RK
59 const minLength = body.length - ((30 * body.length) / 100)
60 const maxLength = body.length + ((30 * body.length) / 100)
288178bf 61
e6dfa586
RK
62 expect(data.length).to.be.above(minLength, "the generated image is way smaller than the recorded fixture")
63 expect(data.length).to.be.below(maxLength, "the generated image is way larger than the recorded fixture")
9ee83eb9
C
64}
65
2284f202 66function buildAbsoluteFixturePath (path: string, customCIPath = false) {
b488ba1e 67 if (isAbsolute(path)) return path
ac81d1a0 68
c928e136
C
69 if (customCIPath) {
70 if (process.env.GITLAB_CI) return join(root(), 'cached-fixtures', path)
71
b488ba1e 72 return join(process.env.HOME, 'fixtures', path)
c928e136 73 }
c1c86c15 74
2a8c5d0a 75 return join(root(), 'server', 'tests', 'fixtures', path)
ac81d1a0
C
76}
77
b488ba1e
C
78function areHttpImportTestsDisabled () {
79 const disabled = process.env.DISABLE_HTTP_IMPORT_TESTS === 'true'
80
81 if (disabled) console.log('Import tests are disabled')
82
83 return disabled
84}
85
74cd011b
C
86async function generateHighBitrateVideo () {
87 const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
88
2284f202
C
89 await ensureDir(dirname(tempFixturePath))
90
74cd011b
C
91 const exists = await pathExists(tempFixturePath)
92 if (!exists) {
93
94 // Generate a random, high bitrate video on the fly, so we don't have to include
95 // a large file in the repo. The video needs to have a certain minimum length so
96 // that FFmpeg properly applies bitrate limits.
97 // https://stackoverflow.com/a/15795112
a1587156 98 return new Promise<string>((res, rej) => {
74cd011b
C
99 ffmpeg()
100 .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ])
101 .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
102 .outputOptions([ '-maxrate 10M', '-bufsize 10M' ])
103 .output(tempFixturePath)
104 .on('error', rej)
105 .on('end', () => res(tempFixturePath))
106 .run()
107 })
108 }
109
110 return tempFixturePath
111}
112
837666fe
RK
113async function generateVideoWithFramerate (fps = 60) {
114 const tempFixturePath = buildAbsoluteFixturePath(`video_${fps}fps.mp4`, true)
115
116 await ensureDir(dirname(tempFixturePath))
117
118 const exists = await pathExists(tempFixturePath)
119 if (!exists) {
a1587156 120 return new Promise<string>((res, rej) => {
837666fe 121 ffmpeg()
c7f36e4f 122 .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ])
837666fe
RK
123 .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ])
124 .outputOptions([ `-r ${fps}` ])
125 .output(tempFixturePath)
126 .on('error', rej)
127 .on('end', () => res(tempFixturePath))
128 .run()
129 })
130 }
131
132 return tempFixturePath
133}
134
0e1dc3e7
C
135// ---------------------------------------------------------------------------
136
137export {
0e1dc3e7
C
138 dateIsValid,
139 wait,
b488ba1e 140 areHttpImportTestsDisabled,
e2600d8b 141 buildServerDirectory,
26d21b78 142 webtorrentAdd,
f05a1c30 143 immutableAssign,
9ee83eb9 144 testImage,
ac81d1a0 145 buildAbsoluteFixturePath,
74cd011b 146 root,
837666fe
RK
147 generateHighBitrateVideo,
148 generateVideoWithFramerate
0e1dc3e7 149}