diff --git a/lib/error-helper.js b/lib/error-helper.js new file mode 100644 index 0000000000..3e56dd5f02 --- /dev/null +++ b/lib/error-helper.js @@ -0,0 +1,23 @@ +'use strict'; + +const checkErrorResponse = function(badgeData, err, res) { + if (err != null) { + badgeData.text[1] = 'inaccessible'; + badgeData.colorscheme = 'red'; + return true; + } else if (res.statusCode === 404) { + badgeData.text[1] = 'not found'; + badgeData.colorscheme = 'lightgrey'; + return true; + } else if (res.statusCode !== 200) { + badgeData.text[1] = 'invalid'; + badgeData.colorscheme = 'lightgrey'; + return true; + } else { + return false; + } +}; + +module.exports = { + checkErrorResponse, +}; diff --git a/lib/error-helper.spec.js b/lib/error-helper.spec.js new file mode 100644 index 0000000000..0d26eb7242 --- /dev/null +++ b/lib/error-helper.spec.js @@ -0,0 +1,31 @@ +'use strict'; + +const { assert } = require('chai'); +const { checkErrorResponse } = require('./error-helper'); + +describe('Standard Error Handler', function() { + it('makes inaccessible badge', function() { + const badgeData = {'text': []}; + assert.equal(true, checkErrorResponse(badgeData, 'something other than null', {})); + assert.equal('inaccessible', badgeData.text[1]); + assert.equal('red', badgeData.colorscheme); + }); + + it('makes not found badge', function() { + const badgeData = {'text': []}; + assert.equal(true, checkErrorResponse(badgeData, null, {statusCode: 404})); + assert.equal('not found', badgeData.text[1]); + assert.equal('lightgrey', badgeData.colorscheme); + }); + + it('makes invalid badge', function() { + const badgeData = {'text': []}; + assert.equal(true, checkErrorResponse(badgeData, null, {statusCode: 500})); + assert.equal('invalid', badgeData.text[1]); + assert.equal('lightgrey', badgeData.colorscheme); + }); + + it('return false on 200 status', function() { + assert.equal(false, checkErrorResponse({'text': []}, null, {statusCode: 200})); + }); +}); diff --git a/server.js b/server.js index b95c855c32..c7283147bc 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,7 @@ const queryString = require('query-string'); const semver = require('semver'); const xml2js = require('xml2js'); +const { checkErrorResponse } = require('./lib/error-helper'); const analytics = require('./lib/analytics'); const config = require('./lib/server-config'); const githubAuth = require('./lib/github-auth'); @@ -5595,18 +5596,16 @@ cache(function(data, match, sendBadge, request) { } var options = { method: 'GET', - json: true, uri: uri }; var badgeData = getBadgeData('requirements', data); - request(options, function(err, res, json) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; - badgeData.colorscheme = 'red'; + request(options, function(err, res, buffer) { + if (checkErrorResponse(badgeData, err, res)) { sendBadge(format, badgeData); return; } try { + const json = JSON.parse(buffer); if (json.status === 'up-to-date') { badgeData.text[1] = 'up to date'; badgeData.colorscheme = 'brightgreen'; @@ -5622,7 +5621,7 @@ cache(function(data, match, sendBadge, request) { } sendBadge(format, badgeData); } catch(e) { - badgeData.text[1] = 'invalid' + e.toString(); + badgeData.text[1] = 'invalid'; sendBadge(format, badgeData); return; } diff --git a/service-tests/requires.js b/service-tests/requires.js new file mode 100644 index 0000000000..d117e480a0 --- /dev/null +++ b/service-tests/requires.js @@ -0,0 +1,41 @@ +'use strict'; + +const Joi = require('joi'); +const ServiceTester = require('./runner/service-tester'); + +const isRequireStatus = Joi.string().regex(/^(up to date|outdated|insecure|unknown)$/); + +const t = new ServiceTester({ id: 'requires', title: 'Requires.io' }); +module.exports = t; + + +t.create('requirements (valid, without branch)') + .get('/github/celery/celery.json') + .expectJSONTypes(Joi.object().keys({ + name: 'requirements', + value: isRequireStatus + })); + +t.create('requirements (valid, with branch)') + .get('/github/celery/celery/master.json') + .expectJSONTypes(Joi.object().keys({ + name: 'requirements', + value: isRequireStatus + })); + +t.create('requirements (not found)') + .get('/github/PyvesB/EmptyRepo.json') + .expectJSON({name: 'requirements', value: 'not found'}); + +t.create('requirements (connection error)') + .get('/github/celery/celery.json') + .networkOff() + .expectJSON({name: 'requirements', value: 'inaccessible'}); + +t.create('requirements (unexpected response)') + .get('/github/celery/celery.json') + .intercept(nock => nock('https://requires.io/') + .get('/api/v1/status/github/celery/celery') + .reply(200, "{{{{{invalid json}}") + ) + .expectJSON({name: 'requirements', value: 'invalid'});