Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Node/Javascript) Support to include JSON.stringify in snippet itself instead on manually doing it #125

Merged
merged 12 commits into from
Nov 15, 2019
Merged
24 changes: 19 additions & 5 deletions codegens/js-fetch/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,22 @@ function parseFormData (body, trim) {
*
* @param {Object} body Raw body data
* @param {boolean} trim trim body option
* @param {String} contentType Content type of the body being sent
*/
function parseRawBody (body, trim) {
var bodySnippet = `var raw = "${sanitize(body.toString(), trim)}";\n`;
function parseRawBody (body, trim, contentType) {
var bodySnippet = 'var raw = ';
if (contentType === 'application/json') {
try {
let jsonBody = JSON.parse(body);
bodySnippet += `JSON.stringify(${JSON.stringify(jsonBody)});\n`;
}
catch (error) {
bodySnippet += `"${sanitize(body.toString(), trim)}";\n`;
}
}
else {
bodySnippet += `"${sanitize(body.toString(), trim)}";\n`;
}
return bodySnippet;
}

Expand Down Expand Up @@ -105,14 +118,15 @@ function parseFileData () {
* @param {Object} body body object from request.
* @param {boolean} trim trim body option
* @param {String} indentString indentation to be added to the snippet
* @param {String} contentType Content type of the body being sent
*/
function parseBody (body, trim, indentString) {
function parseBody (body, trim, indentString, contentType) {
if (!_.isEmpty(body)) {
switch (body.mode) {
case 'urlencoded':
return parseURLEncodedBody(body.urlencoded, trim);
case 'raw':
return parseRawBody(body.raw, trim);
return parseRawBody(body.raw, trim, contentType);
case 'graphql':
return parseGraphQL(body.graphql, trim, indentString);
case 'formdata':
Expand Down Expand Up @@ -232,7 +246,7 @@ function convert (request, options, callback) {
headerSnippet = parseHeaders(headers);

body = request.body && request.body.toJSON();
bodySnippet = parseBody(body, trim, indent);
bodySnippet = parseBody(body, trim, indent, request.headers.get('Content-Type'));

optionsSnippet = `var requestOptions = {\n${indent}`;
optionsSnippet += `method: '${request.method}',\n${indent}`;
Expand Down
34 changes: 34 additions & 0 deletions codegens/js-fetch/test/unit/convert.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,40 @@ describe('js-fetch convert function for test collection', function () {
'" value_containing_whitespaces ");');
});
});

it('should include JSON.stringify in the snippet for raw json bodies', function () {
var request = new sdk.Request({
'method': 'POST',
'header': [
{
'key': 'Content-Type',
'value': 'application/json'
}
],
'body': {
'mode': 'raw',
'raw': '{\n "json": "Test-Test"\n}'
},
'url': {
'raw': 'https://postman-echo.com/post',
'protocol': 'https',
'host': [
'postman-echo',
'com'
],
'path': [
'post'
]
}
});
convert(request, {}, function (error, snippet) {
if (error) {
expect.fail(null, null, error);
}
expect(snippet).to.be.a('string');
expect(snippet).to.include('var raw = JSON.stringify({"json":"Test-Test"})');
});
});
});

describe('getOptions function', function () {
Expand Down
3 changes: 2 additions & 1 deletion codegens/js-jquery/lib/js-jquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ self = module.exports = {
}
}
jQueryCode += `${getHeaders(request, indent)}`;
jQueryCode += `${parseBody(request.toJSON(), options.trimRequestBody, indent)}};\n\n`;
jQueryCode += `${parseBody(request.toJSON(), options.trimRequestBody, indent,
request.headers.get('Content-Type'))}};\n\n`;
jQueryCode += `$.ajax(settings).done(function (response) {\n${indent}console.log(response);\n});`;

return callback(null, jQueryCode);
Expand Down
18 changes: 16 additions & 2 deletions codegens/js-jquery/lib/util/parseBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ var _ = require('../lodash'),
* @param {Object} request - postman SDK-request object
* @param {Boolean} trimRequestBody - whether to trim request body fields
* @param {String} indentation - used for indenting snippet's structure
* @param {String} contentType Content type of the body being sent
* @returns {String} - request body
*/
module.exports = function (request, trimRequestBody, indentation) {
module.exports = function (request, trimRequestBody, indentation, contentType) {
// used to check whether body is present in the request and return accordingly
if (request.body) {
var requestBody = '',
Expand All @@ -19,8 +20,21 @@ module.exports = function (request, trimRequestBody, indentation) {
switch (request.body.mode) {
case 'raw':
if (!_.isEmpty(request.body[request.body.mode])) {
requestBody += `${indentation}"data": ` +
if (contentType === 'application/json') {
// eslint-disable-next-line max-depth
try {
let jsonBody = JSON.parse(request.body[request.body.mode]);
requestBody += `${indentation}"data": JSON.stringify(${JSON.stringify(jsonBody)}),\n`;
}
catch (error) {
requestBody += `${indentation}"data": ` +
`${sanitize(request.body[request.body.mode], request.body.mode, trimRequestBody)},\n`;
}
}
else {
requestBody += `${indentation}"data": ` +
`${sanitize(request.body[request.body.mode], request.body.mode, trimRequestBody)},\n`;
}
}
return requestBody;
// eslint-disable-next-line no-case-declarations
Expand Down
33 changes: 33 additions & 0 deletions codegens/js-jquery/test/unit/converter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,39 @@ describe('jQuery converter', function () {
expect(snippet).to.include('"key_containing_whitespaces": " value_containing_whitespaces "');
});
});
it('should include JSON.stringify in the snippet for raw json bodies', function () {
var request = new sdk.Request({
'method': 'POST',
'header': [
{
'key': 'Content-Type',
'value': 'application/json'
}
],
'body': {
'mode': 'raw',
'raw': '{\n "json": "Test-Test"\n}'
},
'url': {
'raw': 'https://postman-echo.com/post',
'protocol': 'https',
'host': [
'postman-echo',
'com'
],
'path': [
'post'
]
}
});
convert(request, {}, function (error, snippet) {
if (error) {
expect.fail(null, null, error);
}
expect(snippet).to.be.a('string');
expect(snippet).to.include('"data": JSON.stringify({"json":"Test-Test"})');
});
});

it('should include graphql body in the snippet', function () {
var request = new sdk.Request({
Expand Down
2 changes: 1 addition & 1 deletion codegens/js-jquery/test/unit/fixtures/snippetFixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"Resolve URL (Quotes + Special Characters) Copy": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%3Fa%3D%21@%24%5E*%28%29_-%60%2526%26b%3D%2C./%27%3B%5B%5D%7D%7B%5C%22%3A/%3F%3E%3C%7C%7C%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST Raw Text": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22application/x-www-form-urlencoded%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%21@%23%24%25%5E%26*%28%29+POL%3A%7D%2C%27%27%3B%2C%5B%3B%5B%3B%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST urlencoded data with disabled entries": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22application/x-www-form-urlencoded%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%221%22%3A%20%22%27a%27%22%2C%0A%20%20%20%20%20%20%20%20%222%22%3A%20%22%5C%22b%5C%22%22%0A%20%20%20%20%7D%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST json with raw": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22application/json%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22%7B%5Cn%20%20%5C%22json%5C%22%3A%20%5C%22Test-Test%21@%23%24%25%5E%26*%28%29+POL%3A%7D%2C%27%27%3B%2C%5B%3B%5B%3B%3A%3E%5C%22%5Cn%7D%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST json with raw": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22application/json%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20JSON.stringify%28%7B%22json%22%3A%22Test-Test%21@%23%24%25%5E%26*%28%29+POL%3A%7D%2C%27%27%3B%2C%5B%3B%5B%3B%3A%3E%22%7D%29%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST javascript with raw": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22application/javascript%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22var%20val%20%3D%206%3B%5Cnconsole.log%28val%29%3B%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST text/xml with raw": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/xml%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22%3Cxml%3E%5Cn%5CtTest%20Test%21@%23%24%25%5E%26*%28%29+POL%3A%7D%2C%27%27%3B%2C%5B%3B%5B%3B%5Cn%3C/xml%3E%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"POST text/html with raw": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//postman-echo.com/post%22%2C%0A%20%20%20%20%22method%22%3A%20%22POST%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/html%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22%3Chtml%3E%5Cn%20%20Test%20Test%20%21@%23%24%25%5E%26*%28%29+POL%3A%7D%2C%27%27%3B%2C%5B%3B%5B%3B%5Cn%3C/html%3E%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
Expand Down
30 changes: 22 additions & 8 deletions codegens/js-xhr/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,22 @@ function parseURLEncodedBody (body) {
*
* @param {*} body Raw body data
* @param {*} trim trim body option
* @param {String} contentType Content type of the body being sent
*/
function parseRawBody (body, trim) {
var bodySnippet;
bodySnippet = `var data = "${sanitize(body.toString(), trim)}";\n`;
function parseRawBody (body, trim, contentType) {
var bodySnippet = 'var data = ';
if (contentType === 'application/json') {
try {
let jsonBody = JSON.parse(body);
bodySnippet += `JSON.stringify(${JSON.stringify(jsonBody)});\n`;
}
catch (error) {
bodySnippet += `"${sanitize(body.toString(), trim)}";\n`;
}
}
else {
bodySnippet += `"${sanitize(body.toString(), trim)}";\n`;
}
return bodySnippet;
}

Expand Down Expand Up @@ -98,17 +110,18 @@ function parseFile () {
/**
* Parses Body from the Request
*
* @param {Object} body body object from request.
* @param {boolean} trim trim body option
* @param {*} body body object from request.
* @param {*} trim trim body option
* @param {String} indentString indentation to be added to the snippet
* @param {String} contentType Content type of the body being sent
*/
function parseBody (body, trim, indentString) {
function parseBody (body, trim, indentString, contentType) {
if (!_.isEmpty(body)) {
switch (body.mode) {
case 'urlencoded':
return parseURLEncodedBody(body.urlencoded, trim);
case 'raw':
return parseRawBody(body.raw, trim);
return parseRawBody(body.raw, trim, contentType);
case 'graphql':
return parseGraphQL(body.graphql, trim, indentString);
case 'formdata':
Expand Down Expand Up @@ -201,7 +214,8 @@ function convert (request, options, callback) {
indent = indent.repeat(options.indentCount);
trim = options.trimRequestBody;

bodySnippet = request.body && !_.isEmpty(request.body.toJSON()) ? parseBody(request.body.toJSON(), trim, indent) : '';
bodySnippet = request.body && !_.isEmpty(request.body.toJSON()) ? parseBody(request.body.toJSON(), trim,
indent, request.headers.get('Content-Type')) : '';

codeSnippet += bodySnippet + '\n';

Expand Down
33 changes: 33 additions & 0 deletions codegens/js-xhr/test/unit/convert.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@ describe('js-xhr convert function', function () {
'" value_containing_whitespaces ")');
});
});
it('should include JSON.stringify in the snippet for raw json bodies', function () {
var request = new sdk.Request({
'method': 'POST',
'header': [
{
'key': 'Content-Type',
'value': 'application/json'
}
],
'body': {
'mode': 'raw',
'raw': '{\n "json": "Test-Test"\n}'
},
'url': {
'raw': 'https://postman-echo.com/post',
'protocol': 'https',
'host': [
'postman-echo',
'com'
],
'path': [
'post'
]
}
});
convert(request, {}, function (error, snippet) {
if (error) {
expect.fail(null, null, error);
}
expect(snippet).to.be.a('string');
expect(snippet).to.include('var data = JSON.stringify({"json":"Test-Test"})');
});
});

describe('Sanitize function', function () {
it('should return empty string when input is not a string type', function () {
Expand Down
12 changes: 11 additions & 1 deletion codegens/nodejs-native/lib/parseRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,21 @@ function generateMultipartFormData (requestbody) {
* @param {Object} requestbody - json object for body of request
* @param {String} indentString - string for indentation
* @param {Boolean} trimBody - indicates whether to trim body fields or not
* @param {String} contentType Content type of the body being sent
*/
function parseBody (requestbody, indentString, trimBody) {
function parseBody (requestbody, indentString, trimBody, contentType) {
if (requestbody) {
switch (requestbody.mode) {
case 'raw':
if (contentType === 'application/json') {
try {
let jsonBody = JSON.parse(requestbody[requestbody.mode]);
return `JSON.stringify(${JSON.stringify(jsonBody)})`;
}
catch (error) {
return ` ${JSON.stringify(requestbody[requestbody.mode])}`;
}
}
return ` ${JSON.stringify(requestbody[requestbody.mode])}`;
// eslint-disable-next-line no-case-declarations
case 'graphql':
Expand Down
5 changes: 3 additions & 2 deletions codegens/nodejs-native/lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function makeSnippet (request, indentString, options) {
var nativeModule = (request.url.protocol === 'http' ? 'http' : 'https'),
snippet = `var ${nativeModule} = require('${nativeModule}');\n`,
optionsArray = [],
postData;
postData = '';

if (options.followRedirect) {
snippet = `var ${nativeModule} = require('follow-redirects').${nativeModule};\n`;
Expand All @@ -41,7 +41,8 @@ function makeSnippet (request, indentString, options) {
* }
*/
if (request.body && request.body[request.body.mode]) {
postData = parseRequest.parseBody(request.body.toJSON(), indentString, options.trimRequestBody);
postData += parseRequest.parseBody(request.body.toJSON(), indentString, options.trimRequestBody,
request.headers.get('Content-Type'));
}
if (request.body && !request.headers.has('Content-Type')) {
if (request.body.mode === 'file') {
Expand Down
33 changes: 33 additions & 0 deletions codegens/nodejs-native/test/unit/snippet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,37 @@ describe('nodejs-native convert function', function () {
expect(snippet).to.include('\'key_containing_whitespaces\': \' value_containing_whitespaces \'');
});
});
it('should include JSON.stringify in the snippet for raw json bodies', function () {
var request = new sdk.Request({
'method': 'POST',
'header': [
{
'key': 'Content-Type',
'value': 'application/json'
}
],
'body': {
'mode': 'raw',
'raw': '{\n "json": "Test-Test"\n}'
},
'url': {
'raw': 'https://postman-echo.com/post',
'protocol': 'https',
'host': [
'postman-echo',
'com'
],
'path': [
'post'
]
}
});
convert(request, {}, function (error, snippet) {
if (error) {
expect.fail(null, null, error);
}
expect(snippet).to.be.a('string');
expect(snippet).to.include('var postData = JSON.stringify({"json":"Test-Test"})');
});
});
});
12 changes: 11 additions & 1 deletion codegens/nodejs-request/lib/parseRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,21 @@ function extractFormData (dataArray, indentString, trimBody) {
* @param {Object} requestbody - json object for body of request
* @param {String} indentString - string for indentation
* @param {Boolean} trimBody - indicates whether to trim body fields or not
* @param {String} contentType Content type of the body being sent
*/
function parseBody (requestbody, indentString, trimBody) {
function parseBody (requestbody, indentString, trimBody, contentType) {
if (requestbody) {
switch (requestbody.mode) {
case 'raw':
if (contentType === 'application/json') {
try {
let jsonBody = JSON.parse(requestbody[requestbody.mode]);
return `body: JSON.stringify(${JSON.stringify(jsonBody)})\n`;
}
catch (error) {
return `body: ${JSON.stringify(requestbody[requestbody.mode])}\n`;
}
}
return `body: ${JSON.stringify(requestbody[requestbody.mode])}\n`;
// eslint-disable-next-line no-case-declarations
case 'graphql':
Expand Down
3 changes: 2 additions & 1 deletion codegens/nodejs-request/lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ function makeSnippet (request, indentString, options) {

if (request.body && request.body[request.body.mode]) {
optionsArray.push(
indentString + parseRequest.parseBody(request.body.toJSON(), indentString, options.trimRequestBody)
indentString + parseRequest.parseBody(request.body.toJSON(), indentString, options.trimRequestBody,
request.headers.get('Content-Type'))
);
}
if (options.requestTimeout) {
Expand Down
Loading