+ const expectedInitStatus = specialStatus === HttpStatusCode.OK_200
+ ? HttpStatusCode.CREATED_201
+ : specialStatus
+
+ expect(initStatus).to.equal(expectedInitStatus)
+
+ return initializeSessionRes
+}
+
+async function prepareResumableUpload (options: {
+ url: string
+ token: string
+ attributes: VideoAttributes
+ size: number
+ mimetype: string
+}) {
+ const { url, token, attributes, size, mimetype } = options
+
+ const path = '/api/v1/videos/upload-resumable'
+
+ const req = request(url)
+ .post(path)
+ .set('Authorization', 'Bearer ' + token)
+ .set('X-Upload-Content-Type', mimetype)
+ .set('X-Upload-Content-Length', size.toString())
+
+ buildUploadReq(req, attributes)
+
+ if (attributes.fixture) {
+ req.field('filename', attributes.fixture)
+ }
+
+ return req
+}
+
+function sendResumableChunks (options: {
+ url: string
+ token: string
+ pathUploadId: string
+ videoFilePath: string
+ size: number
+ specialStatus?: HttpStatusCode
+ contentLength?: number
+ contentRangeBuilder?: (start: number, chunk: any) => string
+}) {
+ const { url, token, pathUploadId, videoFilePath, size, specialStatus, contentLength, contentRangeBuilder } = options
+
+ const expectedStatus = specialStatus || HttpStatusCode.OK_200
+
+ const path = '/api/v1/videos/upload-resumable'
+ let start = 0
+
+ const readable = createReadStream(videoFilePath, { highWaterMark: 8 * 1024 })
+ return new Promise<GotResponse>((resolve, reject) => {
+ readable.on('data', async function onData (chunk) {
+ readable.pause()
+
+ const headers = {
+ 'Authorization': 'Bearer ' + token,
+ 'Content-Type': 'application/octet-stream',
+ 'Content-Range': contentRangeBuilder
+ ? contentRangeBuilder(start, chunk)
+ : `bytes ${start}-${start + chunk.length - 1}/${size}`,
+ 'Content-Length': contentLength ? contentLength + '' : chunk.length + ''
+ }
+
+ const res = await got({
+ url,
+ method: 'put',
+ headers,
+ path: path + '?' + pathUploadId,
+ body: chunk,
+ responseType: 'json',
+ throwHttpErrors: false
+ })
+
+ start += chunk.length
+
+ if (res.statusCode === expectedStatus) {
+ return resolve(res)
+ }
+
+ if (res.statusCode !== HttpStatusCode.PERMANENT_REDIRECT_308) {
+ readable.off('data', onData)
+ return reject(new Error('Incorrect transient behaviour sending intermediary chunks'))
+ }
+
+ readable.resume()
+ })
+ })