openapi: add jsonp support + test
This commit is contained in:
parent
e821bbcad8
commit
6aa30f213a
2 changed files with 91 additions and 5 deletions
|
@ -19,6 +19,7 @@ const cloneDeep = require('lodash.clonedeep');
|
||||||
|
|
||||||
const apiHandler = require('../../handler/APIHandler');
|
const apiHandler = require('../../handler/APIHandler');
|
||||||
const settings = require('../../utils/Settings');
|
const settings = require('../../utils/Settings');
|
||||||
|
const isValidJSONPName = require('./isValidJSONPName');
|
||||||
|
|
||||||
const log4js = require('log4js');
|
const log4js = require('log4js');
|
||||||
const apiLogger = log4js.getLogger('API');
|
const apiLogger = log4js.getLogger('API');
|
||||||
|
@ -582,11 +583,11 @@ exports.expressCreateServer = async (_, args) => {
|
||||||
api.register({
|
api.register({
|
||||||
notFound: (c, req, res) => {
|
notFound: (c, req, res) => {
|
||||||
res.statusCode = 404;
|
res.statusCode = 404;
|
||||||
return { code: 3, message: 'no such function', data: null };
|
res.send({ code: 3, message: 'no such function', data: null });
|
||||||
},
|
},
|
||||||
notImplemented: (c, req, res) => {
|
notImplemented: (c, req, res) => {
|
||||||
res.statusCode = 501;
|
res.statusCode = 501;
|
||||||
return { code: 3, message: 'not implemented', data: null };
|
res.send({ code: 3, message: 'not implemented', data: null });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -616,12 +617,18 @@ exports.expressCreateServer = async (_, args) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return in common format
|
// return in common format
|
||||||
const response = { code: 0, message: 'ok', data };
|
let response = { code: 0, message: 'ok', data };
|
||||||
|
|
||||||
// log response
|
// log response
|
||||||
apiLogger.info(`RESPONSE, ${funcName}, ${JSON.stringify(response)}`);
|
apiLogger.info(`RESPONSE, ${funcName}, ${JSON.stringify(response)}`);
|
||||||
|
|
||||||
return response;
|
// is this a jsonp call, add the function call
|
||||||
|
if (query.jsonp && isValidJSONPName.check(query.jsonp)) {
|
||||||
|
res.header('Content-Type', 'application/javascript');
|
||||||
|
response = `${req.query.jsonp}(${JSON.stringify(response)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
// each operation can be called with either GET or POST
|
// each operation can be called with either GET or POST
|
||||||
|
@ -635,7 +642,7 @@ exports.expressCreateServer = async (_, args) => {
|
||||||
try {
|
try {
|
||||||
// allow cors
|
// allow cors
|
||||||
res.header('Access-Control-Allow-Origin', '*');
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
res.send(await api.handleRequest(req, req, res));
|
await api.handleRequest(req, req, res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.name == 'apierror') {
|
if (err.name == 'apierror') {
|
||||||
// parameters were wrong and the api stopped execution, pass the error
|
// parameters were wrong and the api stopped execution, pass the error
|
||||||
|
|
79
tests/backend/specs/api/api.js
Normal file
79
tests/backend/specs/api/api.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* API specs
|
||||||
|
*
|
||||||
|
* Tests for generic overarching HTTP API related features not related to any
|
||||||
|
* specific part of the data model or domain. For example: tests for versioning
|
||||||
|
* and openapi definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const supertest = require(__dirname + '/../../../../src/node_modules/supertest');
|
||||||
|
const fs = require('fs');
|
||||||
|
const settings = require(__dirname + '/../../loadSettings').loadSettings();
|
||||||
|
const api = supertest('http://' + settings.ip + ':' + settings.port);
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
var validateOpenAPI = require(__dirname + '/../../../../src/node_modules/openapi-schema-validation').validate;
|
||||||
|
|
||||||
|
var filePath = path.join(__dirname, '../../../../APIKEY.txt');
|
||||||
|
|
||||||
|
var apiKey = fs.readFileSync(filePath, { encoding: 'utf-8' });
|
||||||
|
apiKey = apiKey.replace(/\n$/, '');
|
||||||
|
var apiVersion = 1;
|
||||||
|
|
||||||
|
var testPadId = makeid();
|
||||||
|
|
||||||
|
describe('API Versioning', function() {
|
||||||
|
it('errors if can not connect', function(done) {
|
||||||
|
api
|
||||||
|
.get('/api/')
|
||||||
|
.expect(function(res) {
|
||||||
|
apiVersion = res.body.currentVersion;
|
||||||
|
if (!res.body.currentVersion) throw new Error('No version set in API');
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.expect(200, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('OpenAPI definition', function() {
|
||||||
|
it('generates valid openapi definition document', function(done) {
|
||||||
|
api
|
||||||
|
.get('/api/openapi.json')
|
||||||
|
.expect(function(res) {
|
||||||
|
const { valid, errors } = validateOpenAPI(res.body, 3);
|
||||||
|
if (!valid) {
|
||||||
|
const prettyErrors = JSON.stringify(errors, null, 2);
|
||||||
|
throw new Error(`Document is not valid OpenAPI. ${errors.length} validation errors:\n${prettyErrors}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
.expect(200, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('jsonp support', function() {
|
||||||
|
it('supports jsonp calls', function(done) {
|
||||||
|
api
|
||||||
|
.get(endPoint('createPad') + '&jsonp=jsonp_1&padID=' + testPadId)
|
||||||
|
.expect(function(res) {
|
||||||
|
if (!res.text.match('jsonp_1')) throw new Error('no jsonp call seen');
|
||||||
|
})
|
||||||
|
.expect('Content-Type', /javascript/)
|
||||||
|
.expect(200, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var endPoint = function(point) {
|
||||||
|
return '/api/' + apiVersion + '/' + point + '?apikey=' + apiKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeid() {
|
||||||
|
var text = '';
|
||||||
|
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
Loading…
Reference in a new issue