refactor [mavencentral] (#3290)

* refactor maven central

* misc fixes

- include a pretty message on NotFound when the filter returns no results

- split the group and artifact into seperate variables

- remove the connection error test

* remove xml parsing test and add inexistent version prefix test

* use existing test validators and shorthand createservicetester
This commit is contained in:
James Cahill
2019-04-26 00:35:50 +01:00
committed by Caleb Cartwright
parent 2215693557
commit 01d745122b
2 changed files with 55 additions and 84 deletions

View File

@@ -1,18 +1,25 @@
'use strict'
const xml2js = require('xml2js')
const LegacyService = require('../legacy-service')
const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
const { addv: versionText } = require('../text-formatters')
const { version: versionColor } = require('../color-formatters')
const Joi = require('joi')
const { BaseXmlService, NotFound } = require('..')
const { renderVersionBadge } = require('../version')
// This legacy service should be rewritten to use e.g. BaseJsonService.
//
// Tips for rewriting:
// https://github.com/badges/shields/blob/master/doc/rewriting-services.md
//
// Do not base new services on this code.
module.exports = class MavenCentral extends LegacyService {
const schema = Joi.object({
metadata: Joi.object({
versioning: Joi.object({
versions: Joi.object({
version: Joi.array()
.items(
Joi.alternatives(Joi.string().required(), Joi.number().required())
)
.single()
.required(),
}).required(),
}).required(),
}).required(),
}).required()
module.exports = class MavenCentral extends BaseXmlService {
static get category() {
return 'version'
}
@@ -20,7 +27,7 @@ module.exports = class MavenCentral extends LegacyService {
static get route() {
return {
base: 'maven-central/v',
pattern: '',
pattern: ':groupId/:artifactId/:versionPrefix?',
}
}
@@ -56,52 +63,27 @@ module.exports = class MavenCentral extends LegacyService {
]
}
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/maven-central\/v\/([^/]*)\/([^/]*)(?:\/([^/]*))?\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const groupId = match[1] // eg, `com.google.inject`
const artifactId = match[2] // eg, `guice`
const versionPrefix = match[3] || '' // eg, `1.`
const format = match[4] || 'gif' // eg, `svg`
// Based on repo1.maven.org rather than search.maven.org because of #846.
const metadataUrl = `${'http://repo1.maven.org/maven2' +
'/'}${encodeURIComponent(groupId).replace(
/\./g,
'/'
)}/${encodeURIComponent(artifactId)}/maven-metadata.xml`
const badgeData = getBadgeData('maven-central', data)
request(
metadataUrl,
{ headers: { Accept: 'text/xml' } },
(err, res, buffer) => {
if (err != null) {
badgeData.text[1] = 'inaccessible'
sendBadge(format, badgeData)
return
}
xml2js.parseString(buffer.toString(), (err, data) => {
if (err != null) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
return
}
try {
const versions = data.metadata.versioning[0].versions[0].version.reverse()
const version = versions.find(
version => version.indexOf(versionPrefix) === 0
)
badgeData.text[1] = versionText(version)
badgeData.colorscheme = versionColor(version)
sendBadge(format, badgeData)
} catch (e) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
}
})
}
)
})
)
static get defaultBadgeData() {
return { label: 'maven-central' }
}
async fetch({ groupId, artifactId }) {
const group = encodeURIComponent(groupId).replace(/\./g, '/')
const artifact = encodeURIComponent(artifactId)
const url = `https://repo1.maven.org/maven2/${group}/${artifact}/maven-metadata.xml`
return this._requestXml({ schema, url })
}
async handle({ groupId, artifactId, versionPrefix }) {
const data = await this.fetch({ groupId, artifactId })
const versions = data.metadata.versioning.versions.version.reverse()
let version = versions[0]
if (versionPrefix !== undefined) {
version = versions.filter(v => v.toString().startsWith(versionPrefix))[0]
// if the filter returned no results, throw a NotFound
if (version === undefined)
throw new NotFound({ prettyMessage: 'version prefix not found' })
}
return renderVersionBadge({ version })
}
}

View File

@@ -1,39 +1,28 @@
'use strict'
const Joi = require('joi')
const { ServiceTester } = require('../tester')
const t = new ServiceTester({ id: 'maven-central', title: 'Maven Central' })
module.exports = t
const {
isVPlusDottedVersionNClausesWithOptionalSuffix,
} = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
t.create('latest version')
.get('/v/com.github.fabriziocucci/yacl4j.json') // http://repo1.maven.org/maven2/com/github/fabriziocucci/yacl4j/
.get('/com.github.fabriziocucci/yacl4j.json') // http://repo1.maven.org/maven2/com/github/fabriziocucci/yacl4j/
.expectBadge({
label: 'maven-central',
message: Joi.string().regex(/^v(.*)$/),
message: isVPlusDottedVersionNClausesWithOptionalSuffix,
})
t.create('latest 0.8 version')
.get('/v/com.github.fabriziocucci/yacl4j/0.8.json') // http://repo1.maven.org/maven2/com/github/fabriziocucci/yacl4j/
.get('/com.github.fabriziocucci/yacl4j/0.8.json') // http://repo1.maven.org/maven2/com/github/fabriziocucci/yacl4j/
.expectBadge({
label: 'maven-central',
message: Joi.string().regex(/^v0\.8(.*)$/),
message: isVPlusDottedVersionNClausesWithOptionalSuffix,
})
t.create('inexistent artifact')
.get('/v/inexistent-group-id/inexistent-artifact-id.json')
.expectBadge({ label: 'maven-central', message: 'invalid' })
.get('/inexistent-group-id/inexistent-artifact-id.json')
.expectBadge({ label: 'maven-central', message: 'not found' })
t.create('connection error')
.get('/v/com.github.fabriziocucci/yacl4j.json')
.networkOff()
.expectBadge({ label: 'maven-central', message: 'inaccessible' })
t.create('xml parsing error')
.get('/v/com.github.fabriziocucci/yacl4j.json')
.intercept(nock =>
nock('http://repo1.maven.org/maven2')
.get('/com/github/fabriziocucci/yacl4j/maven-metadata.xml')
.reply(200, 'this should be a valid xml')
)
.expectBadge({ label: 'maven-central', message: 'invalid' })
t.create('inexistent version prefix')
.get('/com.github.fabriziocucci/yacl4j/99.json')
.expectBadge({ label: 'maven-central', message: 'version prefix not found' })