From 28a5a2619afe369273333cf8d93764170486d538 Mon Sep 17 00:00:00 2001 From: Samuel Reed Date: Fri, 12 Dec 2014 13:10:45 +0100 Subject: [PATCH 1/2] Move 200 response to `type` on the operation object. See #75. --- lib/route-helper.js | 19 ++++++------------- lib/swagger.js | 6 +++++- test/route-helper.test.js | 30 ++++++++++++++++++++---------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/lib/route-helper.js b/lib/route-helper.js index 4d5545f..4625e8b 100644 --- a/lib/route-helper.js +++ b/lib/route-helper.js @@ -125,17 +125,9 @@ var routeHelper = module.exports = { var responseDoc = modelHelper.LDLPropToSwaggerDataType(returns); - // Note: Swagger Spec does not provide a way how to specify - // that the responseModel is "array of X". However, - // Swagger UI converts Arrays to the item types anyways, - // therefore it should be ok to do the same here. - var responseModel = responseDoc.type === 'array' ? - responseDoc.items.type : responseDoc.type; - var responseMessages = [{ code: route.returns && route.returns.length ? 200 : 204, - message: 'Request was successful', - responseModel: responseModel + message: 'Request was successful' }]; if (route.errors) { @@ -145,9 +137,10 @@ var routeHelper = module.exports = { var apiDoc = { path: routeHelper.convertPathFragments(route.path), // Create the operation doc. - // Note that we are not calling `extendWithType`, as the response type - // is specified in the first response message. - operations: [{ + // We are using extendWithType to use `type` for the top-level (200) + // response type. We use responseModels for error responses. + // see https://github.com/strongloop/loopback-explorer/issues/75 + operations: [routeHelper.extendWithType({ method: routeHelper.convertVerb(route.verb), // [strml] remove leading model name from op, swagger uses leading // path as class name so it remains unique between models. @@ -158,7 +151,7 @@ var routeHelper = module.exports = { summary: typeConverter.convertText(route.description), notes: typeConverter.convertText(route.notes), deprecated: route.deprecated - }] + }, returns)] }; return apiDoc; diff --git a/lib/swagger.js b/lib/swagger.js index f6ee454..3572c81 100644 --- a/lib/swagger.js +++ b/lib/swagger.js @@ -98,7 +98,11 @@ function Swagger(loopbackApplication, swaggerApp, opts) { addTypeToModels(type); }); - addTypeToModels(routeDoc.type); + if (routeDoc.type === 'array') { + addTypeToModels(routeDoc.items.type); + } else { + addTypeToModels(routeDoc.type); + } routeDoc.responseMessages.forEach(function(msg) { addTypeToModels(msg.responseModel); diff --git a/test/route-helper.test.js b/test/route-helper.test.js index 6654f78..8e35f5c 100644 --- a/test/route-helper.test.js +++ b/test/route-helper.test.js @@ -13,8 +13,8 @@ describe('route-helper', function() { { arg: 'avg', type: 'number' } ] }); - expect(doc.operations[0].type).to.equal(undefined); - expect(getResponseType(doc.operations[0])).to.equal('object'); + expect(doc.operations[0].type).to.equal('object'); + expect(getResponseType(doc.operations[0])).to.equal(undefined); }); it('converts path params when they exist in the route name', function() { @@ -61,12 +61,22 @@ describe('route-helper', function() { ] }); var opDoc = doc.operations[0]; - // Note: swagger-ui treat arrays of X the same way as object X - expect(getResponseType(opDoc)).to.equal('customType'); + expect(getResponseType(opDoc)).to.equal(undefined); // NOTE(bajtos) this would be the case if there was a single response type - // expect(opDoc.type).to.equal('array'); - // expect(opDoc.items).to.eql({type: 'customType'}); + expect(opDoc.type).to.equal('array'); + expect(opDoc.items).to.eql({type: 'customType'}); + }); + + it('correctly converts return types (format)', function() { + var doc = createAPIDoc({ + returns: [ + {arg: 'data', type: 'buffer'} + ] + }); + var opDoc = doc.operations[0]; + expect(opDoc.type).to.equal('string'); + expect(opDoc.format).to.equal('byte'); }); it('includes `notes` metadata', function() { @@ -149,11 +159,11 @@ describe('route-helper', function() { var doc = createAPIDoc({ returns: [{ name: 'result', type: 'object', root: true }] }); + expect(doc.operations[0].type).to.eql('object'); expect(doc.operations[0].responseMessages).to.eql([ { code: 200, - message: 'Request was successful', - responseModel: 'object' + message: 'Request was successful' } ]); }); @@ -162,11 +172,11 @@ describe('route-helper', function() { var doc = createAPIDoc({ returns: [] }); + expect(doc.operations[0].type).to.eql('void'); expect(doc.operations[0].responseMessages).to.eql([ { code: 204, - message: 'Request was successful', - responseModel: 'void' + message: 'Request was successful' } ]); }); From b540651658f3d1b3451f33c16f6e10dae8496ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Fri, 12 Dec 2014 13:56:52 +0100 Subject: [PATCH 2/2] v1.6.2 --- CHANGES.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4e8b4cb..2e4644d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +2014-12-12, Version 1.6.2 +========================= + + * Move 200 response to `type` on the operation object. See #75. (Samuel Reed) + + 2014-12-08, Version 1.6.1 ========================= diff --git a/package.json b/package.json index fce503e..c46b6d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-explorer", - "version": "1.6.1", + "version": "1.6.2", "description": "Browse and test your LoopBack app's APIs", "main": "index.js", "scripts": {