Skip to content

Commit 2be5cfb

Browse files
authored
Merge pull request #712 from postmanlabs/feature/fix-options-merge
Removed unnecessary options merging with each util function.
2 parents c527b80 + 4af1f56 commit 2be5cfb

File tree

5 files changed

+243
-86
lines changed

5 files changed

+243
-86
lines changed

lib/schemaUtils.js

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/sc
1616
openApiErr = require('./error.js'),
1717
ajvValidationError = require('./ajValidation/ajvValidationError'),
1818
utils = require('./utils.js'),
19-
defaultOptions = require('../lib/options.js').getOptions('use'),
2019
{ Node, Trie } = require('./trie.js'),
2120
{ validateSchema } = require('./ajValidation/ajvValidation'),
2221
inputValidation = require('./30XUtils/inputValidation'),
@@ -523,7 +522,6 @@ module.exports = {
523522
* @returns {*} combined requestParams from operation and path params.
524523
*/
525524
getRequestParams: function(operationParam, pathParam, components, options) {
526-
options = _.merge({}, defaultOptions, options);
527525
if (!Array.isArray(operationParam)) {
528526
operationParam = [];
529527
}
@@ -579,7 +577,6 @@ module.exports = {
579577
* @returns {Object} - The final object consists of the tree structure
580578
*/
581579
generateTrieFromPaths: function (spec, options, fromWebhooks = false) {
582-
options = _.merge({}, defaultOptions, options);
583580
let concreteUtils = getConcreteSchemaUtils({ type: 'json', data: spec }),
584581
specComponentsAndUtils = {
585582
concreteUtils
@@ -981,8 +978,6 @@ module.exports = {
981978
* @returns {Array<object>} returns an array of sdk.Variable
982979
*/
983980
convertPathVariables: function(type, providedPathVars, commonPathVars, components, options, schemaCache) {
984-
options = _.merge({}, defaultOptions, options);
985-
986981
var variables = [];
987982
// converting the base uri path variables, if any
988983
// commonPathVars is an object for type = root/method
@@ -1036,7 +1031,6 @@ module.exports = {
10361031
*/
10371032
convertChildToItemGroup: function (openapi, child, components, options,
10381033
schemaCache, variableStore, fromWebhooks = false) {
1039-
options = _.merge({}, defaultOptions, options);
10401034

10411035
var resource = child,
10421036
itemGroup,
@@ -1398,8 +1392,6 @@ module.exports = {
13981392
* @return {object} responseBody, contentType header needed
13991393
*/
14001394
convertToPmResponseBody: function(contentObj, components, options, schemaCache) {
1401-
options = _.merge({}, defaultOptions, options);
1402-
14031395
var responseBody, cTypeHeader, hasComputedType, cTypes,
14041396
isJsonLike = false;
14051397
if (!contentObj) {
@@ -1512,8 +1504,6 @@ module.exports = {
15121504
* @returns {*} first example in the input map type
15131505
*/
15141506
getExampleData: function(exampleObj, components, options) {
1515-
options = _.merge({}, defaultOptions, options);
1516-
15171507
var example,
15181508
exampleKey;
15191509

@@ -1556,7 +1546,6 @@ module.exports = {
15561546
convertToPmBodyData: function(bodyObj, requestType, contentType, parameterSourceOption,
15571547
indentCharacter, components, options, schemaCache) {
15581548

1559-
options = _.merge({}, defaultOptions, options);
15601549
var bodyData = '',
15611550
schemaFormat = SCHEMA_FORMATS.DEFAULT,
15621551
schemaType,
@@ -1672,7 +1661,6 @@ module.exports = {
16721661
* @returns {array} converted queryparam
16731662
*/
16741663
convertToPmQueryParameters: function(param, requestType, components, options, schemaCache) {
1675-
options = _.merge({}, defaultOptions, options);
16761664
var pmParams = [],
16771665
paramValue,
16781666
resolveTo = this.resolveToExampleOrSchema(requestType, options.requestParametersResolution,
@@ -1848,8 +1836,6 @@ module.exports = {
18481836
* @returns {Object} instance of a Postman SDK Header
18491837
*/
18501838
convertToPmHeader: function(header, requestType, parameterSource, components, options, schemaCache) {
1851-
options = _.merge({}, defaultOptions, options);
1852-
18531839
var fakeData,
18541840
convertedHeader,
18551841
reqHeader,
@@ -1891,7 +1877,6 @@ module.exports = {
18911877
* @returns {Object} - Postman requestBody and Content-Type Header
18921878
*/
18931879
convertToPmBody: function(requestBody, requestType, components, options, schemaCache) {
1894-
options = _.merge({}, defaultOptions, options);
18951880
var contentObj, // content is required
18961881
bodyData,
18971882
param,
@@ -2175,7 +2160,6 @@ module.exports = {
21752160
* @returns {Object} postman response
21762161
*/
21772162
convertToPmResponse: function(response, code, originalRequest, components, options, schemaCache) {
2178-
options = _.merge({}, defaultOptions, options);
21792163
var responseHeaders = [],
21802164
previewLanguage = 'text',
21812165
responseBodyWrapper,
@@ -2287,17 +2271,21 @@ module.exports = {
22872271
* @param {object} components - components defined in the OAS spec. These are used to
22882272
* resolve references while generating params.
22892273
* @param {object} options - a standard list of options that's globally passed around. Check options.js for more.
2274+
* @param {*} seenRef - References that are repeated. Used to identify circular references.
22902275
* @returns {Object} reference object from the saved components
22912276
* @no-unit-tests
22922277
*/
2293-
getRefObject: function($ref, components, options) {
2294-
options = _.merge({}, defaultOptions, options);
2278+
getRefObject: function($ref, components, options, seenRef = {}) {
22952279
var refObj, savedSchema;
22962280

22972281
if (typeof $ref !== 'string') {
22982282
return { value: `Invalid $ref: ${$ref} was found` };
22992283
}
23002284

2285+
if (seenRef[$ref]) {
2286+
return { value: `Error: "${$ref}" contains circular references in it.` };
2287+
}
2288+
23012289
savedSchema = $ref.split('/').slice(1).map((elem) => {
23022290
// https://swagger.io/docs/specification/using-ref#escape
23032291
// since / is the default delimiter, slashes are escaped with ~1
@@ -2328,10 +2316,16 @@ module.exports = {
23282316
return { value: `reference ${$ref} not found in the given specification` };
23292317
}
23302318

2319+
// Mark current $ref as seen while processing it further
2320+
seenRef[$ref] = true;
2321+
23312322
if (refObj.$ref) {
2332-
return this.getRefObject(refObj.$ref, components, options);
2323+
return this.getRefObject(refObj.$ref, components, options, seenRef);
23332324
}
23342325

2326+
// Unmark current $ref once resolved
2327+
seenRef[$ref] = false;
2328+
23352329
return refObj;
23362330
},
23372331

@@ -2461,7 +2455,6 @@ module.exports = {
24612455
*/
24622456
convertRequestToItem: function(openapi, operationItem, components,
24632457
options, schemaCache, variableStore, fromWebhooks = false) {
2464-
options = _.merge({}, defaultOptions, options);
24652458
var reqName,
24662459
pathVariables = openapi.baseUrlVariables,
24672460
operation = operationItem.properties,
@@ -2825,7 +2818,6 @@ module.exports = {
28252818
* @returns {*} array of all query params
28262819
*/
28272820
convertToPmQueryArray: function(reqParams, requestType, components, options, schemaCache) {
2828-
options = _.merge({}, defaultOptions, options);
28292821
let requestQueryParams = [];
28302822
_.forEach(reqParams.query, (queryParam) => {
28312823
this.convertToPmQueryParameters(queryParam, requestType, components, options, schemaCache).forEach((pmParam) => {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
openapi: "3.0.0"
2+
info:
3+
version: 1.0.0
4+
title: Swagger Petstore
5+
license:
6+
name: MIT
7+
servers:
8+
- url: http://petstore.swagger.io/v1
9+
paths:
10+
/pets:
11+
get:
12+
summary: List all pets
13+
operationId: listPets
14+
tags:
15+
- pets
16+
parameters:
17+
- $ref: "#/components/parameters/rec-param"
18+
responses:
19+
"401":
20+
$ref: "#/components/responses/Unauthorized"
21+
default:
22+
$ref: "#/components/responses/paramA"
23+
components:
24+
parameters:
25+
rec-param:
26+
$ref: "#/components/parameters/rec-param"
27+
responses:
28+
Unauthorized:
29+
$ref: "#/components/responses/Unauthorized"
30+
paramA:
31+
$ref: "#/components/responses/paramB"
32+
paramB:
33+
$ref: "#/components/responses/paramC"
34+
paramC:
35+
$ref: "#/components/responses/paramA"

test/unit/base.test.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ describe('CONVERT FUNCTION TESTS ', function() {
9292
specWithNullParams =
9393
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml'),
9494
acceptHeaderExample =
95-
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json');
95+
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json'),
96+
recursiveRefComponents =
97+
path.join(__dirname, VALID_OPENAPI_PATH, '/recursiveRefComponents.yaml');
9698

9799

98100
it('Should add collection level auth with type as `bearer`' +
@@ -1888,6 +1890,35 @@ describe('CONVERT FUNCTION TESTS ', function() {
18881890
done();
18891891
});
18901892
});
1893+
1894+
it('Should handle recursive references for non-schema $refs correctly', function(done) {
1895+
var openapi = fs.readFileSync(recursiveRefComponents, 'utf8');
1896+
Converter.convert({ type: 'string', data: openapi }, {},
1897+
(err, conversionResult) => {
1898+
expect(err).to.be.null;
1899+
expect(conversionResult.result).to.equal(true);
1900+
expect(conversionResult.output.length).to.equal(1);
1901+
expect(conversionResult.output[0].type).to.equal('collection');
1902+
expect(conversionResult.output[0].data).to.have.property('info');
1903+
expect(conversionResult.output[0].data).to.have.property('item');
1904+
expect(conversionResult.output[0].data.item.length).to.equal(1);
1905+
1906+
const item = conversionResult.output[0].data.item[0];
1907+
1908+
expect(item.request.header).to.be.undefined;
1909+
expect(item.request.url.query).to.be.empty;
1910+
expect(item.response.length).to.eql(2);
1911+
expect(item.response[0].header.length).to.eql(1);
1912+
expect(item.response[0].header[0].key).to.eql('Content-Type');
1913+
expect(item.response[0].header[0].value).to.eql('text/plain');
1914+
expect(item.response[0].body).to.be.empty;
1915+
expect(item.response[1].header.length).to.eql(1);
1916+
expect(item.response[1].header[0].key).to.eql('Content-Type');
1917+
expect(item.response[1].header[0].value).to.eql('text/plain');
1918+
expect(item.response[1].body).to.be.empty;
1919+
done();
1920+
});
1921+
});
18911922
});
18921923

18931924
describe('Converting swagger 2.0 files', function() {

test/unit/convertV2.test.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ const expect = require('chai').expect,
8787
specWithNullParams =
8888
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml'),
8989
acceptHeaderExample =
90-
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json');
90+
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json'),
91+
recursiveRefComponents =
92+
path.join(__dirname, VALID_OPENAPI_PATH, '/recursiveRefComponents.yaml');
9193

9294

9395
describe('The convert v2 Function', function() {
@@ -2179,4 +2181,29 @@ describe('The convert v2 Function', function() {
21792181
done();
21802182
});
21812183
});
2184+
2185+
it('Should handle recursive references for non-schema $refs correctly', function(done) {
2186+
var openapi = fs.readFileSync(recursiveRefComponents, 'utf8');
2187+
Converter.convertV2({ type: 'string', data: openapi }, {},
2188+
(err, conversionResult) => {
2189+
expect(err).to.be.null;
2190+
expect(conversionResult.result).to.equal(true);
2191+
expect(conversionResult.output.length).to.equal(1);
2192+
expect(conversionResult.output[0].type).to.equal('collection');
2193+
expect(conversionResult.output[0].data).to.have.property('info');
2194+
expect(conversionResult.output[0].data).to.have.property('item');
2195+
expect(conversionResult.output[0].data.item.length).to.equal(1);
2196+
2197+
const item = conversionResult.output[0].data.item[0].item[0];
2198+
2199+
expect(item.request.header).to.be.undefined;
2200+
expect(item.request.url.query).to.be.empty;
2201+
expect(item.response.length).to.eql(2);
2202+
expect(item.response[0].header).to.be.empty;
2203+
expect(item.response[0].body).to.be.undefined;
2204+
expect(item.response[1].header).to.be.empty;
2205+
expect(item.response[1].body).to.be.undefined;
2206+
done();
2207+
});
2208+
});
21822209
});

0 commit comments

Comments
 (0)