add [AppVeyorJobBuild] status badge (#4409)

* feat(service): add AppVeyor Job status badge

* refactor: sync file/class/route names for appveyor job

* tests: update # of build services in frontend test

Co-authored-by: Pierre-Yves B. <PyvesDev@gmail.com>
This commit is contained in:
Caleb Cartwright
2020-01-08 16:22:04 -06:00
committed by repo-ranger[bot]
parent 347e0a81f3
commit fe02ac723f
9 changed files with 199 additions and 3 deletions

View File

@@ -11,6 +11,6 @@ describe('Service definition helpers', function() {
it('getDefinitionsForCategory', function() {
expect(getDefinitionsForCategory('build'))
.to.have.length.greaterThan(10)
.and.lessThan(50)
.and.lessThan(75)
})
})

View File

@@ -10,6 +10,10 @@ const schema = Joi.object({
status: isBuildStatus,
jobs: Joi.array()
.items({
name: Joi.string()
.allow('')
.required(),
status: isBuildStatus,
testsCount: nonNegativeInteger,
passedTestsCount: nonNegativeInteger,
failedTestsCount: nonNegativeInteger,

View File

@@ -0,0 +1,16 @@
'use strict'
const { redirector } = require('..')
module.exports = [
redirector({
category: 'build',
route: {
base: 'appveyor/ci',
pattern: ':user/:repo/:branch*',
},
transformPath: ({ user, repo, branch }) =>
`/appveyor/build/${user}/${repo}${branch ? `/${branch}` : ''}`,
dateAdded: new Date('2019-12-10'),
}),
]

View File

@@ -0,0 +1,23 @@
'use strict'
const { ServiceTester } = require('../tester')
const t = (module.exports = new ServiceTester({
id: 'AppveyorBuildRedirect',
title: 'AppveyorBuildRedirect',
pathPrefix: '/appveyor/ci',
}))
t.create('Appveyor CI')
.get('/gruntjs/grunt', {
followRedirect: false,
})
.expectStatus(301)
.expectHeader('Location', '/appveyor/build/gruntjs/grunt.svg')
t.create('Appveyor CI (branch)')
.get('/gruntjs/grunt/develop', {
followRedirect: false,
})
.expectStatus(301)
.expectHeader('Location', '/appveyor/build/gruntjs/grunt/develop.svg')

View File

@@ -3,9 +3,9 @@
const { renderBuildStatusBadge } = require('../build-status')
const AppVeyorBase = require('./appveyor-base')
module.exports = class AppVeyorCi extends AppVeyorBase {
module.exports = class AppVeyorBuild extends AppVeyorBase {
static get route() {
return this.buildRoute('appveyor/ci')
return this.buildRoute('appveyor/build')
}
static get examples() {

View File

@@ -0,0 +1,68 @@
'use strict'
const { renderBuildStatusBadge } = require('../build-status')
const AppVeyorBase = require('./appveyor-base')
const { NotFound } = require('..')
module.exports = class AppVeyorJobBuild extends AppVeyorBase {
static get route() {
return {
base: 'appveyor/job/build',
pattern: ':user/:repo/:job/:branch*',
}
}
static get examples() {
return [
{
title: 'AppVeyor Job',
pattern: ':user/:repo/:job',
namedParams: {
user: 'wpmgprostotema',
repo: 'voicetranscoder',
job: 'Linux',
},
staticPreview: renderBuildStatusBadge({ status: 'success' }),
},
{
title: 'AppVeyor Job branch',
pattern: ':user/:repo/:job/:branch',
namedParams: {
user: 'wpmgprostotema',
repo: 'voicetranscoder',
job: 'Windows',
branch: 'master',
},
staticPreview: renderBuildStatusBadge({ status: 'success' }),
},
]
}
transform({ data, jobName }) {
if (!data.hasOwnProperty('build')) {
// this project exists but no builds have been run on it yet
return { status: 'no builds found' }
}
const {
build: { jobs },
} = data
if (!jobs) {
throw new NotFound({ prettyMessage: 'no jobs found' })
}
const job = jobs.find(j => j.name === jobName)
if (!job) {
throw new NotFound({ prettyMessage: 'job not found' })
}
return { status: job.status }
}
async handle({ user, repo, job, branch }) {
const data = await this.fetch({ user, repo, branch })
const { status } = this.transform({ data, jobName: job })
return renderBuildStatusBadge({ status })
}
}

View File

@@ -0,0 +1,63 @@
'use strict'
const { expect } = require('chai')
const { test, given } = require('sazerac')
const AppveyorJobBuild = require('./appveyor-job-build.service')
const { NotFound } = require('..')
describe('AppveyorJobBuild', function() {
test(AppveyorJobBuild.prototype.transform, () => {
given({ data: {} }).expect({
status: 'no builds found',
})
given({
jobName: 'linux',
data: {
build: {
jobs: [
{
name: 'windows',
status: 'failed',
},
{
name: 'linux',
status: 'passed',
},
],
},
},
}).expect({
status: 'passed',
})
})
it('throws NotFound when response is missing jobs', function() {
expect(() => AppveyorJobBuild.prototype.transform({ data: { build: {} } }))
.to.throw(NotFound)
.with.property('prettyMessage', 'no jobs found')
})
it('throws NotFound when specified job missing jobs', function() {
expect(() =>
AppveyorJobBuild.prototype.transform({
jobName: 'mac',
data: {
build: {
jobs: [
{
name: 'linux',
status: 'passed',
},
{
name: 'windows',
status: 'passed',
},
],
},
},
})
)
.to.throw(NotFound)
.with.property('prettyMessage', 'job not found')
})
})

View File

@@ -0,0 +1,22 @@
'use strict'
const { isBuildStatus } = require('../build-status')
const t = (module.exports = require('../tester').createServiceTester())
t.create('Job CI status')
.timeout(10000)
.get('/wpmgprostotema/voicetranscoder/Windows.json')
.expectBadge({ label: 'build', message: isBuildStatus })
t.create('Job CI status on branch')
.timeout(10000)
.get('/wpmgprostotema/voicetranscoder/Linux/master.json')
.expectBadge({ label: 'build', message: isBuildStatus })
t.create('Job CI status on nonexistent project')
.timeout(10000)
.get('/somerandomproject/thatdoesntexist/foo.json')
.expectBadge({
label: 'build',
message: 'project not found or access denied',
})