diff --git a/server.js b/server.js index dbf54d2000..1b77da4ebf 100644 --- a/server.js +++ b/server.js @@ -2397,13 +2397,14 @@ cache(function(queryParams, match, sendBadge, request) { })); // Coveralls integration. -camp.route(/^\/coveralls\/([^/]+\/[^/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/, +camp.route(/^\/coveralls\/(?:(bitbucket|github)\/)?([^/]+\/[^/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/, cache(function(data, match, sendBadge, request) { - var userRepo = match[1]; // eg, `jekyll/jekyll`. - var branch = match[2]; - var format = match[3]; + var repoService = match[1] ? match[1] : 'github'; + var userRepo = match[2]; // eg, `jekyll/jekyll`. + var branch = match[3]; + var format = match[4]; var apiUrl = { - url: 'http://badge.coveralls.io/repos/' + userRepo + '/badge.png', + url: `https://coveralls.io/repos/${repoService}/${userRepo}/badge.svg`, followRedirect: false, method: 'HEAD', }; diff --git a/service-tests/coveralls.js b/service-tests/coveralls.js new file mode 100644 index 0000000000..b32ee86781 --- /dev/null +++ b/service-tests/coveralls.js @@ -0,0 +1,103 @@ +'use strict'; + +const Joi = require('joi'); +const ServiceTester = require('./runner/service-tester'); +const { isPercentage } = require('./helpers/validators'); + +const t = new ServiceTester({ id: 'coveralls', title: 'Coveralls.io' }); +module.exports = t; + +t.create('error status code - location header is missing') + .get('/github/not/existed.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/not/existed/badge.svg') + .reply(404) + ) + .expectJSON({ name: 'coverage', value: 'invalid' }); + +t.create('malformed location') + .get('/github/user/repository.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/user/repository/badge.svg') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/malformedlocation.svg' + }) + ) + .expectJSON({ name: 'coverage', value: 'malformed' }); + +t.create('NaN percentage in location') + .get('/github/user/repository.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/user/repository/badge.svg') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_notanumber.svg' + }) + ) + .expectJSON({ name: 'coverage', value: 'unknown' }); + +t.create('connection error') + .get('/github/user/repository.json') + .networkOff() + .expectJSON({ name: 'coverage', value: 'invalid' }); + +t.create('show coverage') + .get('/github/user/repository.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/user/repository/badge.svg') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_50.svg' + }) + ) + .expectJSON({ name: 'coverage', value: '50%' }); + +t.create('show coverage for legacy github link') + .get('/user/repository.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/user/repository/badge.svg') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_50.svg' + }) + ) + .expectJSON({ name: 'coverage', value: '50%' }); + +t.create('show coverage for branch') + .get('/github/user/repository/branch.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/github/user/repository/badge.svg?branch=branch') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_50.svg' + }) + ) + .expectJSON({ name: 'coverage', value: '50%' }); + +t.create('show coverage for bitbucket') + .get('/bitbucket/user/repository.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/bitbucket/user/repository/badge.svg') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_50.svg' + }) + ) + .expectJSON({ name: 'coverage', value: '50%' }); + +t.create('show coverage for bitbucket with branch') + .get('/bitbucket/user/repository/branch.json') + .intercept(nock => nock('https://coveralls.io') + .head('/repos/bitbucket/user/repository/badge.svg?branch=branch') + .reply(302, {}, { + 'Location': 'https://s3.amazonaws.com/assets.coveralls.io/badges/coveralls_50.svg' + }) + ) + .expectJSON({ name: 'coverage', value: '50%' }); + +t.create('github coverage') + .get('/github/jekyll/jekyll.json') + .expectJSONTypes(Joi.object().keys({ name: 'coverage', value: isPercentage })); + +t.create('github coverage for legacy link') + .get('/jekyll/jekyll.json') + .expectJSONTypes(Joi.object().keys({ name: 'coverage', value: isPercentage })); + +t.create('bitbucket coverage') + .get('/bitbucket/pyKLIP/pyklip.json') + .expectJSONTypes(Joi.object().keys({ name: 'coverage', value: isPercentage })); diff --git a/try.html b/try.html index eac87e6ee3..894b35d6cb 100644 --- a/try.html +++ b/try.html @@ -168,13 +168,21 @@ Pixel-perfect   Retina-ready   Fast   Consistent   Hackable https://img.shields.io/jenkins/c/https/jenkins.qa.ubuntu.com/view/Utopic/view/All/job/address-book-service-utopic-i386-ci.svg - Coveralls: - - https://img.shields.io/coveralls/jekyll/jekyll.svg + Coveralls github: + + https://img.shields.io/coveralls/github/jekyll/jekyll.svg - Coveralls branch: - - https://img.shields.io/coveralls/jekyll/jekyll/master.svg + Coveralls github branch: + + https://img.shields.io/coveralls/github/jekyll/jekyll/master.svg + + Coveralls bitbucket: + + https://img.shields.io/coveralls/bitbucket/pyKLIP/pyklip.svg + + Coveralls bitbucket branch: + + https://img.shields.io/coveralls/bitbucket/pyKLIP/pyklip/master.svg SonarQube Coverage: