Rewrite deprecated services and add tests (#2018)

I've rewritten the deprecated services using the `deprecatedService` helper from #1922. I added a test for `Deprecated`, and for `enforceDeprecation`, which isn't being used right now, but is there for future use.

This also makes it possible to write services using BaseService which do not have any named parameters (with a test).

Ref: #1358
This commit is contained in:
Paul Melnikow
2018-08-30 10:03:15 -07:00
committed by GitHub
parent b602284403
commit 7ad5eca26e
15 changed files with 154 additions and 260 deletions

View File

@@ -1518,10 +1518,6 @@ const allBadgeExamples = [
name: 'Other',
},
examples: [
{
title: 'VersionEye',
previewUrl: '/versioneye/d/ruby/rails.svg',
},
{
title: 'Wheelmap',
previewUrl: '/wheelmap/a/2323004600.svg',

View File

@@ -1,27 +1,7 @@
'use strict'
const { makeBadgeData, setBadgeColor } = require('./badge-data')
const { deprecatedServices } = require('./deprecated-services')
const { Deprecated } = require('../services/errors')
const isDeprecated = function(
service,
now = new Date(),
depServices = deprecatedServices
) {
if (!(service in depServices)) {
return false
}
return now.getTime() >= depServices[service].getTime()
}
const getDeprecatedBadge = function(label, data) {
const badgeData = makeBadgeData(label, data)
setBadgeColor(badgeData, 'lightgray')
badgeData.text[1] = 'no longer available'
return badgeData
}
function enforceDeprecation(effectiveDate) {
if (Date.now() >= effectiveDate.getTime()) {
throw new Deprecated()
@@ -29,7 +9,5 @@ function enforceDeprecation(effectiveDate) {
}
module.exports = {
isDeprecated,
getDeprecatedBadge,
enforceDeprecation,
}

View File

@@ -1,33 +1,17 @@
'use strict'
const { expect } = require('chai')
const { test, given } = require('sazerac')
const { isDeprecated, getDeprecatedBadge } = require('./deprecation-helpers')
const { Deprecated } = require('../services/errors')
const { enforceDeprecation } = require('./deprecation-helpers')
describe('Deprecated Badge Helper', function() {
it('makes "no longer available" badge', function() {
const badge = getDeprecatedBadge('foo', {})
expect(badge.text[0]).to.equal('foo')
expect(badge.text[1]).to.equal('no longer available')
expect(badge.colorscheme).to.equal('lightgray')
describe('enforceDeprecation', function() {
it('throws Deprecated for a date in the past', function() {
expect(() => enforceDeprecation(new Date())).to.throw(Deprecated)
})
it('ignores colorB param', function() {
const badge = getDeprecatedBadge('foo', { colorB: 'fedcba' })
expect(badge.colorscheme).to.equal('lightgray')
})
})
describe('isDeprecated function', function() {
test(isDeprecated, function() {
given('fooservice', new Date(), {}).expect(false)
given('fooservice', new Date('2001-01-11 23:59:00Z'), {
fooservice: new Date('2001-01-12'),
}).expect(false)
given('fooservice', new Date('2001-01-12 00:00:01Z'), {
fooservice: new Date('2001-01-12'),
}).expect(true)
it('does not throw for a date in the future', function() {
expect(() =>
enforceDeprecation(new Date(Date.now() + 10000))
).not.to.throw()
})
})

View File

@@ -146,19 +146,21 @@ class BaseService {
}
static _namedParamsForMatch(match) {
const names = this.url.capture || []
// Assume the last match is the format, and drop match[0], which is the
// entire match.
const captures = match.slice(1, -1)
if (this.url.capture.length !== captures.length) {
if (names.length !== captures.length) {
throw new Error(
`Service ${this.name} declares incorrect number of capture groups ` +
`(expected ${this.url.capture.length}, got ${captures.length})`
`(expected ${names.length}, got ${captures.length})`
)
}
const result = {}
this.url.capture.forEach((name, index) => {
names.forEach((name, index) => {
result[name] = captures[index]
})
return result

View File

@@ -10,6 +10,7 @@ const {
Inaccessible,
InvalidResponse,
InvalidParameter,
Deprecated,
} = require('./errors')
const BaseService = require('./base')
@@ -55,41 +56,69 @@ describe('BaseService', function() {
const defaultConfig = { handleInternalErrors: false }
describe('URL pattern matching', function() {
const regexExec = str => DummyService._regex.exec(str)
const getNamedParamA = str => {
const [, namedParamA] = regexExec(str)
return namedParamA
}
const namedParams = str => {
const match = regexExec(str)
return DummyService._namedParamsForMatch(match)
}
context('A named param is declared', function() {
const regexExec = str => DummyService._regex.exec(str)
const getNamedParamA = str => {
const [, namedParamA] = regexExec(str)
return namedParamA
}
const namedParams = str => {
const match = regexExec(str)
return DummyService._namedParamsForMatch(match)
}
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
]).expect(null)
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
]).expect(null)
})
test(getNamedParamA, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect('bar.bar.bar')
})
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
})
})
test(getNamedParamA, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect('bar.bar.bar')
})
describe('No named params are declared', function() {
class ServiceWithZeroNamedParams extends BaseService {
static get url() {
return {
base: 'foo',
format: '(?:[^/]+)',
}
}
}
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
const namedParams = str => {
const match = ServiceWithZeroNamedParams._regex.exec(str)
return ServiceWithZeroNamedParams._namedParamsForMatch(match)
}
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({})
})
})
})
@@ -214,6 +243,20 @@ describe('BaseService', function() {
})
})
it('handles Deprecated', async function() {
serviceInstance.handle = () => {
throw new Deprecated()
}
expect(
await serviceInstance.invokeHandler({
namedParamA: 'bar.bar.bar',
})
).to.deep.equal({
color: 'lightgray',
message: 'no longer available',
})
})
it('handles InvalidParameter errors', async function() {
serviceInstance.handle = () => {
throw new InvalidParameter()

View File

@@ -1,18 +1,12 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
// bitHound integration - deprecated as of July 2018
module.exports = class Bithound extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/bithound\/(code\/|dependencies\/|devDependencies\/)?(.+?)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[3]
const badgeData = getDeprecatedBadge('bithound', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'bithound',
format: '(?:code/|dependencies/|devDependencies/)?(?:.+?)',
},
label: 'bithound',
})

View File

@@ -1,18 +1,11 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
// Cauditor integration - Badge deprectiated as of March 2018
module.exports = class Cauditor extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/cauditor\/(mi|ccn|npath|hi|i|ca|ce|dit)\/([^/]+)\/([^/]+)\/(.+)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[5]
const badgeData = getDeprecatedBadge('cauditor', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'cauditor',
format: '(?:mi|ccn|npath|hi|i|ca|ce|dit)/(?:[^/]+)/(?:[^/]+)/(?:.+)',
},
label: 'cauditor',
})

View File

@@ -1,18 +1,12 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
// dotnet-status integration - deprecated as of April 2018.
module.exports = class DotnetStatus extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/dotnetstatus\/(.+)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[2]
const badgeData = getDeprecatedBadge('dotnet status', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'dotnetstatus',
format: '(?:.+)',
},
label: 'dotnet status',
})

