From d7da425e95a8858ece6200b8d0c7d2a3f4dd46a7 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Tue, 26 Aug 2014 01:30:59 -0700 Subject: [PATCH 1/5] added support for https://github.com/reverb/swagger-spec/issues/107 --- .../json/resources/reusableParameters.json | 103 ++++++++++++++++++ schemas/v2.0/schema.json | 18 ++- src/test/scala/ResourcesTest.scala | 9 ++ src/test/scala/TestBase.scala | 2 +- 4 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 fixtures/v2.0/json/resources/reusableParameters.json diff --git a/fixtures/v2.0/json/resources/reusableParameters.json b/fixtures/v2.0/json/resources/reusableParameters.json new file mode 100644 index 0000000000..4ee6778e1c --- /dev/null +++ b/fixtures/v2.0/json/resources/reusableParameters.json @@ -0,0 +1,103 @@ +{ + "swagger": 2.0, + "info": { + "version": "1.0.9-abcd", + "title": "Swagger Sample API", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://helloreverb.com/terms/", + "contact": { + "name": "wordnik api team", + "url": "http://developer.wordnik.com" + }, + "license": { + "name": "Creative Commons 4.0 International", + "url": "http://creativecommons.org/licenses/by/4.0/" + } + }, + "host": "my.api.com", + "basePath": "/v1", + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json", + "application/xml" + ], + "paths": { + "/pets/{id}": { + "get": { + "description": "Returns pets based on ID", + "summary": "Find pets by ID", + "operationId": "getPetsById", + "parameters": [ + { "$ref": "#/definitions/skipParam" }, + { "$ref": "#/definitions/limitParam" } + ], + "responses": { + "200": { + "description": "pet response", + "schema": { + "type": "array", + "items": { + "$ref": "Pet" + } + } + }, + "default": { + "description": "error payload", + "schema": { + "$ref": "ErrorModel" + } + } + } + } + } + }, + "definitions": { + "skipParam": { + "name": "skip", + "in": "query", + "description": "number of items to skip", + "required": true, + "type": "integer", + "format": "int32" + }, + "limitParam": { + "name": "limit", + "in": "query", + "description": "max records to return", + "required": true, + "type": "integer", + "format": "int32" + }, + "Pet": { + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "ErrorModel": { + "required": [ "code", "message" ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } +} diff --git a/schemas/v2.0/schema.json b/schemas/v2.0/schema.json index 9c54a988b0..9edde3b62e 100644 --- a/schemas/v2.0/schema.json +++ b/schemas/v2.0/schema.json @@ -151,7 +151,18 @@ "minItems": 1, "additionalItems": false, "items": { - "$ref": "#/definitions/parameter" + "oneOf": [ + { "$ref": "#/definitions/parameter" }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "$ref": { + "type": "string" + } + } + } + ] } }, "responses": { @@ -506,7 +517,10 @@ "type": "object", "description": "One or more JSON objects describing the schemas being consumed and produced by the API.", "additionalProperties": { - "$ref": "#/definitions/schema" + "oneOf": [ + { "$ref": "#/definitions/schema" }, + { "$ref": "#/definitions/parameter" } + ] } }, "security": { diff --git a/src/test/scala/ResourcesTest.scala b/src/test/scala/ResourcesTest.scala index 627ecdafab..5c624cafcd 100644 --- a/src/test/scala/ResourcesTest.scala +++ b/src/test/scala/ResourcesTest.scala @@ -107,6 +107,15 @@ class ResourcesTest extends FlatSpec with ShouldMatchers with TestBase { report.isSuccess should be (true) } + it should "validate a spec with reusable parameters" in { + val json = Source.fromFile("fixtures/v2.0/json/resources/reusableParameters.json").mkString + val data = JsonLoader.fromString(json) + val report = jsonSchema.validate(data) + if(report.isSuccess == false) + println(report) + report.isSuccess should be (true) + } + it should "validate the wordnik petstore" in { val json = Source.fromFile("examples/v2.0/json/petstore.json").mkString val data = JsonLoader.fromString(json) diff --git a/src/test/scala/TestBase.scala b/src/test/scala/TestBase.scala index 5af09be90c..932b4a38bf 100644 --- a/src/test/scala/TestBase.scala +++ b/src/test/scala/TestBase.scala @@ -8,7 +8,7 @@ import scala.io.Source **/ trait TestBase { val mapper = new ObjectMapper - val host = "https://raw.githubusercontent.com/reverb/swagger-spec/master/schemas/v2.0/schema.json" + val host = "https://raw.githubusercontent.com/fehguy/swagger-spec/master/schemas/v2.0/schema.json" // val host = "http://localhost:8000/schema.json" def readSchema(makeQualified: Boolean = true) = { From dd9d2790582e974e2f4ed11fae757caa97360ad2 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Tue, 26 Aug 2014 01:31:35 -0700 Subject: [PATCH 2/5] reverted test path --- src/test/scala/TestBase.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/TestBase.scala b/src/test/scala/TestBase.scala index 932b4a38bf..5af09be90c 100644 --- a/src/test/scala/TestBase.scala +++ b/src/test/scala/TestBase.scala @@ -8,7 +8,7 @@ import scala.io.Source **/ trait TestBase { val mapper = new ObjectMapper - val host = "https://raw.githubusercontent.com/fehguy/swagger-spec/master/schemas/v2.0/schema.json" + val host = "https://raw.githubusercontent.com/reverb/swagger-spec/master/schemas/v2.0/schema.json" // val host = "http://localhost:8000/schema.json" def readSchema(makeQualified: Boolean = true) = { From ece64099fb2eeb2e02f92dbc3fcdc7c4dd7739d1 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Fri, 29 Aug 2014 10:09:36 -0700 Subject: [PATCH 3/5] updated per #107 --- schemas/v2.0/schema.json | 173 +++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 87 deletions(-) diff --git a/schemas/v2.0/schema.json b/schemas/v2.0/schema.json index ee1e104e48..5a74462033 100644 --- a/schemas/v2.0/schema.json +++ b/schemas/v2.0/schema.json @@ -4,7 +4,90 @@ "type": "object", "required": [ "swagger", "info", "paths" ], - + "additionalProperties": false, + "patternProperties": { + "^x-": { + "$ref": "#/definitions/vendorExtension" + } + }, + "properties": { + "swagger": { + "type": "number", + "enum": [ 2.0 ], + "description": "The Swagger version of this document." + }, + "info": { + "$ref": "#/definitions/info" + }, + "externalDocs": { + "$ref": "#/definitions/externalDocs" + }, + "host": { + "type": "string", + "format": "uri", + "pattern": "^((?!\\:\/\/).)*$", + "description": "The fully qualified URI to the host of the API." + }, + "basePath": { + "type": "string", + "pattern": "^/", + "description": "The base path to the API. Example: '/api'." + }, + "schemes": { + "type": "array", + "description": "The transfer protocol of the API.", + "items": { + "type": "string", + "enum": [ "http", "https", "ws", "wss" ] + } + }, + "consumes": { + "type": "array", + "description": "A list of MIME types accepted by the API.", + "items": { + "$ref": "#/definitions/mimeType" + } + }, + "produces": { + "type": "array", + "description": "A list of MIME types the API can produce.", + "items": { + "$ref": "#/definitions/mimeType" + } + }, + "paths": { + "type": "object", + "description": "Relative paths to the individual endpoints. They must be relative to the 'basePath'.", + "patternProperties": { + "^x-": { + "$ref": "#/definitions/vendorExtension" + }, + "^/.*[^\/]$": { + "$ref": "#/definitions/pathItem" + } + }, + "additionalProperties": false + }, + "definitions": { + "type": "object", + "description": "One or more JSON objects describing the schemas being consumed and produced by the API.", + "additionalProperties": { "$ref": "#/definitions/schema" }, + }, + "parameters": { + "type": "object", + "description": "One or more JSON representations for parameters", + "additionalProperties": { "$ref": "#/definitions/parameter" } + }, + "security": { + "$ref": "#/definitions/security" + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/definitions/tag" + } + } + }, "definitions": { "externalDocs": { "type": "object", @@ -262,7 +345,7 @@ "properties": { "type": { "type": "string", - "enum": [ "string", "number", "boolean", "integer", "array" ] + "enum": [ "string", "number", "boolean", "integer", "array", "file" ] }, "format": { "type": "string" @@ -310,7 +393,7 @@ }, "type": { "type": "string", - "enum": [ "string", "number", "boolean", "integer", "array", "file" ] + "enum": [ "string", "number", "boolean", "integer", "array" ] }, "format": { "type": "string" @@ -448,89 +531,5 @@ } } } - }, - "additionalProperties": false, - "patternProperties": { - "^x-": { - "$ref": "#/definitions/vendorExtension" - } - }, - "properties": { - "swagger": { - "type": "number", - "enum": [ 2.0 ], - "description": "The Swagger version of this document." - }, - "info": { - "$ref": "#/definitions/info" - }, - "externalDocs": { - "$ref": "#/definitions/externalDocs" - }, - "host": { - "type": "string", - "format": "uri", - "pattern": "^((?!\\:\/\/).)*$", - "description": "The fully qualified URI to the host of the API." - }, - "basePath": { - "type": "string", - "pattern": "^/", - "description": "The base path to the API. Example: '/api'." - }, - "schemes": { - "type": "array", - "description": "The transfer protocol of the API.", - "items": { - "type": "string", - "enum": [ "http", "https", "ws", "wss" ] - } - }, - "consumes": { - "type": "array", - "description": "A list of MIME types accepted by the API.", - "items": { - "$ref": "#/definitions/mimeType" - } - }, - "produces": { - "type": "array", - "description": "A list of MIME types the API can produce.", - "items": { - "$ref": "#/definitions/mimeType" - } - }, - "paths": { - "type": "object", - "description": "Relative paths to the individual endpoints. They must be relative to the 'basePath'.", - "patternProperties": { - "^x-": { - "$ref": "#/definitions/vendorExtension" - }, - "^/.*[^\/]$": { - "$ref": "#/definitions/pathItem" - } - }, - "additionalProperties": false - }, - "definitions": { - "type": "object", - "description": "One or more JSON objects describing the schemas being consumed and produced by the API.", - "additionalProperties": { - "oneOf": [ - { "$ref": "#/definitions/schema" }, - { "$ref": "#/definitions/parameter" } - ] - } - }, - "security": { - "$ref": "#/definitions/security" - }, - "tags": { - "type": "array", - "items": { - "$ref": "#/definitions/tag" - } - } } } From eff9ff130ba562d3abec06c8831aacc8dc970ab7 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Fri, 29 Aug 2014 10:37:20 -0700 Subject: [PATCH 4/5] removed extra comma --- schemas/v2.0/schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/v2.0/schema.json b/schemas/v2.0/schema.json index 5a74462033..94785da6dc 100644 --- a/schemas/v2.0/schema.json +++ b/schemas/v2.0/schema.json @@ -71,7 +71,7 @@ "definitions": { "type": "object", "description": "One or more JSON objects describing the schemas being consumed and produced by the API.", - "additionalProperties": { "$ref": "#/definitions/schema" }, + "additionalProperties": { "$ref": "#/definitions/schema" } }, "parameters": { "type": "object", From 3b9fa2a69b699b5939100068ce9c3cf4a21404ac Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Fri, 29 Aug 2014 10:43:19 -0700 Subject: [PATCH 5/5] fixed to support updated schema --- fixtures/v2.0/json/resources/reusableParameters.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fixtures/v2.0/json/resources/reusableParameters.json b/fixtures/v2.0/json/resources/reusableParameters.json index 4ee6778e1c..77abe0ebf6 100644 --- a/fixtures/v2.0/json/resources/reusableParameters.json +++ b/fixtures/v2.0/json/resources/reusableParameters.json @@ -34,8 +34,8 @@ "summary": "Find pets by ID", "operationId": "getPetsById", "parameters": [ - { "$ref": "#/definitions/skipParam" }, - { "$ref": "#/definitions/limitParam" } + { "$ref": "#/parameters/skipParam" }, + { "$ref": "#/parameters/limitParam" } ], "responses": { "200": { @@ -57,7 +57,7 @@ } } }, - "definitions": { + "parameters": { "skipParam": { "name": "skip", "in": "query", @@ -73,7 +73,9 @@ "required": true, "type": "integer", "format": "int32" - }, + } + }, + "definitions": { "Pet": { "required": [ "name"