diff --git a/services/dub/dub-download.service.js b/services/dub/dub-download.service.js index ac9061a559..188a1cb690 100644 --- a/services/dub/dub-download.service.js +++ b/services/dub/dub-download.service.js @@ -2,7 +2,7 @@ const Joi = require('joi') const { metric } = require('../text-formatters') -const { downloadCount } = require('../color-formatters') +const { downloadCount: downloadCountColor } = require('../color-formatters') const { BaseJsonService } = require('..') const { nonNegativeInteger } = require('../validators') @@ -15,106 +15,101 @@ const schema = Joi.object({ }).required(), }) -function DownloadsForInterval(interval) { - const { base, messageSuffix, name } = { - daily: { - base: 'dub/dd', - messageSuffix: '/day', - name: 'DubDownloadsDay', - }, - weekly: { - base: 'dub/dw', - messageSuffix: '/week', - name: 'DubDownloadsWeek', - }, - monthly: { - base: 'dub/dm', - messageSuffix: '/month', - name: 'DubDownloadsMonth', - }, - total: { - base: 'dub/dt', - messageSuffix: '', - name: 'DubDownloadsTotal', - }, - }[interval] - - return class DubDownloads extends BaseJsonService { - static get name() { - return name - } - - static render({ downloads, version }) { - const label = version ? `downloads@${version}` : 'downloads' - return { - label, - message: `${metric(downloads)}${messageSuffix}`, - color: downloadCount(downloads), - } - } - - async fetch({ packageName, version }) { - let url = `https://code.dlang.org/api/packages/${packageName}` - if (version) { - url += `/${version}` - } - url += '/stats' - return this._requestJson({ schema, url }) - } - - async handle({ packageName, version }) { - const data = await this.fetch({ packageName, version }) - return this.constructor.render({ - downloads: data.downloads[interval], - version, - }) - } - - static get defaultBadgeData() { - return { label: 'downloads' } - } - - static get category() { - return 'downloads' - } - - static get route() { - return { - base, - pattern: ':packageName/:version*', - } - } - - static get examples() { - let examples = [ - { - title: 'DUB', - pattern: ':packageName', - namedParams: { packageName: 'vibe-d' }, - staticPreview: this.render({ downloads: 5000 }), - }, - ] - if (interval === 'monthly') { - examples = examples.concat([ - { - title: 'DUB (version)', - pattern: ':packageName/:version', - namedParams: { packageName: 'vibe-d', version: '0.8.4' }, - staticPreview: this.render({ downloads: 100, version: '0.8.4' }), - }, - { - title: 'DUB (latest)', - pattern: ':packageName/:version', - namedParams: { packageName: 'vibe-d', version: 'latest' }, - staticPreview: this.render({ downloads: 100, version: 'latest' }), - }, - ]) - } - return examples - } - } +const intervalMap = { + dd: { + transform: json => json.downloads.daily, + messageSuffix: '/day', + }, + dw: { + transform: json => json.downloads.weekly, + messageSuffix: '/week', + }, + dm: { + transform: json => json.downloads.monthly, + messageSuffix: '/month', + }, + dt: { + transform: json => json.downloads.total, + messageSuffix: '', + }, } -module.exports = ['daily', 'weekly', 'monthly', 'total'].map( - DownloadsForInterval -) +module.exports = class DubDownloads extends BaseJsonService { + static get category() { + return 'downloads' + } + + static get route() { + return { + base: 'dub', + pattern: ':interval(dd|dw|dm|dt)/:packageName/:version*', + } + } + + static get examples() { + return [ + { + title: 'DUB', + namedParams: { interval: 'dm', packageName: 'vibe-d' }, + staticPreview: this.render({ interval: 'dm', downloadCount: 5000 }), + }, + { + title: 'DUB (version)', + namedParams: { + interval: 'dm', + packageName: 'vibe-d', + version: '0.8.4', + }, + staticPreview: this.render({ + interval: 'dm', + version: '0.8.4', + downloadCount: 100, + }), + }, + { + title: 'DUB (latest)', + namedParams: { + interval: 'dm', + packageName: 'vibe-d', + version: 'latest', + }, + staticPreview: this.render({ + interval: 'dm', + version: 'latest', + downloadCount: 100, + }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'downloads' } + } + + static render({ interval, version, downloadCount }) { + const { messageSuffix } = intervalMap[interval] + + return { + label: version ? `downloads@${version}` : 'downloads', + message: `${metric(downloadCount)}${messageSuffix}`, + color: downloadCountColor(downloadCount), + } + } + + async fetch({ packageName, version }) { + let url = `https://code.dlang.org/api/packages/${packageName}` + if (version) { + url += `/${version}` + } + url += '/stats' + return this._requestJson({ schema, url }) + } + + async handle({ interval, packageName, version }) { + const { transform } = intervalMap[interval] + + const json = await this.fetch({ packageName, version }) + const downloadCount = transform(json) + return this.constructor.render({ interval, downloadCount, version }) + } +} diff --git a/services/dub/dub-download.tester.js b/services/dub/dub-download.tester.js index dc33826d10..22d3407ecf 100644 --- a/services/dub/dub-download.tester.js +++ b/services/dub/dub-download.tester.js @@ -1,8 +1,8 @@ 'use strict' const Joi = require('joi') -const { ServiceTester } = require('../tester') const { isMetric, isMetricOverTimePeriod } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) const isDownloadsColor = Joi.equal( 'red', @@ -12,11 +12,6 @@ const isDownloadsColor = Joi.equal( 'brightgreen' ) -const t = (module.exports = new ServiceTester({ - id: 'dub', - title: 'DubDownloads', -})) - t.create('total downloads (valid)') .get('/dt/vibe-d.json') .expectBadge({ @@ -29,7 +24,7 @@ t.create('total downloads, specific version (valid)') .get('/dt/vibe-d/0.8.4.json') .expectBadge({ label: 'downloads@0.8.4', - message: Joi.string().regex(/^[1-9][0-9]*[kMGTPEZY]?$/), + message: isMetric, color: isDownloadsColor, }) .timeout(15000) @@ -38,7 +33,7 @@ t.create('total downloads, latest version (valid)') .get('/dt/vibe-d/latest.json') .expectBadge({ label: 'downloads@latest', - message: Joi.string().regex(/^[1-9][0-9]*[kMGTPEZY]?$/), + message: isMetric, color: isDownloadsColor, })