aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/server-commands/requests/requests.ts
diff options
context:
space:
mode:
Diffstat (limited to 'shared/server-commands/requests/requests.ts')
-rw-r--r--shared/server-commands/requests/requests.ts259
1 files changed, 0 insertions, 259 deletions
diff --git a/shared/server-commands/requests/requests.ts b/shared/server-commands/requests/requests.ts
deleted file mode 100644
index 8227017eb..000000000
--- a/shared/server-commands/requests/requests.ts
+++ /dev/null
@@ -1,259 +0,0 @@
1/* eslint-disable @typescript-eslint/no-floating-promises */
2
3import { decode } from 'querystring'
4import request from 'supertest'
5import { URL } from 'url'
6import { buildAbsoluteFixturePath, pick } from '@shared/core-utils'
7import { HttpStatusCode } from '@shared/models'
8
9export type CommonRequestParams = {
10 url: string
11 path?: string
12 contentType?: string
13 responseType?: string
14 range?: string
15 redirects?: number
16 accept?: string
17 host?: string
18 token?: string
19 headers?: { [ name: string ]: string }
20 type?: string
21 xForwardedFor?: string
22 expectedStatus?: HttpStatusCode
23}
24
25function makeRawRequest (options: {
26 url: string
27 token?: string
28 expectedStatus?: HttpStatusCode
29 range?: string
30 query?: { [ id: string ]: string }
31 method?: 'GET' | 'POST'
32 headers?: { [ name: string ]: string }
33}) {
34 const { host, protocol, pathname } = new URL(options.url)
35
36 const reqOptions = {
37 url: `${protocol}//${host}`,
38 path: pathname,
39 contentType: undefined,
40
41 ...pick(options, [ 'expectedStatus', 'range', 'token', 'query', 'headers' ])
42 }
43
44 if (options.method === 'POST') {
45 return makePostBodyRequest(reqOptions)
46 }
47
48 return makeGetRequest(reqOptions)
49}
50
51function makeGetRequest (options: CommonRequestParams & {
52 query?: any
53 rawQuery?: string
54}) {
55 const req = request(options.url).get(options.path)
56
57 if (options.query) req.query(options.query)
58 if (options.rawQuery) req.query(options.rawQuery)
59
60 return buildRequest(req, { contentType: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
61}
62
63function makeHTMLRequest (url: string, path: string) {
64 return makeGetRequest({
65 url,
66 path,
67 accept: 'text/html',
68 expectedStatus: HttpStatusCode.OK_200
69 })
70}
71
72function makeActivityPubGetRequest (url: string, path: string, expectedStatus = HttpStatusCode.OK_200) {
73 return makeGetRequest({
74 url,
75 path,
76 expectedStatus,
77 accept: 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8'
78 })
79}
80
81function makeDeleteRequest (options: CommonRequestParams & {
82 query?: any
83 rawQuery?: string
84}) {
85 const req = request(options.url).delete(options.path)
86
87 if (options.query) req.query(options.query)
88 if (options.rawQuery) req.query(options.rawQuery)
89
90 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
91}
92
93function makeUploadRequest (options: CommonRequestParams & {
94 method?: 'POST' | 'PUT'
95
96 fields: { [ fieldName: string ]: any }
97 attaches?: { [ attachName: string ]: any | any[] }
98}) {
99 let req = options.method === 'PUT'
100 ? request(options.url).put(options.path)
101 : request(options.url).post(options.path)
102
103 req = buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
104
105 buildFields(req, options.fields)
106
107 Object.keys(options.attaches || {}).forEach(attach => {
108 const value = options.attaches[attach]
109 if (!value) return
110
111 if (Array.isArray(value)) {
112 req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
113 } else {
114 req.attach(attach, buildAbsoluteFixturePath(value))
115 }
116 })
117
118 return req
119}
120
121function makePostBodyRequest (options: CommonRequestParams & {
122 fields?: { [ fieldName: string ]: any }
123}) {
124 const req = request(options.url).post(options.path)
125 .send(options.fields)
126
127 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
128}
129
130function makePutBodyRequest (options: {
131 url: string
132 path: string
133 token?: string
134 fields: { [ fieldName: string ]: any }
135 expectedStatus?: HttpStatusCode
136 headers?: { [name: string]: string }
137}) {
138 const req = request(options.url).put(options.path)
139 .send(options.fields)
140
141 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
142}
143
144function decodeQueryString (path: string) {
145 return decode(path.split('?')[1])
146}
147
148// ---------------------------------------------------------------------------
149
150function unwrapBody <T> (test: request.Test): Promise<T> {
151 return test.then(res => res.body)
152}
153
154function unwrapText (test: request.Test): Promise<string> {
155 return test.then(res => res.text)
156}
157
158function unwrapBodyOrDecodeToJSON <T> (test: request.Test): Promise<T> {
159 return test.then(res => {
160 if (res.body instanceof Buffer) {
161 try {
162 return JSON.parse(new TextDecoder().decode(res.body))
163 } catch (err) {
164 console.error('Cannot decode JSON.', { res, body: res.body instanceof Buffer ? res.body.toString() : res.body })
165 throw err
166 }
167 }
168
169 if (res.text) {
170 try {
171 return JSON.parse(res.text)
172 } catch (err) {
173 console.error('Cannot decode json', { res, text: res.text })
174 throw err
175 }
176 }
177
178 return res.body
179 })
180}
181
182function unwrapTextOrDecode (test: request.Test): Promise<string> {
183 return test.then(res => res.text || new TextDecoder().decode(res.body))
184}
185
186// ---------------------------------------------------------------------------
187
188export {
189 makeHTMLRequest,
190 makeGetRequest,
191 decodeQueryString,
192 makeUploadRequest,
193 makePostBodyRequest,
194 makePutBodyRequest,
195 makeDeleteRequest,
196 makeRawRequest,
197 makeActivityPubGetRequest,
198 unwrapBody,
199 unwrapTextOrDecode,
200 unwrapBodyOrDecodeToJSON,
201 unwrapText
202}
203
204// ---------------------------------------------------------------------------
205
206function buildRequest (req: request.Test, options: CommonRequestParams) {
207 if (options.contentType) req.set('Accept', options.contentType)
208 if (options.responseType) req.responseType(options.responseType)
209 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
210 if (options.range) req.set('Range', options.range)
211 if (options.accept) req.set('Accept', options.accept)
212 if (options.host) req.set('Host', options.host)
213 if (options.redirects) req.redirects(options.redirects)
214 if (options.xForwardedFor) req.set('X-Forwarded-For', options.xForwardedFor)
215 if (options.type) req.type(options.type)
216
217 Object.keys(options.headers || {}).forEach(name => {
218 req.set(name, options.headers[name])
219 })
220
221 return req.expect(res => {
222 if (options.expectedStatus && res.status !== options.expectedStatus) {
223 const err = new Error(`Expected status ${options.expectedStatus}, got ${res.status}. ` +
224 `\nThe server responded: "${res.body?.error ?? res.text}".\n` +
225 'You may take a closer look at the logs. To see how to do so, check out this page: ' +
226 'https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/development/tests.md#debug-server-logs');
227
228 (err as any).res = res
229
230 throw err
231 }
232
233 return res
234 })
235}
236
237function buildFields (req: request.Test, fields: { [ fieldName: string ]: any }, namespace?: string) {
238 if (!fields) return
239
240 let formKey: string
241
242 for (const key of Object.keys(fields)) {
243 if (namespace) formKey = `${namespace}[${key}]`
244 else formKey = key
245
246 if (fields[key] === undefined) continue
247
248 if (Array.isArray(fields[key]) && fields[key].length === 0) {
249 req.field(key, [])
250 continue
251 }
252
253 if (fields[key] !== null && typeof fields[key] === 'object') {
254 buildFields(req, fields[key], formKey)
255 } else {
256 req.field(formKey, fields[key])
257 }
258 }
259}