diff --git a/lib/common/schemaUtilsCommon.js b/lib/common/schemaUtilsCommon.js index dd18ad2..e41da54 100644 --- a/lib/common/schemaUtilsCommon.js +++ b/lib/common/schemaUtilsCommon.js @@ -345,5 +345,16 @@ module.exports = { isKnownType: function(schema) { return typeof schemaTypeToJsValidator[schema.type] === 'function'; + }, + + getServersPathVars: function(servers) { + return servers.reduce((acc, current) => { + const newVarNames = current.hasOwnProperty('variables') ? + Object.keys(current.variables).filter((varName) => { + return !acc.includes(varName); + }) : + []; + return [...acc, ...newVarNames]; + }, []); } }; diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index 31de451..6344cf3 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -3333,7 +3333,7 @@ module.exports = { /** * - * @param {*} determinedPathVariables the key/determined-value pairs of the path variables (from Postman) + * @param {*} matchedPathData the matchedPath data * @param {*} transactionPathPrefix the jsonpath for this validation (will be prepended to all identified mismatches) * @param {*} schemaPath the applicable pathItem defined at the schema level * @param {*} components the components + paths from the OAS spec that need to be used to resolve $refs @@ -3344,7 +3344,7 @@ module.exports = { * @returns {array} mismatches (in the callback) */ checkPathVariables: function ( - determinedPathVariables, + matchedPathData, transactionPathPrefix, schemaPath, components, @@ -3358,7 +3358,9 @@ module.exports = { var mismatchProperty = 'PATHVARIABLE', // all path variables defined in this path. acc. to the spec, all path params are required schemaPathVariables, - pmPathVariables; + pmPathVariables, + determinedPathVariables = matchedPathData.pathVariables, + unmatchedVariablesFromTransaction = matchedPathData.unmatchedVariablesFromTransaction; if (options.validationPropertiesToIgnore.includes(mismatchProperty)) { return callback(null, []); @@ -3424,17 +3426,41 @@ module.exports = { }, (err, res) => { let mismatches = [], mismatchObj; + const unmatchedSchemaVariableNames = determinedPathVariables.filter((pathVariable) => { + return !pathVariable._varMatched; + }).map((schemaPathVar) => { + return schemaPathVar.key; + }); if (err) { return callback(err); } // go through required schemaPathVariables, and params that aren't found in the given transaction are errors - _.each(schemaPathVariables, (pathVar) => { + _.each(schemaPathVariables, (pathVar, index) => { if (!_.find(determinedPathVariables, (param) => { // only consider variable matching if url path variables is not allowed return param.key === pathVar.name && (options.allowUrlPathVarMatching || param._varMatched); })) { + let reasonCode = 'MISSING_IN_REQUEST', + reason, + actualValue, + currentUnmatchedVariableInTransaction = unmatchedVariablesFromTransaction[index], + isInvalidValue = currentUnmatchedVariableInTransaction !== undefined; + + if (unmatchedSchemaVariableNames.length > 0 && isInvalidValue) { + reason = `The ${currentUnmatchedVariableInTransaction.key} path variable does not match with ` + + `path variable expected (${unmatchedSchemaVariableNames[index]}) in the schema at this position`; + actualValue = { + key: currentUnmatchedVariableInTransaction.key, + description: this.getParameterDescription(currentUnmatchedVariableInTransaction), + value: currentUnmatchedVariableInTransaction.value + }; + } + else { + reason = `The required path variable "${pathVar.name}" was not found in the transaction`; + actualValue = null; + } // assign parameter example(s) as schema examples; this.assignParameterExamples(pathVar); @@ -3443,14 +3469,14 @@ module.exports = { property: mismatchProperty, transactionJsonPath: transactionPathPrefix, schemaJsonPath: pathVar.pathPrefix, - reasonCode: 'MISSING_IN_REQUEST', - reason: `The required path variable "${pathVar.name}" was not found in the transaction` + reasonCode, + reason }; if (options.suggestAvailableFixes) { mismatchObj.suggestedFix = { key: pathVar.name, - actualValue: null, + actualValue, suggestedValue: { key: pathVar.name, value: safeSchemaFaker(pathVar.schema || {}, 'example', PROCESSING_TYPE.VALIDATION, diff --git a/lib/schemapack.js b/lib/schemapack.js index b53e0de..0921d81 100644 --- a/lib/schemapack.js +++ b/lib/schemapack.js @@ -1,6 +1,5 @@ 'use strict'; - // This is the default collection name if one can't be inferred from the OpenAPI spec const COLLECTION_NAME = 'Imported from OpenAPI 3.0', { getConcreteSchemaUtils } = require('./common/versionUtils.js'), @@ -26,7 +25,8 @@ const COLLECTION_NAME = 'Imported from OpenAPI 3.0', // This provides the base class for // errors with the input OpenAPI spec OpenApiErr = require('./error.js'), - schemaUtils = require('./schemaUtils'); + schemaUtils = require('./schemaUtils'), + { getServersPathVars } = require('./common/schemaUtilsCommon.js'); let path = require('path'), concreteUtils, @@ -495,12 +495,29 @@ class SchemaPack { return setTimeout(() => { // 2. perform validation for each identified matchedPath (schema endpoint) return async.map(matchedPaths, (matchedPath, pathsCallback) => { + const transactionPathVariables = _.get(transaction, 'request.url.variable', []), + localServers = matchedPath.path.hasOwnProperty('servers') ? + matchedPath.path.servers : + [], + serversPathVars = [...getServersPathVars(localServers), ...getServersPathVars(schema.servers)], + isNotAServerPathVar = (pathVarName) => { + return !serversPathVars.includes(pathVarName); + }; + matchedPath.unmatchedVariablesFromTransaction = []; // override path variable value with actual value present in transaction // as matched pathvariable contains key as value, as it is generated from url only _.forEach(matchedPath.pathVariables, (pathVar) => { - let mappedPathVar = _.find(_.get(transaction, 'request.url.variable', []), (transactionPathVar) => { - return transactionPathVar.key === pathVar.key; + const mappedPathVar = _.find(transactionPathVariables, (transactionPathVar) => { + let matched = transactionPathVar.key === pathVar.key; + if ( + !matched && + isNotAServerPathVar(transactionPathVar.key) && + !matchedPath.unmatchedVariablesFromTransaction.includes(transactionPathVar) + ) { + matchedPath.unmatchedVariablesFromTransaction.push(transactionPathVar); + } + return matched; }); pathVar.value = _.get(mappedPathVar, 'value', pathVar.value); // set _varMatched flag which represents if variable was found in transaction or not @@ -522,7 +539,7 @@ class SchemaPack { schemaUtils.checkMetadata(transaction, '$', matchedPath.path, matchedPath.name, options, cb); }, path: function(cb) { - schemaUtils.checkPathVariables(matchedPath.pathVariables, '$.request.url.variable', matchedPath.path, + schemaUtils.checkPathVariables(matchedPath, '$.request.url.variable', matchedPath.path, componentsAndPaths, options, schemaCache, jsonSchemaDialect, cb); }, queryparams: function(cb) { diff --git a/package-lock.json b/package-lock.json index 0034add..7f1947f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -334,6 +334,11 @@ "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.0.0-rc.6.tgz", "integrity": "sha512-dDnQizD94EdBwEj/fh3zPRa/HWCS9O5au2PuHhZBbuM3xWHxuaKzPBOEWze7Nn0xW68MIpZ7Xdyn1CoCpjKCuQ==" }, + "@faker-js/faker": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-5.5.3.tgz", + "integrity": "sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==" + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -483,9 +488,9 @@ "dev": true }, "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, "balanced-match": { "version": "1.0.0", @@ -583,15 +588,16 @@ "dev": true }, "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha1-tV5lWzHh6scJm+TAjCGWT84ubEk=", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", + "loupe": "^2.3.1", "pathval": "^1.1.1", "type-detect": "^4.0.5" } @@ -621,7 +627,7 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { @@ -1193,11 +1199,6 @@ "tmp": "^0.0.33" } }, - "faker": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz", - "integrity": "sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1241,7 +1242,7 @@ "file-type": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==" }, "fill-range": { "version": "7.0.1", @@ -1397,7 +1398,7 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-intrinsic": { @@ -1529,7 +1530,7 @@ "http-reasons": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/http-reasons/-/http-reasons-0.1.0.tgz", - "integrity": "sha1-qVPKZwB4Zp3eFCzomUAbnW6F07Q=" + "integrity": "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==" }, "http2-client": { "version": "1.3.5", @@ -2011,7 +2012,7 @@ "liquid-json": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/liquid-json/-/liquid-json-0.3.1.tgz", - "integrity": "sha1-kVWhgTbYprJhXl8W+aJEira1Duo=" + "integrity": "sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==" }, "locate-path": { "version": "5.0.0", @@ -2042,6 +2043,15 @@ "chalk": "^2.4.2" } }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -2070,9 +2080,9 @@ } }, "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-format": { "version": "2.0.1", @@ -2083,11 +2093,11 @@ } }, "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.48.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -2908,20 +2918,20 @@ } }, "postman-collection": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.0.0.tgz", - "integrity": "sha512-vDrXG/dclSu6RMqPqBz4ZqoQBwcj/a80sJYsQZmzWJ6dWgXiudPhwu6Vm3C1Hy7zX5W8A6am1Z6vb/TB4eyURA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/postman-collection/-/postman-collection-4.1.4.tgz", + "integrity": "sha512-3b/ZUrCIXRG3Eh3P6usiBYSZbCHTwMsJJ1l2RID/rdv/EC8YyhVS5PKGKdpYrRB69F/fETD9lOAuhvCwj0h71w==", "requires": { - "faker": "5.5.3", + "@faker-js/faker": "5.5.3", "file-type": "3.9.0", "http-reasons": "0.1.0", "iconv-lite": "0.6.3", "liquid-json": "0.3.1", "lodash": "4.17.21", "mime-format": "2.0.1", - "mime-types": "2.1.31", - "postman-url-encoder": "3.0.1", - "semver": "7.3.5", + "mime-types": "2.1.35", + "postman-url-encoder": "3.0.5", + "semver": "7.3.7", "uuid": "8.3.2" }, "dependencies": { @@ -2941,9 +2951,9 @@ } }, "postman-url-encoder": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.1.tgz", - "integrity": "sha512-dMPqXnkDlstM2Eya+Gw4MIGWEan8TzldDcUKZIhZUsJ/G5JjubfQPhFhVWKzuATDMvwvrWbSjF+8VmAvbu6giw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postman-url-encoder/-/postman-url-encoder-3.0.5.tgz", + "integrity": "sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==", "requires": { "punycode": "^2.1.1" } @@ -3107,9 +3117,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { "lru-cache": "^6.0.0" }, diff --git a/package.json b/package.json index 1610cf8..32ad2c0 100644 --- a/package.json +++ b/package.json @@ -118,14 +118,14 @@ "dependencies": { "ajv": "8.1.0", "ajv-formats": "2.1.1", - "async": "3.2.3", + "async": "3.2.4", "commander": "2.20.3", "js-yaml": "3.14.1", "json-schema-merge-allof": "0.8.1", "lodash": "4.17.21", "oas-resolver-browser": "2.5.6", "path-browserify": "1.0.1", - "postman-collection": "4.0.0", + "postman-collection": "4.1.4", "swagger2openapi": "7.0.8", "traverse": "0.6.6", "yaml": "1.10.2" @@ -133,7 +133,7 @@ "author": "Postman Labs ", "license": "Apache-2.0", "devDependencies": { - "chai": "4.3.4", + "chai": "4.3.6", "editorconfig": "0.15.3", "eslint": "5.16.0", "eslint-plugin-jsdoc": "3.8.0", diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-collection.json b/test/data/validationData/issues/issue#478/global-servers-path-variables-collection.json new file mode 100644 index 0000000..ba4cdf9 --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-collection.json @@ -0,0 +1,225 @@ +{ + "item": [ + { + "id": "1c9e80af-cc42-47c7-beae-f4b78e1bd3e1", + "name": "Info for a specific pet", + "request": { + "name": "Info for a specific pet", + "description": {}, + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "auth": null + }, + "response": [ + { + "id": "291f119a-d162-4676-83c0-91ce6595407b", + "name": "Expected response to a valid request", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"id\": -74238905,\n \"name\": \"et aliqua officia\",\n \"tag\": \"qui do\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "c00295c6-c859-46a4-8aae-8e2a6a2f64f3", + "name": "unexpected error", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"code\": -79318973,\n \"message\": \"ex c\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + } + ], + "event": [] + } + ], + "event": [], + "variable": [ + { + "description": { + "content": "Assigned by the service provider", + "type": "text/plain" + }, + "type": "any", + "value": "demo", + "key": "username" + }, + { + "description": { + "content": " (This can only be one of 8843,443)", + "type": "text/plain" + }, + "type": "any", + "value": "8843", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "type": "string", + "value": "https://{{username}}.myTestServer.com:{{port}}/{{basePath}}", + "key": "baseUrl" + } + ], + "info": { + "_postman_id": "a1d9a3d3-6195-46b3-95ff-016edd9b283d", + "name": "Swagger Petstore", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "", + "type": "text/plain" + } + } +} \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-spec.yaml b/test/data/validationData/issues/issue#478/global-servers-path-variables-spec.yaml new file mode 100644 index 0000000..7311261 --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-spec.yaml @@ -0,0 +1,78 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: https://{username}.myTestServer.com:{port}/{basePath} + description: Common url for all operations in this path + variables: + username: + default: demo + description: Assigned by the service provider + port: + enum: + - '8843' + - '443' + + default: '8843' + basePath: + default: v2 +paths: + /pets/{peterId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: peterId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-collection.json b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-collection.json new file mode 100644 index 0000000..aa97e95 --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-collection.json @@ -0,0 +1,225 @@ +{ + "item": [ + { + "id": "1c9e80af-cc42-47c7-beae-f4b78e1bd3e1", + "name": "Info for a specific pet", + "request": { + "name": "Info for a specific pet", + "description": {}, + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) A test id" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "auth": null + }, + "response": [ + { + "id": "291f119a-d162-4676-83c0-91ce6595407b", + "name": "Expected response to a valid request", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"id\": -74238905,\n \"name\": \"et aliqua officia\",\n \"tag\": \"qui do\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "c00295c6-c859-46a4-8aae-8e2a6a2f64f3", + "name": "unexpected error", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"code\": -79318973,\n \"message\": \"ex c\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + } + ], + "event": [] + } + ], + "event": [], + "variable": [ + { + "description": { + "content": "Assigned by the service provider", + "type": "text/plain" + }, + "type": "any", + "value": "demo", + "key": "username" + }, + { + "description": { + "content": " (This can only be one of 8843,443)", + "type": "text/plain" + }, + "type": "any", + "value": "8843", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "type": "string", + "value": "https://{{username}}.myTestServer.com:{{port}}/{{basePath}}", + "key": "baseUrl" + } + ], + "info": { + "_postman_id": "a1d9a3d3-6195-46b3-95ff-016edd9b283d", + "name": "Swagger Petstore", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "", + "type": "text/plain" + } + } +} \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-spec.yaml b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-spec.yaml new file mode 100644 index 0000000..17b1bfb --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-missing-one-spec.yaml @@ -0,0 +1,84 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: https://{username}.myTestServer.com:{port}/{basePath} + description: Common url for all operations in this path + variables: + username: + default: demo + description: Assigned by the service provider + port: + enum: + - '8843' + - '443' + + default: '8843' + basePath: + default: v2 +paths: + /pets/{peterId}/{correctName}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: peterId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + - name: correctName + in: path + required: true + description: A test id + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-collection.json b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-collection.json new file mode 100644 index 0000000..e5a4d83 --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-collection.json @@ -0,0 +1,233 @@ +{ + "item": [ + { + "id": "1c9e80af-cc42-47c7-beae-f4b78e1bd3e1", + "name": "Info for a specific pet", + "request": { + "name": "Info for a specific pet", + "description": {}, + "url": { + "path": [ + "pets", + ":petId", + "wrongNamedId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) A test id" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "wrongNamedId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "auth": null + }, + "response": [ + { + "id": "291f119a-d162-4676-83c0-91ce6595407b", + "name": "Expected response to a valid request", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"id\": -74238905,\n \"name\": \"et aliqua officia\",\n \"tag\": \"qui do\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "c00295c6-c859-46a4-8aae-8e2a6a2f64f3", + "name": "unexpected error", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "description": "Assigned by the service provider", + "type": "any", + "value": "{{username}}", + "key": "username" + }, + { + "description": " (This can only be one of 8843,443)", + "type": "any", + "value": "{{port}}", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "{{basePath}}", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"code\": -79318973,\n \"message\": \"ex c\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + } + ], + "event": [] + } + ], + "event": [], + "variable": [ + { + "description": { + "content": "Assigned by the service provider", + "type": "text/plain" + }, + "type": "any", + "value": "demo", + "key": "username" + }, + { + "description": { + "content": " (This can only be one of 8843,443)", + "type": "text/plain" + }, + "type": "any", + "value": "8843", + "key": "port" + }, + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "type": "string", + "value": "https://{{username}}.myTestServer.com:{{port}}/{{basePath}}", + "key": "baseUrl" + } + ], + "info": { + "_postman_id": "a1d9a3d3-6195-46b3-95ff-016edd9b283d", + "name": "Swagger Petstore", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "", + "type": "text/plain" + } + } +} \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-spec.yaml b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-spec.yaml new file mode 100644 index 0000000..17b1bfb --- /dev/null +++ b/test/data/validationData/issues/issue#478/global-servers-path-variables-two-vars-wrong-spec.yaml @@ -0,0 +1,84 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: https://{username}.myTestServer.com:{port}/{basePath} + description: Common url for all operations in this path + variables: + username: + default: demo + description: Assigned by the service provider + port: + enum: + - '8843' + - '443' + + default: '8843' + basePath: + default: v2 +paths: + /pets/{peterId}/{correctName}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: peterId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + - name: correctName + in: path + required: true + description: A test id + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/local-servers-path-variables-collection.json b/test/data/validationData/issues/issue#478/local-servers-path-variables-collection.json new file mode 100644 index 0000000..c257207 --- /dev/null +++ b/test/data/validationData/issues/issue#478/local-servers-path-variables-collection.json @@ -0,0 +1,195 @@ +{ + "item": [ + { + "id": "37bb14ea-6f8b-4aed-ba84-65dba00f2866", + "name": "Info for a specific pet", + "request": { + "name": "Info for a specific pet", + "description": {}, + "url": { + "protocol": "https", + "port": "{{port}}", + "path": [ + ":basePath", + "pets", + ":petId" + ], + "host": [ + "{{username}}", + "myTestServer", + "com" + ], + "query": [], + "variable": [ + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "auth": null + }, + "response": [ + { + "id": "788af746-16c3-45aa-a06e-e438c72199ba", + "name": "Expected response to a valid request", + "originalRequest": { + "url": { + "protocol": "https", + "port": "{{port}}", + "path": [ + ":basePath", + "pets", + ":petId" + ], + "host": [ + "{{username}}", + "myTestServer", + "com" + ], + "query": [], + "variable": [ + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"id\": -3764386,\n \"name\": \"minim nulla aliqua fugiat\",\n \"tag\": \"ex commodo irure\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "39776355-ccef-4e5b-921c-98ef03af5b71", + "name": "unexpected error", + "originalRequest": { + "url": { + "protocol": "https", + "port": "{{port}}", + "path": [ + ":basePath", + "pets", + ":petId" + ], + "host": [ + "{{username}}", + "myTestServer", + "com" + ], + "query": [], + "variable": [ + { + "description": { + "content": "", + "type": "text/plain" + }, + "type": "any", + "value": "v2", + "key": "basePath" + }, + { + "disabled": false, + "type": "any", + "value": "", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"code\": 77941721,\n \"message\": \"deserunt eu quis\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + } + ], + "event": [] + } + ], + "event": [], + "variable": [ + { + "type": "string", + "value": "http://petstore.swagger.io/v1", + "key": "baseUrl" + }, + { + "description": { + "content": "Assigned by the service provider", + "type": "text/plain" + }, + "type": "any", + "value": "demo", + "key": "username" + }, + { + "description": { + "content": " (This can only be one of 8843,443)", + "type": "text/plain" + }, + "type": "any", + "value": "8843", + "key": "port" + } + ], + "info": { + "_postman_id": "e1ba04ca-04d6-4993-bfd5-47b17c7e5f29", + "name": "Swagger Petstore", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "", + "type": "text/plain" + } + } +} \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/local-servers-path-variables-spec.yaml b/test/data/validationData/issues/issue#478/local-servers-path-variables-spec.yaml new file mode 100644 index 0000000..0ac4de3 --- /dev/null +++ b/test/data/validationData/issues/issue#478/local-servers-path-variables-spec.yaml @@ -0,0 +1,80 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets/{peterId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: peterId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + servers: + - url: https://{username}.myTestServer.com:{port}/{basePath} + description: Common url for all operations in this path + variables: + username: + default: demo + description: Assigned by the service provider + port: + enum: + - '8843' + - '443' + + default: '8843' + basePath: + default: v2 +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/path-variable-does-not-match-collection.json b/test/data/validationData/issues/issue#478/path-variable-does-not-match-collection.json new file mode 100644 index 0000000..a0cb8c2 --- /dev/null +++ b/test/data/validationData/issues/issue#478/path-variable-does-not-match-collection.json @@ -0,0 +1,146 @@ +{ + "item": [ + { + "id": "6e5b8ef6-6d5c-4e02-9f04-e26cb8b7b16e", + "name": "pets", + "description": { + "content": "", + "type": "text/plain" + }, + "item": [ + { + "id": "79c48c16-3de3-49ab-a92b-e86034a85ea8", + "name": "Info for a specific pet", + "request": { + "name": "Info for a specific pet", + "description": {}, + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "disabled": false, + "type": "any", + "value": "eu consectetur", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "auth": null + }, + "response": [ + { + "id": "897e412c-6070-4bb4-bdcd-ee21fe96af8e", + "name": "Expected response to a valid request", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "disabled": false, + "type": "any", + "value": "eu consectetur", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"id\": -29008976,\n \"name\": \"laborum nostrud\",\n \"tag\": \"et veni\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + }, + { + "id": "64c06a83-0235-47c3-b59a-d715a4fb0813", + "name": "unexpected error", + "originalRequest": { + "url": { + "path": [ + "pets", + ":petId" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [], + "variable": [ + { + "disabled": false, + "type": "any", + "value": "eu consectetur", + "key": "petId", + "description": "(Required) The id of the pet to retrieve" + } + ] + }, + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"code\": -96155831,\n \"message\": \"ex consectetur commodo\"\n}", + "cookie": [], + "_postman_previewlanguage": "json" + } + ], + "event": [] + } + ], + "event": [] + } + ], + "event": [], + "variable": [ + { + "type": "string", + "value": "http://petstore.swagger.io/v1", + "key": "baseUrl" + } + ], + "info": { + "_postman_id": "4cf22e75-4c05-4d03-85a8-4eca00651300", + "name": "Swagger Petstore", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "", + "type": "text/plain" + } + } +} \ No newline at end of file diff --git a/test/data/validationData/issues/issue#478/path-variable-does-not-match-spec.yaml b/test/data/validationData/issues/issue#478/path-variable-does-not-match-spec.yaml new file mode 100644 index 0000000..7d45f84 --- /dev/null +++ b/test/data/validationData/issues/issue#478/path-variable-does-not-match-spec.yaml @@ -0,0 +1,65 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets/{peterId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: peterId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/test/unit/validator.test.js b/test/unit/validator.test.js index 4093bda..548b5e6 100644 --- a/test/unit/validator.test.js +++ b/test/unit/validator.test.js @@ -1348,3 +1348,268 @@ describe('VALIDATE FUNCTION TESTS ', function () { }); }); +describe('validateTransaction method. Path variables matching validation (issue #478)', function() { + it('Should validate correctly while a path param in spec does not matches with collection' + + ' (issue#478)', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync(issueFolder + '/path-variable-does-not-match-spec.yaml', 'utf-8'), + issueCollection = fs.readFileSync(issueFolder + '/path-variable-does-not-match-collection.json', 'utf-8'), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(1); + expect(resultObj.mismatches[0].reasonCode).to.be.equal('MISSING_IN_REQUEST'); + expect(resultObj.mismatches[0].reason).to.be.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + done(); + }); + }); + + it('Should validate correctly while a path param in spec does not matches with collection' + + ' (issue#478), allowUrlPathVarMatching: true', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync(issueFolder + '/path-variable-does-not-match-spec.yaml', 'utf-8'), + issueCollection = fs.readFileSync(issueFolder + '/path-variable-does-not-match-collection.json', 'utf-8'), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: true }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(0); + done(); + }); + }); + + it('Should validate correctly when a path param in spec does not matches with collection ' + + 'and there are path variables in local servers object (issue#478)', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync(issueFolder + '/local-servers-path-variables-spec.yaml', 'utf-8'), + issueCollection = fs.readFileSync(issueFolder + '/local-servers-path-variables-collection.json', 'utf-8'), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(1); + expect(resultObj.mismatches[0].reason).to.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[0].reasonCode).to.equal('MISSING_IN_REQUEST'); + done(); + }); + }); + + it('Should validate correctly when a path param in spec does not matches with collection ' + + 'and there are path variables in global servers object (issue#478)', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync(issueFolder + '/global-servers-path-variables-spec.yaml', 'utf-8'), + issueCollection = fs.readFileSync(issueFolder + '/global-servers-path-variables-collection.json', 'utf-8'), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack({ type: 'string', data: issueSpec }, { allowUrlPathVarMatching: false }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(1); + expect(resultObj.mismatches[0].reason).to.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[0].reasonCode).to.equal('MISSING_IN_REQUEST'); + done(); + }); + }); + + it('Should validate correctly when a path param in spec does not matches with collection ' + + 'and there are path variables in global servers object (issue#478), suggestAvailableFixes: true', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync(issueFolder + '/global-servers-path-variables-spec.yaml', 'utf-8'), + issueCollection = fs.readFileSync(issueFolder + '/global-servers-path-variables-collection.json', 'utf-8'), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack( + { type: 'string', data: issueSpec }, + { allowUrlPathVarMatching: false, suggestAvailableFixes: true }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(1); + expect(resultObj.mismatches[0].reason).to.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[0].reasonCode).to.equal('MISSING_IN_REQUEST'); + expect(resultObj.mismatches[0].suggestedFix.actualValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.actualValue.key).to.be.equal('petId'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue.key).to.be.equal('peterId'); + expect(resultObj.mismatches[0].suggestedFix.key).to.be.equal('peterId'); + done(); + }); + }); + + it('Should validate correctly when two path params in spec does not matches with collection ' + + 'and there are path variables in global servers object (issue#478), suggestAvailableFixes: true', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-wrong-spec.yaml', 'utf-8' + ), + issueCollection = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-wrong-collection.json', 'utf-8' + ), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack( + { type: 'string', data: issueSpec }, + { allowUrlPathVarMatching: false, suggestAvailableFixes: true }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(2); + expect(resultObj.mismatches[0].reason).to.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[0].reasonCode).to.equal('MISSING_IN_REQUEST'); + expect(resultObj.mismatches[1].reason).to.equal( + 'The wrongNamedId path variable does not match with path variable expected (correctName)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[1].reasonCode).to.equal('MISSING_IN_REQUEST'); + + expect(resultObj.mismatches[0].suggestedFix.actualValue.key).to.be.equal('petId'); + expect(resultObj.mismatches[0].suggestedFix.actualValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue.key).to.be.equal('peterId'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.key).to.be.equal('peterId'); + + expect(resultObj.mismatches[1].suggestedFix.actualValue.key).to.be.equal('wrongNamedId'); + expect(resultObj.mismatches[1].suggestedFix.actualValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[1].suggestedFix.suggestedValue.key).to.be.equal('correctName'); + expect(resultObj.mismatches[1].suggestedFix.suggestedValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[1].suggestedFix.key).to.be.equal('correctName'); + done(); + }); + }); + + it('Should validate correctly when one path param in spec does not matches with collection ' + + ', global servers and one path var is not provided (issue#478), suggestAvailableFixes: true', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-missing-one-spec.yaml', 'utf-8' + ), + issueCollection = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-missing-one-collection.json', 'utf-8' + ), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack( + { type: 'string', data: issueSpec }, + { allowUrlPathVarMatching: false, suggestAvailableFixes: true }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(2); + expect(resultObj.mismatches[0].reason).to.equal( + 'The petId path variable does not match with path variable expected (peterId)' + + ' in the schema at this position' + ); + expect(resultObj.mismatches[0].reasonCode).to.equal('MISSING_IN_REQUEST'); + expect(resultObj.mismatches[1].reason).to.equal( + 'The required path variable "correctName" was not found in the transaction' + ); + expect(resultObj.mismatches[1].reasonCode).to.equal('MISSING_IN_REQUEST'); + + expect(resultObj.mismatches[0].suggestedFix.actualValue.key).to.be.equal('petId'); + expect(resultObj.mismatches[0].suggestedFix.actualValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue.key).to.be.equal('peterId'); + expect(resultObj.mismatches[0].suggestedFix.suggestedValue).to.be.an('object') + .to.have.all.keys('key', 'value', 'description'); + expect(resultObj.mismatches[0].suggestedFix.key).to.be.equal('peterId'); + + expect(resultObj.mismatches[1].suggestedFix.actualValue).to.be.equal(null); + expect(resultObj.mismatches[1].suggestedFix.suggestedValue).to.be.an('object') + .to.include.keys(['description', 'key', 'value']); + expect(resultObj.mismatches[1].suggestedFix.key).to.be.equal('correctName'); + done(); + }); + }); + + it('Should validate correctly when one path param in spec does not matches with collection ' + + ', global servers and one path var is not provided (issue#478), ' + + 'suggestAvailableFixes: true, allowUrlPathVarMatching: true', function(done) { + let issueFolder = path.join(__dirname, VALIDATION_DATA_FOLDER_PATH + '/issues/issue#478'), + issueSpec = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-missing-one-spec.yaml', 'utf-8' + ), + issueCollection = fs.readFileSync( + issueFolder + '/global-servers-path-variables-two-vars-missing-one-collection.json', 'utf-8' + ), + resultObj, + historyRequest = [], + schemaPack = new Converter.SchemaPack( + { type: 'string', data: issueSpec }, + { allowUrlPathVarMatching: true, suggestAvailableFixes: true }); + + getAllTransactions(JSON.parse(issueCollection), historyRequest); + + schemaPack.validateTransaction(historyRequest, (err, result) => { + // Schema is sample petsore with one of parameter as empty, expect no mismatch / error + expect(err).to.be.null; + expect(result).to.be.an('object'); + resultObj = result.requests[historyRequest[0].id].endpoints[0]; + expect(resultObj.mismatches).to.have.length(0); + done(); + }); + }); +});