Skip to content
This repository has been archived by the owner on May 15, 2023. It is now read-only.

Commit

Permalink
Make sure that the json property is set when the content is JSON (#140)
Browse files Browse the repository at this point in the history
* Change all calls to request to use the body property instead of the json property
* json property is now set if the produces or consumes is a JSON media type
  • Loading branch information
baynezy authored and noahdietz committed May 5, 2017
1 parent 5ac4575 commit fbaafcb
Show file tree
Hide file tree
Showing 36 changed files with 518 additions and 82 deletions.
1 change: 1 addition & 0 deletions index.js
Expand Up @@ -559,6 +559,7 @@ handlebars.registerHelper('length', helpers.length);
handlebars.registerHelper('pathify', helpers.pathify);
handlebars.registerHelper('printJSON', helpers.printJSON);
handlebars.registerHelper('requestDataParamFormatter', helpers.requestDataParamFormatter);
handlebars.registerHelper('isJsonRepresentation', helpers.isJsonRepresentation);


module.exports = {
Expand Down
23 changes: 20 additions & 3 deletions lib/helpers.js
Expand Up @@ -3,7 +3,6 @@
var _ = require('lodash');
var strObj = require('string');
var url = require('url');
var TYPE_JSON = 'application/json';
var len;

module.exports = {
Expand All @@ -15,7 +14,8 @@ module.exports = {
printJSON: printJSON,
len: len,
setLen: setLen,
requestDataParamFormatter : requestDataParamFormatter
requestDataParamFormatter : requestDataParamFormatter,
isJsonRepresentation : isJsonRepresentation
};

function setLen(descriptionLength) {
Expand Down Expand Up @@ -60,13 +60,30 @@ function validateResponse(type, noSchema,
'needs 2 parameters');
}

if (!noSchema && type === TYPE_JSON) {
if (!noSchema && isJsonMediaType(type)) {
return options.fn(this);
} else {
return options.inverse(this);
}
}

/**
* decides if this request/response has a JSON representation
* @param {string} contentType the media type of the request
* @param {string} returnType the media type of the response
*/
function isJsonRepresentation(contentType, returnType, options) {
return (isJsonMediaType(contentType) || isJsonMediaType(returnType)) ? options.fn(this) : options.inverse(this);
}

/**
* determines if the mediatype is json
* @param {string} type content type to be evaluated
*/
function isJsonMediaType(type) {
return type.trim().toLowerCase().substr(type.length - 4) === 'json';
}

/**
* replaces path params with obvious indicator for filling values
* (i.e. if any part of the path is surrounded in curly braces {})
Expand Down
3 changes: 3 additions & 0 deletions templates/request/delete/delete.handlebars
Expand Up @@ -7,6 +7,9 @@
{{/validateResponse}}
request({
url: '{{pathify path pathParams}}',
{{#isJsonRepresentation contentType returnType}}
json: true,
{{/isJsonRepresentation}}
{{#ifCond queryParameters queryApiKey}}
qs: {
{{#if queryApiKey}}{{queryApiKey.type}}: process.env.{{queryApiKey.name}}{{#if queryParameters}},
Expand Down
3 changes: 3 additions & 0 deletions templates/request/get/get.handlebars
Expand Up @@ -7,6 +7,9 @@
{{/validateResponse}}
request({
url: '{{pathify path pathParams}}',
{{#isJsonRepresentation contentType returnType}}
json: true,
{{/isJsonRepresentation}}
{{#ifCond queryParameters queryApiKey}}
qs: {
{{#if queryApiKey}}{{queryApiKey.type}}: process.env.{{queryApiKey.name}}{{#if queryParameters}},
Expand Down
9 changes: 6 additions & 3 deletions templates/request/patch/patch.handlebars
Expand Up @@ -7,6 +7,9 @@
{{/validateResponse}}
request({
url: '{{pathify path pathParams}}',
{{#isJsonRepresentation contentType returnType}}
json: true,
{{/isJsonRepresentation}}
{{#ifCond queryParameters queryApiKey}}
qs: {
{{#if queryApiKey}}{{queryApiKey.type}}: process.env.{{queryApiKey.name}}{{#if queryParameters}},
Expand All @@ -20,10 +23,10 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
{{#if request}}json: {
{{#if request}}body: {
{{ request }}
}
{{else}}json: {
{{else}}body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down Expand Up @@ -122,7 +125,7 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
json: {
body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down
7 changes: 5 additions & 2 deletions templates/request/post/post.handlebars
Expand Up @@ -7,6 +7,9 @@
{{/validateResponse}}
request({
url: '{{pathify path pathParams}}',
{{#isJsonRepresentation contentType returnType}}
json: true,
{{/isJsonRepresentation}}
{{#ifCond queryParameters queryApiKey}}
qs: {
{{#if queryApiKey}}{{queryApiKey.type}}: process.env.{{queryApiKey.name}}{{#if queryParameters}},
Expand All @@ -21,7 +24,7 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
{{#if request}}json: {{ request }}{{else}}json: {
{{#if request}}body: {{ request }}{{else}}body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down Expand Up @@ -120,7 +123,7 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
json: {
body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down
7 changes: 5 additions & 2 deletions templates/request/put/put.handlebars
Expand Up @@ -7,6 +7,9 @@
{{/validateResponse}}
request({
url: '{{pathify path pathParams}}',
{{#isJsonRepresentation contentType returnType}}
json: true,
{{/isJsonRepresentation}}
{{#ifCond queryParameters queryApiKey}}
qs: {
{{#if queryApiKey}}{{queryApiKey.type}}: process.env.{{queryApiKey.name}}{{#if queryParameters}},
Expand All @@ -21,7 +24,7 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
{{#if request}}json: {{ request }}{{else}}json: {
{{#if request}}body: {{ request }}{{else}}body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down Expand Up @@ -120,7 +123,7 @@
Authorization: '{{headerSecurity.type}} ' + process.env.{{headerSecurity.name}}{{/if}}
},
{{#is contentType 'application/json'}}
json: {
body: {
{{#each bodyParameters}}
{{this.name}}: 'DATA GOES HERE'{{#unless @last}},{{/unless}}
{{/each}}
Expand Down
67 changes: 67 additions & 0 deletions test/jsonProperty/compare/request/expect/no-property-user-test.js
@@ -0,0 +1,67 @@
'use strict';
var chai = require('chai');
var request = require('request');
var expect = chai.expect;

describe('/user', function() {
describe('get', function() {
it('should respond with 200 OK', function(done) {
request({
url: 'https://api.uber.com/user',
json: true,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(200);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

it('should respond with 400 NOT OK', function(done) {
request({
url: 'https://api.uber.com/user',
json: true,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(400);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

it('should respond with 500 SERVER ERROR', function(done) {
request({
url: 'https://api.uber.com/user',
json: true,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(500);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

});

});
67 changes: 67 additions & 0 deletions test/jsonProperty/compare/request/expect/non-json-user-test.js
@@ -0,0 +1,67 @@
'use strict';
var chai = require('chai');
var request = require('request');
var expect = chai.expect;

describe('/user', function() {
describe('post', function() {
it('should respond with 200 OK', function(done) {
request({
url: 'https://api.uber.com/user',
method: 'POST',
headers: {
'Content-Type': 'application/xml'
},
body: 'XML STRING GOES HERE'
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(200);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

it('should respond with 400 NOT OK', function(done) {
request({
url: 'https://api.uber.com/user',
method: 'POST',
headers: {
'Content-Type': 'application/xml'
},
body: 'XML STRING GOES HERE'
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(400);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

it('should respond with 500 SERVER ERROR', function(done) {
request({
url: 'https://api.uber.com/user',
method: 'POST',
headers: {
'Content-Type': 'application/xml'
},
body: 'XML STRING GOES HERE'
},
function(error, res, body) {
if (error) return done(error);

expect(res.statusCode).to.equal(500);

expect(body).to.equal(null); // non-json response or no schema
done();
});
});

});

});
28 changes: 28 additions & 0 deletions test/jsonProperty/swagger-no-type.json
@@ -0,0 +1,28 @@
{
"swagger": "2.0",
"info": {
"version": "0.0.0",
"title": "Simple API"
},
"host": "api.uber.com",
"schemes": [
"https"
],
"paths": {
"/user": {
"get": {
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "NOT OK"
},
"500": {
"description": "SERVER ERROR"
}
}
}
}
}
}
34 changes: 34 additions & 0 deletions test/jsonProperty/swagger-non-json.json
@@ -0,0 +1,34 @@
{
"swagger": "2.0",
"info": {
"version": "0.0.0",
"title": "Simple API"
},
"host": "api.uber.com",
"schemes": [
"https"
],
"paths": {
"/user": {
"post": {
"consumes": [
"application/xml"
],
"produces": [
"application/xml"
],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "NOT OK"
},
"500": {
"description": "SERVER ERROR"
}
}
}
}
}
}

0 comments on commit fbaafcb

Please sign in to comment.