Skip to content

Commit 3f82eda

Browse files
author
Vishal Shingala
committed
Merge branch 'develop' of github.com:postmanlabs/openapi-to-postman into fix496/validateWithServers
2 parents 1f6ce67 + aea666b commit 3f82eda

16 files changed

+1795
-51
lines changed

lib/common/schemaUtilsCommon.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,5 +345,16 @@ module.exports = {
345345

346346
isKnownType: function(schema) {
347347
return typeof schemaTypeToJsValidator[schema.type] === 'function';
348+
},
349+
350+
getServersPathVars: function(servers) {
351+
return servers.reduce((acc, current) => {
352+
const newVarNames = current.hasOwnProperty('variables') ?
353+
Object.keys(current.variables).filter((varName) => {
354+
return !acc.includes(varName);
355+
}) :
356+
[];
357+
return [...acc, ...newVarNames];
358+
}, []);
348359
}
349360
};

lib/schemaUtils.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,7 +3333,7 @@ module.exports = {
33333333

33343334
/**
33353335
*
3336-
* @param {*} determinedPathVariables the key/determined-value pairs of the path variables (from Postman)
3336+
* @param {*} matchedPathData the matchedPath data
33373337
* @param {*} transactionPathPrefix the jsonpath for this validation (will be prepended to all identified mismatches)
33383338
* @param {*} schemaPath the applicable pathItem defined at the schema level
33393339
* @param {*} components the components + paths from the OAS spec that need to be used to resolve $refs
@@ -3344,7 +3344,7 @@ module.exports = {
33443344
* @returns {array} mismatches (in the callback)
33453345
*/
33463346
checkPathVariables: function (
3347-
determinedPathVariables,
3347+
matchedPathData,
33483348
transactionPathPrefix,
33493349
schemaPath,
33503350
components,
@@ -3358,7 +3358,9 @@ module.exports = {
33583358
var mismatchProperty = 'PATHVARIABLE',
33593359
// all path variables defined in this path. acc. to the spec, all path params are required
33603360
schemaPathVariables,
3361-
pmPathVariables;
3361+
pmPathVariables,
3362+
determinedPathVariables = matchedPathData.pathVariables,
3363+
unmatchedVariablesFromTransaction = matchedPathData.unmatchedVariablesFromTransaction;
33623364

33633365
if (options.validationPropertiesToIgnore.includes(mismatchProperty)) {
33643366
return callback(null, []);
@@ -3424,17 +3426,41 @@ module.exports = {
34243426
}, (err, res) => {
34253427
let mismatches = [],
34263428
mismatchObj;
3429+
const unmatchedSchemaVariableNames = determinedPathVariables.filter((pathVariable) => {
3430+
return !pathVariable._varMatched;
3431+
}).map((schemaPathVar) => {
3432+
return schemaPathVar.key;
3433+
});
34273434

34283435
if (err) {
34293436
return callback(err);
34303437
}
34313438

34323439
// go through required schemaPathVariables, and params that aren't found in the given transaction are errors
3433-
_.each(schemaPathVariables, (pathVar) => {
3440+
_.each(schemaPathVariables, (pathVar, index) => {
34343441
if (!_.find(determinedPathVariables, (param) => {
34353442
// only consider variable matching if url path variables is not allowed
34363443
return param.key === pathVar.name && (options.allowUrlPathVarMatching || param._varMatched);
34373444
})) {
3445+
let reasonCode = 'MISSING_IN_REQUEST',
3446+
reason,
3447+
actualValue,
3448+
currentUnmatchedVariableInTransaction = unmatchedVariablesFromTransaction[index],
3449+
isInvalidValue = currentUnmatchedVariableInTransaction !== undefined;
3450+
3451+
if (unmatchedSchemaVariableNames.length > 0 && isInvalidValue) {
3452+
reason = `The ${currentUnmatchedVariableInTransaction.key} path variable does not match with ` +
3453+
`path variable expected (${unmatchedSchemaVariableNames[index]}) in the schema at this position`;
3454+
actualValue = {
3455+
key: currentUnmatchedVariableInTransaction.key,
3456+
description: this.getParameterDescription(currentUnmatchedVariableInTransaction),
3457+
value: currentUnmatchedVariableInTransaction.value
3458+
};
3459+
}
3460+
else {
3461+
reason = `The required path variable "${pathVar.name}" was not found in the transaction`;
3462+
actualValue = null;
3463+
}
34383464

34393465
// assign parameter example(s) as schema examples;
34403466
this.assignParameterExamples(pathVar);
@@ -3443,14 +3469,14 @@ module.exports = {
34433469
property: mismatchProperty,
34443470
transactionJsonPath: transactionPathPrefix,
34453471
schemaJsonPath: pathVar.pathPrefix,
3446-
reasonCode: 'MISSING_IN_REQUEST',
3447-
reason: `The required path variable "${pathVar.name}" was not found in the transaction`
3472+
reasonCode,
3473+
reason
34483474
};
34493475

34503476
if (options.suggestAvailableFixes) {
34513477
mismatchObj.suggestedFix = {
34523478
key: pathVar.name,
3453-
actualValue: null,
3479+
actualValue,
34543480
suggestedValue: {
34553481
key: pathVar.name,
34563482
value: safeSchemaFaker(pathVar.schema || {}, 'example', PROCESSING_TYPE.VALIDATION,

lib/schemapack.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use strict';
22

3-
43
// This is the default collection name if one can't be inferred from the OpenAPI spec
54
const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
65
{ getConcreteSchemaUtils } = require('./common/versionUtils.js'),
@@ -26,7 +25,8 @@ const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
2625
// This provides the base class for
2726
// errors with the input OpenAPI spec
2827
OpenApiErr = require('./error.js'),
29-
schemaUtils = require('./schemaUtils');
28+
schemaUtils = require('./schemaUtils'),
29+
{ getServersPathVars } = require('./common/schemaUtilsCommon.js');
3030

3131
let path = require('path'),
3232
concreteUtils,
@@ -495,12 +495,29 @@ class SchemaPack {
495495
return setTimeout(() => {
496496
// 2. perform validation for each identified matchedPath (schema endpoint)
497497
return async.map(matchedPaths, (matchedPath, pathsCallback) => {
498+
const transactionPathVariables = _.get(transaction, 'request.url.variable', []),
499+
localServers = matchedPath.path.hasOwnProperty('servers') ?
500+
matchedPath.path.servers :
501+
[],
502+
serversPathVars = [...getServersPathVars(localServers), ...getServersPathVars(schema.servers)],
503+
isNotAServerPathVar = (pathVarName) => {
504+
return !serversPathVars.includes(pathVarName);
505+
};
498506

507+
matchedPath.unmatchedVariablesFromTransaction = [];
499508
// override path variable value with actual value present in transaction
500509
// as matched pathvariable contains key as value, as it is generated from url only
501510
_.forEach(matchedPath.pathVariables, (pathVar) => {
502-
let mappedPathVar = _.find(_.get(transaction, 'request.url.variable', []), (transactionPathVar) => {
503-
return transactionPathVar.key === pathVar.key;
511+
const mappedPathVar = _.find(transactionPathVariables, (transactionPathVar) => {
512+
let matched = transactionPathVar.key === pathVar.key;
513+
if (
514+
!matched &&
515+
isNotAServerPathVar(transactionPathVar.key) &&
516+
!matchedPath.unmatchedVariablesFromTransaction.includes(transactionPathVar)
517+
) {
518+
matchedPath.unmatchedVariablesFromTransaction.push(transactionPathVar);
519+
}
520+
return matched;
504521
});
505522
pathVar.value = _.get(mappedPathVar, 'value', pathVar.value);
506523
// set _varMatched flag which represents if variable was found in transaction or not
@@ -522,7 +539,7 @@ class SchemaPack {
522539
schemaUtils.checkMetadata(transaction, '$', matchedPath.path, matchedPath.name, options, cb);
523540
},
524541
path: function(cb) {
525-
schemaUtils.checkPathVariables(matchedPath.pathVariables, '$.request.url.variable', matchedPath.path,
542+
schemaUtils.checkPathVariables(matchedPath, '$.request.url.variable', matchedPath.path,
526543
componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb);
527544
},
528545
queryparams: function(cb) {

package-lock.json

Lines changed: 46 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,22 @@
118118
"dependencies": {
119119
"ajv": "8.1.0",
120120
"ajv-formats": "2.1.1",
121-
"async": "3.2.3",
121+
"async": "3.2.4",
122122
"commander": "2.20.3",
123123
"js-yaml": "3.14.1",
124124
"json-schema-merge-allof": "0.8.1",
125125
"lodash": "4.17.21",
126126
"oas-resolver-browser": "2.5.6",
127127
"path-browserify": "1.0.1",
128-
"postman-collection": "4.0.0",
128+
"postman-collection": "4.1.4",
129129
"swagger2openapi": "7.0.8",
130130
"traverse": "0.6.6",
131131
"yaml": "1.10.2"
132132
},
133133
"author": "Postman Labs <help@getpostman.com>",
134134
"license": "Apache-2.0",
135135
"devDependencies": {
136-
"chai": "4.3.4",
136+
"chai": "4.3.6",
137137
"editorconfig": "0.15.3",
138138
"eslint": "5.16.0",
139139
"eslint-plugin-jsdoc": "3.8.0",

0 commit comments

Comments
 (0)