Mobrovac has submitted this change and it was merged. Change subject: Add the /_info routes and some tests ......................................................................
Add the /_info routes and some tests All services based on the service template expose the /_info routes, which are also used by the health monitoring utilities in production to check on them. This commit adds these routes to Citoid. Also, some more tests have been added checking for correct CORS and CSP headers as well as tests for /_info routes. Change-Id: I9ad49cfe13278c07bef10bee9e736de9f2636706 --- M package.json A routes/info.js M test/features/app/index.js A test/features/app/info.js 4 files changed, 189 insertions(+), 0 deletions(-) Approvals: Mobrovac: Verified; Looks good to me, approved diff --git a/package.json b/package.json index 5023a2c..b03422f 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "citoid", "version": "0.2.6", "description": "Converts search terms such as URL or DOI into citations.", + "homepage": "https://www.mediawiki.org/wiki/Citoid", "scripts": { "start": "service-runner", "test": "mocha test/index.js", diff --git a/routes/info.js b/routes/info.js new file mode 100644 index 0000000..e9b06fe --- /dev/null +++ b/routes/info.js @@ -0,0 +1,90 @@ +'use strict'; + + +var sUtil = require('../lib/util'); + + +/** + * The main router object + */ +var router = sUtil.router(); + +/** + * The main application object reported when this module is require()d + */ +var app; + + +/** + * GET / + * Gets some basic info about this service + */ +router.get('/', function(req, res) { + + // simple sync return + res.json({ + name: app.info.name, + version: app.info.version, + description: app.info.description, + home: app.info.homepage + }); + +}); + + +/** + * GET /name + * Gets the service's name as defined in package.json + */ +router.get('/name', function(req, res) { + + // simple return + res.json({ name: app.info.name }); + +}); + + +/** + * GET /version + * Gets the service's version as defined in package.json + */ +router.get('/version', function(req, res) { + + // simple return + res.json({ version: app.info.version }); + +}); + + +/** + * ALL /home + * Redirects to the service's home page if one is given, + * returns a 404 otherwise + */ +router.all('/home', function(req, res) { + + var home = app.info.homepage; + if(home && /^http/.test(home)) { + // we have a home page URI defined, so send it + res.redirect(301, home); + return; + } else { + // no URI defined for the home page, error out + res.status(404).end('No home page URL defined for ' + app.info.name); + } + +}); + + +module.exports = function(appObj) { + + app = appObj; + + return { + path: '/_info', + skip_domain: true, + router: router + }; + +}; + diff --git a/test/features/app/index.js b/test/features/app/index.js index ac590d6..ed74cd0 100644 --- a/test/features/app/index.js +++ b/test/features/app/index.js @@ -32,5 +32,29 @@ }); }); + it('should set CORS headers', function() { + return preq.get({ + uri: server.config.uri + 'robots.txt' + }).then(function(res) { + assert.deepEqual(res.status, 200); + assert.deepEqual(res.headers['access-control-allow-origin'], '*'); + assert.notDeepEqual(res.headers['access-control-allow-headers'], undefined); + }); + }); + + it('should set CSP headers', function() { + return preq.get({ + uri: server.config.uri + 'robots.txt' + }).then(function(res) { + assert.deepEqual(res.status, 200); + assert.deepEqual(res.headers['x-xss-protection'], '1; mode=block'); + assert.deepEqual(res.headers['x-content-type-options'], 'nosniff'); + assert.deepEqual(res.headers['x-frame-options'], 'SAMEORIGIN'); + assert.deepEqual(res.headers['content-security-policy'], 'default-src'); + assert.deepEqual(res.headers['x-content-security-policy'], 'default-src'); + assert.deepEqual(res.headers['x-webkit-csp'], 'default-src'); + }); + }); + }); diff --git a/test/features/app/info.js b/test/features/app/info.js new file mode 100644 index 0000000..3394c75 --- /dev/null +++ b/test/features/app/info.js @@ -0,0 +1,74 @@ +'use strict'; + + +// mocha defines to avoid JSHint breakage +/* global describe, it, before, beforeEach, after, afterEach */ + + +var preq = require('preq'); +var assert = require('../../utils/assert.js'); +var server = require('../../utils/server.js'); + + +describe('service information', function() { + + this.timeout(20000); + + before(function () { return server.start(); }); + + // common URI prefix for info tests + var infoUri = server.config.uri + '_info/'; + + // common function used for generating requests + // and checking their return values + function checkRet(fieldName) { + return preq.get({ + uri: infoUri + fieldName + }).then(function(res) { + // check the returned Content-Type header + assert.contentType(res, 'application/json'); + // the status as well + assert.status(res, 200); + // finally, check the body has the specified field + assert.notDeepEqual(res.body, undefined, 'No body returned!'); + assert.notDeepEqual(res.body[fieldName], undefined, 'No ' + fieldName + ' field returned!'); + }); + } + + it('should get the service name', function() { + return checkRet('name'); + }); + + it('should get the service version', function() { + return checkRet('version'); + }); + + it('should redirect to the service home page', function() { + return preq.get({ + uri: infoUri + 'home', + followRedirect: false + }).then(function(res) { + // check the status + assert.status(res, 301); + }); + }); + + it('should get the service info', function() { + return preq.get({ + uri: infoUri + }).then(function(res) { + // check the status + assert.status(res, 200); + // check the returned Content-Type header + assert.contentType(res, 'application/json'); + // inspect the body + assert.notDeepEqual(res.body, undefined, 'No body returned!'); + assert.notDeepEqual(res.body.name, undefined, 'No name field returned!'); + assert.notDeepEqual(res.body.version, undefined, 'No version field returned!'); + assert.notDeepEqual(res.body.description, undefined, 'No description field returned!'); + assert.notDeepEqual(res.body.home, undefined, 'No home field returned!'); + }); + }); + +}); + -- To view, visit https://gerrit.wikimedia.org/r/207091 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I9ad49cfe13278c07bef10bee9e736de9f2636706 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/services/citoid Gerrit-Branch: master Gerrit-Owner: Mobrovac <mobro...@wikimedia.org> Gerrit-Reviewer: Mobrovac <mobro...@wikimedia.org> Gerrit-Reviewer: Mvolz <mv...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits