Skip to content

Commit

Permalink
Fixing operation parameter overriding by removing duplicates.
Browse files Browse the repository at this point in the history
* Also adding chai and improving testing.
  • Loading branch information
jsdevel committed Feb 4, 2016
1 parent 922b4d9 commit a4bb783
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 11 deletions.
31 changes: 28 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function initialize(args) {

var app = args.app;
// Make a copy of the apiDoc that we can safely modify.
var apiDoc = JSON.parse(JSON.stringify(args.apiDoc));
var apiDoc = copy(args.apiDoc);
var docsPath = args.docsPath || '/api-docs';
var routesDir = path.resolve(process.cwd(), args.routes);
var basePath = apiDoc.basePath || '';
Expand All @@ -87,7 +87,7 @@ function initialize(args) {
var middleware = [].concat(methodHandler);

if (methodDoc) {
pathItem[methodName] = JSON.parse(JSON.stringify(methodDoc));
pathItem[methodName] = copy(methodDoc);

if (methodDoc.responses) {
// it's invalid for a method doc to not have responses, but the post
Expand All @@ -100,7 +100,7 @@ function initialize(args) {
}

var methodParameters = Array.isArray(methodDoc.parameters) ?
pathParameters.concat(methodDoc.parameters) :
withNoDuplicates(pathParameters.concat(methodDoc.parameters)) :
pathParameters;

if (methodParameters.length) {
Expand Down Expand Up @@ -162,6 +162,31 @@ function byMethods(name) {
.indexOf(name) > -1;
}

function copy(obj) {
return JSON.parse(JSON.stringify(obj));
}

function toExpressParams(part) {
return part.replace(/^\{([^\{]+)\}$/, ':$1');
}

function withNoDuplicates(arr) {
var parameters = [];
var seenParams = {};
var index = arr.length;

while (index > 0) {
--index;
var item = arr[index];
var key = [item.name, item.location].join(';////|||||\\\\;');

if (key in seenParams) {
continue;
}

seenParams[key] = true;
parameters.push(item);
} while(--index > 0);

return parameters;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"homepage": "https://github.com/kogosoftwarellc/express-openapi#readme",
"devDependencies": {
"body-parser": "^1.14.2",
"chai": "^3.4.1",
"chai": "^3.5.0",
"cors": "^2.7.1",
"coveralls": "^2.11.6",
"express": "^4.13.3",
Expand Down
9 changes: 8 additions & 1 deletion test/fixtures/basic-usage-api-doc-after-initialization.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"in": "path",
"name": "id",
"required": true,
"type": "integer"
"type": "string"
}
],
"get": {
Expand All @@ -75,6 +75,13 @@
"pattern": "^fred$",
"type": "string"
},
{
"description": "Fred's age.",
"in": "path",
"name": "id",
"required": true,
"type": "integer"
},
{
"default": 80,
"description": "Fred's age.",
Expand Down
20 changes: 18 additions & 2 deletions test/sample-projects.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var expect = require('chai').expect;
var request = require('supertest');

describe(require('../package.json').name + 'sample-projects', function() {
Expand All @@ -17,10 +18,14 @@ describe(require('../package.json').name + 'sample-projects', function() {
.expect(204, '', done);
});

it('should wire up routes with defaults and coercion', function(done) {
it('should use defaults, coercion, and operation parameter overriding', function(done) {
request(app)
.get('/v3/users/34?name=fred')
.expect(200, {id: 34, name: 'fred', age: 80}, done);
.expect(200)
.end(function(err, res) {
expect(res.body).to.eql({id: 34, name: 'fred', age: 80});
done(err);
});
});

it('should validate input', function(done) {
Expand All @@ -36,6 +41,17 @@ describe(require('../package.json').name + 'sample-projects', function() {
], status: 400}, done);
});

it('should use path parameters', function(done) {
request(app)
.post('/v3/users/34')
.send({name: 'fred'})
.expect(200)
.end(function(err, res) {
expect(res.body).to.eql({id: '34'});
done(err);
});
});

it('should dereference #/definitions/ for validation', function(done) {
var user = {};

Expand Down
16 changes: 12 additions & 4 deletions test/sample-projects/basic-usage/api-routes/users/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
{
name: 'id',
in: 'path',
type: 'integer',
type: 'string',
required: true,
description: 'Fred\'s age.'
}
Expand All @@ -13,9 +13,10 @@ module.exports = {
get: get,
// or they may also be an array of middleware + the method handler. This allows
// for flexible middleware management. express-openapi middleware generated from
// the <methodHandler>.apiDoc.parameters is prepended to this array.
// the <path>.parameters + <methodHandler>.apiDoc.parameters is prepended to this
// array.
post: [function(req, res, next) {next();}, function(req, res) {
res.status(500).json('only one user is returned by this API.');
res.status(200).json({id: req.params.id});
}]
};

Expand Down Expand Up @@ -60,7 +61,14 @@ get.apiDoc = {
pattern: '^fred$',
description: 'The name of this person. It may only be "fred".'
},

// showing that operation parameters override path parameters
{
name: 'id',
in: 'path',
type: 'integer',
required: true,
description: 'Fred\'s age.'
},
{
name: 'age',
in: 'query',
Expand Down

0 comments on commit a4bb783

Please sign in to comment.