View File

@@ -1,64 +1,11 @@
'use strict'
const LegacyService = require('../legacy-service')
const {
makeBadgeData: getBadgeData,
makeLabel: getLabel,
} = require('../../lib/badge-data')
const {
isDeprecated,
getDeprecatedBadge,
} = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
const serverStartTime = new Date(new Date().toGMTString())
module.exports = class Gemnasium extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/gemnasium\/(.+)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const userRepo = match[1] // eg, `jekyll/jekyll`.
const format = match[2]
if (isDeprecated('gemnasium', serverStartTime)) {
const badgeData = getDeprecatedBadge('gemnasium', data)
sendBadge(format, badgeData)
return
}
const options = 'https://gemnasium.com/' + userRepo + '.svg'
const badgeData = getBadgeData('dependencies', data)
request(options, (err, res, buffer) => {
if (err != null) {
badgeData.text[1] = 'inaccessible'
sendBadge(format, badgeData)
return
}
try {
const nameMatch = buffer.match(/(devD|d)ependencies/)[0]
const statusMatch = buffer.match(/'14'>(.+)<\/text>\s*<\/g>/)[1]
badgeData.text[0] = getLabel(nameMatch, data)
badgeData.text[1] = statusMatch
if (statusMatch === 'up-to-date') {
badgeData.text[1] = 'up to date'
badgeData.colorscheme = 'brightgreen'
} else if (statusMatch === 'out-of-date') {
badgeData.text[1] = 'out of date'
badgeData.colorscheme = 'yellow'
} else if (statusMatch === 'update!') {
badgeData.colorscheme = 'red'
} else if (statusMatch === 'none') {
badgeData.colorscheme = 'brightgreen'
} else {
badgeData.text[1] = 'undefined'
}
sendBadge(format, badgeData)
} catch (e) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
}
})
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'gemnasium',
format: '(?:.+)',
},
label: 'gemnasium',
})

