зеркало из https://github.com/Azure/sway.git
Родитель
6ca745d60e
Коммит
6092438bba
|
@ -22,6 +22,7 @@
|
|||
no-multiple-empty-lines: 2
|
||||
no-nested-ternary: 2
|
||||
no-path-concat: 2
|
||||
no-undef: 2
|
||||
no-unused-vars: 2
|
||||
object-curly-spacing: [2, "never"]
|
||||
quotes: [2, "single", "avoid-escape"]
|
||||
|
|
13
README.md
13
README.md
|
@ -1,4 +1,11 @@
|
|||
A library that simplifies [Swagger][swagger] integrations.
|
||||
A library that simplifies [Swagger][swagger] integrations. This library handles the minutiae of loading Swagger
|
||||
documents *(local and remote)*, resolving references *(local, remote)*, building an object model and providing you with
|
||||
a rich set of APIs for things like Swagger document validation, request/response validation, etc. For more details on
|
||||
the available APIs, please view the [API Documentation](https://github.com/apigee-127/sway/blob/master/docs/API.md).
|
||||
|
||||
Sway will always be built around the latest stable release of Swagger, which happens to be version `2.0` right now.
|
||||
This means that its APIs and object model will be specific to that version of Swagger and supporting any other versions
|
||||
of Swagger will require a conversion step prior to using Sway.
|
||||
|
||||
## Project Badges
|
||||
|
||||
|
@ -33,8 +40,8 @@ bower install sway --save
|
|||
|
||||
The standalone binaries come in two flavors:
|
||||
|
||||
* [sway-standalone.js](https://raw.github.com/apigee-127/sway/master/browser/sway.js): _4,400kb_, full source and source maps
|
||||
* [sway-standalone-min.js](https://raw.github.com/apigee-127/sway/master/browser/sway-min.js): _636kb_, minified, compressed and no source map
|
||||
* [sway-standalone.js](https://raw.github.com/apigee-127/sway/master/browser/sway.js): _4,484kb_, full source and source maps
|
||||
* [sway-standalone-min.js](https://raw.github.com/apigee-127/sway/master/browser/sway-min.js): _644kb_, minified, compressed and no source map
|
||||
|
||||
### Node.js
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* `Operation#getResponseExample` -> `Response#getExample`
|
||||
* `Operation#getResponseSample` -> `Response#getSample`
|
||||
* Removed callback support for `Sway#create` *(Issue 51)*
|
||||
* Removed plugin support *(Issue #55)*
|
||||
* Updated invalid/missing JSON References to be a structural validation errors like z-schema does
|
||||
|
||||
### v0.6.0 (2015-11-25)
|
||||
|
|
|
@ -24,10 +24,9 @@
|
|||
"test"
|
||||
],
|
||||
"dependencies": {
|
||||
"js-yaml": "~3.4.6",
|
||||
"json-refs": "~2.0.2",
|
||||
"js-yaml": "~3.5.1",
|
||||
"json-refs": "~2.0.3",
|
||||
"lodash": "~3.10.1",
|
||||
"path-loader": "*",
|
||||
"visionmedia-debug": "~2.2.0",
|
||||
"z-schema": "~3.16.1",
|
||||
"js-base64": "~2.1.9"
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
2025
browser/sway.js
2025
browser/sway.js
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
84
docs/API.md
84
docs/API.md
|
@ -6,7 +6,7 @@ A library for simpler [Swagger](http://swagger.io/) integrations.
|
|||
* [Sway](#module_Sway)
|
||||
* _inner_
|
||||
* [~Operation](#module_Sway..Operation)
|
||||
* [new Operation(api, pathObject, method, ptr, definition, consumes, produces)](#new_module_Sway..Operation_new)
|
||||
* [new Operation(pathObject, method, definition, pathToDefinition)](#new_module_Sway..Operation_new)
|
||||
* [.getParameter(name, [location])](#module_Sway..Operation+getParameter) ⇒ <code>Parameter</code>
|
||||
* [.getParameters()](#module_Sway..Operation+getParameters) ⇒ <code>Array.<Parameter></code>
|
||||
* [.getResponse([statusCode])](#module_Sway..Operation+getResponse) ⇒ <code>Response</code>
|
||||
|
@ -14,26 +14,26 @@ A library for simpler [Swagger](http://swagger.io/) integrations.
|
|||
* [.validateRequest(req)](#module_Sway..Operation+validateRequest) ⇒ <code>ValidationResults</code>
|
||||
* [.validateResponse(res)](#module_Sway..Operation+validateResponse) ⇒ <code>ValidationResults</code>
|
||||
* [~Parameter](#module_Sway..Parameter)
|
||||
* [new Parameter(opOrPath, ptr, definition, schema)](#new_module_Sway..Parameter_new)
|
||||
* [new Parameter(opOrPathObject, definition, pathToDefinition)](#new_module_Sway..Parameter_new)
|
||||
* [.getSample()](#module_Sway..Parameter+getSample) ⇒ <code>\*</code>
|
||||
* [.getSchema()](#module_Sway..Parameter+getSchema) ⇒ <code>object</code>
|
||||
* [.getValue(req)](#module_Sway..Parameter+getValue) ⇒ <code>ParameterValue</code>
|
||||
* [~ParameterValue](#module_Sway..ParameterValue)
|
||||
* [new ParameterValue(parameter, raw)](#new_module_Sway..ParameterValue_new)
|
||||
* [new ParameterValue(parameterObject, raw)](#new_module_Sway..ParameterValue_new)
|
||||
* [~Path](#module_Sway..Path)
|
||||
* [new Path(api, path, ptr, definition, regexp)](#new_module_Sway..Path_new)
|
||||
* [new Path(api, path, definition, pathToDefinition)](#new_module_Sway..Path_new)
|
||||
* [.getOperation(method)](#module_Sway..Path+getOperation) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperations()](#module_Sway..Path+getOperations) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperationsByTag(tag)](#module_Sway..Path+getOperationsByTag) ⇒ <code>Array.<Operation></code>
|
||||
* [.getParameters()](#module_Sway..Path+getParameters) ⇒ <code>Array.<Parameter></code>
|
||||
* [~Response](#module_Sway..Response)
|
||||
* [new Response(operation, ptr, definition, statusCode)](#new_module_Sway..Response_new)
|
||||
* [new Response(operationObject, statusCode, definition, pathToDefinition)](#new_module_Sway..Response_new)
|
||||
* [.getExample([mimeType])](#module_Sway..Response+getExample) ⇒ <code>string</code>
|
||||
* [.getSample()](#module_Sway..Response+getSample) ⇒ <code>\*</code>
|
||||
* [.validateResponse(res)](#module_Sway..Response+validateResponse) ⇒ <code>ValidationResults</code>
|
||||
* [~ServerResponseWrapper](#module_Sway..ServerResponseWrapper) : <code>object</code>
|
||||
* [~SwaggerApi](#module_Sway..SwaggerApi)
|
||||
* [new SwaggerApi(plugin, definition, resolved, references, options)](#new_module_Sway..SwaggerApi_new)
|
||||
* [new SwaggerApi(definition, definitionRemotesResolved, definitionAllResolved, references, options)](#new_module_Sway..SwaggerApi_new)
|
||||
* [.getOperation(pathOrReq, [method])](#module_Sway..SwaggerApi+getOperation) ⇒ <code>Operation</code>
|
||||
* [.getOperations([path])](#module_Sway..SwaggerApi+getOperations) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperationsByTag([tag])](#module_Sway..SwaggerApi+getOperationsByTag) ⇒ <code>Array.<Operation></code>
|
||||
|
@ -54,17 +54,17 @@ A library for simpler [Swagger](http://swagger.io/) integrations.
|
|||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| api | <code>SwaggerApi</code> | The Swagger API object |
|
||||
| definition | <code>object</code> | The operation definition |
|
||||
| method | <code>string</code> | The HTTP method for this operation |
|
||||
| pathObject | <code>Path</code> | The Path object |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the operation definition |
|
||||
| parameterObjects | <code>Array.<Parameter></code> | The Parameter objects |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the operation |
|
||||
| securityDefinitions | <code>object</code> | The security definitions used by this operation |
|
||||
|
||||
|
||||
* [~Operation](#module_Sway..Operation)
|
||||
* [new Operation(api, pathObject, method, ptr, definition, consumes, produces)](#new_module_Sway..Operation_new)
|
||||
* [new Operation(pathObject, method, definition, pathToDefinition)](#new_module_Sway..Operation_new)
|
||||
* [.getParameter(name, [location])](#module_Sway..Operation+getParameter) ⇒ <code>Parameter</code>
|
||||
* [.getParameters()](#module_Sway..Operation+getParameters) ⇒ <code>Array.<Parameter></code>
|
||||
* [.getResponse([statusCode])](#module_Sway..Operation+getResponse) ⇒ <code>Response</code>
|
||||
|
@ -73,7 +73,7 @@ A library for simpler [Swagger](http://swagger.io/) integrations.
|
|||
* [.validateResponse(res)](#module_Sway..Operation+validateResponse) ⇒ <code>ValidationResults</code>
|
||||
|
||||
<a name="new_module_Sway..Operation_new"></a>
|
||||
#### new Operation(api, pathObject, method, ptr, definition, consumes, produces)
|
||||
#### new Operation(pathObject, method, definition, pathToDefinition)
|
||||
The Swagger Operation object.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -84,13 +84,10 @@ The Swagger Operation object.
|
|||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| api | <code>SwaggerApi</code> | The Swagger API object |
|
||||
| pathObject | <code>Path</code> | The Path object |
|
||||
| method | <code>string</code> | The operation method |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the operation |
|
||||
| definition | <code>object</code> | The operation definition |
|
||||
| consumes | <code>Array.<string></code> | The mime types this operation consumes |
|
||||
| produces | <code>Array.<string></code> | The mime types this operation produces |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the operation definition |
|
||||
|
||||
<a name="module_Sway..Operation+getParameter"></a>
|
||||
#### operation.getParameter(name, [location]) ⇒ <code>Parameter</code>
|
||||
|
@ -169,21 +166,22 @@ Validates the response.
|
|||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| computedSchema | <code>object</code> | The computed JSON Schema for the parameter |
|
||||
| definition | <code>object</code> | The parameter definition |
|
||||
| operationObject | <code>Operation</code> | The Operation object (Can be undefined for path-level parameters) |
|
||||
| pathObject | <code>Path</code> | The Path object |
|
||||
| operationObject | <code>Operation</code> | The `Operation` object the parameter belongs to *(Can be undefined for path-level parameters)* |
|
||||
| pathObject | <code>Path</code> | The `Path` object the parameter belongs t |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the parameter definition |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the parameter definition |
|
||||
| schema | <code>object</code> | The JSON Schema for the parameter |
|
||||
|
||||
|
||||
* [~Parameter](#module_Sway..Parameter)
|
||||
* [new Parameter(opOrPath, ptr, definition, schema)](#new_module_Sway..Parameter_new)
|
||||
* [new Parameter(opOrPathObject, definition, pathToDefinition)](#new_module_Sway..Parameter_new)
|
||||
* [.getSample()](#module_Sway..Parameter+getSample) ⇒ <code>\*</code>
|
||||
* [.getSchema()](#module_Sway..Parameter+getSchema) ⇒ <code>object</code>
|
||||
* [.getValue(req)](#module_Sway..Parameter+getValue) ⇒ <code>ParameterValue</code>
|
||||
|
||||
<a name="new_module_Sway..Parameter_new"></a>
|
||||
#### new Parameter(opOrPath, ptr, definition, schema)
|
||||
#### new Parameter(opOrPathObject, definition, pathToDefinition)
|
||||
The Swagger Parameter object.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -194,10 +192,9 @@ object.
|
|||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| opOrPath | <code>Operation</code> | <code>Path</code> | The Operation or Path object |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the parameter |
|
||||
| opOrPathObject | <code>Operation</code> | <code>Path</code> | The `Operation` or `Path` object |
|
||||
| definition | <code>object</code> | The parameter definition |
|
||||
| schema | <code>object</code> | The JSON Schema for the parameter |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the parameter definition |
|
||||
|
||||
<a name="module_Sway..Parameter+getSample"></a>
|
||||
#### parameter.getSample() ⇒ <code>\*</code>
|
||||
|
@ -254,7 +251,7 @@ property.
|
|||
| value | <code>\*</code> | The processed value *(Takes default values into account and does type coercion when necessary and possible)*. This can the original value in the event that processing the value is impossible *(missing schema type)* or `undefined` if processing the value failed *(invalid types, etc.)*. |
|
||||
|
||||
<a name="new_module_Sway..ParameterValue_new"></a>
|
||||
#### new ParameterValue(parameter, raw)
|
||||
#### new ParameterValue(parameterObject, raw)
|
||||
Object representing a parameter value.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -262,7 +259,7 @@ Object representing a parameter value.
|
|||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| parameter | <code>Parameter</code> | The Parameter Object |
|
||||
| parameterObject | <code>Parameter</code> | The Parameter Object |
|
||||
| raw | <code>\*</code> | The original/raw value |
|
||||
|
||||
<a name="module_Sway..Path"></a>
|
||||
|
@ -274,22 +271,23 @@ Object representing a parameter value.
|
|||
| --- | --- | --- |
|
||||
| api | <code>SwaggerApi</code> | The Swagger API object |
|
||||
| definition | <code>object</code> | The path definition |
|
||||
| operationObjects | <code>Array.<Operation></code> | The operation objects |
|
||||
| parameterObjects | <code>Array.<Parameter></code> | The path-level parameter objects |
|
||||
| operationObjects | <code>Array.<Operation></code> | The `Operation` objects |
|
||||
| parameterObjects | <code>Array.<Parameter></code> | The path-level `Parameter` objects |
|
||||
| path | <code>string</code> | The path string |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the path definition |
|
||||
| ptr | <code>ptr</code> | The JSON Pointer to the path |
|
||||
| regexp | <code>regexp</code> | The regexp used to match request paths against this path |
|
||||
| regexp | <code>regexp</code> | The `RegExp` used to match request paths against this path |
|
||||
|
||||
|
||||
* [~Path](#module_Sway..Path)
|
||||
* [new Path(api, path, ptr, definition, regexp)](#new_module_Sway..Path_new)
|
||||
* [new Path(api, path, definition, pathToDefinition)](#new_module_Sway..Path_new)
|
||||
* [.getOperation(method)](#module_Sway..Path+getOperation) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperations()](#module_Sway..Path+getOperations) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperationsByTag(tag)](#module_Sway..Path+getOperationsByTag) ⇒ <code>Array.<Operation></code>
|
||||
* [.getParameters()](#module_Sway..Path+getParameters) ⇒ <code>Array.<Parameter></code>
|
||||
|
||||
<a name="new_module_Sway..Path_new"></a>
|
||||
#### new Path(api, path, ptr, definition, regexp)
|
||||
#### new Path(api, path, definition, pathToDefinition)
|
||||
The Path object.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -302,9 +300,8 @@ The Path object.
|
|||
| --- | --- | --- |
|
||||
| api | <code>SwaggerApi</code> | The Swagger API object |
|
||||
| path | <code>string</code> | The path string |
|
||||
| ptr | <code>ptr</code> | The JSON Pointer to the path |
|
||||
| definition | <code>object</code> | The path definition |
|
||||
| regexp | <code>regexp</code> | The regexp used to match request paths against this path |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the path definition |
|
||||
|
||||
<a name="module_Sway..Path+getOperation"></a>
|
||||
#### path.getOperation(method) ⇒ <code>Array.<Operation></code>
|
||||
|
@ -350,18 +347,19 @@ Return the parameters for this path.
|
|||
| --- | --- | --- |
|
||||
| definition | <code>object</code> | The response definition |
|
||||
| operationObject | <code>Operation</code> | The Operation object |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the path definition |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the response definition |
|
||||
| statusCode | <code>string</code> | The status code |
|
||||
|
||||
|
||||
* [~Response](#module_Sway..Response)
|
||||
* [new Response(operation, ptr, definition, statusCode)](#new_module_Sway..Response_new)
|
||||
* [new Response(operationObject, statusCode, definition, pathToDefinition)](#new_module_Sway..Response_new)
|
||||
* [.getExample([mimeType])](#module_Sway..Response+getExample) ⇒ <code>string</code>
|
||||
* [.getSample()](#module_Sway..Response+getSample) ⇒ <code>\*</code>
|
||||
* [.validateResponse(res)](#module_Sway..Response+validateResponse) ⇒ <code>ValidationResults</code>
|
||||
|
||||
<a name="new_module_Sway..Response_new"></a>
|
||||
#### new Response(operation, ptr, definition, statusCode)
|
||||
#### new Response(operationObject, statusCode, definition, pathToDefinition)
|
||||
The Swagger Response object.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -372,10 +370,10 @@ object.
|
|||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| operation | <code>Operation</code> | The Operation object |
|
||||
| ptr | <code>string</code> | The JSON Pointer to the response |
|
||||
| definition | <code>object</code> | The parameter definition |
|
||||
| operationObject | <code>Operation</code> | The `Operation` object |
|
||||
| statusCode | <code>string</code> | The status code |
|
||||
| definition | <code>object</code> | The parameter definition |
|
||||
| pathToDefinition | <code>Array.<string></code> | The path segments to the path definition |
|
||||
|
||||
<a name="module_Sway..Response+getExample"></a>
|
||||
#### response.getExample([mimeType]) ⇒ <code>string</code>
|
||||
|
@ -431,17 +429,18 @@ information to perform response validation.
|
|||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| customValidators | <code>Array.<ValidatorCallback></code> | The array of custom validators |
|
||||
| definition | <code>object</code> | The API definition |
|
||||
| definition | <code>object</code> | The original Swagger definition |
|
||||
| definitionRemotesResolved | <code>obejct</code> | The Swagger definition with all of its remote references resolved |
|
||||
| definitionAllResolved | <code>object</code> | The Swagger definition with all of its references resolved |
|
||||
| documentation | <code>string</code> | The URL to the Swagger documentation |
|
||||
| pathObjects | <code>Array.<Path></code> | The unique path objects |
|
||||
| options | <code>object</code> | The options passed to the constructor |
|
||||
| references | <code>object</code> | The reference metadata *(See [JsonRefs~ResolvedRefDetails](https://github.com/whitlockjc/json-refs/blob/master/docs/API.md#module_JsonRefs..ResolvedRefDetails))* |
|
||||
| resolved | <code>object</code> | The fully resolved API definition |
|
||||
| version | <code>string</code> | The Swagger API version |
|
||||
|
||||
|
||||
* [~SwaggerApi](#module_Sway..SwaggerApi)
|
||||
* [new SwaggerApi(plugin, definition, resolved, references, options)](#new_module_Sway..SwaggerApi_new)
|
||||
* [new SwaggerApi(definition, definitionRemotesResolved, definitionAllResolved, references, options)](#new_module_Sway..SwaggerApi_new)
|
||||
* [.getOperation(pathOrReq, [method])](#module_Sway..SwaggerApi+getOperation) ⇒ <code>Operation</code>
|
||||
* [.getOperations([path])](#module_Sway..SwaggerApi+getOperations) ⇒ <code>Array.<Operation></code>
|
||||
* [.getOperationsByTag([tag])](#module_Sway..SwaggerApi+getOperationsByTag) ⇒ <code>Array.<Operation></code>
|
||||
|
@ -451,7 +450,7 @@ information to perform response validation.
|
|||
* [.validate()](#module_Sway..SwaggerApi+validate) ⇒ <code>ValidationResults</code>
|
||||
|
||||
<a name="new_module_Sway..SwaggerApi_new"></a>
|
||||
#### new SwaggerApi(plugin, definition, resolved, references, options)
|
||||
#### new SwaggerApi(definition, definitionRemotesResolved, definitionAllResolved, references, options)
|
||||
The Swagger API object.
|
||||
|
||||
**Note:** Do not use directly.
|
||||
|
@ -462,12 +461,11 @@ The Swagger API object.
|
|||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| plugin | <code>object</code> | The Swagger version plugin |
|
||||
| definition | <code>object</code> | The Swagger definition |
|
||||
| resolved | <code>object</code> | The fully resolved Swagger definition |
|
||||
| definition | <code>object</code> | The original Swagger definition |
|
||||
| definitionRemotesResolved | <code>obejct</code> | The Swagger definition with all of its remote references resolved |
|
||||
| definitionAllResolved | <code>object</code> | The Swagger definition with all of its references resolved |
|
||||
| references | <code>object</code> | The location and resolution of the resolved references in the Swagger definition |
|
||||
| options | <code>object</code> | The options passed to swaggerApi.create |
|
||||
| [options.customValidators] | <code>ValidatorCallback</code> | The custom validators |
|
||||
|
||||
<a name="module_Sway..SwaggerApi+getOperation"></a>
|
||||
#### swaggerApi.getOperation(pathOrReq, [method]) ⇒ <code>Operation</code>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
A library that simplifies [Swagger][swagger] integrations. The APIs provided attempt to solve common
|
||||
problems when working with Swagger definitions, like loading a Swagger definition. _(For example: You might want to compose
|
||||
a Swagger definition programmatically or you might want to load a Swagger definition from the filesystem...or some URL.)_
|
||||
A library that simplifies [Swagger][swagger] integrations. This library handles the minutiae of loading Swagger
|
||||
documents *(local and remote)*, resolving references *(local and remote)*, building an object model and providing you
|
||||
with a rich set of APIs for things like Swagger document validation, request/response validation, etc. For more details
|
||||
on the available APIs, please view the [API Documentation](https://github.com/apigee-127/sway/blob/master/docs/API.md).
|
||||
|
||||
What you will find below is information on how to install sway based on your environment. You will also
|
||||
find detailed information about how to use the provided APIs.
|
||||
Sway will always be built around the latest stable release of Swagger, which happens to be version `2.0` right now.
|
||||
This means that its APIs and object model will be specific to that version of Swagger and supporting any other versions
|
||||
of Swagger will require a conversion step prior to using Sway.
|
||||
|
||||
# Disclaimer
|
||||
|
||||
|
@ -28,8 +30,8 @@ bower install sway --save
|
|||
|
||||
The standalone binaries come in two flavors:
|
||||
|
||||
* [sway-standalone.js](https://raw.github.com/apigee-127/sway/master/browser/sway.js): _4,0400kb_, full source and source maps
|
||||
* [sway-standalone-min.js](https://raw.github.com/apigee-127/sway/master/browser/sway-min.js): _636kb_, minified, compressed and no source map
|
||||
* [sway-standalone.js](https://raw.github.com/apigee-127/sway/master/browser/sway.js): _4,484kb_, full source and source maps
|
||||
* [sway-standalone-min.js](https://raw.github.com/apigee-127/sway/master/browser/sway-min.js): _644kb_, minified, compressed and no source map
|
||||
|
||||
### Node.js
|
||||
|
||||
|
@ -43,14 +45,10 @@ npm install sway --save
|
|||
|
||||
The sway project's API documentation can be found here: https://github.com/apigee-127/sway/blob/master/docs/API.md
|
||||
|
||||
## Swagger Versions
|
||||
## Swagger Resources
|
||||
|
||||
sway uses [The Factory Method Pattern][factory-method-pattern] to create the `SwaggerApi` object you see
|
||||
documented in the API documentation above. The core API is concrete but how each version of Swagger generates the
|
||||
`SwaggerApi` object and its business logic is Swagger version dependent. That being said, below are the supported
|
||||
versions of Swagger and their documentation:
|
||||
|
||||
* [2.0][version-2.0-documentation]
|
||||
* Specification Documentation: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
|
||||
* JSON Schema: https://github.com/swagger-api/swagger-spec/blob/master/schemas/v2.0/schema.json
|
||||
|
||||
## Swagger Validation
|
||||
|
||||
|
@ -67,37 +65,27 @@ situations where the existing JSON Schema for Swagger is broken or not as strict
|
|||
no other validation will occur. But once the structural validation happens, `Semantic Validation` and
|
||||
`Custom Validation` will happen.
|
||||
|
||||
## Dependencies
|
||||
### Semantic Validation
|
||||
|
||||
Below is the list of projects being used by sway and the purpose(s) they are used for:
|
||||
|
||||
* [debug][debug]: Used for producing useful debugging information
|
||||
* [js-base64][js-base64]: Used for generating mock/sample data for the `byte` format
|
||||
* [js-yaml][js-yaml]: Used for parsing YAML Swagger files
|
||||
* [json-refs][json-refs]: Used for dereferncing JSON References in Swagger files
|
||||
* [json-schema-faker][json-schema-faker]: Used for generating mock/sample values from JSON Schemas
|
||||
* [lodash-compat][lodash-compat]: Used for browser compatibility and miscellaneous utilities _(We use `lodash-compat`
|
||||
instead of `lodash` for compatibility with IE8 and IE9. We will likely change this but the reasons behind it were the
|
||||
Swagger project itself has JavaScript libraries that support IE8+ and we wanted to support the same level of browsers
|
||||
they did just in case they wanted to use these libraries.)_
|
||||
* [native-promise-only][native-promise-only]: Used to shim in [Promises][promises] support
|
||||
* [path-loader][path-loader]: Used to load Swagger files from the local filesystem and remote URLs
|
||||
* [path-to-regexp][path-to-regexp]: Used to create `RegExp` objects from Swagger paths
|
||||
* [z-schema][z-schema]: Used for JSON Schema validation
|
||||
| Description | Type |
|
||||
| :--------- | :---: |
|
||||
| Operations cannot have both a `body` parameter and a `formData` parameter | Error |
|
||||
| Operations must have only one `body` parameter | Error |
|
||||
| Operations must have unique *(`name` + `in` combination)* parameters | Error |
|
||||
| Operations must have unique `operationId` | Error |
|
||||
| Path parameters declared in the path string need matching parameter definitions *(Either at the path-level or the operation)* | Error |
|
||||
| Path parameter declarations do not allow empty names *(`/path/{}` is not valid)* | Error |
|
||||
| Path parameters definition *(Either at the path-level or the operation)* need matching paramater declarations | Error |
|
||||
| Path strings must be *(equivalently)* different *(Example: `/pet/{petId}` and `/pet/{petId2}` are equivalently the same and would generate an error)* | Error |
|
||||
| Paths must have unique *(`name` + `in` combination)* parameters | Error |
|
||||
| Referenceable definitions should be *used* by being referenced in the appropriate way | Warning |
|
||||
| References must point to existing documents or document fragments | Error |
|
||||
| The `default` property for [Schema Objects][schema-object], or schema-like objects *(non-body parameters)*, must validate against the respective JSON Schema | Error |
|
||||
| Circular composition/inheritance for [Schema Objects][schema-object] is not allowed *(You can have circular references everywhere except in composition/inheritance.)* | Error |
|
||||
| The `items` property for [Schema Objects][schema-object], or schema-like objects *(non-body parameters)*, is required when `type` is set to `array` _(See [swagger-api/swagger-spec/issues/174](https://github.com/swagger-api/swagger-spec/issues/174))_ | Error |
|
||||
| The `required` properties for a [Schema Object][schema-object] must be defined in the object or one of its ancestors | Error |
|
||||
|
||||
[bower]: http://bower.io/
|
||||
[debug]: https://www.npmjs.com/package/debug
|
||||
[factory-method-pattern]: https://en.wikipedia.org/wiki/Factory_method_pattern
|
||||
[js-base64]: https://www.npmjs.com/package/js-base64
|
||||
[js-yaml]: https://www.npmjs.com/package/js-yaml
|
||||
[json-refs]: https://www.npmjs.com/package/json-refs
|
||||
[json-schema-faker]: https://www.npmjs.com/package/json-schema-faker
|
||||
[lodash-compat]: https://www.npmjs.com/package/lodash-compat
|
||||
[native-promise-only]: https://www.npmjs.com/package/native-promise-only
|
||||
[npm]: https://www.npmjs.org/
|
||||
[path-loader]: https://www.npmjs.com/package/path-loader
|
||||
[path-to-regexp]: https://github.com/pillarjs/path-to-regexp
|
||||
[promises]: https://www.promisejs.org/
|
||||
[version-2.0-documentation]: https://github.com/apigee-127/sway/blob/master/docs/versions/2.0.md
|
||||
[schema-object]: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject
|
||||
[swagger]: http://swagger.io
|
||||
[z-schema]: https://www.npmjs.com/package/z-schema
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
sway's Swagger 2.0 support is documented below. There are also some helpful pieces of information about Swagger 2.0 as
|
||||
well.
|
||||
|
||||
## Swagger 2.0 Resources
|
||||
|
||||
* Specification Documentation: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
|
||||
* JSON Schema: https://github.com/swagger-api/swagger-spec/blob/master/schemas/v2.0/schema.json
|
||||
|
||||
## Semantic Validation
|
||||
|
||||
| Description | Type |
|
||||
| :--------- | :---: |
|
||||
| Operations cannot have both a `body` parameter and a `formData` parameter | Error |
|
||||
| Operations must have only one `body` parameter | Error |
|
||||
| Operations must have unique *(`name` + `in` combination)* parameters | Error |
|
||||
| Operations must have unique `operationId` | Error |
|
||||
| Path parameters declared in the path string need matching parameter definitions *(Either at the path-level or the operation)* | Error |
|
||||
} Path parameter declarations do not allow empty names *(`/path/{}` is not valid)* | Error |
|
||||
| Path parameters definition *(Either at the path-level or the operation)* need matching paramater declarations | Error |
|
||||
| Path strings must be *(equivalently)* different *(Example: `/pet/{petId}` and `/pet/{petId2}` are equivalently the same and would generate an error)* | Error |
|
||||
| Paths must have unique *(`name` + `in` combination)* parameters | Error |
|
||||
| Referenceable definitions should be *used* by being referenced in the appropriate way | Warning |
|
||||
| References must point to existing documents or document fragments | Error |
|
||||
| The `default` property for [Schema Objects][schema-object], or schema-like objects *(non-body parameters)*, must validate against the respective JSON Schema | Error |
|
||||
| Circular composition/inheritance for [Schema Objects][schema-object] is not allowed *(You can have circular references everywhere except in composition/inheritance.)* | Error |
|
||||
| The `items` property for [Schema Objects][schema-object], or schema-like objects *(non-body parameters)*, is required when `type` is set to `array` _(See [swagger-api/swagger-spec/issues/174](https://github.com/swagger-api/swagger-spec/issues/174))_ | Error |
|
||||
| The `required` properties for a [Schema Object][schema-object] must be defined in the object or one of its ancestors | Error |
|
||||
|
||||
[schema-object]: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject
|
17
gulpfile.js
17
gulpfile.js
|
@ -62,7 +62,7 @@ gulp.task('browserify', function () {
|
|||
return new Promise(function (resolve, reject) {
|
||||
var b = browserify('./index.js', {
|
||||
debug: useDebug,
|
||||
standalone: 'SwaggerApi'
|
||||
standalone: 'Sway'
|
||||
});
|
||||
|
||||
// Only include the 'en' faker.js locale
|
||||
|
@ -83,8 +83,7 @@ gulp.task('browserify', function () {
|
|||
exposify.config = {
|
||||
'json-refs': 'JsonRefs',
|
||||
'js-yaml': 'jsyaml',
|
||||
'lodash': '_',
|
||||
'path-loader': 'PathLoader'
|
||||
'lodash': '_'
|
||||
};
|
||||
|
||||
b.transform('exposify');
|
||||
|
@ -122,12 +121,12 @@ gulp.task('clean', function (done) {
|
|||
|
||||
gulp.task('docs', function () {
|
||||
return gulp.src([
|
||||
'./index.js',
|
||||
'lib/types/*.js'
|
||||
])
|
||||
.pipe($.concat('API.md'))
|
||||
.pipe($.jsdoc2MD({'sort-by': ['category', 'name']}))
|
||||
.pipe(gulp.dest('docs'));
|
||||
'./index.js',
|
||||
'lib/types/*.js'
|
||||
])
|
||||
.pipe($.concat('API.md'))
|
||||
.pipe($.jsdoc2MD({'sort-by': ['category', 'name']}))
|
||||
.pipe(gulp.dest('docs'));
|
||||
});
|
||||
|
||||
gulp.task('lint', function () {
|
||||
|
|
109
index.js
109
index.js
|
@ -25,8 +25,9 @@
|
|||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var pathLoader = require('path-loader');
|
||||
var helpers = require('./lib/helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var SwaggerApi = require('./lib/types/api');
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
// Load promises polyfill if necessary
|
||||
|
@ -35,10 +36,6 @@ if (typeof Promise === 'undefined') {
|
|||
require('native-promise-only');
|
||||
}
|
||||
|
||||
var supportedVersions = {
|
||||
'2.0': require('./lib/versions/2.0/')
|
||||
};
|
||||
|
||||
/**
|
||||
* A library for simpler [Swagger](http://swagger.io/) integrations.
|
||||
*
|
||||
|
@ -113,6 +110,7 @@ var supportedVersions = {
|
|||
*/
|
||||
module.exports.create = function (options) {
|
||||
var allTasks = Promise.resolve();
|
||||
var cOptions;
|
||||
|
||||
// Validate arguments
|
||||
allTasks = allTasks.then(function () {
|
||||
|
@ -142,38 +140,89 @@ module.exports.create = function (options) {
|
|||
});
|
||||
|
||||
// Make a copy of the input options so as not to alter them
|
||||
options = _.cloneDeep(options);
|
||||
cOptions = _.cloneDeep(options);
|
||||
|
||||
// Retrieve the definition if it is a path/URL (The reason we do this here instead of using JsonRefs#resolveRefsAt is
|
||||
// because we use this to identify which plugin we want to use.)
|
||||
//
|
||||
allTasks = allTasks
|
||||
// Load the remote definition or return options.definition
|
||||
// Resolve relative/remote references
|
||||
.then(function () {
|
||||
if (_.isString(options.definition)) {
|
||||
return pathLoader.load(options.jsonRefs && options.jsonRefs.relativeBase ?
|
||||
path.join(options.jsonRefs.relativeBase, options.definition) :
|
||||
options.definition,
|
||||
options.jsonRefs && options.jsonRefs.loaderOptions ?
|
||||
options.jsonRefs.loaderOptions :
|
||||
{})
|
||||
.then(YAML.safeLoad);
|
||||
// Prepare the json-refs options
|
||||
if (_.isUndefined(cOptions.jsonRefs)) {
|
||||
cOptions.jsonRefs = {};
|
||||
}
|
||||
|
||||
// Include invalid reference information
|
||||
cOptions.jsonRefs.includeInvalid = true;
|
||||
|
||||
// Resolve only relative/remote references
|
||||
cOptions.jsonRefs.filter = ['relative', 'remote'];
|
||||
|
||||
// Update the json-refs options to process YAML
|
||||
if (_.isUndefined(cOptions.jsonRefs.loaderOptions)) {
|
||||
cOptions.jsonRefs.loaderOptions = {};
|
||||
}
|
||||
|
||||
if (_.isUndefined(cOptions.jsonRefs.loaderOptions.processContent)) {
|
||||
cOptions.jsonRefs.loaderOptions.processContent = function (res, cb) {
|
||||
cb(undefined, YAML.safeLoad(res.text));
|
||||
};
|
||||
}
|
||||
|
||||
// Call the appropriate json-refs API
|
||||
if (_.isString(cOptions.definition)) {
|
||||
return JsonRefs.resolveRefsAt(cOptions.definition, cOptions.jsonRefs);
|
||||
} else {
|
||||
return options.definition;
|
||||
return JsonRefs.resolveRefs(cOptions.definition, cOptions.jsonRefs);
|
||||
}
|
||||
});
|
||||
})
|
||||
// Resolve local references and merge results
|
||||
.then(function (remoteResults) {
|
||||
// Resolve all references (Should only resolve locals now since the remote references are resolved)
|
||||
delete cOptions.jsonRefs.filter;
|
||||
|
||||
// Process the Swagger definition (if possible)
|
||||
allTasks = allTasks
|
||||
.then(function (apiDefinition) {
|
||||
var definition = _.find(supportedVersions, function (pDefinition) {
|
||||
return pDefinition.canProcess(apiDefinition);
|
||||
});
|
||||
return JsonRefs.resolveRefs(remoteResults.resolved, cOptions.jsonRefs)
|
||||
.then(function (results) {
|
||||
return {
|
||||
// The original Swagger definition
|
||||
definition: _.isString(cOptions.definition) ? remoteResults.value : cOptions.definition,
|
||||
// The original Swagger definition with its remote references resolved
|
||||
definitionRemotesResolved: remoteResults.resolved,
|
||||
// The original Swagger definition with all its references resolved
|
||||
definitionAllResolved: results.resolved,
|
||||
// Merge the local reference details with the remote reference details
|
||||
refs: _.reduce(results.refs, function (allRefs, refDetails, refPtr) {
|
||||
var refPath = JsonRefs.pathFromPtr(refPtr);
|
||||
|
||||
if (_.isUndefined(definition)) {
|
||||
throw new TypeError('Unable to identify the Swagger version or the Swagger version is unsupported');
|
||||
}
|
||||
if (!_.has(allRefs, refPtr)) {
|
||||
if (_.has(remoteResults.resolved, refPath)) {
|
||||
refDetails.value = _.get(remoteResults.resolved, refPath);
|
||||
} else {
|
||||
refDetails.missing = true;
|
||||
refDetails.type = 'invalid';
|
||||
}
|
||||
|
||||
return definition.createSwaggerApi(apiDefinition, options);
|
||||
allRefs[refPtr] = refDetails;
|
||||
}
|
||||
|
||||
return allRefs;
|
||||
}, remoteResults.refs)
|
||||
}
|
||||
});
|
||||
})
|
||||
// Process the Swagger document and return the API
|
||||
.then(function (results) {
|
||||
// We need to remove all circular objects as z-schema does not work with them:
|
||||
// https://github.com/zaggino/z-schema/issues/137
|
||||
helpers.removeCirculars(results.definition);
|
||||
helpers.removeCirculars(results.definitionRemotesResolved);
|
||||
helpers.removeCirculars(results.definitionAllResolved);
|
||||
|
||||
// Create object model
|
||||
return new SwaggerApi(results.definition,
|
||||
results.definitionRemotesResolved,
|
||||
results.definitionAllResolved,
|
||||
results.refs,
|
||||
options);
|
||||
});
|
||||
|
||||
return allTasks;
|
||||
|
|
347
lib/helpers.js
347
lib/helpers.js
|
@ -25,11 +25,71 @@
|
|||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var formatGenerators = require('./validation/format-generators');
|
||||
var formatValidators = require('./validation/format-validators');
|
||||
var mocker = require('json-schema-faker');
|
||||
var ZSchema = require('z-schema');
|
||||
|
||||
var collectionFormats = [undefined, 'csv', 'multi', 'pipes', 'ssv', 'tsv'];
|
||||
var draft04Json = require('./json-schema-draft-04.json');
|
||||
var draft04Url = 'http://json-schema.org/draft-04/schema';
|
||||
var jsonMocker = createJSONMocker();
|
||||
var jsonSchemaValidator = createJSONValidator();
|
||||
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameter-object
|
||||
var parameterSchemaProperties = [
|
||||
'allowEmptyValue',
|
||||
'default',
|
||||
'description',
|
||||
'enum',
|
||||
'exclusiveMaximum',
|
||||
'exclusiveMinimum',
|
||||
'format',
|
||||
'items',
|
||||
'maxItems',
|
||||
'maxLength',
|
||||
'maximum',
|
||||
'minItems',
|
||||
'minLength',
|
||||
'minimum',
|
||||
'multipleOf',
|
||||
'pattern',
|
||||
'type',
|
||||
'uniqueItems'
|
||||
];
|
||||
var types = ['array', 'boolean', 'integer', 'object', 'number', 'string'];
|
||||
|
||||
function createJSONMocker () {
|
||||
// Extend faker.js to only include the 'en' locale
|
||||
mocker.extend('faker', function (faker) {
|
||||
faker.locale = 'en';
|
||||
|
||||
return faker;
|
||||
});
|
||||
|
||||
// Add the custom format generators
|
||||
_.each(formatGenerators, function (handler, name) {
|
||||
mocker.formats(name, handler);
|
||||
});
|
||||
|
||||
return mocker;
|
||||
}
|
||||
|
||||
function createJSONValidator () {
|
||||
var validator = new ZSchema({
|
||||
ignoreUnknownFormats: true,
|
||||
reportPathAsArray: true
|
||||
});
|
||||
|
||||
// Add the draft-04 spec
|
||||
validator.setRemoteReference(draft04Url, draft04Json);
|
||||
|
||||
// Add the custom validators
|
||||
_.each(formatValidators, function (handler, name) {
|
||||
ZSchema.registerFormat(name, handler);
|
||||
});
|
||||
|
||||
return validator;
|
||||
}
|
||||
|
||||
function normalizeError (obj) {
|
||||
// Remove fields that are not important or are not a part of the exposed contract
|
||||
|
@ -42,66 +102,261 @@ function normalizeError (obj) {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to create a JSON Schema Mocker.
|
||||
* Helper method to take a Swagger parameter definition and compute its schema.
|
||||
*
|
||||
* @param {object} [options] - The mocker options
|
||||
* @param {object} [options.formatGenerators] - The custom format generators to use
|
||||
* For non-body Swagger parameters, the definition itself is not suitable as a JSON Schema so we must compute it.
|
||||
*
|
||||
* @returns {object} The JSON Schema mocker
|
||||
* @param {object} paramDef - The parameter definition
|
||||
*
|
||||
* @returns {object} The computed schema
|
||||
*/
|
||||
module.exports.createJSONSchemaMocker = function (options) {
|
||||
/* istanbul ignore if */
|
||||
if (_.isUndefined(options)) {
|
||||
options = {};
|
||||
module.exports.computeParameterSchema = function (paramDef) {
|
||||
var schema;
|
||||
|
||||
if (_.isUndefined(paramDef.schema)) {
|
||||
schema = {};
|
||||
|
||||
// Build the schema from the schema-like parameter structure
|
||||
_.forEach(parameterSchemaProperties, function (name) {
|
||||
if (!_.isUndefined(paramDef[name])) {
|
||||
schema[name] = paramDef[name];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
schema = paramDef.schema;
|
||||
}
|
||||
|
||||
// Extend faker.js to only include the 'en' locale
|
||||
mocker.extend('faker', function (faker) {
|
||||
faker.locale = 'en';
|
||||
|
||||
return faker;
|
||||
});
|
||||
|
||||
// Add the custom format generators
|
||||
_.each(options.formatGenerators, function (handler, name) {
|
||||
mocker.formats(name, handler);
|
||||
});
|
||||
|
||||
return mocker;
|
||||
return schema;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to create a JSON Validator.
|
||||
* Converts a raw JavaScript value to a JSON Schema value based on its schema.
|
||||
*
|
||||
* @param {object} [options] - The validator options
|
||||
* @param {object} [options.formatValidators] - The custom format validators to use
|
||||
* @param {object} schema - The schema for the value
|
||||
* @param {object} options - The conversion options
|
||||
* @param {string} [options.collectionFormat] - The collection format
|
||||
* @param {string} [options.encoding] - The encoding if the raw value is a `Buffer`
|
||||
* @param {*} value - The value to convert
|
||||
*
|
||||
* @returns {object} The JSON Schema validator
|
||||
* @returns {*} The converted value
|
||||
*
|
||||
* @throws {TypeError} IF the `collectionFormat` or `type` is invalid for the `schema`, or if conversion fails
|
||||
*/
|
||||
module.exports.createJSONValidator = function (options) {
|
||||
var validator = new ZSchema({
|
||||
ignoreUnknownFormats: true,
|
||||
reportPathAsArray: true
|
||||
});
|
||||
var convertValue = module.exports.convertValue = function (schema, options, value) {
|
||||
var originalValue = value; // Used in error reporting for invalid values
|
||||
var type = _.isPlainObject(schema) ? schema.type : undefined;
|
||||
var pValue = value;
|
||||
var pType = typeof pValue;
|
||||
var err;
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (_.isUndefined(options)) {
|
||||
options = {};
|
||||
// If there is an explicit type provided, make sure it's one of the supported ones
|
||||
if (_.has(schema, 'type') && types.indexOf(type) === -1) {
|
||||
throw new TypeError('Invalid \'type\' value: ' + type);
|
||||
}
|
||||
|
||||
// Add the draft-04 spec
|
||||
validator.setRemoteReference(draft04Url, draft04Json);
|
||||
// Since JSON Schema allows you to not specify a type and it is treated as a wildcard of sorts, we should not do any
|
||||
// coercion for these types of values.
|
||||
if (_.isUndefined(type)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Add the custom validators
|
||||
_.each(options.formatValidators, function (handler, name) {
|
||||
ZSchema.registerFormat(name, handler);
|
||||
});
|
||||
// If there is no value, do not convert it
|
||||
if (_.isUndefined(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return validator;
|
||||
// Convert Buffer value to String
|
||||
// (We use this type of check to identify Buffer objects. The browser does not have a Buffer type and to avoid having
|
||||
// import the browserify buffer module, we just do a simple check. This is brittle but should work.)
|
||||
if (_.isFunction(value.readUInt8)) {
|
||||
value = value.toString(options.encoding);
|
||||
pValue = value;
|
||||
pType = typeof value;
|
||||
}
|
||||
|
||||
// If the value is empty and empty is allowed, use it
|
||||
if (schema.allowEmptyValue && value === '') {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Attempt to parse the string as JSON if the type is array or object
|
||||
if (['array', 'object'].indexOf(type) > -1) {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
// Nothing to do here, just fall through
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'array':
|
||||
if (_.isString(value)) {
|
||||
if (collectionFormats.indexOf(options.collectionFormat) === -1) {
|
||||
throw new TypeError('Invalid \'collectionFormat\' value: ' + options.collectionFormat);
|
||||
}
|
||||
|
||||
switch (options.collectionFormat) {
|
||||
case 'csv':
|
||||
case undefined:
|
||||
value = value.split(',');
|
||||
break;
|
||||
case 'multi':
|
||||
value = [value];
|
||||
break;
|
||||
case 'pipes':
|
||||
value = value.split('|');
|
||||
break;
|
||||
case 'ssv':
|
||||
value = value.split(' ');
|
||||
break;
|
||||
case 'tsv':
|
||||
value = value.split('\t');
|
||||
break;
|
||||
|
||||
// no default
|
||||
}
|
||||
}
|
||||
|
||||
if (_.isArray(value)) {
|
||||
value = _.map(value, function (item, index) {
|
||||
return convertValue(_.isArray(schema.items) ? schema.items[index] : schema.items, options, item);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'boolean':
|
||||
if (!_.isBoolean(value)) {
|
||||
if (value === 'true') {
|
||||
value = true;
|
||||
} else if (value === 'false') {
|
||||
value = false;
|
||||
} else {
|
||||
err = new TypeError('Not a valid boolean: ' + value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'integer':
|
||||
if (!_.isNumber(value)) {
|
||||
if (_.isString(value) && _.trim(value).length === 0) {
|
||||
value = NaN;
|
||||
}
|
||||
|
||||
value = Number(value);
|
||||
|
||||
if (_.isNaN(value)) {
|
||||
err = new TypeError('Not a valid integer: ' + originalValue);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'number':
|
||||
if (!_.isNumber(value)) {
|
||||
if (_.isString(value) && _.trim(value).length === 0) {
|
||||
value = NaN;
|
||||
}
|
||||
|
||||
value = Number(value);
|
||||
|
||||
if (_.isNaN(value)) {
|
||||
err = new TypeError('Not a valid number: ' + originalValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
if (['date', 'date-time'].indexOf(schema.format) > -1) {
|
||||
if (_.isString(value)) {
|
||||
value = new Date(value);
|
||||
}
|
||||
|
||||
if (!_.isDate(value) || value.toString() === 'Invalid Date') {
|
||||
err = new TypeError('Not a valid ' + schema.format + ' string: ' + originalValue);
|
||||
|
||||
err.code = 'INVALID_FORMAT';
|
||||
}
|
||||
} else if (!_.isString(value)) {
|
||||
err = new TypeError('Not a valid string: ' + value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// no default
|
||||
}
|
||||
|
||||
if (!_.isUndefined(err)) {
|
||||
// Convert the error to be more like a JSON Schema validation error
|
||||
if (_.isUndefined(err.code)) {
|
||||
err.code = 'INVALID_TYPE';
|
||||
err.message = 'Expected type ' + type + ' but found type ' + pType;
|
||||
} else {
|
||||
err.message = 'Object didn\'t pass validation for format ' + schema.format + ': ' + pValue;
|
||||
}
|
||||
|
||||
// Format and type errors resemble JSON Schema validation errors
|
||||
err.failedValidation = true;
|
||||
err.path = [];
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a json-schema-faker mocker.
|
||||
*
|
||||
* @returns {object} The json-schema-faker mocker to use
|
||||
*/
|
||||
module.exports.getJSONSchemaMocker = function () {
|
||||
return jsonMocker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a z-schema validator.
|
||||
*
|
||||
* @returns {object} The z-schema validator to use
|
||||
*/
|
||||
module.exports.getJSONSchemaValidator = function () {
|
||||
return jsonSchemaValidator;
|
||||
};
|
||||
|
||||
module.exports.parameterLocations = ['body', 'formData', 'header', 'path', 'query'];
|
||||
|
||||
/**
|
||||
* Replaces the circular references in the provided object with an empty object.
|
||||
*
|
||||
* @param {object} obj - The JavaScript object
|
||||
*/
|
||||
module.exports.removeCirculars = function (obj) {
|
||||
function walk (ancestors, node, path) {
|
||||
function walkItem (item, segment) {
|
||||
path.push(segment);
|
||||
walk(ancestors, item, path);
|
||||
path.pop();
|
||||
}
|
||||
|
||||
// We do not process circular objects again
|
||||
if (ancestors.indexOf(node) === -1) {
|
||||
ancestors.push(node);
|
||||
|
||||
if (_.isArray(node) || _.isPlainObject(node)) {
|
||||
_.each(node, function (member, indexOrKey) {
|
||||
walkItem(member, indexOrKey.toString());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
_.set(obj, path, {});
|
||||
}
|
||||
|
||||
ancestors.pop();
|
||||
}
|
||||
|
||||
walk([], obj, []);
|
||||
}
|
||||
|
||||
module.exports.supportedHttpMethods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'];
|
||||
|
||||
/**
|
||||
* Validates the provided value against the JSON Schema by name or value.
|
||||
*
|
||||
|
@ -148,10 +403,10 @@ module.exports.validateContentType = function (contentType, supportedTypes, resu
|
|||
// Check for exact match or mime-type only match
|
||||
if (_.indexOf(supportedTypes, rawContentType) === -1 && _.indexOf(supportedTypes, contentType) === -1) {
|
||||
results.errors.push({
|
||||
code: 'INVALID_CONTENT_TYPE',
|
||||
message: 'Invalid Content-Type (' + contentType + '). These are supported: ' +
|
||||
supportedTypes.join(', '),
|
||||
path: []
|
||||
});
|
||||
code: 'INVALID_CONTENT_TYPE',
|
||||
message: 'Invalid Content-Type (' + contentType + '). These are supported: ' +
|
||||
supportedTypes.join(', '),
|
||||
path: []
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
var _ = require('lodash');
|
||||
var debug = require('debug')('sway:api');
|
||||
var parseUrl = require('url').parse;
|
||||
var Path = require('./path');
|
||||
var validators = require('../validation/validators');
|
||||
|
||||
/**
|
||||
* The Swagger API object.
|
||||
|
@ -36,43 +38,53 @@ var parseUrl = require('url').parse;
|
|||
* **Extra Properties:** Other than the documented properties, this object also exposes all properties of the definition
|
||||
* object.
|
||||
*
|
||||
* @param {object} plugin - The Swagger version plugin
|
||||
* @param {object} definition - The Swagger definition
|
||||
* @param {object} resolved - The fully resolved Swagger definition
|
||||
* @param {object} definition - The original Swagger definition
|
||||
* @param {obejct} definitionRemotesResolved - The Swagger definition with all of its remote references resolved
|
||||
* @param {object} definitionAllResolved - The Swagger definition with all of its references resolved
|
||||
* @param {object} references - The location and resolution of the resolved references in the Swagger definition
|
||||
* @param {object} options - The options passed to swaggerApi.create
|
||||
* @param {ValidatorCallback} [options.customValidators] - The custom validators
|
||||
*
|
||||
* @property {ValidatorCallback[]} customValidators - The array of custom validators
|
||||
* @property {object} definition - The API definition
|
||||
* @property {object} definition - The original Swagger definition
|
||||
* @property {obejct} definitionRemotesResolved - The Swagger definition with all of its remote references resolved
|
||||
* @property {object} definitionAllResolved - The Swagger definition with all of its references resolved
|
||||
* @property {string} documentation - The URL to the Swagger documentation
|
||||
* @property {Path[]} pathObjects - The unique path objects
|
||||
* @property {object} options - The options passed to the constructor
|
||||
* @property {object} references - The reference metadata *(See [JsonRefs~ResolvedRefDetails](https://github.com/whitlockjc/json-refs/blob/master/docs/API.md#module_JsonRefs..ResolvedRefDetails))*
|
||||
* @property {object} resolved - The fully resolved API definition
|
||||
* @property {string} version - The Swagger API version
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function SwaggerApi (plugin, definition, resolved, references, options) {
|
||||
function SwaggerApi (definition, definitionRemotesResolved, definitionAllResolved, references, options) {
|
||||
var that = this;
|
||||
|
||||
// Assign local properties
|
||||
this.customValidators = [];
|
||||
this.definition = definition;
|
||||
this.documentation = plugin.documentation;
|
||||
this.definitionAllResolved = definitionAllResolved;
|
||||
this.definitionRemotesResolved = definitionRemotesResolved;
|
||||
this.documentation = 'https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md';
|
||||
this.options = options;
|
||||
this.plugin = plugin;
|
||||
this.references = references;
|
||||
this.resolved = resolved;
|
||||
this.version = plugin.version;
|
||||
this.version = '2.0';
|
||||
|
||||
// Assign Swagger definition properties to the api for easy access
|
||||
// Assign local properties from the Swagger definition properties
|
||||
_.assign(this, definition);
|
||||
|
||||
debug('Initializing Sway using %s', _.isString(options.definition) ? options.definition : 'the provided document');
|
||||
|
||||
this.pathObjects = plugin.getPaths(this);
|
||||
|
||||
// Register custom validators
|
||||
_.forEach(options.customValidators, SwaggerApi.prototype.registerValidator, this);
|
||||
_.each(options.customValidators, SwaggerApi.prototype.registerValidator, this);
|
||||
|
||||
// Create the Path objects
|
||||
this.pathObjects = _.map(definitionAllResolved.paths, function (pathDef, path) {
|
||||
return new Path(that,
|
||||
path,
|
||||
pathDef,
|
||||
['paths', path]);
|
||||
|
||||
});
|
||||
|
||||
debug('Creating SwaggerApi from %s', _.isString(options.definition) ? options.definition : 'the provided document');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -231,15 +243,15 @@ SwaggerApi.prototype.validate = function () {
|
|||
}
|
||||
|
||||
// Validate the document structurally
|
||||
doValidation(this.plugin.getStructuralValidator());
|
||||
doValidation(validators.jsonSchemaValidator);
|
||||
|
||||
// Perform remaining validation only if the document is structurally valid
|
||||
if (results.errors.length === 0) {
|
||||
// Run plugin validators
|
||||
_.forEach(this.plugin.getSemanticValidators(), doValidation);
|
||||
_.each(validators.semanticValidators, doValidation);
|
||||
|
||||
// Run custom validators
|
||||
_.forEach(this.customValidators, doValidation);
|
||||
_.each(this.customValidators, doValidation);
|
||||
}
|
||||
|
||||
return results;
|
||||
|
|
|
@ -26,7 +26,10 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var debug = require('debug')('sway:operation');
|
||||
var sHelpers = require('../helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var Parameter = require('./parameter');
|
||||
var Response = require('./response');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
/**
|
||||
* The Swagger Operation object.
|
||||
|
@ -36,47 +39,85 @@ var sHelpers = require('../helpers');
|
|||
* **Extra Properties:** Other than the documented properties, this object also exposes all properties of the definition
|
||||
* object.
|
||||
*
|
||||
* @param {SwaggerApi} api - The Swagger API object
|
||||
* @param {Path} pathObject - The Path object
|
||||
* @param {string} method - The operation method
|
||||
* @param {string} ptr - The JSON Pointer to the operation
|
||||
* @param {object} definition - The operation definition
|
||||
* @param {string[]} consumes - The mime types this operation consumes
|
||||
* @param {string[]} produces - The mime types this operation produces
|
||||
* @param {string[]} pathToDefinition - The path segments to the operation definition
|
||||
*
|
||||
* @property {SwaggerApi} api - The Swagger API object
|
||||
* @property {object} definition - The operation definition
|
||||
* @property {string} method - The HTTP method for this operation
|
||||
* @property {Path} pathObject - The Path object
|
||||
* @property {string[]} pathToDefinition - The path segments to the operation definition
|
||||
* @property {Parameter[]} parameterObjects - The Parameter objects
|
||||
* @property {string} ptr - The JSON Pointer to the operation
|
||||
* @property {object} securityDefinitions - The security definitions used by this operation
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function Operation (api, pathObject, method, ptr, definition, consumes, produces) {
|
||||
this.api = api;
|
||||
this.pathObject = pathObject;
|
||||
this.method = method;
|
||||
this.ptr = ptr;
|
||||
this.definition = definition;
|
||||
function Operation (pathObject, method, definition, pathToDefinition) {
|
||||
var seenParameters = [];
|
||||
var that = this;
|
||||
|
||||
// Assign Swagger definition properties to the operation for easy access
|
||||
// Assign local properties
|
||||
this.consumes = definition.consumes || pathObject.api.consumes || [];
|
||||
this.definition = _.cloneDeep(definition); // Clone so we do not alter the original
|
||||
this.method = method;
|
||||
this.parameterObjects = []; // Computed below
|
||||
this.pathObject = pathObject;
|
||||
this.pathToDefinition = pathToDefinition;
|
||||
this.produces = definition.produces || pathObject.api.produces || [];
|
||||
this.ptr = JsonRefs.pathToPtr(pathToDefinition);
|
||||
|
||||
// Assign local properties from the Swagger definition properties
|
||||
_.assign(this, definition);
|
||||
|
||||
// Assign consumes/produces after merging properties
|
||||
this.consumes = consumes;
|
||||
this.produces = produces;
|
||||
// Default to the global security
|
||||
if (_.isUndefined(this.security)) {
|
||||
this.security = this.definition.security = pathObject.api.definitionAllResolved.security;
|
||||
}
|
||||
|
||||
debug('Found operation at %s', ptr);
|
||||
// Add the Parameter objects from the Path object that were not redefined in the operation definition
|
||||
this.parameterObjects = _.map(pathObject.parameterObjects, function (parameterObject) {
|
||||
seenParameters.push(parameterObject.in + ':' + parameterObject.name);
|
||||
|
||||
this.parameterObjects = api.plugin.getOperationParameters(this);
|
||||
this.responseObjects = api.plugin.getOperationResponses(this);
|
||||
return parameterObject;
|
||||
});
|
||||
|
||||
// Create Parameter objects from parameters defined in the operation definition
|
||||
_.each(definition.parameters, function (paramDef, index) {
|
||||
var key = paramDef.in + ':' + paramDef.name;
|
||||
var seenIndex = seenParameters.indexOf(key);
|
||||
var parameterObject = new Parameter(that,
|
||||
paramDef,
|
||||
pathToDefinition.concat(['parameters', index.toString()]));
|
||||
|
||||
if (seenIndex > -1) {
|
||||
that.parameterObjects[seenIndex] = parameterObject;
|
||||
} else {
|
||||
that.parameterObjects.push(parameterObject);
|
||||
|
||||
seenParameters.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
this.parameters = this.definition.parameters = _.map(this.parameterObjects, function (parameterObject) {
|
||||
return parameterObject.definition;
|
||||
});
|
||||
|
||||
// Create response objects from responses defined in the operation definition
|
||||
this.responseObjects = _.map(definition.responses, function (responseDef, code) {
|
||||
return new Response(that,
|
||||
code,
|
||||
responseDef,
|
||||
pathToDefinition.concat(['responses', code]));
|
||||
});
|
||||
|
||||
// Bring in the security definitions for easier access
|
||||
this.securityDefinitions = _.reduce(definition.security, function (defs, reqs) {
|
||||
this.securityDefinitions = _.reduce(this.security, function (defs, reqs) {
|
||||
_.each(reqs, function (req, name) {
|
||||
var def = api.resolved.securityDefinitions ? api.resolved.securityDefinitions[name] : undefined;
|
||||
var def = pathObject.api.definitionAllResolved.securityDefinitions ?
|
||||
pathObject.api.definitionAllResolved.securityDefinitions[name] :
|
||||
undefined;
|
||||
|
||||
if (!_.isUndefined(def)) {
|
||||
defs[name] = def;
|
||||
|
@ -85,6 +126,8 @@ function Operation (api, pathObject, method, ptr, definition, consumes, produces
|
|||
|
||||
return defs;
|
||||
}, {});
|
||||
|
||||
debug('Found operation at %s', this.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,7 +210,7 @@ Operation.prototype.validateRequest = function (req) {
|
|||
// Validate the Content-Type but only for POST and PUT (The rest do not have bodies)
|
||||
if (['post', 'put'].indexOf(this.method) > -1) {
|
||||
// Defaults to application/octet-stream per http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
|
||||
sHelpers.validateContentType(req.headers['content-type'] || 'application/octet-stream', this.consumes, results);
|
||||
helpers.validateContentType(req.headers['content-type'] || 'application/octet-stream', this.consumes, results);
|
||||
}
|
||||
|
||||
// Validate the parameters
|
||||
|
|
|
@ -33,7 +33,7 @@ var JsonRefs = require('json-refs');
|
|||
*
|
||||
* **Note:** Do not use directly.
|
||||
*
|
||||
* @param {Parameter} parameter - The Parameter Object
|
||||
* @param {Parameter} parameterObject - The Parameter Object
|
||||
* @param {*} raw - The original/raw value
|
||||
*
|
||||
* @property {Error} error - The error(s) encountered during processing/validating the parameter value
|
||||
|
@ -47,16 +47,15 @@ var JsonRefs = require('json-refs');
|
|||
*
|
||||
* @constructor
|
||||
*/
|
||||
function ParameterValue (parameter, raw) {
|
||||
var plugin = parameter.pathObject.api.plugin;
|
||||
var pPath = JsonRefs.pathFromPtr(parameter.ptr);
|
||||
function ParameterValue (parameterObject, raw) {
|
||||
var pPath = JsonRefs.pathFromPtr(parameterObject.ptr);
|
||||
var processed = false;
|
||||
var schema = parameter.computedSchema;
|
||||
var schema = parameterObject.computedSchema;
|
||||
var error;
|
||||
var isValid;
|
||||
var processedValue;
|
||||
|
||||
this.parameterObject = parameter;
|
||||
this.parameterObject = parameterObject;
|
||||
this.raw = raw;
|
||||
|
||||
// Use Object.defineProperty for 'value' to allow for lazy processing of the raw value
|
||||
|
@ -90,7 +89,7 @@ function ParameterValue (parameter, raw) {
|
|||
if (_.isUndefined(error)) {
|
||||
try {
|
||||
// Validate requiredness
|
||||
if (parameter.required === true && _.isUndefined(value)) {
|
||||
if (parameterObject.required === true && _.isUndefined(value)) {
|
||||
vError = new Error('Value is required but was not provided');
|
||||
|
||||
vError.code = 'REQUIRED';
|
||||
|
@ -105,11 +104,11 @@ function ParameterValue (parameter, raw) {
|
|||
// * The schema defines a file parameter
|
||||
// * The schema is for a string type with date/date-time format and the value is a date
|
||||
// * The schema is for a string type and the value is a Buffer
|
||||
if (parameter.required === false && _.isUndefined(value)) {
|
||||
if (parameterObject.required === false && _.isUndefined(value)) {
|
||||
skipValidation = true;
|
||||
} else if (schema.allowEmptyValue === true && value === '') {
|
||||
skipValidation = true;
|
||||
} else if (parameter.type === 'file') {
|
||||
} else if (parameterObject.type === 'file') {
|
||||
skipValidation = true;
|
||||
} else if (schema.type === 'string') {
|
||||
if (['date', 'date-time'].indexOf(schema.format) > -1 && _.isDate(value)) {
|
||||
|
@ -121,7 +120,7 @@ function ParameterValue (parameter, raw) {
|
|||
|
||||
if (!skipValidation) {
|
||||
// Validate against JSON Schema
|
||||
result = helpers.validateAgainstSchema(plugin.getJSONSchemaValidator(), parameter.getSchema(), value);
|
||||
result = helpers.validateAgainstSchema(helpers.getJSONSchemaValidator(), parameterObject.getSchema(), value);
|
||||
}
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
|
@ -156,8 +155,8 @@ function ParameterValue (parameter, raw) {
|
|||
} else {
|
||||
// Convert/Coerce the raw value from the request object
|
||||
try {
|
||||
processedValue = plugin.convertValue(schema, {
|
||||
collectionFormat: parameter.collectionFormat
|
||||
processedValue = helpers.convertValue(schema, {
|
||||
collectionFormat: parameterObject.collectionFormat
|
||||
}, raw);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var debug = require('debug')('sway:parameter');
|
||||
var Operation = require('./operation');
|
||||
var helpers = require('../helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var ParameterValue = require('./parameter-value');
|
||||
var parseUrl = require('url').parse;
|
||||
|
||||
|
@ -38,40 +39,43 @@ var parseUrl = require('url').parse;
|
|||
* **Extra Properties:** Other than the documented properties, this object also exposes all properties of the definition
|
||||
* object.
|
||||
*
|
||||
* @param {Operation|Path} opOrPath - The Operation or Path object
|
||||
* @param {string} ptr - The JSON Pointer to the parameter
|
||||
* @param {Operation|Path} opOrPathObject - The `Operation` or `Path` object
|
||||
* @param {object} definition - The parameter definition
|
||||
* @param {object} schema - The JSON Schema for the parameter
|
||||
* @param {string[]} pathToDefinition - The path segments to the parameter definition
|
||||
*
|
||||
* @property {object} computedSchema - The computed JSON Schema for the parameter
|
||||
* @property {object} definition - The parameter definition
|
||||
* @property {Operation} operationObject - The Operation object (Can be undefined for path-level parameters)
|
||||
* @property {Path} pathObject - The Path object
|
||||
* @property {Operation} operationObject - The `Operation` object the parameter belongs to *(Can be undefined for
|
||||
* path-level parameters)*
|
||||
* @property {Path} pathObject - The `Path` object the parameter belongs t
|
||||
* @property {string[]} pathToDefinition - The path segments to the parameter definition
|
||||
* @property {string} ptr - The JSON Pointer to the parameter definition
|
||||
* @property {object} schema - The JSON Schema for the parameter
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function Parameter (opOrPath, ptr, definition, schema) {
|
||||
this.computedSchema = schema;
|
||||
function Parameter (opOrPathObject, definition, pathToDefinition) {
|
||||
// Assign local properties
|
||||
this.computedSchema = helpers.computeParameterSchema(definition);
|
||||
this.definition = definition;
|
||||
this.ptr = ptr;
|
||||
this.pathToDefinition = pathToDefinition;
|
||||
this.ptr = JsonRefs.pathToPtr(pathToDefinition);
|
||||
|
||||
if (opOrPath instanceof Operation) {
|
||||
this.operationObject = opOrPath;
|
||||
this.pathObject = opOrPath.pathObject;
|
||||
if (_.has(opOrPathObject, 'consumes')) {
|
||||
this.operationObject = opOrPathObject;
|
||||
this.pathObject = opOrPathObject.pathObject;
|
||||
} else {
|
||||
this.operationObject = undefined;
|
||||
this.pathObject = opOrPath;
|
||||
this.pathObject = opOrPathObject;
|
||||
}
|
||||
|
||||
// Assign Swagger definition properties to the parameter for easy access
|
||||
// Assign local properties from the Swagger definition properties
|
||||
_.assign(this, definition);
|
||||
|
||||
debug('Found %s parameter (%s in %s) at %s',
|
||||
_.isUndefined(this.operationObject) ? 'path-level' : 'operation',
|
||||
definition.name,
|
||||
definition.in,
|
||||
ptr);
|
||||
this.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +93,7 @@ Parameter.prototype.getSchema = function () {
|
|||
* @returns {*} The sample value
|
||||
*/
|
||||
Parameter.prototype.getSample = function () {
|
||||
return this.pathObject.api.plugin.getSample(this.computedSchema);
|
||||
return helpers.getJSONSchemaMocker()(this.computedSchema);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -116,11 +120,9 @@ Parameter.prototype.getSample = function () {
|
|||
* parameter is missing.
|
||||
*/
|
||||
Parameter.prototype.getValue = function (req) {
|
||||
var api = (this.operationObject || this.pathObject).api;
|
||||
|
||||
if (_.isUndefined(req)) {
|
||||
throw new TypeError('req is required');
|
||||
} else if (api.plugin.parameterLocations.indexOf(this.in) === -1) {
|
||||
} else if (helpers.parameterLocations.indexOf(this.in) === -1) {
|
||||
throw new Error('Invalid \'in\' value: ' + this.in);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var debug = require('debug')('sway:path');
|
||||
var helpers = require('../helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var Operation = require('./operation');
|
||||
var Parameter = require('./parameter');
|
||||
var pathToRegexp = require('path-to-regexp');
|
||||
|
||||
/**
|
||||
* The Path object.
|
||||
|
@ -37,34 +42,59 @@ var debug = require('debug')('sway:path');
|
|||
*
|
||||
* @param {SwaggerApi} api - The Swagger API object
|
||||
* @param {string} path - The path string
|
||||
* @param {ptr} ptr - The JSON Pointer to the path
|
||||
* @param {object} definition - The path definition
|
||||
* @param {regexp} regexp - The regexp used to match request paths against this path
|
||||
* @param {string[]} pathToDefinition - The path segments to the path definition
|
||||
*
|
||||
* @property {SwaggerApi} api - The Swagger API object
|
||||
* @property {object} definition - The path definition
|
||||
* @property {Operation[]} operationObjects - The operation objects
|
||||
* @property {Parameter[]} parameterObjects - The path-level parameter objects
|
||||
* @property {Operation[]} operationObjects - The `Operation` objects
|
||||
* @property {Parameter[]} parameterObjects - The path-level `Parameter` objects
|
||||
* @property {string} path - The path string
|
||||
* @property {string[]} pathToDefinition - The path segments to the path definition
|
||||
* @property {ptr} ptr - The JSON Pointer to the path
|
||||
* @property {regexp} regexp - The regexp used to match request paths against this path
|
||||
* @property {regexp} regexp - The `RegExp` used to match request paths against this path
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function Path (api, path, ptr, definition, regexp) {
|
||||
this.api = api;
|
||||
this.path = path;
|
||||
this.ptr = ptr;
|
||||
this.definition = definition;
|
||||
this.regexp = regexp;
|
||||
function Path (api, path, definition, pathToDefinition) {
|
||||
var basePathPrefix = api.definitionAllResolved.basePath || '/';
|
||||
var that = this;
|
||||
|
||||
// Assign Swagger definition properties to the operation for easy access
|
||||
// TODO: We could/should refactor this to use the path module
|
||||
|
||||
// Remove trailing slash from the basePathPrefix so we do not end up with double slashes
|
||||
if (basePathPrefix.charAt(basePathPrefix.length - 1) === '/') {
|
||||
basePathPrefix = basePathPrefix.substring(0, basePathPrefix.length - 1);
|
||||
}
|
||||
|
||||
// Assign local properties
|
||||
this.api = api;
|
||||
this.definition = definition;
|
||||
this.path = path;
|
||||
this.pathToDefinition = pathToDefinition;
|
||||
this.ptr = JsonRefs.pathToPtr(pathToDefinition);
|
||||
this.regexp = pathToRegexp(basePathPrefix + path.replace(/\{/g, ':').replace(/\}/g, ''));
|
||||
|
||||
// Assign local properties from the Swagger definition properties
|
||||
_.assign(this, definition);
|
||||
|
||||
debug('Found path at %s', ptr);
|
||||
this.parameterObjects = _.map(definition.parameters, function (paramDef, index) {
|
||||
return new Parameter(that,
|
||||
paramDef,
|
||||
pathToDefinition.concat(['parameters', index.toString()]));
|
||||
});
|
||||
this.operationObjects = _.reduce(definition, function (operations, operationDef, method) {
|
||||
if (helpers.supportedHttpMethods.indexOf(method) > -1) {
|
||||
operations.push(new Operation(that,
|
||||
method,
|
||||
operationDef,
|
||||
pathToDefinition.concat(method)));
|
||||
}
|
||||
|
||||
this.parameterObjects = api.plugin.getPathParameters(this);
|
||||
this.operationObjects = api.plugin.getOperations(this);
|
||||
return operations;
|
||||
}, []);
|
||||
|
||||
debug('Found path at %s', this.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var debug = require('debug')('sway:response');
|
||||
var sHelpers = require('../helpers');
|
||||
var helpers = require('../helpers');
|
||||
var jsonValidator = helpers.getJSONSchemaValidator();
|
||||
var JsonRefs = require('json-refs');
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
var jsonValidator;
|
||||
|
||||
/**
|
||||
* The Swagger Response object.
|
||||
*
|
||||
|
@ -39,30 +39,31 @@ var jsonValidator;
|
|||
* **Extra Properties:** Other than the documented properties, this object also exposes all properties of the definition
|
||||
* object.
|
||||
*
|
||||
* @param {Operation} operation - The Operation object
|
||||
* @param {string} ptr - The JSON Pointer to the response
|
||||
* @param {object} definition - The parameter definition
|
||||
* @param {Operation} operationObject - The `Operation` object
|
||||
* @param {string} statusCode - The status code
|
||||
* @param {object} definition - The parameter definition
|
||||
* @param {string[]} pathToDefinition - The path segments to the path definition
|
||||
*
|
||||
* @property {object} definition - The response definition
|
||||
* @property {Operation} operationObject - The Operation object
|
||||
* @property {string[]} pathToDefinition - The path segments to the path definition
|
||||
* @property {string} ptr - The JSON Pointer to the response definition
|
||||
* @property {string} statusCode - The status code
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function Response (operation, ptr, definition, statusCode) {
|
||||
function Response (operationObject, statusCode, definition, pathToDefinition) {
|
||||
// Assign local properties
|
||||
this.definition = definition;
|
||||
this.operationObject = operation;
|
||||
this.ptr = ptr;
|
||||
this.operationObject = operationObject;
|
||||
this.pathToDefinition = pathToDefinition;
|
||||
this.ptr = JsonRefs.pathToPtr(pathToDefinition);
|
||||
this.statusCode = statusCode;
|
||||
|
||||
// Assign Swagger definition properties to the parameter for easy access
|
||||
// Assign local properties from the Swagger definition properties
|
||||
_.assign(this, definition);
|
||||
|
||||
debug('Found %s response at %s', statusCode, ptr);
|
||||
|
||||
jsonValidator = operation.api.plugin.getJSONSchemaValidator();
|
||||
debug('Found %s response at %s', statusCode, this.ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +100,7 @@ Response.prototype.getSample = function () {
|
|||
var sample;
|
||||
|
||||
if (!_.isUndefined(this.definition.schema)) {
|
||||
sample = this.operationObject.api.plugin.getSample(this.definition.schema);
|
||||
sample = helpers.getJSONSchemaMocker()(this.definition.schema);
|
||||
}
|
||||
|
||||
return sample;
|
||||
|
@ -117,7 +118,6 @@ Response.prototype.validateResponse = function (res) {
|
|||
errors: [],
|
||||
warnings: []
|
||||
};
|
||||
var that = this;
|
||||
var bodyValue;
|
||||
var bvResults;
|
||||
|
||||
|
@ -132,7 +132,7 @@ Response.prototype.validateResponse = function (res) {
|
|||
|
||||
// Validate the Content-Type except for void responses, 204 responses and 304 responses as they have no body
|
||||
if (!_.isUndefined(this.definition.schema) && _.indexOf(['204', '304'], this.statusCode) === -1) {
|
||||
sHelpers.validateContentType(res.headers['content-type'], this.operationObject.produces, results);
|
||||
helpers.validateContentType(res.headers['content-type'], this.operationObject.produces, results);
|
||||
}
|
||||
|
||||
// Validate the response headers
|
||||
|
@ -141,28 +141,28 @@ Response.prototype.validateResponse = function (res) {
|
|||
var hvResults;
|
||||
|
||||
try {
|
||||
headerValue = that.operationObject.api.plugin.convertValue(schema,
|
||||
{
|
||||
collectionFormat: schema.collectionFormat
|
||||
},
|
||||
// Overly cautious
|
||||
res.headers[name.toLowerCase()] ||
|
||||
res.headers[name] ||
|
||||
schema.default);
|
||||
headerValue = helpers.convertValue(schema,
|
||||
{
|
||||
collectionFormat: schema.collectionFormat
|
||||
},
|
||||
// Overly cautious
|
||||
res.headers[name.toLowerCase()] ||
|
||||
res.headers[name] ||
|
||||
schema.default);
|
||||
} catch (err) {
|
||||
results.errors.push({
|
||||
code: 'INVALID_RESPONSE_HEADER',
|
||||
errors: err.errors || [
|
||||
{
|
||||
code: err.code,
|
||||
message: err.message,
|
||||
path: err.path
|
||||
}
|
||||
],
|
||||
message: 'Invalid header (' + name + '): ' + err.message,
|
||||
name: name,
|
||||
path: err.path
|
||||
});
|
||||
code: 'INVALID_RESPONSE_HEADER',
|
||||
errors: err.errors || [
|
||||
{
|
||||
code: err.code,
|
||||
message: err.message,
|
||||
path: err.path
|
||||
}
|
||||
],
|
||||
message: 'Invalid header (' + name + '): ' + err.message,
|
||||
name: name,
|
||||
path: err.path
|
||||
});
|
||||
}
|
||||
|
||||
// Due to ambiguity in the Swagger 2.0 Specification (https://github.com/swagger-api/swagger-spec/issues/321), it
|
||||
|
@ -172,7 +172,7 @@ Response.prototype.validateResponse = function (res) {
|
|||
// We also do not want to validate date objects because it is redundant. If we have already converted the value
|
||||
// from a string+format to a date, we know it passes schema validation.
|
||||
if (!_.isUndefined(headerValue) && !_.isDate(headerValue)) {
|
||||
hvResults = sHelpers.validateAgainstSchema(jsonValidator, schema, headerValue);
|
||||
hvResults = helpers.validateAgainstSchema(jsonValidator, schema, headerValue);
|
||||
|
||||
if (hvResults.errors.length > 0) {
|
||||
results.errors.push({
|
||||
|
@ -193,10 +193,10 @@ Response.prototype.validateResponse = function (res) {
|
|||
// Validate response for non-void responses
|
||||
if (!_.isUndefined(this.definition.schema) && _.indexOf(['204', '304'], this.statusCode) === -1) {
|
||||
try {
|
||||
bodyValue = that.operationObject.api.plugin.convertValue(this.definition.schema, {
|
||||
bodyValue = helpers.convertValue(this.definition.schema, {
|
||||
encoding: res.encoding
|
||||
}, res.body);
|
||||
bvResults = sHelpers.validateAgainstSchema(jsonValidator, this.definition.schema, bodyValue);
|
||||
bvResults = helpers.validateAgainstSchema(jsonValidator, this.definition.schema, bodyValue);
|
||||
} catch (err) {
|
||||
bvResults = {
|
||||
errors: [
|
||||
|
|
|
@ -25,10 +25,9 @@
|
|||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var helpers = require('../../helpers');
|
||||
var helpers = require('../helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var swaggerSchema = require('./schema.json');
|
||||
var vHelpers = require('./helpers');
|
||||
|
||||
function getSchemaProperties (schema) {
|
||||
var properties = _.keys(schema.properties); // Start with the defined properties
|
||||
|
@ -105,7 +104,7 @@ function walkSchema (api, blacklist, schema, path, handlers, response) {
|
|||
* @returns {object} Object containing the errors and warnings of the validation
|
||||
*/
|
||||
function validateStructure (api) {
|
||||
var results = helpers.validateAgainstSchema(api.plugin.getJSONSchemaValidator(), swaggerSchema, api.resolved);
|
||||
var results = helpers.validateAgainstSchema(helpers.getJSONSchemaValidator(), swaggerSchema, api.definitionAllResolved);
|
||||
|
||||
// Make complex JSON Schema validation errors easier to understand (Issue 15)
|
||||
results.errors = results.errors.map(function (error) {
|
||||
|
@ -180,7 +179,7 @@ function validateDefaultValue (api, response, schema, path) {
|
|||
var result;
|
||||
|
||||
if (!_.isUndefined(schema.default)) {
|
||||
result = helpers.validateAgainstSchema(api.plugin.getJSONSchemaValidator(), schema, schema.default);
|
||||
result = helpers.validateAgainstSchema(helpers.getJSONSchemaValidator(), schema, schema.default);
|
||||
|
||||
_.forEach(result.errors, function (error) {
|
||||
error.path = path.concat(error.path.concat('default'));
|
||||
|
@ -305,19 +304,19 @@ function validateReferences (api) {
|
|||
}
|
||||
|
||||
// Identify referenceable definitions
|
||||
_.forEach(api.resolved.definitions, function (def, name) {
|
||||
_.forEach(api.definitionAllResolved.definitions, function (def, name) {
|
||||
referenceable.push(JsonRefs.pathToPtr(['definitions', name]));
|
||||
});
|
||||
|
||||
_.forEach(api.resolved.parameters, function (def, name) {
|
||||
_.forEach(api.definitionAllResolved.parameters, function (def, name) {
|
||||
referenceable.push(JsonRefs.pathToPtr(['parameters', name]));
|
||||
});
|
||||
|
||||
_.forEach(api.resolved.responses, function (def, name) {
|
||||
_.forEach(api.definitionAllResolved.responses, function (def, name) {
|
||||
referenceable.push(JsonRefs.pathToPtr(['responses', name]));
|
||||
});
|
||||
|
||||
_.forEach(api.resolved.securityDefinitions, function (def, name) {
|
||||
_.forEach(api.definitionAllResolved.securityDefinitions, function (def, name) {
|
||||
var sPath = ['securityDefinitions', name];
|
||||
|
||||
referenceable.push(JsonRefs.pathToPtr(sPath));
|
||||
|
@ -360,16 +359,16 @@ function validateReferences (api) {
|
|||
});
|
||||
|
||||
// Identify references and validate missing references for non-JSON References (security)
|
||||
_.forEach(api.resolved.security, createSecurityProcessor(['security']));
|
||||
_.forEach(api.definitionAllResolved.security, createSecurityProcessor(['security']));
|
||||
|
||||
_.forEach(api.resolved.paths, function (pathDef, name) {
|
||||
_.forEach(api.definitionAllResolved.paths, function (pathDef, name) {
|
||||
var pPath = ['paths', name];
|
||||
|
||||
_.forEach(pathDef.security, createSecurityProcessor(pPath.concat('security')));
|
||||
|
||||
_.forEach(pathDef, function (operationDef, method) {
|
||||
// Do not process non-operations
|
||||
if (_.indexOf(vHelpers.supportedHttpMethods, method) === -1) {
|
||||
if (_.indexOf(helpers.supportedHttpMethods, method) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -433,7 +432,7 @@ function validateSchemaObjects (api) {
|
|||
|
||||
// Create JSON Schema for non-body parameters
|
||||
if (parameterDef.in !== 'body') {
|
||||
parameterDef = vHelpers.getParameterSchema(parameterDef);
|
||||
parameterDef = helpers.computeParameterSchema(parameterDef);
|
||||
}
|
||||
|
||||
walkSchema(api, blacklist, parameterDef, pPath, validators, response);
|
||||
|
@ -455,18 +454,18 @@ function validateSchemaObjects (api) {
|
|||
}
|
||||
|
||||
// Validate definitions
|
||||
_.forEach(api.resolved.definitions, function (definitionDef, name) {
|
||||
_.forEach(api.definitionAllResolved.definitions, function (definitionDef, name) {
|
||||
walkSchema(api, blacklist, definitionDef, ['definitions', name], validators, response);
|
||||
});
|
||||
|
||||
// Validate global parameter definitions
|
||||
validateParameters(api.resolved.parameters, ['parameters']);
|
||||
validateParameters(api.definitionAllResolved.parameters, ['parameters']);
|
||||
|
||||
// Validate global response definitions
|
||||
validateResponses(api.resolved.responses, ['responses']);
|
||||
validateResponses(api.definitionAllResolved.responses, ['responses']);
|
||||
|
||||
// Validate paths and operations
|
||||
_.forEach(api.resolved.paths, function (pathDef, path) {
|
||||
_.forEach(api.definitionAllResolved.paths, function (pathDef, path) {
|
||||
var pPath = ['paths', path];
|
||||
|
||||
// Validate path-level parameter definitions
|
||||
|
@ -476,7 +475,7 @@ function validateSchemaObjects (api) {
|
|||
var oPath = pPath.concat(method);
|
||||
|
||||
// Do not process non-operations
|
||||
if (_.indexOf(vHelpers.supportedHttpMethods, method) === -1) {
|
||||
if (_.indexOf(helpers.supportedHttpMethods, method) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -530,7 +529,7 @@ function validatePathsAndOperations (api) {
|
|||
return seenParameters;
|
||||
}
|
||||
|
||||
_.reduce(api.resolved.paths, function (metadata, pathDef, path) {
|
||||
_.reduce(api.definitionAllResolved.paths, function (metadata, pathDef, path) {
|
||||
var declaredPathParameters = [];
|
||||
var normalizedPath = path;
|
||||
var pPath = ['paths', path];
|
||||
|
@ -576,7 +575,7 @@ function validatePathsAndOperations (api) {
|
|||
var parameters;
|
||||
|
||||
// Do not process non-operations
|
||||
if (_.indexOf(vHelpers.supportedHttpMethods, method) === -1) {
|
||||
if (_.indexOf(helpers.supportedHttpMethods, method) === -1) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Apigee Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
// https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameter-object
|
||||
var parameterSchemaProperties = [
|
||||
'allowEmptyValue',
|
||||
'default',
|
||||
'description',
|
||||
'enum',
|
||||
'exclusiveMaximum',
|
||||
'exclusiveMinimum',
|
||||
'format',
|
||||
'items',
|
||||
'maxItems',
|
||||
'maxLength',
|
||||
'maximum',
|
||||
'minItems',
|
||||
'minLength',
|
||||
'minimum',
|
||||
'multipleOf',
|
||||
'pattern',
|
||||
'type',
|
||||
'uniqueItems'
|
||||
];
|
||||
|
||||
module.exports.getParameterSchema = function (parameter) {
|
||||
var schema;
|
||||
|
||||
if (_.isUndefined(parameter.schema)) {
|
||||
schema = {};
|
||||
|
||||
// Build the schema from the schema-like parameter structure
|
||||
_.forEach(parameterSchemaProperties, function (name) {
|
||||
if (!_.isUndefined(parameter[name])) {
|
||||
schema[name] = parameter[name];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
schema = parameter.schema;
|
||||
}
|
||||
|
||||
return schema;
|
||||
};
|
||||
|
||||
module.exports.supportedHttpMethods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'];
|
|
@ -1,513 +0,0 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Apigee Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var dirname = require('path').dirname;
|
||||
var formatGenerators = require('./format-generators');
|
||||
var helpers = require('../../helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var Operation = require('../../types/operation');
|
||||
var Parameter = require('../../types/parameter');
|
||||
var Path = require('../../types/path');
|
||||
var pathToRegexp = require('path-to-regexp');
|
||||
var Response = require('../../types/response');
|
||||
var SwaggerApi = require('../../types/api');
|
||||
var validators = require('./validators');
|
||||
var vHelpers = require('./helpers');
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
var collectionFormats = [undefined, 'csv', 'multi', 'pipes', 'ssv', 'tsv'];
|
||||
var customFormatValidators = require('./format-validators');
|
||||
var docsUrl = 'https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md';
|
||||
var jsonSchemaValidator = helpers.createJSONValidator({
|
||||
formatValidators: customFormatValidators
|
||||
});
|
||||
var mocker = helpers.createJSONSchemaMocker({
|
||||
formatGenerators: formatGenerators
|
||||
});
|
||||
var parameterLocations = ['body', 'formData', 'header', 'path', 'query'];
|
||||
var types = ['array', 'boolean', 'integer', 'object', 'number', 'string'];
|
||||
var version = '2.0';
|
||||
|
||||
function realConvertValue (schema, options, value) {
|
||||
var originalValue = value; // Used in error reporting for invalid values
|
||||
var type = _.isPlainObject(schema) ? schema.type : undefined;
|
||||
var pValue = value;
|
||||
var pType = typeof pValue;
|
||||
var err;
|
||||
|
||||
// If there is an explicit type provided, make sure it's one of the supported ones
|
||||
if (_.has(schema, 'type') && types.indexOf(type) === -1) {
|
||||
throw new TypeError('Invalid \'type\' value: ' + type);
|
||||
}
|
||||
|
||||
// Since JSON Schema allows you to not specify a type and it is treated as a wildcard of sorts, we should not do any
|
||||
// coercion for these types of values.
|
||||
if (_.isUndefined(type)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// If there is no value, do not convert it
|
||||
if (_.isUndefined(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Convert Buffer value to String
|
||||
// (We use this type of check to identify Buffer objects. The browser does not have a Buffer type and to avoid having
|
||||
// import the browserify buffer module, we just do a simple check. This is brittle but should work.)
|
||||
if (_.isFunction(value.readUInt8)) {
|
||||
value = value.toString(options.encoding);
|
||||
pValue = value;
|
||||
pType = typeof value;
|
||||
}
|
||||
|
||||
// If the value is empty and empty is allowed, use it
|
||||
if (schema.allowEmptyValue && value === '') {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Attempt to parse the string as JSON if the type is array or object
|
||||
if (['array', 'object'].indexOf(type) > -1) {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
// Nothing to do here, just fall through
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'array':
|
||||
if (_.isString(value)) {
|
||||
if (collectionFormats.indexOf(options.collectionFormat) === -1) {
|
||||
throw new TypeError('Invalid \'collectionFormat\' value: ' + options.collectionFormat);
|
||||
}
|
||||
|
||||
switch (options.collectionFormat) {
|
||||
case 'csv':
|
||||
case undefined:
|
||||
value = value.split(',');
|
||||
break;
|
||||
case 'multi':
|
||||
value = [value];
|
||||
break;
|
||||
case 'pipes':
|
||||
value = value.split('|');
|
||||
break;
|
||||
case 'ssv':
|
||||
value = value.split(' ');
|
||||
break;
|
||||
case 'tsv':
|
||||
value = value.split('\t');
|
||||
break;
|
||||
|
||||
// no default
|
||||
}
|
||||
}
|
||||
|
||||
if (_.isArray(value)) {
|
||||
value = _.map(value, function (item, index) {
|
||||
return realConvertValue(_.isArray(schema.items) ? schema.items[index] : schema.items, options, item);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'boolean':
|
||||
if (!_.isBoolean(value)) {
|
||||
if (value === 'true') {
|
||||
value = true;
|
||||
} else if (value === 'false') {
|
||||
value = false;
|
||||
} else {
|
||||
err = new TypeError('Not a valid boolean: ' + value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'integer':
|
||||
if (!_.isNumber(value)) {
|
||||
if (_.isString(value) && _.trim(value).length === 0) {
|
||||
value = NaN;
|
||||
}
|
||||
|
||||
value = Number(value);
|
||||
|
||||
if (_.isNaN(value)) {
|
||||
err = new TypeError('Not a valid integer: ' + originalValue);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'number':
|
||||
if (!_.isNumber(value)) {
|
||||
if (_.isString(value) && _.trim(value).length === 0) {
|
||||
value = NaN;
|
||||
}
|
||||
|
||||
value = Number(value);
|
||||
|
||||
if (_.isNaN(value)) {
|
||||
err = new TypeError('Not a valid number: ' + originalValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
if (['date', 'date-time'].indexOf(schema.format) > -1) {
|
||||
if (_.isString(value)) {
|
||||
value = new Date(value);
|
||||
}
|
||||
|
||||
if (!_.isDate(value) || value.toString() === 'Invalid Date') {
|
||||
err = new TypeError('Not a valid ' + schema.format + ' string: ' + originalValue);
|
||||
|
||||
err.code = 'INVALID_FORMAT';
|
||||
}
|
||||
} else if (!_.isString(value)) {
|
||||
err = new TypeError('Not a valid string: ' + value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// no default
|
||||
}
|
||||
|
||||
if (!_.isUndefined(err)) {
|
||||
// Convert the error to be more like a JSON Schema validation error
|
||||
if (_.isUndefined(err.code)) {
|
||||
err.code = 'INVALID_TYPE';
|
||||
err.message = 'Expected type ' + type + ' but found type ' + pType;
|
||||
} else {
|
||||
err.message = 'Object didn\'t pass validation for format ' + schema.format + ': ' + pValue;
|
||||
}
|
||||
|
||||
// Format and type errors resemble JSON Schema validation errors
|
||||
err.failedValidation = true;
|
||||
err.path = [];
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function removeCirculars (doc) {
|
||||
function walk (ancestors, node, path) {
|
||||
function walkItem (item, segment) {
|
||||
path.push(segment);
|
||||
walk(ancestors, item, path);
|
||||
path.pop();
|
||||
}
|
||||
|
||||
// We do not process circular objects again
|
||||
if (ancestors.indexOf(node) === -1) {
|
||||
ancestors.push(node);
|
||||
|
||||
if (_.isArray(node) || _.isPlainObject(node)) {
|
||||
_.each(node, function (member, indexOrKey) {
|
||||
walkItem(member, indexOrKey.toString());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
_.set(doc, path, {});
|
||||
}
|
||||
|
||||
ancestors.pop();
|
||||
}
|
||||
|
||||
walk([], doc, []);
|
||||
}
|
||||
|
||||
module.exports.collectionFormats = collectionFormats;
|
||||
|
||||
// The URL to the Swagger 2.0 documentation
|
||||
module.exports.documentation = docsUrl;
|
||||
|
||||
module.exports.parameterLocations = parameterLocations;
|
||||
|
||||
// The array of supported HTTP methods for each path
|
||||
module.exports.supportedHttpMethods = vHelpers.supportedHttpMethods;
|
||||
|
||||
module.exports.types = types;
|
||||
|
||||
// The version for this Swagger version
|
||||
module.exports.version = version;
|
||||
|
||||
/**
|
||||
* Returns whether or not the provided definition can be processed.
|
||||
*
|
||||
* @param {object} definition - The potential Swagger definition to test
|
||||
*
|
||||
* @returns {boolean} Returns true only if the definition represents a Swagger 2.0 definition
|
||||
*/
|
||||
module.exports.canProcess = function (definition) {
|
||||
return definition.swagger === version;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a raw JavaScript value to a JSON Schema value based on its schema.
|
||||
*
|
||||
* @param {object} schema - The schema for the value
|
||||
* @param {object} options - The conversion options
|
||||
* @param {string} [options.collectionFormat] - The collection format
|
||||
* @param {string} [options.encoding] - The encoding if the raw value is a `Buffer`
|
||||
* @param {*} value - The value to convert
|
||||
*
|
||||
* @returns {*} The converted value
|
||||
*/
|
||||
module.exports.convertValue = function (schema, options, value) {
|
||||
return realConvertValue(schema, options, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a SwaggerApi object from the provided Swagger definition.
|
||||
*
|
||||
* @param {object} definition - The Swagger definition
|
||||
* @param {object} options - The options passed to swaggerApi.create
|
||||
*
|
||||
* @returns {Promise} A promise that resolves the SwaggerApi after processing
|
||||
*/
|
||||
module.exports.createSwaggerApi = function (definition, options) {
|
||||
var cOptions = _.cloneDeep(options);
|
||||
var jsonRefsOptions = cOptions.jsonRefs || {};
|
||||
|
||||
// Include invalid reference information
|
||||
jsonRefsOptions.includeInvalid = true;
|
||||
|
||||
// Update the json-refs options to use the definition location
|
||||
if (_.isString(cOptions.definition)) {
|
||||
jsonRefsOptions.relativeBase = dirname(cOptions.definition);
|
||||
}
|
||||
|
||||
// Update the json-refs options to process YAML
|
||||
if (_.isUndefined(jsonRefsOptions.loaderOptions)) {
|
||||
jsonRefsOptions.loaderOptions = {};
|
||||
}
|
||||
|
||||
if (_.isUndefined(jsonRefsOptions.loaderOptions.processContent)) {
|
||||
jsonRefsOptions.loaderOptions.processContent = function (res, cb) {
|
||||
cb(undefined, YAML.safeLoad(res.text));
|
||||
};
|
||||
}
|
||||
|
||||
return JsonRefs.resolveRefs(definition, jsonRefsOptions)
|
||||
.then(function (results) {
|
||||
// We need to remove all circular objects as z-schema does not work with them:
|
||||
// https://github.com/zaggino/z-schema/issues/137
|
||||
removeCirculars(results.resolved);
|
||||
|
||||
return new SwaggerApi(module.exports, definition, results.resolved, results.refs, options);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a z-schema validator.
|
||||
*
|
||||
* @returns {Object} The z-schema validator to use
|
||||
*/
|
||||
module.exports.getJSONSchemaValidator = function () {
|
||||
return jsonSchemaValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of Operation objects for each operation defined in path definition.
|
||||
*
|
||||
* @param {Path} pathObject - The Path object
|
||||
*
|
||||
* @returns {Operation[]} The Operation object array
|
||||
*/
|
||||
module.exports.getOperations = function (pathObject) {
|
||||
var operations = [];
|
||||
var pPath = JsonRefs.pathFromPtr(pathObject.ptr);
|
||||
var pParams = _.reduce(pathObject.definition.parameters, function (parameters, paramDef, index) {
|
||||
parameters[paramDef.name + ':' + paramDef.in] = {
|
||||
path: pPath.concat(['parameters', index.toString()]),
|
||||
definition: paramDef
|
||||
};
|
||||
|
||||
return parameters;
|
||||
}, {});
|
||||
|
||||
_.forEach(pathObject.definition, function (operation, method) {
|
||||
// Do not process non-operations
|
||||
if (_.indexOf(vHelpers.supportedHttpMethods, method) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cOperation = _.cloneDeep(operation); // Clone so we do not alter the input
|
||||
var oParams = {}; // Used to keep track of unique parameters
|
||||
var oPath = pPath.concat(method);
|
||||
|
||||
// Add path parameters
|
||||
_.forEach(pParams, function (pParam, key) {
|
||||
oParams[key] = pParam;
|
||||
});
|
||||
|
||||
// Add operation parameters (Overrides path-level parameters of same name+in combination)
|
||||
_.forEach(operation.parameters, function (paramDef, index) {
|
||||
oParams[paramDef.name + ':' + paramDef.in] = {
|
||||
path: oPath.concat(['parameters', index.toString()]),
|
||||
definition: paramDef
|
||||
};
|
||||
});
|
||||
|
||||
// Attach our computed parameters/security to the operation
|
||||
cOperation.parameters = _.map(_.values(oParams), function (parameter) {
|
||||
// Used later by getOperationParameters to circumvent the chicken/egg situation (Removed there as well)
|
||||
parameter.definition.$$$ptr$$$ = JsonRefs.pathToPtr(parameter.path);
|
||||
|
||||
return parameter.definition;
|
||||
});
|
||||
|
||||
|
||||
if (_.isUndefined(cOperation.security)) {
|
||||
cOperation.security = pathObject.api.resolved.security;
|
||||
}
|
||||
|
||||
operations.push(new Operation(pathObject.api,
|
||||
pathObject,
|
||||
method,
|
||||
JsonRefs.pathToPtr(oPath),
|
||||
cOperation,
|
||||
cOperation.consumes || pathObject.api.resolved.consumes || [],
|
||||
cOperation.produces || pathObject.api.resolved.produces || []));
|
||||
});
|
||||
|
||||
return operations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of Parameter objects for the provided Operation.
|
||||
*
|
||||
* @param {Operation} operation - The Operation object
|
||||
*
|
||||
* @returns {Parameter[]} The Parameter object array
|
||||
*/
|
||||
module.exports.getOperationParameters = function (operation) {
|
||||
var pParams = _.reduce(operation.pathObject.getParameters(), function (params, param) {
|
||||
params[param.ptr] = param;
|
||||
|
||||
return params;
|
||||
}, {});
|
||||
|
||||
return _.map(operation.parameters, function (paramDef) {
|
||||
var ptr = paramDef.$$$ptr$$$;
|
||||
var pParam = pParams[ptr];
|
||||
|
||||
// Remove so we do not have these properties littered throughout the document
|
||||
delete paramDef.$$$ptr$$$;
|
||||
|
||||
if (_.isUndefined(pParam)) {
|
||||
return new Parameter(operation, ptr, paramDef, vHelpers.getParameterSchema(paramDef));
|
||||
} else {
|
||||
return pParam;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of Response objects for the provided Operation.
|
||||
*
|
||||
* @param {Operation} operation - The Operation object
|
||||
*
|
||||
* @returns {Response[]} The Response object array
|
||||
*/
|
||||
module.exports.getOperationResponses = function (operation) {
|
||||
return _.map(operation.definition.responses, function (responseDef, code) {
|
||||
return new Response(operation,
|
||||
JsonRefs.pathToPtr(JsonRefs.pathFromPtr(operation.ptr).concat(['responses', code])),
|
||||
responseDef,
|
||||
code);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of path-level Parameter objects for the provided Path.
|
||||
*
|
||||
* @param {Path} path - The Path object
|
||||
*
|
||||
* @returns {Parameter[]} The Parameter object array
|
||||
*/
|
||||
module.exports.getPathParameters = function (path) {
|
||||
return _.map(path.definition.parameters, function (paramDef, index) {
|
||||
return new Parameter(path,
|
||||
JsonRefs.pathToPtr(JsonRefs.pathFromPtr(path.ptr).concat(index.toString())),
|
||||
paramDef,
|
||||
vHelpers.getParameterSchema(paramDef));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an array of Path objects for each path defined in the Swagger document.
|
||||
*
|
||||
* @param {SwaggerApi} api - The Swagger API object
|
||||
*
|
||||
* @returns {Path[]} The Operation object array
|
||||
*/
|
||||
module.exports.getPaths = function (api) {
|
||||
var basePathPrefix = api.resolved.basePath || '/';
|
||||
|
||||
// Remove trailing slash from the basePathPrefix so we do not end up with double slashes
|
||||
if (basePathPrefix.charAt(basePathPrefix.length - 1) === '/') {
|
||||
basePathPrefix = basePathPrefix.substring(0, basePathPrefix.length - 1);
|
||||
}
|
||||
|
||||
return _.map(api.resolved.paths, function (pathDef, path) {
|
||||
return new Path(api,
|
||||
path,
|
||||
JsonRefs.pathToPtr(['paths', path]),
|
||||
pathDef,
|
||||
pathToRegexp(basePathPrefix + path.replace(/\{/g, ':').replace(/\}/g, '')));
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a sample value for the provided JSON Schema.
|
||||
*
|
||||
* @param {*} schema - The JSON Schema
|
||||
*
|
||||
* @returns {*} The sample value
|
||||
*/
|
||||
module.exports.getSample = function (schema) {
|
||||
return mocker(schema);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of functions used to validate Swagger 2.0 documents semantically.
|
||||
*
|
||||
* @returns {function[]} The validators to use
|
||||
*/
|
||||
module.exports.getSemanticValidators = function () {
|
||||
return validators.semanticValidators;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function used to validate Swagger 2.0 documents against its JSON Schema.
|
||||
*
|
||||
* @returns {function} The validator to use
|
||||
*/
|
||||
module.exports.getStructuralValidator = function () {
|
||||
return validators.jsonSchemaValidator;
|
||||
};
|
|
@ -31,10 +31,11 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"brfs": "^1.4.2",
|
||||
"browserify": "^12.0.1",
|
||||
"browserify": "^13.0.0",
|
||||
"connect": "^3.4.0",
|
||||
"del": "^2.2.0",
|
||||
"exposify": "^0.5.0",
|
||||
"glob": "^6.0.4",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-eslint": "^1.1.1",
|
||||
|
@ -59,14 +60,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"debug": "^2.2.0",
|
||||
"glob": "^6.0.3",
|
||||
"js-base64": "^2.1.9",
|
||||
"js-yaml": "^3.4.6",
|
||||
"json-refs": "^2.0.2",
|
||||
"js-yaml": "^3.5.1",
|
||||
"json-refs": "^2.0.3",
|
||||
"json-schema-faker": "^0.2.6",
|
||||
"lodash": "^3.10.1",
|
||||
"native-promise-only": "^0.8.1",
|
||||
"path-loader": "^1.0.1",
|
||||
"path-to-regexp": "^1.2.1",
|
||||
"z-schema": "^3.16.1"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-env browser, mocha */
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
@ -25,10 +27,17 @@
|
|||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
var helpers = require('../lib/helpers');
|
||||
var path = require('path');
|
||||
var Sway = typeof window === 'undefined' ? require('..') : window.Sway;
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
var documentBase = path.join(__dirname, 'browser', 'documents');
|
||||
var relativeBase = typeof window === 'undefined' ? documentBase : 'base/documents';
|
||||
var swaggerDoc = YAML.safeLoad(fs.readFileSync(path.join(__dirname, './browser/documents/2.0/swagger.yaml'), 'utf8'));
|
||||
var swaggerDocValidator = helpers.getJSONSchemaValidator();
|
||||
var swaggerApi
|
||||
|
||||
function fail (msg) {
|
||||
assert.fail(msg);
|
||||
|
@ -38,7 +47,26 @@ module.exports.documentBase = documentBase;
|
|||
|
||||
module.exports.fail = fail;
|
||||
|
||||
module.exports.relativeBase = relativeBase;
|
||||
module.exports.getSwaggerApi = function (callback) {
|
||||
if (swaggerApi) {
|
||||
callback(swaggerApi);
|
||||
} else {
|
||||
Sway.create({
|
||||
definition: swaggerDoc
|
||||
})
|
||||
.then(function (obj) {
|
||||
swaggerApi = obj;
|
||||
|
||||
callback(swaggerApi);
|
||||
}, function (err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.getSway = function () {
|
||||
return Sway;
|
||||
};
|
||||
|
||||
module.exports.shouldHadFailed = function () {
|
||||
fail('The code above should had thrown an error');
|
||||
|
@ -49,3 +77,11 @@ module.exports.shouldNotHadFailed = function (err) {
|
|||
|
||||
fail('The code above should not had thrown an error');
|
||||
};
|
||||
|
||||
module.exports.swaggerDoc = swaggerDoc;
|
||||
|
||||
module.exports.swaggerDocPath = path.join(relativeBase, './2.0/swagger.yaml');
|
||||
|
||||
module.exports.swaggerDocRelativeRefsPath = path.join(relativeBase, './2.0/swagger-relative-refs.yaml');
|
||||
|
||||
module.exports.swaggerDocValidator = swaggerDocValidator;
|
||||
|
|
|
@ -28,32 +28,43 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var tHelpers = require('../../helpers'); // Helpers for tests
|
||||
var helpers = require('./helpers');
|
||||
var sHelpers = require('../lib/helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('SwaggerApi (Swagger 2.0)', function () {
|
||||
var sway;
|
||||
function getOperationCount (pathDef) {
|
||||
var count = 0;
|
||||
|
||||
_.each(pathDef, function (operation, method) {
|
||||
if (sHelpers.supportedHttpMethods.indexOf(method) > -1) {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
describe('SwaggerApi', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
sway.customValidators = [];
|
||||
sway.errors = [];
|
||||
sway.warnings = [];
|
||||
swaggerApi.customValidators = [];
|
||||
});
|
||||
|
||||
describe('#getOperations', function () {
|
||||
it('should return return all operations', function () {
|
||||
var operations = sway.getOperations();
|
||||
it('should return all operations', function () {
|
||||
var operations = swaggerApi.getOperations();
|
||||
|
||||
assert.equal(operations.length, _.reduce(sway.definition.paths, function (count, path) {
|
||||
count += helpers.getOperationCount(path);
|
||||
assert.equal(operations.length, _.reduce(swaggerApi.definition.paths, function (count, path) {
|
||||
count += getOperationCount(path);
|
||||
|
||||
return count;
|
||||
}, 0));
|
||||
|
@ -62,53 +73,53 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should return return all operations for the given path', function () {
|
||||
var operations = sway.getOperations('/pet/{petId}');
|
||||
var operations = swaggerApi.getOperations('/pet/{petId}');
|
||||
|
||||
assert.ok(sway.getOperations().length > operations.length);
|
||||
assert.equal(operations.length, helpers.getOperationCount(sway.definition.paths['/pet/{petId}']));
|
||||
assert.ok(swaggerApi.getOperations().length > operations.length);
|
||||
assert.equal(operations.length, getOperationCount(swaggerApi.definition.paths['/pet/{petId}']));
|
||||
});
|
||||
|
||||
it('should return return no operations for a missing path', function () {
|
||||
assert.equal(sway.getOperations('/some/fake/path').length, 0);
|
||||
assert.equal(swaggerApi.getOperations('/some/fake/path').length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getOperation', function () {
|
||||
describe('path + method', function () {
|
||||
it('should return the expected operation', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}', 'get');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}', 'get');
|
||||
|
||||
assert.ok(!_.isUndefined(operation));
|
||||
});
|
||||
|
||||
it('should return no operation for missing path', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation('/petz/{petId}', 'get')));
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation('/petz/{petId}', 'get')));
|
||||
});
|
||||
|
||||
it('should return no operation for missing method', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation('/pet/{petId}', 'head')));
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation('/pet/{petId}', 'head')));
|
||||
});
|
||||
});
|
||||
|
||||
describe('http.ClientRequest (or similar)', function () {
|
||||
it('should return the expected operation', function () {
|
||||
assert.ok(!_.isUndefined(sway.getOperation({
|
||||
assert.ok(!_.isUndefined(swaggerApi.getOperation({
|
||||
method: 'GET',
|
||||
url: sway.basePath + '/pet/1'
|
||||
url: swaggerApi.basePath + '/pet/1'
|
||||
})));
|
||||
});
|
||||
|
||||
it('should return no operation for missing path', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation({
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation({
|
||||
method: 'GET',
|
||||
url: sway.basePath + '/petz/1'
|
||||
url: swaggerApi.basePath + '/petz/1'
|
||||
})));
|
||||
});
|
||||
|
||||
it('should return no operation for missing method', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation({
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation({
|
||||
method: 'HEAD',
|
||||
url: sway.basePath + '/pet/1'
|
||||
url: swaggerApi.basePath + '/pet/1'
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
@ -116,42 +127,42 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
describe('#getOperationsByTag', function () {
|
||||
it('should return no operation for incorrect tag', function () {
|
||||
var operations = sway.getOperationsByTag('incorrect tag');
|
||||
var operations = swaggerApi.getOperationsByTag('incorrect tag');
|
||||
|
||||
assert.equal(operations.length, 0);
|
||||
});
|
||||
|
||||
it('should return all operations for the given tag', function () {
|
||||
var operations = sway.getOperationsByTag('store');
|
||||
var operations = swaggerApi.getOperationsByTag('store');
|
||||
|
||||
assert.equal(operations.length,
|
||||
helpers.getOperationCount(sway.definition.paths['/store/inventory']) +
|
||||
helpers.getOperationCount(sway.definition.paths['/store/order']) +
|
||||
helpers.getOperationCount(sway.definition.paths['/store/order/{orderId}']));
|
||||
getOperationCount(swaggerApi.definition.paths['/store/inventory']) +
|
||||
getOperationCount(swaggerApi.definition.paths['/store/order']) +
|
||||
getOperationCount(swaggerApi.definition.paths['/store/order/{orderId}']));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getPath', function () {
|
||||
describe('path', function () {
|
||||
it('should return the expected path object', function () {
|
||||
assert.ok(!_.isUndefined(sway.getPath('/pet/{petId}')));
|
||||
assert.ok(!_.isUndefined(swaggerApi.getPath('/pet/{petId}')));
|
||||
});
|
||||
|
||||
it('should return no path object', function () {
|
||||
assert.ok(_.isUndefined(sway.getPath('/petz/{petId}')));
|
||||
assert.ok(_.isUndefined(swaggerApi.getPath('/petz/{petId}')));
|
||||
});
|
||||
});
|
||||
|
||||
describe('http.ClientRequest (or similar)', function () {
|
||||
it('should return the expected path object', function () {
|
||||
assert.ok(!_.isUndefined(sway.getPath({
|
||||
url: sway.basePath + '/pet/1'
|
||||
assert.ok(!_.isUndefined(swaggerApi.getPath({
|
||||
url: swaggerApi.basePath + '/pet/1'
|
||||
})));
|
||||
});
|
||||
|
||||
it('should return no path object', function () {
|
||||
assert.ok(_.isUndefined(sway.getPath({
|
||||
url: sway.basePath + '/petz/1'
|
||||
assert.ok(_.isUndefined(swaggerApi.getPath({
|
||||
url: swaggerApi.basePath + '/petz/1'
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
@ -159,7 +170,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
describe('#getPaths', function () {
|
||||
it('should return the expected path objects', function () {
|
||||
assert.equal(sway.getPaths().length, Object.keys(sway.resolved.paths).length);
|
||||
assert.equal(swaggerApi.getPaths().length, Object.keys(swaggerApi.definitionAllResolved.paths).length);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -172,9 +183,9 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
_.forEach(scenarios, function (scenario) {
|
||||
try {
|
||||
sway.registerValidator.apply(sway, scenario[0]);
|
||||
swaggerApi.registerValidator.apply(swaggerApi, scenario[0]);
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(scenario[1], err.message);
|
||||
}
|
||||
|
@ -182,7 +193,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should add validator to list of validators', function () {
|
||||
var results = sway.validate();
|
||||
var results = swaggerApi.validate();
|
||||
var expectedErrors = [
|
||||
'error'
|
||||
];
|
||||
|
@ -193,14 +204,14 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
assert.deepEqual(results.errors, []);
|
||||
assert.deepEqual(results.warnings, []);
|
||||
|
||||
sway.registerValidator(function () {
|
||||
swaggerApi.registerValidator(function () {
|
||||
return {
|
||||
errors: expectedErrors,
|
||||
warnings: expectedWarnings
|
||||
};
|
||||
});
|
||||
|
||||
results = sway.validate();
|
||||
results = swaggerApi.validate();
|
||||
|
||||
assert.deepEqual(results.errors, expectedErrors);
|
||||
assert.deepEqual(results.warnings, expectedWarnings);
|
||||
|
@ -209,7 +220,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
describe('#validate', function () {
|
||||
it('should return zero errors/warnings for a valid document', function () {
|
||||
var results = sway.validate();
|
||||
var results = swaggerApi.validate();
|
||||
|
||||
assert.deepEqual(results.errors, []);
|
||||
assert.deepEqual(results.warnings, []);
|
||||
|
@ -221,7 +232,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.paths;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -241,7 +252,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
describe('array type missing required items property', function () {
|
||||
function validateBrokenArray (cSwagger, path, done) {
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -510,7 +521,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
additionalProperties: errorSchema
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -759,7 +770,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
]
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -809,7 +820,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
]
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -855,7 +866,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
]
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -884,7 +895,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -910,7 +921,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
default: 123
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -934,7 +945,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.definitions.Pet.properties.name.default = 123;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -963,7 +974,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters.push(cParam);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -990,7 +1001,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/{petId}'].parameters.push(cParam);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1016,7 +1027,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
$ref: '/file[/].html'
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1039,7 +1050,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/invalid/{}'] = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1070,7 +1081,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
];
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1093,7 +1104,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/{petId}'].parameters = [];
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1126,7 +1137,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/{notPetId}'] = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1150,7 +1161,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].put.operationId = operationId;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1176,7 +1187,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.parameters.push(dBodyParam);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1205,7 +1216,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
type: 'string'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1239,7 +1250,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.definitions.Pet.properties;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1262,7 +1273,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.definitions.Pet.properties.name;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1287,7 +1298,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.definitions.Missing = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1316,7 +1327,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1343,7 +1354,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1370,7 +1381,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
in: 'header'
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1393,7 +1404,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.securityDefinitions.petstore_auth.scopes.missing = 'I am missing';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1419,7 +1430,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.parameters[0].schema.$ref = '#/definitions/Missing';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1443,7 +1454,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.parameters[0].schema.$ref = 'fake.json';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1472,7 +1483,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
missing: []
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1497,7 +1508,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
missing: []
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1522,7 +1533,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.security[0].petstore_auth.push('missing');
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1549,7 +1560,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
]
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1584,7 +1595,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.parameters[0] = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1600,7 +1611,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
broken: {}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1614,7 +1625,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.responses.default = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1631,7 +1642,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
schema: []
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1648,7 +1659,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
additionalProperties: []
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1670,7 +1681,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1684,7 +1695,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.securityDefinitions.broken = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1706,7 +1717,7 @@ describe('SwaggerApi (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
|
@ -29,8 +29,9 @@
|
|||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('format generators (Swagger 2.0)', function () {
|
||||
describe('format generators', function () {
|
||||
it('byte', function (done) {
|
||||
var cSwaggerDoc = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
|
@ -41,7 +42,7 @@ describe('format generators (Swagger 2.0)', function () {
|
|||
format: 'byte'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -60,7 +61,7 @@ describe('format generators (Swagger 2.0)', function () {
|
|||
format: 'password'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
|
@ -29,8 +29,9 @@
|
|||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('format validators (Swagger 2.0)', function () {
|
||||
describe('format validators', function () {
|
||||
it('always truthy', function (done) {
|
||||
var cSwaggerDoc = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
|
@ -66,7 +67,7 @@ describe('format validators (Swagger 2.0)', function () {
|
|||
default: 'somepassword'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({definition: cSwaggerDoc})
|
||||
Sway.create({definition: cSwaggerDoc})
|
||||
.then(function (api) {
|
||||
assert.ok(api.validate());
|
||||
})
|
||||
|
@ -88,7 +89,7 @@ describe('format validators (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
// Test the format validator using parameter validation
|
||||
helpers.swaggerApi.create({definition: cSwaggerDoc})
|
||||
Sway.create({definition: cSwaggerDoc})
|
||||
.then(function (api) {
|
||||
badParamValue = api.getOperation('/pet/findByStatus', 'get').getParameter('int32').getValue({
|
||||
query: {
|
||||
|
@ -142,7 +143,7 @@ describe('format validators (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
// Test the format validator using parameter validation
|
||||
helpers.swaggerApi.create({definition: cSwaggerDoc})
|
||||
Sway.create({definition: cSwaggerDoc})
|
||||
.then(function (api) {
|
||||
badParamValue = api.getOperation('/pet/findByStatus', 'get').getParameter('int64').getValue({
|
||||
query: {
|
|
@ -28,15 +28,15 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var tHelpers = require('../../helpers'); // Helpers for tests
|
||||
var helpers = require('./helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('issues (Swagger 2.0)', function () {
|
||||
var sway;
|
||||
describe('issues', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -47,16 +47,16 @@ describe('issues (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/{petId}'].get = null;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function () {
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
})
|
||||
.catch(function (err) {
|
||||
var errorMessages = [
|
||||
'Cannot read property \'parameters\' of null', // Node.js
|
||||
'\'null\' is not an object (evaluating \'operation.parameters\')' // PhantomJS (browser)
|
||||
'Cannot read property \'consumes\' of null', // Node.js
|
||||
'\'null\' is not an object (evaluating \'definition.consumes\')' // PhantomJS (browser)
|
||||
];
|
||||
|
||||
assert.ok(errorMessages.indexOf(err.message) > -1);
|
||||
|
@ -65,21 +65,18 @@ describe('issues (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should support relative references (and to YAML files) (Issue 17)', function (done) {
|
||||
helpers.swaggerApi.create({
|
||||
definition: './2.0/swagger-relative-refs.yaml',
|
||||
jsonRefs: {
|
||||
relativeBase: tHelpers.relativeBase
|
||||
}
|
||||
Sway.create({
|
||||
definition: helpers.swaggerDocRelativeRefsPath
|
||||
})
|
||||
.then(function () {
|
||||
assert.ok(_.isUndefined(sway.resolved.info.$ref));
|
||||
assert.ok(Object.keys(sway.resolved.definitions).length > 1);
|
||||
assert.ok(Object.keys(sway.resolved.paths).length > 1);
|
||||
assert.equal(sway.resolved.info.title, 'Swagger Petstore');
|
||||
assert.ok(_.isPlainObject(sway.resolved.definitions.Pet));
|
||||
assert.ok(_.isPlainObject(sway.resolved.paths['/pet/{petId}'].get));
|
||||
assert.ok(_.isUndefined(swaggerApi.definitionAllResolved.info.$ref));
|
||||
assert.ok(Object.keys(swaggerApi.definitionAllResolved.definitions).length > 1);
|
||||
assert.ok(Object.keys(swaggerApi.definitionAllResolved.paths).length > 1);
|
||||
assert.equal(swaggerApi.definitionAllResolved.info.title, 'Swagger Petstore');
|
||||
assert.ok(_.isPlainObject(swaggerApi.definitionAllResolved.definitions.Pet));
|
||||
assert.ok(_.isPlainObject(swaggerApi.definitionAllResolved.paths['/pet/{petId}'].get));
|
||||
|
||||
_.each(sway.references, function (entry) {
|
||||
_.each(swaggerApi.references, function (entry) {
|
||||
assert.ok(typeof entry.missing === 'undefined');
|
||||
});
|
||||
})
|
||||
|
@ -91,7 +88,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
|
||||
cSwaggerDoc.definitions.Pet.properties.name.format = 'unknown';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -105,7 +102,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
|
||||
cSwaggerDoc.definitions.Pet.properties.default = {type: 'string'};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -120,9 +117,9 @@ describe('issues (Swagger 2.0)', function () {
|
|||
mockReq.url = '/pet/1';
|
||||
|
||||
try {
|
||||
sway.getOperation('/pet/{petId}', 'get').getParameter('petId').getValue(mockReq);
|
||||
swaggerApi.getOperation('/pet/{petId}', 'get').getParameter('petId').getValue(mockReq);
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed();
|
||||
helpers.shouldNotHadFailed();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -131,7 +128,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
originalname: 'swagger.yaml',
|
||||
mimetype: 'application/x-yaml'
|
||||
};
|
||||
var paramValue = sway.getOperation('/pet/{petId}/uploadImage', 'post').getParameter('file').getValue({
|
||||
var paramValue = swaggerApi.getOperation('/pet/{petId}/uploadImage', 'post').getParameter('file').getValue({
|
||||
url: '/pet/1/uploadImage',
|
||||
files: {
|
||||
file: mockFile
|
||||
|
@ -176,7 +173,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
]
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -197,7 +194,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
type: 'object'
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -246,7 +243,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
type: 'object'
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -308,7 +305,7 @@ describe('issues (Swagger 2.0)', function () {
|
|||
type: 'integer'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
|
@ -28,14 +28,15 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var helpers = require('./helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('Operation (Swagger 2.0)', function () {
|
||||
var sway;
|
||||
describe('Operation', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -44,9 +45,9 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
it('should handle composite parameters', function () {
|
||||
var method = 'post';
|
||||
var path = '/pet/{petId}';
|
||||
var operation = sway.getOperation(path, method);
|
||||
var pathDef = sway.resolved.paths[path];
|
||||
var operationDef = sway.resolved.paths[path][method];
|
||||
var operation = swaggerApi.getOperation(path, method);
|
||||
var pathDef = swaggerApi.definitionAllResolved.paths[path];
|
||||
var operationDef = swaggerApi.definitionAllResolved.paths[path][method];
|
||||
|
||||
assert.equal(operation.pathObject.path, path);
|
||||
assert.equal(operation.method, method);
|
||||
|
@ -79,8 +80,8 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
it('should handle explicit parameters', function () {
|
||||
var method = 'post';
|
||||
var path = '/pet/{petId}/uploadImage';
|
||||
var operation = sway.getOperation(path, method);
|
||||
var pathDef = sway.resolved.paths[path];
|
||||
var operation = swaggerApi.getOperation(path, method);
|
||||
var pathDef = swaggerApi.definitionAllResolved.paths[path];
|
||||
|
||||
assert.equal(operation.pathObject.path, path);
|
||||
assert.equal(operation.method, method);
|
||||
|
@ -103,7 +104,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should handle composite security', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}', 'get');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}', 'get');
|
||||
|
||||
assert.deepEqual(operation.security, [
|
||||
{
|
||||
|
@ -114,12 +115,12 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
}
|
||||
]);
|
||||
assert.deepEqual(operation.securityDefinitions, {
|
||||
'petstore_auth': sway.resolved.securityDefinitions.petstore_auth
|
||||
'petstore_auth': swaggerApi.definitionAllResolved.securityDefinitions.petstore_auth
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle explicit parameters', function () {
|
||||
assert.deepEqual(sway.getOperation('/user/{username}', 'get').security, [
|
||||
assert.deepEqual(swaggerApi.getOperation('/user/{username}', 'get').security, [
|
||||
{
|
||||
'api_key': []
|
||||
}
|
||||
|
@ -147,7 +148,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
}
|
||||
|
||||
it('should create proper regexp (with basePath)', function () {
|
||||
validateRegExps(sway, sway.basePath);
|
||||
validateRegExps(swaggerApi, swaggerApi.basePath);
|
||||
});
|
||||
|
||||
it('should create proper regexp (with basePath ending in slash)', function (done) {
|
||||
|
@ -155,7 +156,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.basePath = '/';
|
||||
|
||||
helpers.swaggerApi.create({definition: cSwagger})
|
||||
Sway.create({definition: cSwagger})
|
||||
.then(function (api) {
|
||||
validateRegExps(api, '');
|
||||
})
|
||||
|
@ -167,7 +168,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.basePath;
|
||||
|
||||
helpers.swaggerApi.create({definition: cSwagger})
|
||||
Sway.create({definition: cSwagger})
|
||||
.then(function (api) {
|
||||
validateRegExps(api, '');
|
||||
})
|
||||
|
@ -187,14 +188,14 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
}
|
||||
];
|
||||
|
||||
helpers.swaggerApi.create({definition: cSwagger})
|
||||
Sway.create({definition: cSwagger})
|
||||
.then(function (api) {
|
||||
var operation = api.getOperation('/pet/{petId}', 'get');
|
||||
|
||||
assert.ok(_.isUndefined(operation.getParameter()));
|
||||
assert.ok(_.isUndefined(operation.getParameter('missing')));
|
||||
assert.ok(_.isUndefined(operation.getParameter('petId', 'header')));
|
||||
assert.deepEqual(operation.getParameter('petId').definition,
|
||||
assert.deepEqual(operation.getParameter('petId', 'path').definition,
|
||||
cSwagger.paths['/pet/{petId}'].parameters[0]);
|
||||
assert.deepEqual(operation.getParameter('petId', 'query').definition,
|
||||
cSwagger.paths['/pet/{petId}'].get.parameters[0]);
|
||||
|
@ -206,7 +207,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
// More vigorous testing of the Parameter object itself and the parameter composition are done elsewhere
|
||||
describe('#getParameters', function () {
|
||||
it('should return the proper parameter objects', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}', 'post');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}', 'post');
|
||||
|
||||
assert.deepEqual(operation.getParameters(), operation.parameterObjects);
|
||||
});
|
||||
|
@ -226,7 +227,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
var operation;
|
||||
|
||||
before(function () {
|
||||
operation = sway.getOperation('/pet', 'post');
|
||||
operation = swaggerApi.getOperation('/pet', 'post');
|
||||
});
|
||||
|
||||
it('should return an error for an unsupported value', function () {
|
||||
|
@ -286,7 +287,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwaggerDoc.paths['/pet'].post.consumes;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -319,7 +320,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
|
||||
cSwaggerDoc.paths['/pet'].post.consumes.push(mimeType);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -344,7 +345,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
// ParameterValue's validation and which is heavily tested elsewhere.
|
||||
|
||||
it('should return an error for invalid non-primitive parameters', function () {
|
||||
var operation = sway.getOperation('/pet', 'post');
|
||||
var operation = swaggerApi.getOperation('/pet', 'post');
|
||||
var results = operation.validateRequest({
|
||||
url: '/v2/pet',
|
||||
headers: {
|
||||
|
@ -379,7 +380,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should return an error for invalid primitive parameters', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}/uploadImage', 'post');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}/uploadImage', 'post');
|
||||
var results = operation.validateRequest({
|
||||
url: '/v2/pet/notANumber/uploadImage',
|
||||
headers: {
|
||||
|
@ -409,7 +410,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should not return an error for valid parameters', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}', 'post');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}', 'post');
|
||||
var results = operation.validateRequest({
|
||||
url: '/v2/pet/1',
|
||||
headers: {
|
||||
|
@ -432,7 +433,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
// is in test-response.js.
|
||||
describe('should return an error for undefined response', function () {
|
||||
it('undefined value but no default', function () {
|
||||
var results = sway.getOperation('/pet', 'post').validateResponse();
|
||||
var results = swaggerApi.getOperation('/pet', 'post').validateResponse();
|
||||
|
||||
assert.deepEqual(results.warnings, []);
|
||||
assert.deepEqual(results.errors, [
|
||||
|
@ -445,7 +446,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('provided value', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'post').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'post').validateResponse({
|
||||
statusCode: 201
|
||||
});
|
||||
|
||||
|
@ -461,7 +462,7 @@ describe('Operation (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('should return the \'default\' response when validating an undefined response', function () {
|
||||
var results = sway.getOperation('/user', 'post').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user', 'post').validateResponse({
|
||||
statusCode: 201
|
||||
});
|
||||
|
|
@ -29,15 +29,15 @@
|
|||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var sHelpers = require('../../../lib/helpers'); // Helpers from Sway
|
||||
var tHelpers = require('../../helpers'); // Helpers for test
|
||||
var sHelpers = require('../lib/helpers'); // Helpers from Sway
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('Parameter (Swagger 2.0)', function () {
|
||||
var sway;
|
||||
describe('Parameter', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -45,9 +45,9 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
it('should have proper structure', function () {
|
||||
var path = '/pet/{petId}';
|
||||
var pathDef = sway.resolved.paths[path];
|
||||
var pathDef = swaggerApi.definitionAllResolved.paths[path];
|
||||
|
||||
_.each(sway.getOperation(path, 'post').getParameters(), function (parameter, index) {
|
||||
_.each(swaggerApi.getOperation(path, 'post').getParameters(), function (parameter, index) {
|
||||
var ptr = '#/paths/~1pet~1{petId}/';
|
||||
var def;
|
||||
|
||||
|
@ -66,10 +66,10 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
describe('#getSchema', function () {
|
||||
it('should handle parameter with explicit schema definition (body parameter)', function () {
|
||||
var schema = sway.getOperation('/pet', 'post').getParameter('body').getSchema();
|
||||
var schema = swaggerApi.getOperation('/pet', 'post').getParameter('body').getSchema();
|
||||
|
||||
// Make sure the generated JSON Schema is identical to its referenced schema
|
||||
assert.deepEqual(schema, sway.resolved.definitions.Pet);
|
||||
assert.deepEqual(schema, swaggerApi.definitionAllResolved.definitions.Pet);
|
||||
|
||||
// Make sure the generated JSON Schema validates an invalid object properly
|
||||
try {
|
||||
|
@ -99,12 +99,12 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
name: 'Test Pet'
|
||||
});
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed(err);
|
||||
helpers.shouldNotHadFailed(err);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle parameter with schema-like definition (non-body parameter)', function () {
|
||||
var schema = sway.getOperation('/pet/findByTags', 'get').getParameter('tags').getSchema();
|
||||
var schema = swaggerApi.getOperation('/pet/findByTags', 'get').getParameter('tags').getSchema();
|
||||
|
||||
// Make sure the generated JSON Schema is as expected
|
||||
assert.deepEqual(schema, {
|
||||
|
@ -140,33 +140,33 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
'tag3'
|
||||
]);
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed(err);
|
||||
helpers.shouldNotHadFailed(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getSample', function () {
|
||||
it('should handle parameter with explicit schema definition (body parameter)', function () {
|
||||
var parameter = sway.getOperation('/pet', 'post').getParameter('body');
|
||||
var parameter = swaggerApi.getOperation('/pet', 'post').getParameter('body');
|
||||
|
||||
try {
|
||||
sHelpers.validateAgainstSchema(helpers.swaggerDocValidator,
|
||||
parameter.getSchema(),
|
||||
parameter.getSample());
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed(err);
|
||||
helpers.shouldNotHadFailed(err);
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle parameter with schema-like definition (non-body parameter)', function () {
|
||||
var parameter = sway.getOperation('/pet/findByTags', 'get').getParameter('tags');
|
||||
var parameter = swaggerApi.getOperation('/pet/findByTags', 'get').getParameter('tags');
|
||||
|
||||
try {
|
||||
sHelpers.validateAgainstSchema(helpers.swaggerDocValidator,
|
||||
parameter.getSchema(),
|
||||
parameter.getSample());
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed(err);
|
||||
helpers.shouldNotHadFailed(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -177,7 +177,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet', 'post').getParameter('body');
|
||||
parameter = swaggerApi.getOperation('/pet', 'post').getParameter('body');
|
||||
});
|
||||
|
||||
it('missing value', function () {
|
||||
|
@ -199,14 +199,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/{petId}/uploadImage', 'post').getParameter('file');
|
||||
parameter = swaggerApi.getOperation('/pet/{petId}/uploadImage', 'post').getParameter('file');
|
||||
});
|
||||
|
||||
it('missing req.files', function () {
|
||||
try {
|
||||
parameter.getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req.files must be provided for \'formData\' parameters of type \'file\'');
|
||||
}
|
||||
|
@ -231,14 +231,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/{petId}', 'post').getParameter('name');
|
||||
parameter = swaggerApi.getOperation('/pet/{petId}', 'post').getParameter('name');
|
||||
});
|
||||
|
||||
it('missing req.body', function () {
|
||||
try {
|
||||
parameter.getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req.body must be provided for \'formData\' parameters');
|
||||
}
|
||||
|
@ -264,14 +264,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/{petId}', 'delete').getParameter('api_key');
|
||||
parameter = swaggerApi.getOperation('/pet/{petId}', 'delete').getParameter('api_key');
|
||||
});
|
||||
|
||||
it('missing req.headers', function () {
|
||||
try {
|
||||
parameter.getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req.headers must be provided for \'header\' parameters');
|
||||
}
|
||||
|
@ -310,14 +310,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/{petId}', 'post').getParameter('petId');
|
||||
parameter = swaggerApi.getOperation('/pet/{petId}', 'post').getParameter('petId');
|
||||
});
|
||||
|
||||
it('missing req.url', function () {
|
||||
try {
|
||||
parameter.getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req.url must be provided for \'path\' parameters');
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -399,14 +399,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/findByStatus', 'get').getParameter('status');
|
||||
parameter = swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status');
|
||||
});
|
||||
|
||||
it('missing req.query', function () {
|
||||
try {
|
||||
parameter.getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req.query must be provided for \'query\' parameters');
|
||||
}
|
||||
|
@ -434,14 +434,14 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/{petId}'].parameters[0].in = 'invalid';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
try {
|
||||
api.getOperation('/pet/{petId}', 'get').getParameter('petId').getValue({});
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'Invalid \'in\' value: invalid');
|
||||
}
|
||||
|
@ -451,9 +451,9 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
it('missing request', function () {
|
||||
try {
|
||||
sway.getOperation('/pet/{petId}', 'get').getParameter('petId').getValue();
|
||||
swaggerApi.getOperation('/pet/{petId}', 'get').getParameter('petId').getValue();
|
||||
|
||||
tHelpers.shouldHadFailed();
|
||||
helpers.shouldHadFailed();
|
||||
} catch (err) {
|
||||
assert.equal(err.message, 'req is required');
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var parameter;
|
||||
|
||||
before(function () {
|
||||
parameter = sway.getOperation('/pet/{petId}', 'get').getParameter('petId');
|
||||
parameter = swaggerApi.getOperation('/pet/{petId}', 'get').getParameter('petId');
|
||||
});
|
||||
|
||||
it('never processed', function () {
|
||||
|
@ -501,7 +501,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
];
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -515,7 +515,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
it('provided (array items object)', function (done) {
|
||||
var cSwagger = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -529,7 +529,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
it('provided (non-array)', function (done) {
|
||||
var cSwagger = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -552,7 +552,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
];
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -568,7 +568,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.paths['/pet/findByStatus'].get.parameters[0].items.default;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -582,7 +582,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
it('missing (non-array)', function (done) {
|
||||
var cSwagger = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -604,7 +604,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
required: false
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -639,7 +639,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
];
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -655,7 +655,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('items object', function () {
|
||||
assert.deepEqual(sway.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
assert.deepEqual(swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
query: {
|
||||
status: [
|
||||
'available', 'pending'
|
||||
|
@ -665,7 +665,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('non-array JSON string request value', function () {
|
||||
assert.deepEqual(sway.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
assert.deepEqual(swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
query: {
|
||||
status: '["pending"]'
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('non-array string request value', function () {
|
||||
assert.deepEqual(sway.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
assert.deepEqual(swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
query: {
|
||||
status: 'pending'
|
||||
}
|
||||
|
@ -681,7 +681,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('array request value', function () {
|
||||
assert.deepEqual(sway.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
assert.deepEqual(swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
query: {
|
||||
status: ['available', 'pending']
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
delete cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -712,7 +712,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat = 'csv';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -729,7 +729,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
it('multiple values', function (done) {
|
||||
var cSwagger = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -749,7 +749,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
it('single value', function (done) {
|
||||
var cSwagger = _.cloneDeep(helpers.swaggerDoc);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -768,7 +768,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat = 'pipes';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -786,7 +786,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat = 'ssv';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -804,7 +804,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat = 'tsv';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -822,7 +822,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet/findByStatus'].get.parameters[0].collectionFormat = 'invalid';
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -863,7 +863,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -927,7 +927,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -970,7 +970,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -997,7 +997,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var cParam;
|
||||
|
||||
before(function () {
|
||||
cParam = sway.getOperation('/pet', 'post').getParameter('body');
|
||||
cParam = swaggerApi.getOperation('/pet', 'post').getParameter('body');
|
||||
});
|
||||
|
||||
it('object request value', function () {
|
||||
|
@ -1084,7 +1084,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1126,7 +1126,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1150,7 +1150,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
var cParam;
|
||||
|
||||
before(function () {
|
||||
cParam = sway.getOperation('/pet/{petId}', 'post').getParameter('name');
|
||||
cParam = swaggerApi.getOperation('/pet/{petId}', 'post').getParameter('name');
|
||||
});
|
||||
|
||||
it('string request value', function () {
|
||||
|
@ -1187,7 +1187,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
format: 'date'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1245,7 +1245,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
format: 'date-time'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1296,7 +1296,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
type: 'invalid'
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1317,7 +1317,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths['/pet'].post.parameters[0].schema = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1336,7 +1336,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
|
||||
describe('validation', function () {
|
||||
it('missing required value (with default)', function () {
|
||||
var paramValue = sway.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
var paramValue = swaggerApi.getOperation('/pet/findByStatus', 'get').getParameter('status').getValue({
|
||||
query: {}
|
||||
});
|
||||
|
||||
|
@ -1346,7 +1346,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('missing required value (without default)', function () {
|
||||
var paramValue = sway.getOperation('/pet/findByTags', 'get').getParameter('tags').getValue({
|
||||
var paramValue = swaggerApi.getOperation('/pet/findByTags', 'get').getParameter('tags').getValue({
|
||||
query: {}
|
||||
});
|
||||
var error = paramValue.error;
|
||||
|
@ -1370,7 +1370,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
in: 'query'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1399,7 +1399,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
allowEmptyValue: true
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1428,7 +1428,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
in: 'query'
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1457,7 +1457,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
allowEmptyValue: true
|
||||
});
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -1481,7 +1481,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
name: 'Sparky',
|
||||
photoUrls: []
|
||||
};
|
||||
var paramValue = sway.getOperation('/pet', 'post').getParameter('body').getValue({
|
||||
var paramValue = swaggerApi.getOperation('/pet', 'post').getParameter('body').getValue({
|
||||
body: pet
|
||||
});
|
||||
|
||||
|
@ -1491,7 +1491,7 @@ describe('Parameter (Swagger 2.0)', function () {
|
|||
});
|
||||
|
||||
it('provided value fails JSON Schema validation', function () {
|
||||
var paramValue = sway.getOperation('/pet', 'post').getParameter('body').getValue({
|
||||
var paramValue = swaggerApi.getOperation('/pet', 'post').getParameter('body').getValue({
|
||||
body: {}
|
||||
});
|
||||
var error = paramValue.error;
|
|
@ -28,15 +28,16 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var helpers = require('./helpers');
|
||||
var JsonRefs = require('json-refs');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
describe('Path (Swagger 2.0)', function () {
|
||||
var sway;
|
||||
describe('Path', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -44,12 +45,12 @@ describe('Path (Swagger 2.0)', function () {
|
|||
|
||||
it('should have proper structure', function () {
|
||||
var path = '/pet/{petId}';
|
||||
var pathObject = sway.getOperation(path, 'get').pathObject;
|
||||
var pathObject = swaggerApi.getOperation(path, 'get').pathObject;
|
||||
|
||||
assert.deepEqual(pathObject.api, sway);
|
||||
assert.deepEqual(pathObject.api, swaggerApi);
|
||||
assert.equal(pathObject.path, path);
|
||||
assert.equal(pathObject.ptr, JsonRefs.pathToPtr(['paths', path]));
|
||||
assert.deepEqual(pathObject.definition, sway.resolved.paths[path]);
|
||||
assert.deepEqual(pathObject.definition, swaggerApi.definitionAllResolved.paths[path]);
|
||||
|
||||
// Make sure they are of the proper type
|
||||
assert.ok(pathObject.regexp instanceof RegExp);
|
||||
|
@ -59,23 +60,23 @@ describe('Path (Swagger 2.0)', function () {
|
|||
assert.equal('petId', pathObject.regexp.keys[0].name);
|
||||
|
||||
// Make sure they match the expected URLs
|
||||
assert.ok(_.isArray(pathObject.regexp.exec(sway.resolved.basePath + '/pet/1')));
|
||||
assert.ok(!_.isArray(pathObject.regexp.exec(sway.resolved.basePath + '/pets/1')));
|
||||
assert.ok(_.isArray(pathObject.regexp.exec(swaggerApi.definitionAllResolved.basePath + '/pet/1')));
|
||||
assert.ok(!_.isArray(pathObject.regexp.exec(swaggerApi.definitionAllResolved.basePath + '/pets/1')));
|
||||
});
|
||||
|
||||
describe('#getOperation', function () {
|
||||
it('should return the expected operation', function () {
|
||||
assert.ok(!_.isUndefined(sway.getPath('/pet/{petId}').getOperation('get')));
|
||||
assert.ok(!_.isUndefined(swaggerApi.getPath('/pet/{petId}').getOperation('get')));
|
||||
});
|
||||
|
||||
it('should return no operation for the missing method', function () {
|
||||
assert.ok(_.isUndefined(sway.getPath('/pet/{petId}').getOperation('head')));
|
||||
assert.ok(_.isUndefined(swaggerApi.getPath('/pet/{petId}').getOperation('head')));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getOperations', function () {
|
||||
it('should return the expected operations', function () {
|
||||
assert.equal(sway.getPath('/pet/{petId}').getOperations().length, 3);
|
||||
assert.equal(swaggerApi.getPath('/pet/{petId}').getOperations().length, 3);
|
||||
});
|
||||
|
||||
it('should return no operations', function (done) {
|
||||
|
@ -84,7 +85,7 @@ describe('Path (Swagger 2.0)', function () {
|
|||
|
||||
cSwagger.paths[path] = {};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwagger
|
||||
}).then(function (api) {
|
||||
assert.equal(api.getPath(path).getOperations().length, 0);
|
||||
|
@ -94,23 +95,23 @@ describe('Path (Swagger 2.0)', function () {
|
|||
|
||||
describe('#getOperationsByTag', function () {
|
||||
it('should return the expected operations', function () {
|
||||
assert.equal(sway.getPath('/pet/{petId}').getOperationsByTag('pet').length, 3);
|
||||
assert.equal(swaggerApi.getPath('/pet/{petId}').getOperationsByTag('pet').length, 3);
|
||||
});
|
||||
|
||||
it('should return no operations', function () {
|
||||
assert.equal(sway.getPath('/pet/{petId}').getOperationsByTag('petz').length, 0);
|
||||
assert.equal(swaggerApi.getPath('/pet/{petId}').getOperationsByTag('petz').length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getParameters', function () {
|
||||
it('should return the expected parameters', function () {
|
||||
var parameters = sway.getPath('/pet/{petId}').getParameters();
|
||||
var parameters = swaggerApi.getPath('/pet/{petId}').getParameters();
|
||||
|
||||
assert.equal(parameters.length, 1);
|
||||
});
|
||||
|
||||
it('should return no parameters', function () {
|
||||
assert.equal(sway.getPath('/pet').getParameters().length, 0);
|
||||
assert.equal(swaggerApi.getPath('/pet').getParameters().length, 0);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -28,17 +28,17 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers'); // Helpers for this suite of tests
|
||||
var sHelpers = require('../../../lib/helpers'); // Helpers from Sway
|
||||
var tHelpers = require('../../helpers'); // Helpers for tests
|
||||
var helpers = require('./helpers');
|
||||
var sHelpers = require('../lib/helpers');
|
||||
var Sway = helpers.getSway();
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
describe('Response (Swagger 2.0', function () {
|
||||
var sway;
|
||||
describe('Response', function () {
|
||||
var swaggerApi;
|
||||
|
||||
before(function (done) {
|
||||
helpers.getSway(function (api) {
|
||||
sway = api;
|
||||
helpers.getSwaggerApi(function (api) {
|
||||
swaggerApi = api;
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
};
|
||||
cSwaggerDoc.paths['/pet/{petId}'].get.responses['200'].examples = examples;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -103,23 +103,23 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
describe('#getSample', function () {
|
||||
it('should return sample for default response when no code is provided', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation('/user', 'post').getResponse().getSample()));
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation('/user', 'post').getResponse().getSample()));
|
||||
});
|
||||
|
||||
it('should return sample for the requested response code', function () {
|
||||
var operation = sway.getOperation('/pet/{petId}', 'get');
|
||||
var operation = swaggerApi.getOperation('/pet/{petId}', 'get');
|
||||
|
||||
try {
|
||||
sHelpers.validateAgainstSchema(helpers.swaggerDocValidator,
|
||||
operation.getResponse(200).definition.schema,
|
||||
operation.getResponse(200).getSample());
|
||||
} catch (err) {
|
||||
tHelpers.shouldNotHadFailed(err);
|
||||
helpers.shouldNotHadFailed(err);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return undefined for void response', function () {
|
||||
assert.ok(_.isUndefined(sway.getOperation('/pet', 'post').getResponse(405).getSample()));
|
||||
assert.ok(_.isUndefined(swaggerApi.getOperation('/pet', 'post').getResponse(405).getSample()));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -150,7 +150,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -161,7 +161,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
describe('unsupported value', function () {
|
||||
it('should return an error for a provided value', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
body: validPet,
|
||||
headers: {
|
||||
'content-type': 'application/x-yaml'
|
||||
|
@ -181,7 +181,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('should not return an error for a void response', function () {
|
||||
var results = sway.getOperation('/user', 'post').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user', 'post').validateResponse({
|
||||
headers: {
|
||||
'content-type': 'application/x-yaml'
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('should not return an error for a supported value', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
body: validPet,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
|
@ -233,7 +233,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
describe('undefined value', function () {
|
||||
it('should return an error when not a void/204/304 response', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
body: validPet,
|
||||
statusCode: 200
|
||||
});
|
||||
|
@ -290,7 +290,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
delete cSwaggerDoc.paths['/pet/{petId}'].get.produces;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -321,7 +321,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
cSwaggerDoc.paths['/pet/{petId}'].get.produces.push(mimeType);
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -346,7 +346,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
cSwaggerDoc.paths['/user/login'].get.responses['200'].headers['X-Rate-Limit'].maximum = 5;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
||||
|
@ -381,7 +381,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('should return errors for invalid headers (type)', function () {
|
||||
var results = sway.getOperation('/user/login', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user/login', 'get').validateResponse({
|
||||
body: 'OK',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
|
@ -423,7 +423,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('should not return errors for valid headers', function () {
|
||||
var results = sway.getOperation('/user/login', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user/login', 'get').validateResponse({
|
||||
body: 'OK',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
|
@ -441,7 +441,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
describe('validate body', function () {
|
||||
describe('should not return an error for a valid response body', function () {
|
||||
it('empty body for void response', function () {
|
||||
var results = sway.getOperation('/pet', 'post').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet', 'post').validateResponse({
|
||||
statusCode: 405
|
||||
});
|
||||
|
||||
|
@ -450,7 +450,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('non-empty body for void response', function () {
|
||||
var results = sway.getOperation('/pet', 'post').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet', 'post').validateResponse({
|
||||
body: 'Bad Request',
|
||||
statusCode: 405
|
||||
});
|
||||
|
@ -460,7 +460,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('primitive body', function () {
|
||||
var results = sway.getOperation('/user/login', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user/login', 'get').validateResponse({
|
||||
body: 'OK',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
|
@ -475,7 +475,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('complex body', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
body: {
|
||||
name: 'First Pet',
|
||||
photoUrls: []
|
||||
|
@ -501,7 +501,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
value = 'OK';
|
||||
}
|
||||
|
||||
results = sway.getOperation('/user/login', 'get').validateResponse({
|
||||
results = swaggerApi.getOperation('/user/login', 'get').validateResponse({
|
||||
body: value,
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
|
@ -516,7 +516,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
describe('should return an error for an invalid response body', function () {
|
||||
it('primitive body', function () {
|
||||
var results = sway.getOperation('/user/login', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/user/login', 'get').validateResponse({
|
||||
body: {},
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
|
@ -544,7 +544,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
});
|
||||
|
||||
it('complex body', function () {
|
||||
var results = sway.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
var results = swaggerApi.getOperation('/pet/{petId}', 'get').validateResponse({
|
||||
body: {},
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
|
@ -579,7 +579,7 @@ describe('Response (Swagger 2.0', function () {
|
|||
|
||||
cSwaggerDoc.paths['/user/login'].get.responses['200'].schema.minLength = 3;
|
||||
|
||||
helpers.swaggerApi.create({
|
||||
Sway.create({
|
||||
definition: cSwaggerDoc
|
||||
})
|
||||
.then(function (api) {
|
|
@ -28,24 +28,50 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var swaggerApi = typeof window === 'undefined' ? require('..') : window.SwaggerApi;
|
||||
var helpers = require('./helpers');
|
||||
var Sway = helpers.getSway();
|
||||
|
||||
var invalidCreateScenarios = [
|
||||
[[], 'options is required'],
|
||||
[['wrongType'], 'options must be an object'],
|
||||
[[{}], 'options.definition is required'],
|
||||
[[{definition: false}], 'options.definition must be either an object or a string'],
|
||||
[[{definition: {}}], 'Unable to identify the Swagger version or the Swagger version is unsupported'],
|
||||
[[{definition: {}, jsonRefs: 'wrongType'}], 'options.jsonRefs must be an object'],
|
||||
[[{definition: {}, customValidators: 'wrongType'}], 'options.customValidators must be an array'],
|
||||
[[{definition: {}, customValidators: ['wrongType']}], 'options.customValidators at index 0 must be a function']
|
||||
];
|
||||
|
||||
describe('sway (General)', function () {
|
||||
describe('sway', function () {
|
||||
describe('sway#create', function () {
|
||||
function validateCreateSwaggerApi (options) {
|
||||
return function (theApi) {
|
||||
assert.deepEqual(theApi.definition, helpers.swaggerDoc);
|
||||
assert.equal(theApi.documentation, 'https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md');
|
||||
assert.deepEqual(theApi.options, options);
|
||||
assert.equal(theApi.version, '2.0');
|
||||
|
||||
// Make sure all references were found
|
||||
_.forEach(theApi.references, function (details) {
|
||||
assert.ok(!_.has(details, 'missing'));
|
||||
});
|
||||
|
||||
// Validate the merging of the Swagger definition properties and the SwaggerApi properties
|
||||
_.forEach(helpers.swaggerDoc, function (val, key) {
|
||||
assert.deepEqual(theApi[key], val);
|
||||
});
|
||||
|
||||
// Validate the operations (Simple tests for now, deeper testing is below)
|
||||
assert.ok(_.isArray(theApi.pathObjects));
|
||||
assert.ok(theApi.pathObjects.length > 0);
|
||||
|
||||
// Validate the registration of customValidator on SwaggerApi
|
||||
assert.deepEqual(theApi.customValidators, options.customValidators || [])
|
||||
};
|
||||
}
|
||||
|
||||
it('should always return a promise', function () {
|
||||
assert.ok(swaggerApi.create({}) instanceof Promise);
|
||||
assert.ok(swaggerApi.create({}, function () {}) instanceof Promise);
|
||||
assert.ok(Sway.create({}) instanceof Promise);
|
||||
assert.ok(Sway.create({}, function () {}) instanceof Promise);
|
||||
});
|
||||
|
||||
it('should return proper error', function (done) {
|
||||
|
@ -55,9 +81,9 @@ describe('sway (General)', function () {
|
|||
allTests = allTests
|
||||
.then(function () {
|
||||
return new Promise(function (resolve, reject) {
|
||||
swaggerApi.create.apply(swaggerApi, scenario[0])
|
||||
Sway.create.apply(Sway, scenario[0])
|
||||
.then(function () {
|
||||
reject(new Error('swaggerApi.create should had failed (Test #' + index + ')'));
|
||||
reject(new Error('Sway#create should had failed (Test #' + index + ')'));
|
||||
}, function (err) {
|
||||
try {
|
||||
assert.ok(err instanceof TypeError);
|
||||
|
@ -74,5 +100,45 @@ describe('sway (General)', function () {
|
|||
|
||||
allTests.then(done, done);
|
||||
});
|
||||
|
||||
it('should handle definition object', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDoc
|
||||
};
|
||||
|
||||
Sway.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
it('should handle definition file location', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDocPath
|
||||
};
|
||||
|
||||
Sway.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
it('should register customValidators', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDoc,
|
||||
customValidators: [
|
||||
function validator1 () {
|
||||
return {
|
||||
errors: [],
|
||||
warnings: []
|
||||
};
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Sway.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
// TODO: Add test for definition file URL (remote)
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/* eslint-env browser, mocha */
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Apigee Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var plugin = require('../../../lib/versions/2.0');
|
||||
var sHelpers = require('../../../lib/helpers'); // Helpers from Sway
|
||||
var tHelpers = require('../../helpers');
|
||||
var YAML = require('js-yaml');
|
||||
|
||||
var swaggerApi = typeof window === 'undefined' ? require('../../..') : window.SwaggerApi;
|
||||
var swaggerDoc = YAML.safeLoad(fs.readFileSync(path.join(__dirname, '../../browser/documents/2.0/swagger.yaml'),
|
||||
'utf8'));
|
||||
var swaggerDocValidator = sHelpers.createJSONValidator({
|
||||
formatValidators: require('../../../lib/versions/2.0/format-validators')
|
||||
});
|
||||
var sway;
|
||||
|
||||
function getOperationCount (pathDef) {
|
||||
var count = 0;
|
||||
|
||||
_.each(pathDef, function (operation, method) {
|
||||
if (plugin.supportedHttpMethods.indexOf(method) > -1) {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
function getSway (callback) {
|
||||
if (sway) {
|
||||
callback(sway);
|
||||
} else {
|
||||
swaggerApi.create({
|
||||
definition: swaggerDoc,
|
||||
jsonRefs: {
|
||||
relativeBase: tHelpers.relativeBase
|
||||
}
|
||||
})
|
||||
.then(function (obj) {
|
||||
sway = obj;
|
||||
|
||||
callback(sway);
|
||||
}, function (err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getOperationCount: getOperationCount,
|
||||
getSway: getSway,
|
||||
plugin: plugin,
|
||||
swaggerApi: swaggerApi,
|
||||
swaggerDoc: swaggerDoc,
|
||||
swaggerDocPath: './2.0/swagger.yaml',
|
||||
swaggerDocValidator: swaggerDocValidator
|
||||
};
|
|
@ -1,108 +0,0 @@
|
|||
/* eslint-env browser, mocha */
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Apigee Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var assert = require('assert');
|
||||
var helpers = require('./helpers');
|
||||
var tHelpers = require('../../helpers');
|
||||
|
||||
// This should be broken out into a test framework that runs the same tests against the different version(s) of Swagger
|
||||
// we support but for now, only one version is supported so let's keep it simple.
|
||||
|
||||
describe('sway (Swagger 2.0)', function () {
|
||||
describe('#create', function () {
|
||||
function validateCreateSwaggerApi (options) {
|
||||
return function (theApi) {
|
||||
assert.deepEqual(theApi.definition, helpers.swaggerDoc);
|
||||
assert.equal(theApi.documentation, helpers.plugin.documentation);
|
||||
assert.deepEqual(theApi.options, options);
|
||||
assert.equal(theApi.version, helpers.plugin.version);
|
||||
|
||||
// Make sure all references were found
|
||||
_.forEach(theApi.references, function (details) {
|
||||
assert.ok(!_.has(details, 'missing'));
|
||||
});
|
||||
|
||||
// Validate the merging of the Swagger definition properties and the SwaggerApi properties
|
||||
_.forEach(helpers.swaggerDoc, function (val, key) {
|
||||
assert.deepEqual(theApi[key], val);
|
||||
});
|
||||
|
||||
// Validate the operations (Simple tests for now, deeper testing is below)
|
||||
assert.ok(_.isArray(theApi.pathObjects));
|
||||
assert.ok(theApi.pathObjects.length > 0);
|
||||
|
||||
// Validate the registration of customValidator on SwaggerApi
|
||||
assert.deepEqual(theApi.customValidators, options.customValidators || [])
|
||||
};
|
||||
}
|
||||
|
||||
it('should handle definition object', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDoc
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
it('should handle definition file location', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDocPath,
|
||||
jsonRefs: {
|
||||
relativeBase: tHelpers.relativeBase
|
||||
}
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
it('should register customValidators', function (done) {
|
||||
var options = {
|
||||
definition: helpers.swaggerDoc,
|
||||
customValidators: [
|
||||
function validator1 () {
|
||||
return {
|
||||
errors: [],
|
||||
warnings: []
|
||||
};
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
helpers.swaggerApi.create(options)
|
||||
.then(validateCreateSwaggerApi(options))
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
// TODO: Add test for definition file URL (remote)
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче