From 83c3c709086f73f4ec1576a0121d188c21ce5982 Mon Sep 17 00:00:00 2001 From: chris48s Date: Sun, 7 Apr 2019 19:35:30 +0100 Subject: [PATCH] refactor [puppetforge] service, add tests (#3275) This migrates the puppetforge-modules from legacy services to the new service arch There are also some changes to the puppetforge-users badges, but its just moving code around --- services/puppetforge/puppetforge-base.js | 57 ++++ .../puppetforge-module-downloads.service.js | 47 +++ .../puppetforge-module-downloads.tester.js | 18 ++ .../puppetforge-module-endorsement.service.js | 54 ++++ .../puppetforge-module-endorsement.tester.js | 35 +++ .../puppetforge-module-feedback.service.js | 52 ++++ .../puppetforge-module-feedback.tester.js | 35 +++ .../puppetforge-module-pdk-version.service.js | 46 +++ .../puppetforge-module-pdk-version.tester.js | 25 ++ .../puppetforge-module-version.service.js | 39 +++ .../puppetforge-module-version.tester.js | 18 ++ .../puppetforge-modules.service.js | 281 ------------------ .../puppetforge/puppetforge-modules.tester.js | 24 -- .../puppetforge-user-module-count.service.js | 46 +++ .../puppetforge-user-module-count.tester.js | 18 ++ .../puppetforge-user-release-count.service.js | 46 +++ .../puppetforge-user-release-count.tester.js | 18 ++ .../puppetforge/puppetforge-users.service.js | 104 ------- .../puppetforge/puppetforge-users.tester.js | 38 --- 19 files changed, 554 insertions(+), 447 deletions(-) create mode 100644 services/puppetforge/puppetforge-base.js create mode 100644 services/puppetforge/puppetforge-module-downloads.service.js create mode 100644 services/puppetforge/puppetforge-module-downloads.tester.js create mode 100644 services/puppetforge/puppetforge-module-endorsement.service.js create mode 100644 services/puppetforge/puppetforge-module-endorsement.tester.js create mode 100644 services/puppetforge/puppetforge-module-feedback.service.js create mode 100644 services/puppetforge/puppetforge-module-feedback.tester.js create mode 100644 services/puppetforge/puppetforge-module-pdk-version.service.js create mode 100644 services/puppetforge/puppetforge-module-pdk-version.tester.js create mode 100644 services/puppetforge/puppetforge-module-version.service.js create mode 100644 services/puppetforge/puppetforge-module-version.tester.js delete mode 100644 services/puppetforge/puppetforge-modules.service.js delete mode 100644 services/puppetforge/puppetforge-modules.tester.js create mode 100644 services/puppetforge/puppetforge-user-module-count.service.js create mode 100644 services/puppetforge/puppetforge-user-module-count.tester.js create mode 100644 services/puppetforge/puppetforge-user-release-count.service.js create mode 100644 services/puppetforge/puppetforge-user-release-count.tester.js delete mode 100644 services/puppetforge/puppetforge-users.service.js delete mode 100644 services/puppetforge/puppetforge-users.tester.js diff --git a/services/puppetforge/puppetforge-base.js b/services/puppetforge/puppetforge-base.js new file mode 100644 index 0000000000..e8b876a12d --- /dev/null +++ b/services/puppetforge/puppetforge-base.js @@ -0,0 +1,57 @@ +'use strict' + +const Joi = require('joi') +const { BaseJsonService } = require('..') +const { nonNegativeInteger, semver } = require('../validators') + +const usersSchema = Joi.object({ + module_count: nonNegativeInteger, + release_count: nonNegativeInteger, +}).required() + +const modulesSchema = Joi.object({ + endorsement: Joi.string().allow(null), + feedback_score: Joi.number() + .integer() + .min(0) + .allow(null), + downloads: nonNegativeInteger, + current_release: Joi.alternatives( + Joi.object({ + pdk: Joi.boolean() + .valid(true) + .required(), + version: semver, + metadata: Joi.object({ 'pdk-version': semver }).required(), + }).required(), + Joi.object({ + pdk: Joi.boolean() + .valid(false) + .required(), + version: semver, + }).required() + ), +}).required() + +class BasePuppetForgeUsersService extends BaseJsonService { + async fetch({ user }) { + return this._requestJson({ + schema: usersSchema, + url: `https://forgeapi.puppetlabs.com/v3/users/${user}`, + }) + } +} + +class BasePuppetForgeModulesService extends BaseJsonService { + async fetch({ user, moduleName }) { + return this._requestJson({ + schema: modulesSchema, + url: `https://forgeapi.puppetlabs.com/v3/modules/${user}-${moduleName}`, + }) + } +} + +module.exports = { + BasePuppetForgeModulesService, + BasePuppetForgeUsersService, +} diff --git a/services/puppetforge/puppetforge-module-downloads.service.js b/services/puppetforge/puppetforge-module-downloads.service.js new file mode 100644 index 0000000000..f5607b11d3 --- /dev/null +++ b/services/puppetforge/puppetforge-module-downloads.service.js @@ -0,0 +1,47 @@ +'use strict' + +const { downloadCount } = require('../color-formatters') +const { metric } = require('../text-formatters') +const { BasePuppetForgeModulesService } = require('./puppetforge-base') + +module.exports = class PuppetforgeModuleDownloads extends BasePuppetForgeModulesService { + static get category() { + return 'downloads' + } + + static get route() { + return { + base: 'puppetforge/dt', + pattern: ':user/:moduleName', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge downloads', + namedParams: { + user: 'camptocamp', + moduleName: 'openldap', + }, + staticPreview: this.render({ downloads: 720000 }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'downloads' } + } + + static render({ downloads }) { + return { + message: metric(downloads), + color: downloadCount(downloads), + } + } + + async handle({ user, moduleName }) { + const data = await this.fetch({ user, moduleName }) + return this.constructor.render({ downloads: data.downloads }) + } +} diff --git a/services/puppetforge/puppetforge-module-downloads.tester.js b/services/puppetforge/puppetforge-module-downloads.tester.js new file mode 100644 index 0000000000..ddfd0293bb --- /dev/null +++ b/services/puppetforge/puppetforge-module-downloads.tester.js @@ -0,0 +1,18 @@ +'use strict' + +const { isMetric } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('module downloads') + .get('/camptocamp/openssl.json') + .expectBadge({ + label: 'downloads', + message: isMetric, + }) + +t.create('module downloads (not found)') + .get('/notarealuser/notarealpackage.json') + .expectBadge({ + label: 'downloads', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-module-endorsement.service.js b/services/puppetforge/puppetforge-module-endorsement.service.js new file mode 100644 index 0000000000..f326d4076f --- /dev/null +++ b/services/puppetforge/puppetforge-module-endorsement.service.js @@ -0,0 +1,54 @@ +'use strict' + +const { NotFound } = require('..') +const { BasePuppetForgeModulesService } = require('./puppetforge-base') + +module.exports = class PuppetforgeModuleEndorsement extends BasePuppetForgeModulesService { + static get category() { + return 'rating' + } + + static get route() { + return { + base: 'puppetforge/e', + pattern: ':user/:moduleName', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge endorsement', + namedParams: { + user: 'camptocamp', + moduleName: 'openssl', + }, + staticPreview: this.render({ endorsement: 'approved' }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'endorsement' } + } + + static render({ endorsement }) { + let color + if (endorsement === 'approved') { + color = 'green' + } else if (endorsement === 'supported') { + color = 'brightgreen' + } else { + color = 'red' + } + return { message: endorsement, color } + } + + async handle({ user, moduleName }) { + const { endorsement } = await this.fetch({ user, moduleName }) + if (endorsement == null) { + throw new NotFound({ prettyMessage: 'none' }) + } + return this.constructor.render({ endorsement }) + } +} diff --git a/services/puppetforge/puppetforge-module-endorsement.tester.js b/services/puppetforge/puppetforge-module-endorsement.tester.js new file mode 100644 index 0000000000..83c5e07758 --- /dev/null +++ b/services/puppetforge/puppetforge-module-endorsement.tester.js @@ -0,0 +1,35 @@ +'use strict' + +const { withRegex } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('module endorsement') + .get('/camptocamp/openssl.json') + .expectBadge({ + label: 'endorsement', + message: withRegex(/^approved|supported$/), + }) + +t.create('module endorsement (no ratings)') + .get('/camptocamp/openssl.json') + .intercept(nock => + nock('https://forgeapi.puppetlabs.com/v3/modules') + .get('/camptocamp-openssl') + .reply(200, { + endorsement: null, + feedback_score: null, + downloads: 0, + current_release: { pdk: false, version: '1.0.0' }, + }) + ) + .expectBadge({ + label: 'endorsement', + message: 'none', + }) + +t.create('module endorsement (not found)') + .get('/notarealuser/notarealpackage.json') + .expectBadge({ + label: 'endorsement', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-module-feedback.service.js b/services/puppetforge/puppetforge-module-feedback.service.js new file mode 100644 index 0000000000..1634575b83 --- /dev/null +++ b/services/puppetforge/puppetforge-module-feedback.service.js @@ -0,0 +1,52 @@ +'use strict' + +const { NotFound } = require('..') +const { + coveragePercentage: coveragePercentageColor, +} = require('../color-formatters') +const { BasePuppetForgeModulesService } = require('./puppetforge-base') + +module.exports = class PuppetforgeModuleFeedback extends BasePuppetForgeModulesService { + static get category() { + return 'rating' + } + + static get route() { + return { + base: 'puppetforge/f', + pattern: ':user/:moduleName', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge feedback score', + namedParams: { + user: 'camptocamp', + moduleName: 'openssl', + }, + staticPreview: this.render({ score: 61 }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'score' } + } + + static render({ score }) { + return { + message: `${score}%`, + color: coveragePercentageColor(score), + } + } + + async handle({ user, moduleName }) { + const data = await this.fetch({ user, moduleName }) + if (data.feedback_score == null) { + throw new NotFound({ prettyMessage: 'unknown' }) + } + return this.constructor.render({ score: data.feedback_score }) + } +} diff --git a/services/puppetforge/puppetforge-module-feedback.tester.js b/services/puppetforge/puppetforge-module-feedback.tester.js new file mode 100644 index 0000000000..c8412b8025 --- /dev/null +++ b/services/puppetforge/puppetforge-module-feedback.tester.js @@ -0,0 +1,35 @@ +'use strict' + +const { isPercentage } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('module feedback') + .get('/camptocamp/openssl.json') + .expectBadge({ + label: 'score', + message: isPercentage, + }) + +t.create('module feedback (no ratings)') + .get('/camptocamp/openssl.json') + .intercept(nock => + nock('https://forgeapi.puppetlabs.com/v3/modules') + .get('/camptocamp-openssl') + .reply(200, { + endorsement: null, + feedback_score: null, + downloads: 0, + current_release: { pdk: false, version: '1.0.0' }, + }) + ) + .expectBadge({ + label: 'score', + message: 'unknown', + }) + +t.create('module feedback (not found)') + .get('/notarealuser/notarealpackage.json') + .expectBadge({ + label: 'score', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-module-pdk-version.service.js b/services/puppetforge/puppetforge-module-pdk-version.service.js new file mode 100644 index 0000000000..7d294088a0 --- /dev/null +++ b/services/puppetforge/puppetforge-module-pdk-version.service.js @@ -0,0 +1,46 @@ +'use strict' + +const { NotFound } = require('..') +const { renderVersionBadge } = require('../version') +const { BasePuppetForgeModulesService } = require('./puppetforge-base') + +module.exports = class PuppetforgeModulePdkVersion extends BasePuppetForgeModulesService { + static get category() { + return 'platform-support' + } + + static get route() { + return { + base: 'puppetforge/pdk-version', + pattern: ':user/:moduleName', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge – PDK version', + namedParams: { + user: 'tragiccode', + moduleName: 'azure_key_vault', + }, + staticPreview: renderVersionBadge({ version: '1.7.1' }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'pdk version' } + } + + async handle({ user, moduleName }) { + const data = await this.fetch({ user, moduleName }) + if (data.current_release.pdk) { + return renderVersionBadge({ + version: data.current_release.metadata['pdk-version'], + }) + } else { + throw new NotFound({ prettyMessage: 'none' }) + } + } +} diff --git a/services/puppetforge/puppetforge-module-pdk-version.tester.js b/services/puppetforge/puppetforge-module-pdk-version.tester.js new file mode 100644 index 0000000000..8400c535be --- /dev/null +++ b/services/puppetforge/puppetforge-module-pdk-version.tester.js @@ -0,0 +1,25 @@ +'use strict' + +const { isSemver } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('PDK version') + .get('/tragiccode/azure_key_vault.json') + .expectBadge({ + label: 'pdk version', + message: isSemver, + }) + +t.create("PDK version (library doesn't use the PDK)") + .get('/camptocamp/openssl.json') + .expectBadge({ + label: 'pdk version', + message: 'none', + }) + +t.create('PDK version (not found)') + .get('/notarealuser/notarealpackage.json') + .expectBadge({ + label: 'pdk version', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-module-version.service.js b/services/puppetforge/puppetforge-module-version.service.js new file mode 100644 index 0000000000..b083804bf4 --- /dev/null +++ b/services/puppetforge/puppetforge-module-version.service.js @@ -0,0 +1,39 @@ +'use strict' + +const { renderVersionBadge } = require('../version') +const { BasePuppetForgeModulesService } = require('./puppetforge-base') + +module.exports = class PuppetforgeModuleVersion extends BasePuppetForgeModulesService { + static get category() { + return 'version' + } + + static get route() { + return { + base: 'puppetforge/v', + pattern: ':user/:moduleName', + } + } + + static get defaultBadgeData() { + return { label: 'puppetforge' } + } + + static get examples() { + return [ + { + title: 'Puppet Forge version', + namedParams: { + user: 'vStone', + moduleName: 'percona', + }, + staticPreview: renderVersionBadge({ version: '1.3.3' }), + }, + ] + } + + async handle({ user, moduleName }) { + const data = await this.fetch({ user, moduleName }) + return renderVersionBadge({ version: data.current_release.version }) + } +} diff --git a/services/puppetforge/puppetforge-module-version.tester.js b/services/puppetforge/puppetforge-module-version.tester.js new file mode 100644 index 0000000000..5a9720912d --- /dev/null +++ b/services/puppetforge/puppetforge-module-version.tester.js @@ -0,0 +1,18 @@ +'use strict' + +const { isSemver } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('module version') + .get('/camptocamp/openssl.json') + .expectBadge({ + label: 'puppetforge', + message: isSemver, + }) + +t.create('module version (not found)') + .get('/notarealuser/notarealpackage.json') + .expectBadge({ + label: 'puppetforge', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-modules.service.js b/services/puppetforge/puppetforge-modules.service.js deleted file mode 100644 index 7ccbfe6f02..0000000000 --- a/services/puppetforge/puppetforge-modules.service.js +++ /dev/null @@ -1,281 +0,0 @@ -'use strict' - -const LegacyService = require('../legacy-service') -const { - makeBadgeData: getBadgeData, - makeLabel: getLabel, -} = require('../../lib/badge-data') -const { metric, addv: versionText } = require('../text-formatters') -const { - version: versionColor, - coveragePercentage: coveragePercentageColor, - downloadCount: downloadCountColor, -} = require('../color-formatters') - -class PuppetforgeModuleVersion extends LegacyService { - static get category() { - return 'version' - } - - static get route() { - return { - base: 'puppetforge/v', - pattern: ':user/:moduleName', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge version', - namedParams: { - user: 'vStone', - moduleName: 'percona', - }, - staticPreview: { - label: 'puppetforge', - message: 'v1.3.3', - color: 'blue', - }, - }, - ] - } - - static registerLegacyRouteHandler() {} -} - -class PuppetforgeModulePdkVersion extends LegacyService { - static get category() { - return 'platform-support' - } - - static get route() { - return { - base: 'puppetforge/pdk-version', - pattern: ':user/:moduleName', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge – PDK version', - namedParams: { - user: 'tragiccode', - moduleName: 'azure_key_vault', - }, - staticPreview: { - label: 'pdk version', - message: 'v1.7.1', - color: 'blue', - }, - }, - ] - } - - static registerLegacyRouteHandler() {} -} - -class PuppetforgeModuleDownloads extends LegacyService { - static get category() { - return 'downloads' - } - - static get route() { - return { - base: 'puppetforge/dt', - pattern: ':user/:moduleName', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge downloads', - namedParams: { - user: 'camptocamp', - moduleName: 'openldap', - }, - staticPreview: { - label: 'downloads', - message: '720k', - color: 'brightgreen', - }, - }, - ] - } - - static registerLegacyRouteHandler() {} -} - -class PuppetforgeModuleEndorsement extends LegacyService { - static get category() { - return 'rating' - } - - static get route() { - return { - base: 'puppetforge/e', - pattern: ':user/:moduleName', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge endorsement', - namedParams: { - user: 'camptocamp', - moduleName: 'openssl', - }, - staticPreview: { - label: 'endorsement', - message: 'approved', - color: 'green', - }, - }, - ] - } - - static registerLegacyRouteHandler() {} -} - -class PuppetforgeModuleFeedback extends LegacyService { - static get category() { - return 'rating' - } - - static get route() { - return { - base: 'puppetforge/f', - pattern: ':user/:moduleName', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge feedback score', - namedParams: { - user: 'camptocamp', - moduleName: 'openssl', - }, - staticPreview: { - label: 'score', - message: '61%', - color: 'yellow', - }, - }, - ] - } - - static registerLegacyRouteHandler() {} -} - -// 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. -class PuppetforgeModules extends LegacyService { - static get category() { - return 'other' - } - - static get route() { - return { - base: 'puppetforge', - pattern: '([^/]+)/([^/]+)/([^/]+)', - } - } - - static registerLegacyRouteHandler({ camp, cache }) { - camp.route( - /^\/puppetforge\/([^/]+)\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/, - cache((data, match, sendBadge, request) => { - const info = match[1] // either `v`, `dt`, `e`, `f`, or `p` - const user = match[2] - const module = match[3] - const format = match[4] - const options = { - json: true, - uri: `https://forgeapi.puppetlabs.com/v3/modules/${user}-${module}`, - } - const badgeData = getBadgeData('puppetforge', data) - request(options, (err, res, json) => { - if (err != null || (json.length !== undefined && json.length === 0)) { - badgeData.text[1] = 'inaccessible' - sendBadge(format, badgeData) - return - } - try { - if (info === 'v') { - if (json.current_release) { - const version = json.current_release.version - badgeData.text[1] = versionText(version) - badgeData.colorscheme = versionColor(version) - } else { - badgeData.text[1] = 'none' - badgeData.colorscheme = 'lightgrey' - } - } else if (info === 'dt') { - const total = json.downloads - badgeData.colorscheme = downloadCountColor(total) - badgeData.text[0] = getLabel('downloads', data) - badgeData.text[1] = metric(total) - } else if (info === 'e') { - const endorsement = json.endorsement - if (endorsement === 'approved') { - badgeData.colorscheme = 'green' - } else if (endorsement === 'supported') { - badgeData.colorscheme = 'brightgreen' - } else { - badgeData.colorscheme = 'red' - } - badgeData.text[0] = getLabel('endorsement', data) - if (endorsement != null) { - badgeData.text[1] = endorsement - } else { - badgeData.text[1] = 'none' - } - } else if (info === 'f') { - const feedback = json.feedback_score - badgeData.text[0] = getLabel('score', data) - if (feedback != null) { - badgeData.text[1] = `${feedback}%` - badgeData.colorscheme = coveragePercentageColor(feedback) - } else { - badgeData.text[1] = 'unknown' - badgeData.colorscheme = 'lightgrey' - } - } else if (info === 'pdk-version') { - badgeData.text[0] = 'pdk version' - if (json.current_release.pdk) { - const pdkVersion = json.current_release.metadata['pdk-version'] - badgeData.text[1] = versionText(pdkVersion) - badgeData.colorscheme = versionColor(pdkVersion) - } else { - badgeData.text[1] = 'none' - badgeData.colorscheme = 'lightgrey' - } - } - sendBadge(format, badgeData) - } catch (e) { - badgeData.text[1] = 'invalid' - sendBadge(format, badgeData) - } - }) - }) - ) - } -} - -module.exports = { - PuppetforgeModuleVersion, - PuppetforgeModulePdkVersion, - PuppetforgeModuleDownloads, - PuppetforgeModuleFeedback, - PuppetforgeModuleEndorsement, - PuppetforgeModules, -} diff --git a/services/puppetforge/puppetforge-modules.tester.js b/services/puppetforge/puppetforge-modules.tester.js deleted file mode 100644 index 577a4544d8..0000000000 --- a/services/puppetforge/puppetforge-modules.tester.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict' - -const { ServiceTester } = require('../tester') -const { isSemver } = require('../test-validators') - -const t = (module.exports = new ServiceTester({ - id: 'PuppetForgeModules', - title: 'PuppetForge Modules', - pathPrefix: '/puppetforge', -})) - -t.create('PDK version') - .get('/pdk-version/tragiccode/azure_key_vault.json') - .expectBadge({ - label: 'pdk version', - message: isSemver, - }) - -t.create("PDK version of a library that doesn't use the PDK") - .get('/pdk-version/camptocamp/openssl.json') - .expectBadge({ - label: 'pdk version', - message: 'none', - }) diff --git a/services/puppetforge/puppetforge-user-module-count.service.js b/services/puppetforge/puppetforge-user-module-count.service.js new file mode 100644 index 0000000000..c9663ed6e9 --- /dev/null +++ b/services/puppetforge/puppetforge-user-module-count.service.js @@ -0,0 +1,46 @@ +'use strict' + +const { metric } = require('../text-formatters') +const { floorCount: floorCountColor } = require('../color-formatters') +const { BasePuppetForgeUsersService } = require('./puppetforge-base') + +module.exports = class PuppetForgeModuleCountService extends BasePuppetForgeUsersService { + static get category() { + return 'other' + } + + static get defaultBadgeData() { + return { label: 'modules' } + } + + static get route() { + return { + base: 'puppetforge/mc', + pattern: ':user', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge modules by user', + namedParams: { + user: 'camptocamp', + }, + staticPreview: this.render({ modules: 60 }), + }, + ] + } + + async handle({ user }) { + const data = await this.fetch({ user }) + return this.constructor.render({ modules: data.module_count }) + } + + static render({ modules }) { + return { + message: metric(modules), + color: floorCountColor(modules, 5, 10, 50), + } + } +} diff --git a/services/puppetforge/puppetforge-user-module-count.tester.js b/services/puppetforge/puppetforge-user-module-count.tester.js new file mode 100644 index 0000000000..a5f871194b --- /dev/null +++ b/services/puppetforge/puppetforge-user-module-count.tester.js @@ -0,0 +1,18 @@ +'use strict' + +const { isMetric } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('modules by user') + .get('/camptocamp.json') + .expectBadge({ + label: 'modules', + message: isMetric, + }) + +t.create('modules by user') + .get('/not-a-real-user.json') + .expectBadge({ + label: 'modules', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-user-release-count.service.js b/services/puppetforge/puppetforge-user-release-count.service.js new file mode 100644 index 0000000000..43d14e7495 --- /dev/null +++ b/services/puppetforge/puppetforge-user-release-count.service.js @@ -0,0 +1,46 @@ +'use strict' + +const { metric } = require('../text-formatters') +const { floorCount: floorCountColor } = require('../color-formatters') +const { BasePuppetForgeUsersService } = require('./puppetforge-base') + +module.exports = class PuppetForgeReleaseCountService extends BasePuppetForgeUsersService { + static get category() { + return 'other' + } + + static get defaultBadgeData() { + return { label: 'releases' } + } + + static get route() { + return { + base: 'puppetforge/rc', + pattern: ':user', + } + } + + static get examples() { + return [ + { + title: 'Puppet Forge releases by user', + namedParams: { + user: 'camptocamp', + }, + staticPreview: this.render({ releases: 1000 }), + }, + ] + } + + async handle({ user }) { + const data = await this.fetch({ user }) + return this.constructor.render({ releases: data.release_count }) + } + + static render({ releases }) { + return { + message: metric(releases), + color: floorCountColor(releases, 10, 50, 100), + } + } +} diff --git a/services/puppetforge/puppetforge-user-release-count.tester.js b/services/puppetforge/puppetforge-user-release-count.tester.js new file mode 100644 index 0000000000..13ba3ef1ed --- /dev/null +++ b/services/puppetforge/puppetforge-user-release-count.tester.js @@ -0,0 +1,18 @@ +'use strict' + +const { isMetric } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('releases by user') + .get('/camptocamp.json') + .expectBadge({ + label: 'releases', + message: isMetric, + }) + +t.create('releases by user') + .get('/not-a-real-user.json') + .expectBadge({ + label: 'releases', + message: 'not found', + }) diff --git a/services/puppetforge/puppetforge-users.service.js b/services/puppetforge/puppetforge-users.service.js deleted file mode 100644 index f840b8388d..0000000000 --- a/services/puppetforge/puppetforge-users.service.js +++ /dev/null @@ -1,104 +0,0 @@ -'use strict' - -const Joi = require('joi') -const { BaseJsonService } = require('..') -const { metric } = require('../text-formatters') -const { floorCount: floorCountColor } = require('../color-formatters') -const { nonNegativeInteger } = require('../validators') - -const schema = Joi.object({ - module_count: nonNegativeInteger, - release_count: nonNegativeInteger, -}).required() - -class BasePuppetForgeUsersService extends BaseJsonService { - async fetch({ user }) { - return this._requestJson({ - schema, - url: `https://forgeapi.puppetlabs.com/v3/users/${user}`, - }) - } - - static get category() { - return 'other' - } -} - -class PuppetForgeReleaseCountService extends BasePuppetForgeUsersService { - static get defaultBadgeData() { - return { label: 'releases' } - } - - static get route() { - return { - base: 'puppetforge/rc', - pattern: ':user', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge releases by user', - namedParams: { - user: 'camptocamp', - }, - staticPreview: this.render({ releases: 1000 }), - }, - ] - } - - async handle({ user }) { - const data = await this.fetch({ user }) - return this.constructor.render({ releases: data.release_count }) - } - - static render({ releases }) { - return { - message: metric(releases), - color: floorCountColor(releases, 10, 50, 100), - } - } -} - -class PuppetForgeModuleCountService extends BasePuppetForgeUsersService { - static get defaultBadgeData() { - return { label: 'modules' } - } - - static get route() { - return { - base: 'puppetforge/mc', - pattern: ':user', - } - } - - static get examples() { - return [ - { - title: 'Puppet Forge modules by user', - namedParams: { - user: 'camptocamp', - }, - staticPreview: this.render({ modules: 60 }), - }, - ] - } - - async handle({ user }) { - const data = await this.fetch({ user }) - return this.constructor.render({ modules: data.module_count }) - } - - static render({ modules }) { - return { - message: metric(modules), - color: floorCountColor(modules, 5, 10, 50), - } - } -} - -module.exports = { - PuppetForgeReleaseCountService, - PuppetForgeModuleCountService, -} diff --git a/services/puppetforge/puppetforge-users.tester.js b/services/puppetforge/puppetforge-users.tester.js deleted file mode 100644 index 7a3b8f5fd3..0000000000 --- a/services/puppetforge/puppetforge-users.tester.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict' - -const { ServiceTester } = require('../tester') -const { isMetric } = require('../test-validators') - -const t = (module.exports = new ServiceTester({ - id: 'PuppetForgeUsers', - title: 'PuppetForge Users', - pathPrefix: '/puppetforge', -})) - -t.create('releases by user') - .get('/rc/camptocamp.json') - .expectBadge({ - label: 'releases', - message: isMetric, - }) - -t.create('releases by user') - .get('/rc/not-a-real-user.json') - .expectBadge({ - label: 'releases', - message: 'not found', - }) - -t.create('modules by user') - .get('/mc/camptocamp.json') - .expectBadge({ - label: 'modules', - message: isMetric, - }) - -t.create('modules by user') - .get('/mc/not-a-real-user.json') - .expectBadge({ - label: 'modules', - message: 'not found', - })