From 1530142a2addd4fb99e84f0c60254a3f0301c116 Mon Sep 17 00:00:00 2001 From: Vlad Barosan Date: Thu, 15 Mar 2018 14:53:01 -0700 Subject: [PATCH] Add test and address feedback --- lib/util/utils.js | 82 ++++++++++++++++++++-------------- lib/validators/specResolver.js | 7 ++- package-lock.json | 2 +- test/liveValidatorTests.js | 26 ++++++++++- 4 files changed, 80 insertions(+), 37 deletions(-) diff --git a/lib/util/utils.js b/lib/util/utils.js index 7373424a..eb8b99ef 100644 --- a/lib/util/utils.js +++ b/lib/util/utils.js @@ -759,42 +759,58 @@ function isPropertyRequired(propName, model) { */ exports.statusCodeStringToStatusCode = lodash.invert(lodash.mapValues(http.STATUS_CODES, value => { return value.replace(/ |-/g, "").toLowerCase(); })); - /** - * Models an ARM cloud error. + * Models an ARM cloud error schema. */ -exports.CloudError = { +exports.CloudErrorSchema = { description: "Error response describing why the operation failed.", schema: { - properties: { - error: { - properties: { - code: { - type: "string", - description: "An identifier for the error. Codes are invariant and are intended to be consumed programmatically." - }, - message: { - type: "string", - description: "A message describing the error, intended to be suitable for display in a user interface." - }, - target: { - type: "string", - description: "The target of the particular error. For example, the name of the property in error." - }, - details: { - type: "array", - items: { type: "object" }, - description: "A list of additional details about the error." - }, - additionalInfo: { - type: "array", - items: { type: "object" }, - description: "A list of additional info about an error." - } - }, - additionalProperties: false - } - }, - additionalProperties: false + "$ref": "#/definitions/CloudErrorWrapper" } +}; + +/** + * Models an ARM cloud error wrapper. + */ +exports.CloudErrorWrapper = { + type: "object", + properties: { + error: { + "$ref": "#/definitions/CloudError" + } + }, + additionalProperties: false +}; + +/** + * Models a Cloud Error + */ +exports.CloudError = { + type: "object", + properties: { + code: { + type: "string", + description: "An identifier for the error. Codes are invariant and are intended to be consumed programmatically." + }, + message: { + type: "string", + description: "A message describing the error, intended to be suitable for display in a user interface." + }, + target: { + type: "string", + description: "The target of the particular error. For example, the name of the property in error." + }, + details: { + type: "array", + items: { type: "object" }, + description: "A list of additional details about the error." + }, + additionalInfo: { + type: "array", + items: { type: "object" }, + description: "A list of additional info about an error." + } + }, + required: ["code", "message"], + additionalProperties: false }; \ No newline at end of file diff --git a/lib/validators/specResolver.js b/lib/validators/specResolver.js index 90a5cd78..af62a395 100644 --- a/lib/validators/specResolver.js +++ b/lib/validators/specResolver.js @@ -607,12 +607,15 @@ class SpecResolver { modelImplicitDefaultResponse() { let self = this; let spec = self.specInJson; + if (!spec.definitions.CloudError) { + spec.definitions.CloudErrorWrapper = utils.CloudErrorWrapper; + spec.definitions.CloudError = utils.CloudError; + } for (let pathObj of utils.getValues(spec.paths)) { for (let operation of utils.getValues(pathObj)) { - // going through responses if (operation.responses && !operation.responses.default) { - operation.responses.default = utils.CloudError; + operation.responses.default = utils.CloudErrorSchema; } } } diff --git a/package-lock.json b/package-lock.json index 014ca209..e57867b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2333,7 +2333,7 @@ } }, "sway": { - "version": "github:amarzavery/sway#21d2160311380134e31e252a7e1ce1268441c8c3", + "version": "github:amarzavery/sway#6fe07a9dc10d301b84b985c8f0a27eed7bb0e4c9", "requires": { "debug": "3.1.0", "faker": "4.1.0", diff --git a/test/liveValidatorTests.js b/test/liveValidatorTests.js index 4f519f5f..1be41cf3 100644 --- a/test/liveValidatorTests.js +++ b/test/liveValidatorTests.js @@ -6,7 +6,8 @@ var assert = require('assert'), os = require('os'), glob = require('glob'), LiveValidator = require('../lib/validators/liveValidator.js'), - Constants = require('../lib/util/constants'); + Constants = require('../lib/util/constants'), + utils = require('../lib/util/utils'); const livePaths = glob.sync(path.join(__dirname, 'liveValidation/swaggers/**/live/*.json')); describe('Live Validator', function () { @@ -260,6 +261,29 @@ describe('Live Validator', function () { done(); }).catch(done); }); + it('it should create an implicit default response and find it', function (done) { + let options = { + "directory": "./test/liveValidation/swaggers/specification/scenarios", + "swaggerPathsPattern": "**/*.json", + "shouldModelImplicitDefaultResponse": true + }; + let apiUrl = "https://management.azure.com/subscriptions/subscriptionId/providers/Microsoft.Test/storageAccounts?api-version=2016-01-01"; + + let validator = new LiveValidator(options); + validator.initialize().then(() => { + // Operations to match is StorageAccounts_List + let operations = validator.cache['microsoft.test']['2016-01-01']['post']; + + for (const operation of operations) { + assert(operation.responses.default); + assert.deepEqual(operation.responses.default.schema.properties.error, utils.CloudError); + } + done(); + }).catch((err) => { + assert.ifError(err); + done(); + }).catch(done); + }); }); describe('Initialize cache and validate', function () {