View File

@@ -1,20 +1,13 @@
'use strict'
const ServiceTester = require('../service-tester')
const { expect } = require('chai')
const { isDeprecated } = require('../../lib/deprecation-helpers')
const t = new ServiceTester({ id: 'gemnasium', title: 'gemnasium' })
module.exports = t
t.create('no longer available (previously dependencies)')
.get('/mathiasbynens/he.json')
.afterJSON(badge => {
if (isDeprecated('gemnasium')) {
expect(badge.name).to.equal('gemnasium')
expect(badge.value).to.equal('no longer available')
} else {
expect(badge.name).to.equal('dependencies')
}
.expectJSON({
name: 'gemnasium',
value: 'no longer available',
})

View File

@@ -1,21 +1,10 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const { makeLogo: getLogo } = require('../../lib/badge-data')
const deprecatedService = require('../deprecated-service')
module.exports = class Gratipay extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/(?:gittip|gratipay(\/user|\/team|\/project)?)\/(.*)\.(svg|png|gif|jpg|json)$/,
cache((queryParams, match, sendBadge, request) => {
const format = match[3]
const badgeData = getDeprecatedBadge('gratipay', queryParams)
if (badgeData.template === 'social') {
badgeData.logo = getLogo('gratipay', queryParams)
}
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
format: '(?:gittip|gratipay(?:/user|/team|/project)?)/(?:.*)',
},
label: 'gratipay',
})

View File

@@ -1,18 +1,12 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
// Magnum CI integration - deprecated as of July 2018
module.exports = class MagnumCi extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/magnumci\/ci\/([^/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[3]
const badgeData = getDeprecatedBadge('magnum ci', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'magnumci/ci',
format: '(?:[^/]+)(?:/(?:.+))?',
},
label: 'magnum ci',
})

View File

@@ -1,17 +1,10 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
module.exports = class SnapCi extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/snap(-ci?)\/([^/]+\/[^/]+)(?:\/(.+))\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[4]
const badgeData = getDeprecatedBadge('snap CI', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
format: 'snap(?:-ci?)/(?:[^/]+/[^/]+)(?:/(?:.+))',
},
label: 'snap ci',
})

View File

@@ -8,6 +8,6 @@ module.exports = t
t.create('no longer available (previously build state)')
.get('/snap-ci/ThoughtWorksStudios/eb_deployer/master.json')
.expectJSON({
name: 'snap CI',
name: 'snap ci',
value: 'no longer available',
})

View File

@@ -1,18 +1,12 @@
'use strict'
const LegacyService = require('../legacy-service')
const { getDeprecatedBadge } = require('../../lib/deprecation-helpers')
const deprecatedService = require('../deprecated-service')
// VersionEye integration - deprecated as of August 2018.
module.exports = class VersionEye extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/versioneye\/d\/(.+)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
const format = match[2]
const badgeData = getDeprecatedBadge('versioneye', data)
sendBadge(format, badgeData)
})
)
}
}
module.exports = deprecatedService({
url: {
base: 'versioneye',
format: 'd/(?:.+)',
},
label: 'versioneye',
})