Skip to content

Commit 9d8fb0a

Browse files
authored
test: add test case for fs.ReadStream (#2219)
Refs #2209
1 parent dc08d90 commit 9d8fb0a

File tree

5 files changed

+127
-4
lines changed

5 files changed

+127
-4
lines changed

test/http/data/file1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test file data1

test/http/data/file2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test file data2

test/http/http-multipart.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import fetchMock from 'fetch-mock';
1+
import path from 'path';
22
import { Readable } from 'stream';
3-
import { File } from 'formdata-node';
3+
import fetchMock from 'fetch-mock';
4+
import { File, Blob } from 'formdata-node';
5+
import { fileFromPathSync } from 'formdata-node/lib/cjs/fileFromPath';
46

57
import { buildRequest } from '../../src/execute';
68
import sampleMultipartOpenApi2 from '../data/sample-multipart-oas2';
@@ -258,11 +260,47 @@ describe('buildRequest - openapi 3.0', () => {
258260
});
259261
});
260262

263+
describe('formData with fs.createReadStream', () => {
264+
/**
265+
* fs.ReadStream is not supported as a value in FormData according to the spec.
266+
* `fileFromPathSync` helper should be used to load files from Node.js env
267+
* that are further used as values for FormData.
268+
*/
269+
const file1 = fileFromPathSync(path.join(__dirname, 'data', 'file1.txt'));
270+
const file2 = fileFromPathSync(path.join(__dirname, 'data', 'file2.txt'));
271+
272+
const req = buildRequest({
273+
spec: sampleMultipartOpenApi3,
274+
operationId: 'post_land_content_uploadImage',
275+
requestBody: {
276+
imageId: 'id',
277+
'images[]': [file1, file2],
278+
},
279+
});
280+
281+
test('should return FormData entry list and item entries (in order)', async () => {
282+
expect(req).toMatchObject({
283+
method: 'POST',
284+
url: '/api/v1/land/content/uploadImage',
285+
credentials: 'same-origin',
286+
headers: {
287+
'Content-Type': expect.stringMatching(/^multipart\/form-data/),
288+
},
289+
});
290+
expect(req.body).toBeInstanceOf(Readable);
291+
const itemEntries = req.formdata.getAll('images[]');
292+
293+
expect(itemEntries.length).toEqual(2);
294+
expect(await itemEntries[0].text()).toEqual(await file1.text());
295+
expect(await itemEntries[1].text()).toEqual(await file2.text());
296+
});
297+
});
298+
261299
describe('formData with File/Blob', () => {
262300
const file1 = new File(['test file data1'], 'file1.txt', {
263301
type: 'text/plain',
264302
});
265-
const file2 = new File(['test file data2'], 'file2.txt', {
303+
const file2 = new Blob(['test file data2'], {
266304
type: 'text/plain',
267305
});
268306

test/oas3/execute/data/payload.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
this is a test

test/oas3/execute/main.js

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ describe('buildRequest - OpenAPI Specification 3.0', () => {
12031203
});
12041204
describe('special media types', () => {
12051205
describe('file-as-body types', () => {
1206-
it('should preserve blobs for application/octet-stream', () => {
1206+
it('should preserve Buffer for application/octet-stream', () => {
12071207
const spec = {
12081208
openapi: '3.0.0',
12091209
paths: {
@@ -1241,6 +1241,88 @@ describe('buildRequest - OpenAPI Specification 3.0', () => {
12411241

12421242
expect(req.body.toString('base64')).toEqual('dGhpcyBpcyBhIHRlc3Q=');
12431243
});
1244+
1245+
it('should preserve fs.ReadStream for application/octet-stream', () => {
1246+
const spec = {
1247+
openapi: '3.0.0',
1248+
paths: {
1249+
'/one': {
1250+
get: {
1251+
operationId: 'getMe',
1252+
requestBody: {
1253+
content: {
1254+
'application/octet-stream': {
1255+
schema: {
1256+
type: 'string',
1257+
format: 'binary',
1258+
},
1259+
},
1260+
},
1261+
},
1262+
},
1263+
},
1264+
},
1265+
};
1266+
1267+
// when
1268+
const readStream = fs.createReadStream(path.join(__dirname, 'data', 'payload.txt'));
1269+
1270+
const req = buildRequest({
1271+
spec,
1272+
operationId: 'getMe',
1273+
requestBody: readStream,
1274+
});
1275+
1276+
expect(req).toMatchObject({
1277+
method: 'GET',
1278+
url: '/one',
1279+
credentials: 'same-origin',
1280+
headers: {},
1281+
});
1282+
1283+
expect(req.body).toStrictEqual(readStream);
1284+
});
1285+
1286+
it('should preserve fs.ReadStream for application/octet-stream', () => {
1287+
const spec = {
1288+
openapi: '3.0.0',
1289+
paths: {
1290+
'/one': {
1291+
get: {
1292+
operationId: 'getMe',
1293+
requestBody: {
1294+
content: {
1295+
'application/octet-stream': {
1296+
schema: {
1297+
type: 'string',
1298+
format: 'binary',
1299+
},
1300+
},
1301+
},
1302+
},
1303+
},
1304+
},
1305+
},
1306+
};
1307+
1308+
// when
1309+
const readStream = fs.createReadStream(path.join(__dirname, 'data', 'payload.txt'));
1310+
1311+
const req = buildRequest({
1312+
spec,
1313+
operationId: 'getMe',
1314+
requestBody: readStream,
1315+
});
1316+
1317+
expect(req).toMatchObject({
1318+
method: 'GET',
1319+
url: '/one',
1320+
credentials: 'same-origin',
1321+
headers: {},
1322+
});
1323+
1324+
expect(req.body).toStrictEqual(readStream);
1325+
});
12441326
});
12451327
});
12461328
});

0 commit comments

Comments
 (0)