From 7c6723a79dcdd0c3213648e68c942546921bfaeb Mon Sep 17 00:00:00 2001 From: chris48s Date: Tue, 16 Jan 2018 03:03:52 +0000 Subject: [PATCH] service tests for [docker] (#1428) --- lib/error-helper.js | 7 +- lib/error-helper.spec.js | 7 ++ server.js | 22 +++--- service-tests/docker.js | 140 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 service-tests/docker.js diff --git a/lib/error-helper.js b/lib/error-helper.js index 3e56dd5f02..4359520090 100644 --- a/lib/error-helper.js +++ b/lib/error-helper.js @@ -1,12 +1,15 @@ 'use strict'; -const checkErrorResponse = function(badgeData, err, res) { +const checkErrorResponse = function(badgeData, err, res, notFoundMessage) { + if (typeof(notFoundMessage) === 'undefined') { + notFoundMessage = 'not found'; + } if (err != null) { badgeData.text[1] = 'inaccessible'; badgeData.colorscheme = 'red'; return true; } else if (res.statusCode === 404) { - badgeData.text[1] = 'not found'; + badgeData.text[1] = notFoundMessage; badgeData.colorscheme = 'lightgrey'; return true; } else if (res.statusCode !== 200) { diff --git a/lib/error-helper.spec.js b/lib/error-helper.spec.js index 0d26eb7242..e3ab65103e 100644 --- a/lib/error-helper.spec.js +++ b/lib/error-helper.spec.js @@ -18,6 +18,13 @@ describe('Standard Error Handler', function() { assert.equal('lightgrey', badgeData.colorscheme); }); + it('makes not found badge with custom error', function() { + const badgeData = {'text': []}; + assert.equal(true, checkErrorResponse(badgeData, null, {statusCode: 404}, 'custom message')); + assert.equal('custom message', badgeData.text[1]); + assert.equal('lightgrey', badgeData.colorscheme); + }); + it('makes invalid badge', function() { const badgeData = {'text': []}; assert.equal(true, checkErrorResponse(badgeData, null, {statusCode: 500})); diff --git a/server.js b/server.js index 3850e9a59a..dcda60ca9b 100644 --- a/server.js +++ b/server.js @@ -6251,13 +6251,15 @@ cache(function(data, match, sendBadge, request) { var url = 'https://hub.docker.com/v2/repositories/' + path + '/stars/count/'; var badgeData = getBadgeData('docker stars', data); request(url, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; + if (checkErrorResponse(badgeData, err, res, 'repo not found')) { sendBadge(format, badgeData); return; } try { - var stars = +("" + buffer); + const stars = parseInt(buffer, 10); + if (Number.isNaN(stars)) { + throw Error('Unexpected response.'); + } badgeData.text[1] = metric(stars); badgeData.colorscheme = null; badgeData.colorB = data.colorB || '#008bb8'; @@ -6282,8 +6284,7 @@ cache(function(data, match, sendBadge, request) { var url = 'https://hub.docker.com/v2/repositories/' + path; var badgeData = getBadgeData('docker pulls', data); request(url, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; + if (checkErrorResponse(badgeData, err, res, 'repo not found')) { sendBadge(format, badgeData); return; } @@ -6315,8 +6316,7 @@ cache(function(data, match, sendBadge, request) { var url = 'https://registry.hub.docker.com/v2/repositories/' + path; var badgeData = getBadgeData('docker build', data); request(url, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; + if (checkErrorResponse(badgeData, err, res, 'repo not found')) { sendBadge(format, badgeData); return; } @@ -6352,17 +6352,11 @@ cache(function(data, match, sendBadge, request) { var url = 'https://registry.hub.docker.com/v2/repositories/' + path + '/buildhistory'; var badgeData = getBadgeData('docker build', data); request(url, function(err, res, buffer) { - if (err != null) { - badgeData.text[1] = 'inaccessible'; + if (checkErrorResponse(badgeData, err, res, 'repo not found')) { sendBadge(format, badgeData); return; } try { - if (res.statusCode == 404) { - badgeData.text[1] = 'repo not found'; - sendBadge(format, badgeData); - return; - } var data = JSON.parse(buffer); var most_recent_status = data.results[0].status; if (most_recent_status == 10) { diff --git a/service-tests/docker.js b/service-tests/docker.js new file mode 100644 index 0000000000..903caf4c4b --- /dev/null +++ b/service-tests/docker.js @@ -0,0 +1,140 @@ +'use strict'; + +const Joi = require('joi'); +const ServiceTester = require('./runner/service-tester'); + +const { isMetric } = require('./helpers/validators.js'); +const isAutomatedBuildStatus = Joi.string().valid('automated', 'manual'); +const isBuildStatus = Joi.string().regex(/^(passing|failing|building)$/); + +const t = new ServiceTester({ id: 'docker', title: 'Docker Hub' }); +module.exports = t; + + +// stars endpoint + +t.create('docker stars (valid, library)') + .get('/stars/_/ubuntu.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker stars', + value: isMetric + })); + +t.create('docker stars (valid, user)') + .get('/stars/jrottenberg/ffmpeg.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker stars', + value: isMetric + })); + +t.create('docker stars (not found)') + .get('/stars/_/not-a-real-repo.json') + .expectJSON({name: 'docker stars', value: 'repo not found'}); + +t.create('docker stars (connection error)') + .get('/stars/_/ubuntu.json') + .networkOff() + .expectJSON({name: 'docker stars', value: 'inaccessible'}); + +t.create('docker stars (unexpected response)') + .get('/stars/_/ubuntu.json') + .intercept(nock => nock('https://hub.docker.com/') + .get('/v2/repositories/library/ubuntu/stars/count/') + .reply(200, "some kind of error") + ) + .expectJSON({name: 'docker stars', value: 'invalid'}); + + +// pulls endpoint + +t.create('docker pulls (valid, library)') + .get('/pulls/_/ubuntu.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker pulls', + value: isMetric + })); + +t.create('docker pulls (valid, user)') + .get('/pulls/jrottenberg/ffmpeg.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker pulls', + value: isMetric + })); + +t.create('docker pulls (not found)') + .get('/pulls/_/not-a-real-repo.json') + .expectJSON({name: 'docker pulls', value: 'repo not found'}); + +t.create('docker pulls (connection error)') + .get('/pulls/_/ubuntu.json') + .networkOff() + .expectJSON({name: 'docker pulls', value: 'inaccessible'}); + +t.create('docker pulls (unexpected response)') + .get('/pulls/_/ubuntu.json') + .intercept(nock => nock('https://hub.docker.com/') + .get('/v2/repositories/library/ubuntu') + .reply(200, "{{{{{invalid json}}") + ) + .expectJSON({name: 'docker pulls', value: 'invalid'}); + + +// automated build endpoint + +t.create('docker automated build (valid, library)') + .get('/automated/_/ubuntu.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker build', + value: isAutomatedBuildStatus + })); + +t.create('docker automated build (valid, user)') + .get('/automated/jrottenberg/ffmpeg.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker build', + value: isAutomatedBuildStatus + })); + +t.create('docker automated build (not found)') + .get('/automated/_/not-a-real-repo.json') + .expectJSON({name: 'docker build', value: 'repo not found'}); + +t.create('docker automated build (connection error)') + .get('/automated/_/ubuntu.json') + .networkOff() + .expectJSON({name: 'docker build', value: 'inaccessible'}); + +t.create('docker automated build (unexpected response)') + .get('/automated/_/ubuntu.json') + .intercept(nock => nock('https://registry.hub.docker.com/') + .get('/v2/repositories/library/ubuntu') + .reply(200, "{{{{{invalid json}}") + ) + .expectJSON({name: 'docker build', value: 'invalid'}); + + +// build status endpoint + +t.create('docker build status (valid, user)') + .get('/build/jrottenberg/ffmpeg.json') + .expectJSONTypes(Joi.object().keys({ + name: 'docker build', + value: isBuildStatus + })); + +t.create('docker build status (not found)') + .get('/build/_/not-a-real-repo.json') + .expectJSON({name: 'docker build', value: 'repo not found'}); + +t.create('docker build status (connection error)') + .get('/build/_/ubuntu.json') + .networkOff() + .expectJSON({name: 'docker build', value: 'inaccessible'}); + +t.create('docker build status (unexpected response)') + .get('/build/_/ubuntu.json') + .intercept(nock => nock('https://registry.hub.docker.com/') + .get('/v2/repositories/library/ubuntu/buildhistory') + .reply(200, "{{{{{invalid json}}") + ) + .expectJSON({name: 'docker build', value: 'invalid'});