X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;ds=sidebyside;f=shared%2Fextra-utils%2Frequests%2Frequests.ts;h=501e0b374b949ad613c26090fc768e2a29de0aee;hb=790c2837ddcb443c0f1ea6adcdcb101dfe159d01;hp=61167f212db424cfab522c6f478d79fa5f25eb6d;hpb=818c449b3c34e9f324ac744120c8774e724ab25e;p=github%2FChocobozzz%2FPeerTube.git diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts index 61167f212..501e0b374 100644 --- a/shared/extra-utils/requests/requests.ts +++ b/shared/extra-utils/requests/requests.ts @@ -1,97 +1,91 @@ -/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ +/* eslint-disable @typescript-eslint/no-floating-promises */ -import * as request from 'supertest' -import { buildAbsoluteFixturePath, root } from '../miscs/miscs' -import { isAbsolute, join } from 'path' +import { decode } from 'querystring' +import request from 'supertest' import { URL } from 'url' +import { HttpStatusCode } from '@shared/models' +import { buildAbsoluteFixturePath } from '../miscs/tests' -function get4KFileUrl () { - return 'https://download.cpy.re/peertube/4k_file.txt' +export type CommonRequestParams = { + url: string + path?: string + contentType?: string + range?: string + redirects?: number + accept?: string + host?: string + token?: string + headers?: { [ name: string ]: string } + type?: string + xForwardedFor?: string + expectedStatus?: HttpStatusCode } -function makeRawRequest (url: string, statusCodeExpected?: number, range?: string) { +function makeRawRequest (url: string, expectedStatus?: HttpStatusCode, range?: string) { const { host, protocol, pathname } = new URL(url) - return makeGetRequest({ url: `${protocol}//${host}`, path: pathname, statusCodeExpected, range }) + return makeGetRequest({ url: `${protocol}//${host}`, path: pathname, expectedStatus, range }) } -function makeGetRequest (options: { - url: string - path?: string +function makeGetRequest (options: CommonRequestParams & { query?: any - token?: string - statusCodeExpected?: number - contentType?: string - range?: string + rawQuery?: string }) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - if (options.contentType === undefined) options.contentType = 'application/json' - const req = request(options.url).get(options.path) - if (options.contentType) req.set('Accept', options.contentType) - if (options.token) req.set('Authorization', 'Bearer ' + options.token) if (options.query) req.query(options.query) - if (options.range) req.set('Range', options.range) + if (options.rawQuery) req.query(options.rawQuery) - return req.expect(options.statusCodeExpected) + return buildRequest(req, { contentType: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options }) } -function makeDeleteRequest (options: { - url: string - path: string - token?: string - statusCodeExpected?: number -}) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - - const req = request(options.url) - .delete(options.path) - .set('Accept', 'application/json') - - if (options.token) req.set('Authorization', 'Bearer ' + options.token) +function makeHTMLRequest (url: string, path: string) { + return makeGetRequest({ + url, + path, + accept: 'text/html', + expectedStatus: HttpStatusCode.OK_200 + }) +} - return req.expect(options.statusCodeExpected) +function makeActivityPubGetRequest (url: string, path: string, expectedStatus = HttpStatusCode.OK_200) { + return makeGetRequest({ + url, + path, + expectedStatus: expectedStatus, + accept: 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8' + }) } -function makeUploadRequest (options: { - url: string - method?: 'POST' | 'PUT' - path: string - token?: string - fields: { [ fieldName: string ]: any } - attaches: { [ attachName: string ]: any | any[] } - statusCodeExpected?: number +function makeDeleteRequest (options: CommonRequestParams & { + query?: any + rawQuery?: string }) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 + const req = request(options.url).delete(options.path) - let req: request.Test - if (options.method === 'PUT') { - req = request(options.url).put(options.path) - } else { - req = request(options.url).post(options.path) - } + if (options.query) req.query(options.query) + if (options.rawQuery) req.query(options.rawQuery) - req.set('Accept', 'application/json') + return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options }) +} - if (options.token) req.set('Authorization', 'Bearer ' + options.token) +function makeUploadRequest (options: CommonRequestParams & { + method?: 'POST' | 'PUT' - Object.keys(options.fields).forEach(field => { - const value = options.fields[field] + fields: { [ fieldName: string ]: any } + attaches?: { [ attachName: string ]: any | any[] } +}) { + let req = options.method === 'PUT' + ? request(options.url).put(options.path) + : request(options.url).post(options.path) - if (value === undefined) return + req = buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options }) - if (Array.isArray(value)) { - for (let i = 0; i < value.length; i++) { - req.field(field + '[' + i + ']', value[i]) - } - } else { - req.field(field, value) - } - }) + buildFields(req, options.fields) - Object.keys(options.attaches).forEach(attach => { + Object.keys(options.attaches || {}).forEach(attach => { const value = options.attaches[attach] + if (Array.isArray(value)) { req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1]) } else { @@ -99,27 +93,16 @@ function makeUploadRequest (options: { } }) - return req.expect(options.statusCodeExpected) + return req } -function makePostBodyRequest (options: { - url: string - path: string - token?: string +function makePostBodyRequest (options: CommonRequestParams & { fields?: { [ fieldName: string ]: any } - statusCodeExpected?: number }) { - if (!options.fields) options.fields = {} - if (!options.statusCodeExpected) options.statusCodeExpected = 400 - - const req = request(options.url) - .post(options.path) - .set('Accept', 'application/json') + const req = request(options.url).post(options.path) + .send(options.fields) - if (options.token) req.set('Authorization', 'Bearer ' + options.token) - - return req.send(options.fields) - .expect(options.statusCodeExpected) + return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options }) } function makePutBodyRequest (options: { @@ -127,60 +110,98 @@ function makePutBodyRequest (options: { path: string token?: string fields: { [ fieldName: string ]: any } - statusCodeExpected?: number + expectedStatus?: HttpStatusCode }) { - if (!options.statusCodeExpected) options.statusCodeExpected = 400 + const req = request(options.url).put(options.path) + .send(options.fields) - const req = request(options.url) - .put(options.path) - .set('Accept', 'application/json') + return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options }) +} - if (options.token) req.set('Authorization', 'Bearer ' + options.token) +function decodeQueryString (path: string) { + return decode(path.split('?')[1]) +} - return req.send(options.fields) - .expect(options.statusCodeExpected) +function unwrapBody (test: request.Test): Promise { + return test.then(res => res.body) } -function makeHTMLRequest (url: string, path: string) { - return request(url) - .get(path) - .set('Accept', 'text/html') - .expect(200) +function unwrapText (test: request.Test): Promise { + return test.then(res => res.text) } -function updateAvatarRequest (options: { - url: string - path: string - accessToken: string - fixture: string -}) { - let filePath = '' - if (isAbsolute(options.fixture)) { - filePath = options.fixture - } else { - filePath = join(root(), 'server', 'tests', 'fixtures', options.fixture) - } +function unwrapBodyOrDecodeToJSON (test: request.Test): Promise { + return test.then(res => { + if (res.body instanceof Buffer) { + return JSON.parse(new TextDecoder().decode(res.body)) + } - return makeUploadRequest({ - url: options.url, - path: options.path, - token: options.accessToken, - fields: {}, - attaches: { avatarfile: filePath }, - statusCodeExpected: 200 + return res.body }) } +function unwrapTextOrDecode (test: request.Test): Promise { + return test.then(res => res.text || new TextDecoder().decode(res.body)) +} + // --------------------------------------------------------------------------- export { - get4KFileUrl, makeHTMLRequest, makeGetRequest, + decodeQueryString, makeUploadRequest, makePostBodyRequest, makePutBodyRequest, makeDeleteRequest, makeRawRequest, - updateAvatarRequest + makeActivityPubGetRequest, + unwrapBody, + unwrapTextOrDecode, + unwrapBodyOrDecodeToJSON, + unwrapText +} + +// --------------------------------------------------------------------------- + +function buildRequest (req: request.Test, options: CommonRequestParams) { + if (options.contentType) req.set('Accept', options.contentType) + if (options.token) req.set('Authorization', 'Bearer ' + options.token) + if (options.range) req.set('Range', options.range) + if (options.accept) req.set('Accept', options.accept) + if (options.host) req.set('Host', options.host) + if (options.redirects) req.redirects(options.redirects) + if (options.expectedStatus) req.expect(options.expectedStatus) + if (options.xForwardedFor) req.set('X-Forwarded-For', options.xForwardedFor) + if (options.type) req.type(options.type) + + Object.keys(options.headers || {}).forEach(name => { + req.set(name, options.headers[name]) + }) + + return req +} + +function buildFields (req: request.Test, fields: { [ fieldName: string ]: any }, namespace?: string) { + if (!fields) return + + let formKey: string + + for (const key of Object.keys(fields)) { + if (namespace) formKey = `${namespace}[${key}]` + else formKey = key + + if (fields[key] === undefined) continue + + if (Array.isArray(fields[key]) && fields[key].length === 0) { + req.field(key, []) + continue + } + + if (fields[key] !== null && typeof fields[key] === 'object') { + buildFields(req, fields[key], formKey) + } else { + req.field(formKey, fields[key]) + } + } }