From b05d93c9c11cf1657b978d7abb19915a88109a8c Mon Sep 17 00:00:00 2001 From: chris48s Date: Thu, 5 Jul 2018 19:06:06 +0100 Subject: [PATCH] fix [waffle] labels badge (#1745) fix [waffle] labels badge - update URL and parsing code to use /columns endpoint - add error handling for 'not found' case - add missing test cases - update home page example Closes #1731 --- lib/all-badge-examples.js | 2 +- server.js | 39 +++++++------ services/waffle/waffle.tester.js | 99 ++++++++++++++++++++++---------- 3 files changed, 90 insertions(+), 50 deletions(-) diff --git a/lib/all-badge-examples.js b/lib/all-badge-examples.js index 997b1ae9f3e24..e01e7d3e50a59 100644 --- a/lib/all-badge-examples.js +++ b/lib/all-badge-examples.js @@ -1935,7 +1935,7 @@ const allBadgeExamples = [ }, { title: 'Waffle.io', - previewUri: '/waffle/label/evancohen/smart-mirror/in%20progress.svg' + previewUri: '/waffle/label/evancohen/smart-mirror/status%3A%20in%20progress.svg' }, { title: 'Chrome Web Store', diff --git a/server.js b/server.js index 6761c97d81682..c478a889758ba 100644 --- a/server.js +++ b/server.js @@ -6606,32 +6606,33 @@ cache({ // Waffle.io integration camp.route(/^\/waffle\/label\/([^/]+)\/([^/]+)\/?([^/]+)?\.(svg|png|gif|jpg|json)$/, cache(function(data, match, sendBadge, request) { - var user = match[1]; // eg, evancohen - var repo = match[2]; // eg, smart-mirror - var ghLabel = match[3] || 'ready'; // eg, in%20progress - var format = match[4]; - var apiUrl = 'https://api.waffle.io/' + user + '/' + repo + '/cards'; - var badgeData = getBadgeData('issues', data); + const user = match[1]; // eg, evancohen + const repo = match[2]; // eg, smart-mirror + const ghLabel = match[3] || 'ready'; // eg, in%20progress + const format = match[4]; + const apiUrl = `https://api.waffle.io/${user}/${repo}/columns?with=count`; + const badgeData = getBadgeData('waffle', data); request(apiUrl, function(err, res, buffer) { try { - var cards = JSON.parse(buffer); - if (cards.length === 0) { + if (checkErrorResponse(badgeData, err, res)) { + sendBadge(format, badgeData); + return; + } + const cols = JSON.parse(buffer); + if (cols.length === 0) { badgeData.text[1] = 'absent'; sendBadge(format, badgeData); return; } - var count = 0; - var color = '78bdf2'; - for (var i = 0; i < cards.length; i++) { - var cardMetadata = cards[i].githubMetadata; - if (cardMetadata.labels && cardMetadata.labels.length > 0) { - for (var j = 0; j < cardMetadata.labels.length; j++) { - var label = cardMetadata.labels[j]; - if (label.name === ghLabel) { - count++; - color = label.color; - } + let count = 0; + let color = '78bdf2'; + for (let i = 0; i < cols.length; i++) { + if (('label' in cols[i]) && (cols[i].label !== null)) { + if (cols[i].label.name === ghLabel) { + count = cols[i].count; + color = cols[i].label.color; + break; } } } diff --git a/services/waffle/waffle.tester.js b/services/waffle/waffle.tester.js index 2c9c3030fcfe8..0fc5d735b6136 100644 --- a/services/waffle/waffle.tester.js +++ b/services/waffle/waffle.tester.js @@ -2,6 +2,7 @@ const Joi = require('joi'); const ServiceTester = require('../service-tester'); +const { invalidJSON } = require('../response-fixtures'); const t = new ServiceTester({ id: 'waffle', title: 'Waffle.io' }); module.exports = t; @@ -9,43 +10,81 @@ module.exports = t; const fakeData = [ { - githubMetadata: { - labels: [ - { color: 'c5def5', name: 'feature' }, - { color: 'fbca04', name: 'bug' }, - { color: 'e11d21', name: 'bug' } - ] - } + "label": null, + "count": 20 }, { - githubMetadata: { - labels: [ - { color: 'c5def5', name: 'feature' }, - { color: 'fbca04', name: 'bug' }, - { color: 'e11d21', name: 'feature' } - ] - } + "count": 10 }, { - githubMetadata: { - labels: [ - { color: 'c5def5', name: 'bug' }, - { color: 'fbca04', name: 'bug' } - ] - } + "label": { + "color": "c5def5", + "name": "feature" + }, + "count": 3 }, + { + "label": { + "name": "bug", + "color": "fbca04" + }, + "count": 5 + } ]; + t.create('label should be `bug` & value should be exactly 5 as supplied in `fakeData`. e.g: bug|5') - .get('/label/userName/repoName/bug.json') - .intercept(nock => nock('https://api.waffle.io/') - .get('/userName/repoName/cards') - .reply(200, fakeData)) - .expectJSON({ name: 'bug', value: '5' }); + .get('/label/userName/repoName/bug.json?style=_shields_test') + .intercept(nock => nock('https://api.waffle.io/') + .get('/userName/repoName/columns?with=count') + .reply(200, fakeData)) + .expectJSON({ + name: 'bug', + value: '5', + colorB: '#fbca04', + }); t.create('label should be `Mybug` & value should be formated. e.g: Mybug|25') - .get('/label/ritwickdey/vscode-live-server/bug.json?label=Mybug') - .expectJSONTypes(Joi.object().keys({ - name: 'Mybug', - value: Joi.string().regex(/^\d+$/) - })); + .get('/label/ritwickdey/vscode-live-server/bug.json?label=Mybug') + .expectJSONTypes(Joi.object().keys({ + name: 'Mybug', + value: Joi.number().integer().positive() + })); + +t.create('label (repo not found)') + .get('/label/not-a-user/not-a-repo/bug.json') + .expectJSON({ + name: 'waffle', + value: 'not found', + }); + +t.create('label (label not found)') + .get('/label/ritwickdey/vscode-live-server/not-a-real-label.json?style=_shields_test') + .expectJSON({ + name: 'not-a-real-label', + value: '0', + colorB: '#78bdf2', + }); + +t.create('label (empty response)') + .get('/label/userName/repoName/bug.json') + .intercept(nock => nock('https://api.waffle.io/') + .get('/userName/repoName/columns?with=count') + .reply(200, [])) + .expectJSON({ + name: 'waffle', + value: 'absent', + }); + +t.create('label (connection error)') + .get('/label/ritwickdey/vscode-live-server/bug.json') + .networkOff() + .expectJSON({name: 'waffle', value: 'inaccessible'}); + +t.create('label (unexpected response)') + .get('/label/userName/repoName/bug.json') + .intercept(nock => nock('https://api.waffle.io/') + .get('/userName/repoName/columns?with=count') + .reply(invalidJSON) + ) + .expectJSON({name: 'waffle', value: 'invalid'});