Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Missing models in resource API #9

Merged
merged 2 commits into from
Mar 29, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions src/generator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ validateParameters = (parameters, models, path, method) ->
# only on put an post
unless method?.toLowerCase() in ['put', 'post']
throw new Error("#{errorPrefix} does not allowed body parameters - do you really knows http ?")

# only known dataType
allowedDataTypes = ['byte', 'boolean', 'int', 'long', 'float', 'double', 'string', 'date', 'file']
unless parameter.dataType?.toLowerCase() in allowedDataTypes or models[parameter.dataType]
throw new Error("'#{parameter.dataType}' does not match an allowed dataType [#{allowedDataTypes}] nor a known model [#{Object.keys(models)}]")
when 'header', 'query'
# nothing to check
else
Expand Down Expand Up @@ -105,9 +110,9 @@ addRoutes = (descriptor, resources) ->
throw new Error("Resource must contain 'api' attribute")

# add models
if _.isObject(resource.api.models)
for id, model of resource.api.models
descriptor.models[id] = validateModel(model, id, descriptor.models)
resource.api.models or= {}
for id, model of resource.api.models
descriptor.models[id] = validateModel(model, id, descriptor.models)

# allow api without controllers, but do not generate routes
if _.isObject(resource.controller)
Expand All @@ -132,10 +137,21 @@ addRoutes = (descriptor, resources) ->
unless _.isString(operation.nickname)
throw new Error("Api #{api.path} operation #{operation.httpMethod} does not specify a nickname - we cannot guess the corresponding controller method")

# make sure the responseClass model is defined
if operation.responseClass
resource.api.models[operation.responseClass] or= descriptor.models[operation.responseClass]
unless resource.api.models[operation.responseClass]
throw new Error("responseClass #{operation.responseClass} doesn't match a model")

# Validates parameters
if _.isArray(operation.parameters)
# parameter validations
validateParameters(operation.parameters, descriptor.models, api.path, operation.httpMethod)

# make sure the dataType model is defined
for parameter in operation.parameters
if parameter.dataType
resource.api.models[parameter.dataType] or= descriptor.models[parameter.dataType]

route = utils.pathToRoute(api.path)
unless operation.nickname of resource.controller
Expand Down Expand Up @@ -199,7 +215,9 @@ module.exports = (app, descriptor, resources, options = {}) ->
# Add descriptor to express application for other middlewares
app.descriptor = descriptor
catch err
throw new Error("Failed to create routes from resources: #{err.toString()}");
err2 = new Error("Failed to create routes from resources: #{err.toString()}")
err2.stack = err.stack
throw err2;

# Express middleware for serving the descRoute.
return (req, res, next) ->
Expand All @@ -225,4 +243,4 @@ module.exports = (app, descriptor, resources, options = {}) ->

return res.json(result)

next()
next()
30 changes: 14 additions & 16 deletions test/apiGeneration.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ describe 'API generation tests', ->
httpMethod: 'GET'
]
],
models: {},
resourcePath: '/source'
server.close()
done()
Expand All @@ -475,10 +476,13 @@ describe 'API generation tests', ->
.use(swagger.generator(app,
apiVersion: '1.0',
basePath: root
, [
, [{
api: require './fixtures/addressApi.yml'
controller: passed: (req, res) -> res.json status: 'passed'
},{
api: require './fixtures/complexApi.yml'
controller: passed: (req, res) -> res.json status: 'passed'
]))
}]))
# use validator also because it manipulates models
.use(swagger.validator(app))
server = http.createServer app
Expand All @@ -491,7 +495,7 @@ describe 'API generation tests', ->
it 'should reference models be untouched', (done) ->
# when requesting the API description details
request.get
url: 'http://'+host+':'+port+'/api-docs.json/example'
url: 'http://'+host+':'+port+'/api-docs.json/address'
json: true
, (err, res, body) ->
return done err if err?
Expand All @@ -500,14 +504,14 @@ describe 'API generation tests', ->
assert.deepEqual body,
apiVersion: '1.0'
basePath: '/api'
resourcePath: '/example'
resourcePath: '/address'
apis: [
path: '/example'
path: '/address'
operations: [
httpMethod: 'POST'
nickname: 'passed'
parameters: [
dataType: 'User'
dataType: 'Address'
paramType: 'body'
required: true
]
Expand All @@ -524,18 +528,11 @@ describe 'API generation tests', ->
city:
type: 'string'

User:
id: 'User'
SomethingElse:
id: 'SomethingElse'
properties:
id:
type: 'int'
required: true
name:
type: 'string'
addresses:
type: 'array'
items:
$ref: 'Address'
done()

describe 'given a properly configured and started server', ->
Expand Down Expand Up @@ -682,4 +679,5 @@ describe 'API generation tests', ->
nickname: 'remove'
]
]
done()
models: {}
done()
31 changes: 31 additions & 0 deletions test/fixtures/addressApi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
resourcePath: /address
apis:

- path: /address
operations:

- httpMethod: POST
nickname: passed
parameters:

- dataType: Address
paramType: body
required: true

models:

Address:
id: Address
properties:
zipcode:
type: long
street:
type: string
city:
type: string

SomethingElse:
id: SomethingElse
properties:
name:
type: string
13 changes: 2 additions & 11 deletions test/fixtures/complexApi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ apis:

- httpMethod: POST
nickname: passed
responseClass: SomethingElse
parameters:

- dataType: User
Expand All @@ -14,16 +15,6 @@ apis:

models:

Address:
id: Address
properties:
zipcode:
type: long
street:
type: string
city:
type: string

User:
id: User
properties:
Expand All @@ -35,4 +26,4 @@ models:
addresses:
type: array
items:
$ref: Address
$ref: Address