diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..80f0b96 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,25 @@ +{ + "rules": { + "indent": [ + 2, + 4 + ], + "quotes": [ + 2, + "single" + ], + "linebreak-style": [ + 2, + "unix" + ], + "semi": [ + 2, + "always" + ] + }, + "env": { + "es6": true, + "node": true + }, + "extends": "eslint:recommended" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7be1880 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +*.orig + +work +build +pids +logs +results +coverage +lib-cov +html-report +xunit.xml +node_modules +npm-debug.log + +.project +.idea +.settings +.iml +*.sublime-workspace +*.sublime-project + +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +.AppleDouble +.LSOverride +.Spotlight-V100 +.Trashes + +test/temp diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..a75e2a4 --- /dev/null +++ b/.npmignore @@ -0,0 +1,51 @@ +# Automatically ignored per: +# https://www.npmjs.org/doc/developers.html#Keeping-files-out-of-your-package +# +# .*.swp +# ._* +# .DS_Store +# .git +# .hg +# .lock-wscript +# .svn +# .wafpickle-* +# CVS +# npm-debug.log +# node_modules + +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +*.orig + +work +build +test +pids +logs +results +coverage +lib-cov +html-report +xunit.xml + +.project +.idea +.settings +.iml +*.sublime-workspace +*.sublime-project + +ehthumbs.db +Icon? +Thumbs.db +.AppleDouble +.LSOverride +.Spotlight-V100 +.Trashes + +test/temp diff --git a/README.md b/README.md index a78300b..77f7539 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # swagmock Mock data generator for swagger api + +~THIS MODULE IS UNDER ACTIVE DEVELOPMENT~ diff --git a/lib/format.js b/lib/format.js new file mode 100644 index 0000000..cd2712c --- /dev/null +++ b/lib/format.js @@ -0,0 +1,15 @@ +'use strict'; +var Moment = require('moment'); + +module.exports = { + 'date': dateMock, + 'date-time': dataTimeMock +}; + +function dateMock() { + return Moment().format('YYYY-MM-DD'); +} + +function dataTimeMock() { + return Moment().toISOString(); +} diff --git a/lib/generators.js b/lib/generators.js new file mode 100644 index 0000000..cab5e3f --- /dev/null +++ b/lib/generators.js @@ -0,0 +1,139 @@ +'use strict'; +var Chance = require('chance').Chance(); +var Format = require('./format'); + +var Generators = module.exports = { + object: objectMock, + array: arrayMock, + string: stringMock, + integer: integerMock, + number: numberMock, + boolean: booleanMock, + mock: mock +}; + +function mock(schema) { + var mock; + if (schema) { + var type = schema.type; + var example = schema.examples || schema.example; + /** + * Use examples as Mock if provided + */ + if (example) { + mock = example; + } else if (type) { + /** + * Get the mock generator from the `type` of the schema + */ + var generator = Generators[type]; + if (generator) { + mock = generator.call(null, schema); + } + } + } + return mock; +} + +function objectMock(schema) { + var mockObj = {}; + var props = schema.properties; + if (props) { + Object.keys(props).forEach(function (key) { + mockObj[key] = mock(props[key]); + }); + /** + * In the absense of `properties`, check if `additionalProperties` is defined or not. + * (If additionalProperties is an object, that object is a schema that will be used to validate + * any additional properties not listed in properties.) + * + * If present, use this to generate mocks. + */ + } else if (schema.additionalProperties) { + //Create a random property + mockObj[Chance.word()] = mock(schema.additionalProperties); + } + return mockObj; +} + +function arrayMock(schema) { + var items = schema.items; + var min = 0; + var max = 1; + var arr = []; + + if (items) { + if (schema.minItems) { + min = schema.minItems; + } + if (schema.maxItems) { + max = schema.maxItems; + } + for (; min <= max; min++) { + arr.push(mock(items)); + } + } + return arr; +} + +function integerMock(schema) { + var opts = {}; + if (schema.minimum) { + opts.min = schema.minimum; + } + if (schema.maximum) { + opts.max = schema.maximum; + } + return Chance.integer(opts); +} + +function numberMock(schema) { + var opts = {}; + if (schema.minimum) { + opts.min = schema.minimum; + } + if (schema.maximum) { + opts.max = schema.maximum; + } + return Chance.floating(opts); +} + +function booleanMock() { + return Chance.bool(); +} + +function stringMock(schema) { + var mockStr; + var opts = {}; + var minLength = schema.minLength || 1; + var maxLength = schema.maxLength || minLength + 10; + opts.min = minLength; + opts.max = maxLength; + + if (schema.enum && schema.enum.length > 0) { + /** + * If `enum` is defined for the property + */ + mockStr = enumMock(schema); + } else if(Format[schema.format]) { + /** + * If a `format` is defined for the property + */ + mockStr = Format[schema.format].call(null, schema); + } else { + mockStr = Chance.string({ + length: Chance.integer(opts) + }); + } + + return mockStr; +} + +function enumMock(schema) { + var len = schema.enum.length; + var opts = { + min: 0, + max: len - 1 + }; + return schema.enum[Chance.integer(opts)]; +} diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..611a374 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,65 @@ +'use strict'; +var Parser = require('swagger-parser'); +var Generators = require('./generators'); + +module.exports = function mockGen(apiPath, options, callback) { + options = options || {}; + + Parser.validate(apiPath, function (error, api) { + if (error) { + callback(error); + return; + } + callback(null, mockSchema(api, options)); + }); +}; + +function mockSchema(api, options) { + var mock = {}; + var paths = api.paths; + if (paths) { + var pathObj = paths[options.path]; + if (pathObj) { + //Found the requested path + var opsObj = pathObj[options.operation]; + if (opsObj) { + //Found the operation + //Mock response + if (options.mockResponse) { + mock.response = mockResponse(opsObj, options); + } + //Mock Parameters + if (options.mockParams) { + mock.params = mockParameters(opsObj, options); + } + } + } + } + return mock; +} + +function mockResponse(opsObj, options) { + var mockResp; + var response = opsObj.responses[options.response]; + if (response) { + //Found the response + var schema = response.schema; + if (schema) { + mockResp = Generators.mock(schema); + } + } + return mockResp; +} + +function mockParameters(opsObj, options) { + var mockParam; + var parameter = opsObj.parameters[options.parameter]; + if (parameter) { + //Found the parameter + var schema = parameter.schema; + if (schema) { + mockParam = Generators.mock(schema); + } + } + return mockParam; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..03897d2 --- /dev/null +++ b/package.json @@ -0,0 +1,37 @@ +{ + "name": "swagmock", + "version": "0.0.1", + "description": "Mock data generator for swagger api", + "main": "lib/index.js", + "scripts": { + "lint": "eslint lib", + "test": "mocha tests" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/subeeshcbabu/swagmock.git" + }, + "keywords": [ + "swagger", + "openapi", + "mock", + "data", + "generator", + "swaggermock" + ], + "author": "subeesh chothendavida ", + "license": "MIT", + "bugs": { + "url": "https://github.com/subeeshcbabu/swagmock/issues" + }, + "homepage": "https://github.com/subeeshcbabu/swagmock#readme", + "dependencies": { + "chance": "^1.0.3", + "moment": "^2.13.0", + "swagger-parser": "^3.4.1" + }, + "devDependencies": { + "eslint": "^2.13.0", + "mocha": "^2.5.3" + } +} diff --git a/tests/fixture/petstore.json b/tests/fixture/petstore.json new file mode 100644 index 0000000..35c4e85 --- /dev/null +++ b/tests/fixture/petstore.json @@ -0,0 +1,824 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "version": "1.0.0", + "title": "Swagger Petstore", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "email": "apiteam@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host": "petstore.swagger.io", + "basePath": "/v2", + "tags": [{ + "name": "pet", + "description": "Everything about your Pets", + "externalDocs": { + "description": "Find out more", + "url": "http://swagger.io" + } + }, { + "name": "store", + "description": "Access to Petstore orders" + }, { + "name": "user", + "description": "Operations about user", + "externalDocs": { + "description": "Find out more about our store", + "url": "http://swagger.io" + } + }], + "schemes": ["http"], + "paths": { + "/pet": { + "post": { + "tags": ["pet"], + "summary": "Add a new pet to the store", + "description": "", + "operationId": "addPet", + "consumes": ["application/json", "application/xml"], + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + }], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + }, + "put": { + "tags": ["pet"], + "summary": "Update an existing pet", + "description": "", + "operationId": "updatePet", + "consumes": ["application/json", "application/xml"], + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + }], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "405": { + "description": "Validation exception" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + } + }, + "/pet/findByStatus": { + "get": { + "tags": ["pet"], + "summary": "Finds Pets by status", + "description": "Multiple status values can be provided with comma separated strings", + "operationId": "findPetsByStatus", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "status", + "in": "query", + "description": "Status values that need to be considered for filter", + "required": true, + "type": "array", + "items": { + "type": "string", + "enum": ["available", "pending", "sold"], + "default": "available" + }, + "collectionFormat": "multi" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid status value" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + } + }, + "/pet/findByTags": { + "get": { + "tags": ["pet"], + "summary": "Finds Pets by tags", + "description": "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "operationId": "findPetsByTags", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "tags", + "in": "query", + "description": "Tags to filter by", + "required": true, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid tag value" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }], + "deprecated": true + } + }, + "/pet/{petId}": { + "get": { + "tags": ["pet"], + "summary": "Find pet by ID", + "description": "Returns a single pet", + "operationId": "getPetById", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "petId", + "in": "path", + "description": "ID of pet to return", + "required": true, + "type": "integer", + "format": "int64" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Pet" + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + } + }, + "security": [{ + "api_key": [] + }] + }, + "post": { + "tags": ["pet"], + "summary": "Updates a pet in the store with form data", + "description": "", + "operationId": "updatePetWithForm", + "consumes": ["application/x-www-form-urlencoded"], + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be updated", + "required": true, + "type": "integer", + "format": "int64" + }, { + "name": "name", + "in": "formData", + "description": "Updated name of the pet", + "required": false, + "type": "string" + }, { + "name": "status", + "in": "formData", + "description": "Updated status of the pet", + "required": false, + "type": "string" + }], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + }, + "delete": { + "tags": ["pet"], + "summary": "Deletes a pet", + "description": "", + "operationId": "deletePet", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "api_key", + "in": "header", + "required": false, + "type": "string" + }, { + "name": "petId", + "in": "path", + "description": "Pet id to delete", + "required": true, + "type": "integer", + "format": "int64" + }], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + } + }, + "/pet/{petId}/uploadImage": { + "post": { + "tags": ["pet"], + "summary": "uploads an image", + "description": "", + "operationId": "uploadFile", + "consumes": ["multipart/form-data"], + "produces": ["application/json"], + "parameters": [{ + "name": "petId", + "in": "path", + "description": "ID of pet to update", + "required": true, + "type": "integer", + "format": "int64" + }, { + "name": "additionalMetadata", + "in": "formData", + "description": "Additional data to pass to server", + "required": false, + "type": "string" + }, { + "name": "file", + "in": "formData", + "description": "file to upload", + "required": false, + "type": "file" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/ApiResponse" + } + } + }, + "security": [{ + "petstore_auth": ["write:pets", "read:pets"] + }] + } + }, + "/store/inventory": { + "get": { + "tags": ["store"], + "summary": "Returns pet inventories by status", + "description": "Returns a map of status codes to quantities", + "operationId": "getInventory", + "produces": ["application/json"], + "parameters": [], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" + } + } + } + }, + "security": [{ + "api_key": [] + }] + } + }, + "/store/order": { + "post": { + "tags": ["store"], + "summary": "Place an order for a pet", + "description": "", + "operationId": "placeOrder", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "order placed for purchasing the pet", + "required": true, + "schema": { + "$ref": "#/definitions/Order" + } + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid Order" + } + } + } + }, + "/store/order/{orderId}": { + "get": { + "tags": ["store"], + "summary": "Find purchase order by ID", + "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", + "operationId": "getOrderById", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "orderId", + "in": "path", + "description": "ID of pet that needs to be fetched", + "required": true, + "type": "integer", + "maximum": 10.0, + "minimum": 1.0, + "format": "int64" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + }, + "delete": { + "tags": ["store"], + "summary": "Delete purchase order by ID", + "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors", + "operationId": "deleteOrder", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "orderId", + "in": "path", + "description": "ID of the order that needs to be deleted", + "required": true, + "type": "integer", + "minimum": 1.0, + "format": "int64" + }], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + } + }, + "/user": { + "post": { + "tags": ["user"], + "summary": "Create user", + "description": "This can only be done by the logged in user.", + "operationId": "createUser", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "Created user object", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + }], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithArray": { + "post": { + "tags": ["user"], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithArrayInput", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + }], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithList": { + "post": { + "tags": ["user"], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithListInput", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + }], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/login": { + "get": { + "tags": ["user"], + "summary": "Logs user into the system", + "description": "", + "operationId": "loginUser", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "username", + "in": "query", + "description": "The user name for login", + "required": true, + "type": "string" + }, { + "name": "password", + "in": "query", + "description": "The password for login in clear text", + "required": true, + "type": "string" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "string" + }, + "headers": { + "X-Rate-Limit": { + "type": "integer", + "format": "int32", + "description": "calls per hour allowed by the user" + }, + "X-Expires-After": { + "type": "string", + "format": "date-time", + "description": "date in UTC when token expires" + } + } + }, + "400": { + "description": "Invalid username/password supplied" + } + } + } + }, + "/user/logout": { + "get": { + "tags": ["user"], + "summary": "Logs out current logged in user session", + "description": "", + "operationId": "logoutUser", + "produces": ["application/xml", "application/json"], + "parameters": [], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/{username}": { + "get": { + "tags": ["user"], + "summary": "Get user by user name", + "description": "", + "operationId": "getUserByName", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "username", + "in": "path", + "description": "The name that needs to be fetched. Use user1 for testing. ", + "required": true, + "type": "string" + }], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/User" + } + }, + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + }, + "put": { + "tags": ["user"], + "summary": "Updated user", + "description": "This can only be done by the logged in user.", + "operationId": "updateUser", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "username", + "in": "path", + "description": "name that need to be updated", + "required": true, + "type": "string" + }, { + "in": "body", + "name": "body", + "description": "Updated user object", + "required": true, + "schema": { + "$ref": "#/definitions/User" + } + }], + "responses": { + "400": { + "description": "Invalid user supplied" + }, + "404": { + "description": "User not found" + } + } + }, + "delete": { + "tags": ["user"], + "summary": "Delete user", + "description": "This can only be done by the logged in user.", + "operationId": "deleteUser", + "produces": ["application/xml", "application/json"], + "parameters": [{ + "name": "username", + "in": "path", + "description": "The name that needs to be deleted", + "required": true, + "type": "string" + }], + "responses": { + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + } + } + }, + "securityDefinitions": { + "petstore_auth": { + "type": "oauth2", + "authorizationUrl": "http://petstore.swagger.io/oauth/dialog", + "flow": "implicit", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + }, + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + } + }, + "definitions": { + "Order": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "petId": { + "type": "integer", + "format": "int64" + }, + "quantity": { + "type": "integer", + "format": "int32" + }, + "shipDate": { + "type": "string", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Order Status", + "enum": ["placed", "approved", "delivered"] + }, + "complete": { + "type": "boolean", + "default": false + } + }, + "xml": { + "name": "Order" + } + }, + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Category" + } + }, + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "username": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "userStatus": { + "type": "integer", + "format": "int32", + "description": "User Status" + } + }, + "xml": { + "name": "User" + } + }, + "Tag": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Tag" + } + }, + "Pet": { + "type": "object", + "required": ["name", "photoUrls"], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "category": { + "$ref": "#/definitions/Category" + }, + "name": { + "type": "string", + "example": "doggie" + }, + "photoUrls": { + "type": "array", + "xml": { + "name": "photoUrl", + "wrapped": true + }, + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "xml": { + "name": "tag", + "wrapped": true + }, + "items": { + "$ref": "#/definitions/Tag" + } + }, + "status": { + "type": "string", + "description": "pet status in the store", + "enum": ["available", "pending", "sold"] + } + }, + "xml": { + "name": "Pet" + } + }, + "ApiResponse": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "type": { + "type": "string" + }, + "message": { + "type": "string" + } + } + } + }, + "externalDocs": { + "description": "Find out more about Swagger", + "url": "http://swagger.io" + } +} diff --git a/tests/response_mockgen.js b/tests/response_mockgen.js new file mode 100644 index 0000000..c73d487 --- /dev/null +++ b/tests/response_mockgen.js @@ -0,0 +1,156 @@ +var Assert = require('assert'); +var Swagmock = require('../lib'); +var Path = require('path') +//isInteger pollyfil for pre es6 +Number.isInteger = Number.isInteger || function(value) { + return typeof value === "number" && + isFinite(value) && + Math.floor(value) === value; +}; + +describe('Mock generator', function () { + var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + it('should generate response mock for path /store/order/{orderId}', function(done) { + Swagmock(apiPath,{ + path: '/store/order/{orderId}', + mockResponse: true, + operation: 'get', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + Assert.ok(Number.isInteger(resp.id), 'id is integer'); + Assert.ok(Number.isInteger(resp.petId), 'petId is integer'); + Assert.ok(Number.isInteger(resp.quantity), 'quantity is integer'); + Assert.ok(typeof resp.shipDate === 'string', 'shipDate is string'); + Assert.ok(['placed','approved','delivered'].indexOf(resp.status) !== -1, 'status is enum'); + Assert.ok(typeof resp.complete === 'boolean', 'complete is boolean'); + done(); + }); + }); + + it('should generate response mock for path /pet/findByStatus', function(done) { + Swagmock(apiPath,{ + path: '/pet/findByStatus', + mockResponse: true, + operation: 'get', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + Assert.ok(Array.isArray(resp), 'response is Pet array'); + var pet = resp[0]; + Assert.ok(pet, 'Ok Pet response'); + Assert.ok(Number.isInteger(pet.id), 'id is integer'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /pet/{petId}', function(done) { + Swagmock(apiPath,{ + path: '/pet/{petId}', + mockResponse: true, + operation: 'get', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /pet/{petId}/uploadImage', function(done) { + Swagmock(apiPath,{ + path: '/pet/{petId}/uploadImage', + mockResponse: true, + operation: 'post', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /store/inventory', function(done) { + Swagmock(apiPath,{ + path: '/store/inventory', + mockResponse: true, + operation: 'get', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /store/order', function(done) { + Swagmock(apiPath,{ + path: '/store/order', + mockResponse: true, + operation: 'post', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /user/login', function(done) { + Swagmock(apiPath,{ + path: '/user/login', + mockResponse: true, + operation: 'get', + response: '200' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(resp, 'Generated response'); + //TODO add asserts for pending props + done(); + }); + }); + + it('should generate response mock for path /pet', function(done) { + Swagmock(apiPath,{ + path: '/pet', + mockResponse: true, + operation: 'post', + response: '405' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + + Assert.ok(mock, 'Generated mock'); + var resp = mock.response; + Assert.ok(!resp, 'No response'); + //TODO add asserts for pending props + done(); + }); + }); +})