diff --git a/lib/options.js b/lib/options.js index a6ecdd4..ac62c7a 100644 --- a/lib/options.js +++ b/lib/options.js @@ -294,7 +294,7 @@ module.exports = { type: 'boolean', default: false, description: 'Select whether to include Webhooks in the generated collection', - external: true, + external: false, usage: ['CONVERSION'], supportedIn: [VERSION31] } diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index 7e77ce7..b3ff35a 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -205,29 +205,6 @@ function safeSchemaFaker(oldSchema, resolveTo, resolveFor, parameterSourceOption } } -/** -* concatenates webhooks and paths into a single object and marks the property kind -* to identify the tyype -* @param {object} schema openapi query params object -* @returns {object} the concatenation of paths and webhooks -*/ -function concatPathsAndWebhooks(schema) { - let schemaPathItems = {}, - deepCopy = _.cloneDeep(schema); - _.forOwn(deepCopy.paths, (pathItemObject) => { - pathItemObject.kind = 'paths'; - }); - schemaPathItems = deepCopy.paths; - - if (deepCopy.webhooks) { - _.forOwn(deepCopy.webhooks, (webhookItemObject) => { - webhookItemObject.kind = 'webhooks'; - }); - schemaPathItems = Object.assign(schemaPathItems, deepCopy.webhooks); - } - return schemaPathItems; -} - module.exports = { safeSchemaFaker: safeSchemaFaker, @@ -2614,11 +2591,9 @@ module.exports = { pathToMatch, matchedPath, matchedPathJsonPath, - schemaPathItems, + schemaPathItems = schema.paths, filteredPathItemsArray = []; - schemaPathItems = concatPathsAndWebhooks(schema); - // Return no matches for invalid url (if unable to decode parsed url) try { pathToMatch = decodeURI(parsedUrl.pathname); @@ -2689,7 +2664,6 @@ module.exports = { _.each(filteredPathItemsArray, (fp) => { let path = fp.path, pathItemObject = fp.pathItem, - kind = pathItemObject.kind, score = fp.matchScore, pathVars = fp.pathVars; @@ -2699,7 +2673,7 @@ module.exports = { return true; } - matchedPathJsonPath = `$.${kind}[${path}]`; + matchedPathJsonPath = `$.paths[${path}]`; // filter empty parameters matchedPath.parameters = _.reduce(matchedPath.parameters, (accumulator, param) => { @@ -4687,28 +4661,20 @@ module.exports = { */ getMissingSchemaEndpoints: function (schema, matchedEndpoints, components, options, schemaCache) { let endpoints = [], + schemaPaths = schema.paths, rootCollectionVariables, - schemaJsonPath, - schemaPathItems; - schemaPathItems = concatPathsAndWebhooks(schema); - _.forEach(schemaPathItems, (schemaPathObj, schemaPath) => { + schemaJsonPath; + + // collection variables generated for resolving for baseUrl and variables + rootCollectionVariables = this.convertToPmCollectionVariables( + schema.baseUrlVariables, + 'baseUrl', + schema.baseUrl + ); + + _.forEach(schemaPaths, (schemaPathObj, schemaPath) => { _.forEach(_.keys(schemaPathObj), (pathKey) => { - schemaJsonPath = `$.${schemaPathObj.kind}[${schemaPath}].${_.toLower(pathKey)}`; - if (schemaPathObj.kind === 'webhooks') { - rootCollectionVariables = this.convertToPmCollectionVariables( - schema.baseUrlVariables, - schemaPath.startsWith('/') ? this.cleanWebhookName(schemaPath.slice(1)) : this.cleanWebhookName(schemaPath), - schema.baseUrl - ); - } - else { - // collection variables generated for resolving for baseUrl and variables - rootCollectionVariables = this.convertToPmCollectionVariables( - schema.baseUrlVariables, - 'baseUrl', - schema.baseUrl - ); - } + schemaJsonPath = `$.paths[${schemaPath}].${_.toLower(pathKey)}`; if (METHODS.includes(pathKey) && !matchedEndpoints.includes(schemaJsonPath)) { let mismatchObj = { property: 'ENDPOINT', diff --git a/test/unit/validator.test.js b/test/unit/validator.test.js index 5f7d977..a1f9655 100644 --- a/test/unit/validator.test.js +++ b/test/unit/validator.test.js @@ -1074,146 +1074,5 @@ describe('VALIDATE FUNCTION TESTS ', function () { expect(result[1].name).to.eql('GET /lookups'); done(); }); - - it('Should find matching request when comes from a webhook', function (done) { - let schema = { - paths: { - '/lookups': { - 'get': { 'summary': 'Lookup Job Values' } - }, - '/{jobid}': { - 'get': { - 'summary': 'Get Job by ID', - 'parameters': [ - { - 'in': 'path', - 'name': 'jobid', - 'schema': { - 'type': 'string' - }, - 'required': true, - 'description': 'Unique identifier for a job to retrieve.', - 'example': '{{jobid}}' - } - ] - } - } - }, - webhooks: { - '/ACCOUNT_CLOSED': { - post: { - description: 'This notification is sent when an account has been closed.', - operationId: 'post-ACCOUNT_CLOSED', - requestBody: { - content: { - 'application/json': { - examples: { - accountClosed: { - $ref: '#/components/examples/post-ACCOUNT_CLOSED-accountClosed' - } - }, - schema: { - $ref: '#/components/schemas/AccountCloseNotification' - } - } - } - }, - responses: { - '200': { - content: { - 'application/json': { - examples: { - accountClosed: { - $ref: '#/components/examples/WebhookAck' - } - }, - schema: { - $ref: '#/components/schemas/NotificationResponse' - } - } - }, - description: 'OK - the request has succeeded.' - } - }, - security: [ - { - BasicAuth: [ - ] - }, - { - ApiKeyAuth: [ - ] - } - ], - summary: 'Triggered upon the closure of an account.', - tags: [ - 'Accounts' - ], - 'x-groupName': 'Accounts', - 'x-sortIndex': 3, - parameters: [ - ], - schemaPathName: '/ACCOUNT_CLOSED' - }, - parameters: [ - ] - }, - '/ACCOUNT_CREATED': { - post: { - description: 'This notification is sent when an account has been created.', - operationId: 'post-ACCOUNT_CREATED', - requestBody: { - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/AccountCreateNotification' - } - } - } - }, - responses: { - '200': { - content: { - 'application/json': { - schema: { - $ref: '#/components/schemas/NotificationResponse' - } - } - }, - description: 'OK - the request has succeeded.' - } - }, - security: [ - { - BasicAuth: [ - ] - }, - { - ApiKeyAuth: [ - ] - } - ], - summary: 'Triggered upon the creation of an account.', - tags: [ - 'Accounts' - ], - 'x-groupName': 'Accounts', - 'x-sortIndex': 1 - }, - parameters: [ - ] - } - } - }, - schemaPath = '{{baseUrl}}/ACCOUNT_CLOSED', - result; - - result = schemaUtils.findMatchingRequestFromSchema('POST', schemaPath, schema, { strictRequestMatching: true }); - - expect(result).to.have.lengthOf(1); - expect(result[0].name).to.eql('POST /ACCOUNT_CLOSED'); - expect(result[0].jsonPath).to.eql('$.webhooks[/ACCOUNT_CLOSED].post'); - done(); - }); }); }); diff --git a/test/unit/x31schemapack.test.js b/test/unit/x31schemapack.test.js index 38db515..9b673df 100644 --- a/test/unit/x31schemapack.test.js +++ b/test/unit/x31schemapack.test.js @@ -166,113 +166,6 @@ describe('Openapi 3.1 schema pack validateTransactions', function() { }); }); - it('Should not generate any mismatch webhook return 4 missing endpoints from paths', function() { - const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + - '/simpleCollectionsWithWebhooksNoPaths.json'), - collectionData = fs.readFileSync(collectionSource, 'utf8'), - schemaSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/simpleCollectionsWithWebhooksSpec.yaml'), - schemaData = fs.readFileSync(schemaSource, 'utf8'), - validator = new SchemaPack({ - type: 'string', - data: schemaData - }); - let transactions = [], - failRequests = []; - getAllTransactions(JSON.parse(collectionData), transactions); - - validator.validateTransaction(transactions, (err, result) => { - let requestIds = Object.keys(result.requests); - expect(err).to.be.null; - requestIds.forEach((requestId) => { - if (result.requests[requestId].endpoints[0].matched === false) { - failRequests.push(result.requests[requestId]); - } - }); - expect(failRequests).to.be.empty; - expect(result.missingEndpoints.length).to.equal(4); - }); - }); - - it('Should generate mismatch with errors in paths valid webhooks', function() { - const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + - '/simpleCollectionsWithWebhooksErrorsInPaths.json'), - collectionData = fs.readFileSync(collectionSource, 'utf8'), - schemaSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/simpleCollectionsWithWebhooksSpec.yaml'), - schemaData = fs.readFileSync(schemaSource, 'utf8'), - validator = new SchemaPack({ - type: 'string', - data: schemaData - }); - let transactions = [], - failRequests = []; - getAllTransactions(JSON.parse(collectionData), transactions); - - validator.validateTransaction(transactions, (err, result) => { - let requestIds = Object.keys(result.requests); - expect(err).to.be.null; - requestIds.forEach((requestId) => { - if (result.requests[requestId].endpoints[0].matched === false) { - failRequests.push(result.requests[requestId]); - } - }); - expect(failRequests.length).to.equal(4); - expect(result.missingEndpoints.length).to.equal(0); - }); - }); - - it('Should not generate mismatch with valid webhooks and paths', function() { - const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + - '/simpleCollectionsWithWebhooks.json'), - collectionData = fs.readFileSync(collectionSource, 'utf8'), - schemaSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/simpleCollectionsWithWebhooksSpec.yaml'), - schemaData = fs.readFileSync(schemaSource, 'utf8'), - validator = new SchemaPack({ - type: 'string', - data: schemaData - }, { suggestAvailableFixes: true }); - let transactions = [], - failRequests = []; - getAllTransactions(JSON.parse(collectionData), transactions); - - validator.validateTransaction(transactions, (err, result) => { - let requestIds = Object.keys(result.requests); - expect(err).to.be.null; - requestIds.forEach((requestId) => { - if (result.requests[requestId].endpoints[0].matched === false) { - failRequests.push(result.requests[requestId]); - } - }); - expect(failRequests.length).to.equal(0); - expect(result.missingEndpoints.length).to.equal(0); - }); - }); - - it('Should generate mismatch with invalid webhook', function() { - const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + - '/simpleCollectionsWithWebhooksErrorWebhook.json'), - collectionData = fs.readFileSync(collectionSource, 'utf8'), - schemaSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/simpleCollectionsWithWebhooksSpec.yaml'), - schemaData = fs.readFileSync(schemaSource, 'utf8'), - validator = new SchemaPack({ - type: 'string', - data: schemaData - }, { suggestAvailableFixes: true }); - let transactions = [], - failRequests = []; - getAllTransactions(JSON.parse(collectionData), transactions); - - validator.validateTransaction(transactions, (err, result) => { - let requestIds = Object.keys(result.requests); - expect(err).to.be.null; - requestIds.forEach((requestId) => { - if (result.requests[requestId].endpoints[0].matched === false) { - failRequests.push(result.requests[requestId]); - } - }); - expect(failRequests.length).to.equal(1); - expect(result.missingEndpoints.length).to.equal(0); - }); - }); it('Should not generate any mismatch with a correct file with null type', function() { const collectionSource = path.join(__dirname, OPENAPI_31_COLLECTIONS + '/compositeSchemaNullableCollection.json'),