From baab63cc94f2f5cef0ae71eb86c940a343333d57 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 28 Sep 2021 20:06:54 -0500 Subject: [PATCH] refactor: tweak libraries/bower service classes and tests --- services/bower/bower-license.tester.js | 9 -- services/bower/bower-version.service.js | 12 ++- services/bower/bower-version.spec.js | 92 +++++++++++++++++++ services/bower/bower-version.tester.js | 18 ---- .../librariesio-dependencies.service.js | 14 +-- .../librariesio-dependent-repos.service.js | 13 +-- .../librariesio-dependents.service.js | 7 +- .../librariesio-sourcerank.service.js | 7 +- .../librariesio-sourcerank.spec.js | 52 +++++++++++ 9 files changed, 171 insertions(+), 53 deletions(-) create mode 100644 services/bower/bower-version.spec.js create mode 100644 services/librariesio/librariesio-sourcerank.spec.js diff --git a/services/bower/bower-license.tester.js b/services/bower/bower-license.tester.js index 18ba64b760210..6f895cfed0a6b 100644 --- a/services/bower/bower-license.tester.js +++ b/services/bower/bower-license.tester.js @@ -6,15 +6,6 @@ t.create('licence') .get('/bootstrap.json') .expectBadge({ label: 'license', message: 'MIT' }) -t.create('license not declared') - .get('/bootstrap.json') - .intercept(nock => - nock('https://libraries.io') - .get('/api/bower/bootstrap') - .reply(200, { normalized_licenses: [] }) - ) - .expectBadge({ label: 'license', message: 'missing' }) - t.create('licence for Invalid Package') .timeout(10000) .get('/it-is-a-invalid-package-should-error.json') diff --git a/services/bower/bower-version.service.js b/services/bower/bower-version.service.js index 277d704021d88..1459c74e2af46 100644 --- a/services/bower/bower-version.service.js +++ b/services/bower/bower-version.service.js @@ -27,9 +27,7 @@ class BowerVersion extends BaseBowerService { static defaultBadgeData = { label: 'bower' } - async handle({ packageName }, queryParams) { - const data = await this.fetch({ packageName }) - const includePrereleases = queryParams.include_prereleases !== undefined + static transform(data, includePrereleases) { const version = includePrereleases ? data.latest_release_number : data.latest_stable_release_number @@ -38,6 +36,14 @@ class BowerVersion extends BaseBowerService { throw new InvalidResponse({ prettyMessage: 'no releases' }) } + return version + } + + async handle({ packageName }, queryParams) { + const data = await this.fetch({ packageName }) + const includePrereleases = queryParams.include_prereleases !== undefined + const version = this.constructor.transform(data, includePrereleases) + return renderVersionBadge({ version }) } } diff --git a/services/bower/bower-version.spec.js b/services/bower/bower-version.spec.js new file mode 100644 index 0000000000000..bd8ef72aafe3b --- /dev/null +++ b/services/bower/bower-version.spec.js @@ -0,0 +1,92 @@ +import { expect } from 'chai' +import { test, given } from 'sazerac' +import nock from 'nock' +import { cleanUpNockAfterEach, defaultContext } from '../test-helpers.js' +import { InvalidResponse } from '../index.js' +import LibrariesIoApiProvider from '../librariesio/librariesio-api-provider.js' +import { BowerVersion } from './bower-version.service.js' + +describe('BowerVersion', function () { + test(BowerVersion.transform, () => { + given( + { + latest_release_number: '2.0.0-beta', + latest_stable_release_number: '1.8.3', + }, + false + ).expect('1.8.3') + given( + { + latest_release_number: '2.0.0-beta', + latest_stable_release_number: '1.8.3', + }, + true + ).expect('2.0.0-beta') + }) + + it('throws `no releases` InvalidResponse if no stable version', function () { + expect(() => + BowerVersion.transform({ latest_release_number: 'panda' }, false) + ) + .to.throw(InvalidResponse) + .with.property('prettyMessage', 'no releases') + }) + + it('throws `no releases` InvalidResponse if no prereleases', function () { + expect(() => + BowerVersion.transform({ latest_stable_release_number: 'penguin' }, true) + ) + .to.throw(InvalidResponse) + .with.property('prettyMessage', 'no releases') + }) + + context('auth', function () { + cleanUpNockAfterEach() + const fakeApiKey = 'fakeness' + const response = { + normalized_licenses: [], + latest_release_number: '2.0.0-beta', + latest_stable_release_number: '1.8.3', + } + const config = { + private: { + librariesio_tokens: fakeApiKey, + }, + } + const librariesIoApiProvider = new LibrariesIoApiProvider({ + baseUrl: 'https://libraries.io/api', + tokens: [fakeApiKey], + }) + + it('sends the auth information as configured', async function () { + const scope = nock('https://libraries.io/api') + // This ensures that the expected credentials are actually being sent with the HTTP request. + // Without this the request wouldn't match and the test would fail. + .get(`/bower/bootstrap?api_key=${fakeApiKey}`) + .reply(200, response) + + expect( + await BowerVersion.invoke( + { + ...defaultContext, + librariesIoApiProvider, + }, + config, + { + platform: 'bower', + packageName: 'bootstrap', + }, + { + include_prereleases: '', + } + ) + ).to.deep.equal({ + message: 'v2.0.0-beta', + color: 'orange', + label: undefined, + }) + + scope.done() + }) + }) +}) diff --git a/services/bower/bower-version.tester.js b/services/bower/bower-version.tester.js index acccf3a756fec..6d37ababfcf33 100644 --- a/services/bower/bower-version.tester.js +++ b/services/bower/bower-version.tester.js @@ -34,24 +34,6 @@ t.create('Pre Version for Invalid Package') .get('/v/it-is-a-invalid-package-should-error.json?include_prereleases') .expectBadge({ label: 'bower', message: 'package not found' }) -t.create('Version label should be `no releases` if no stable version') - .get('/v/bootstrap.json') - .intercept(nock => - nock('https://libraries.io') - .get('/api/bower/bootstrap') - .reply(200, { normalized_licenses: [], latest_stable_release: null }) - ) - .expectBadge({ label: 'bower', message: 'no releases' }) - -t.create('Version label should be `no releases` if no pre-release') - .get('/v/bootstrap.json?include_prereleases') - .intercept(nock => - nock('https://libraries.io') - .get('/api/bower/bootstrap') - .reply(200, { normalized_licenses: [], latest_release_number: null }) - ) - .expectBadge({ label: 'bower', message: 'no releases' }) - t.create('Version (legacy redirect: vpre)') .get('/vpre/bootstrap.svg') .expectRedirect('/bower/v/bootstrap.svg?include_prereleases') diff --git a/services/librariesio/librariesio-dependencies.service.js b/services/librariesio/librariesio-dependencies.service.js index 05df0e6ae6420..1811c6423b6ef 100644 --- a/services/librariesio/librariesio-dependencies.service.js +++ b/services/librariesio/librariesio-dependencies.service.js @@ -1,5 +1,5 @@ import Joi from 'joi' -import { BaseJsonService } from '../index.js' +import LibrariesIoBase from './librariesio-base.js' import { transform, renderDependenciesBadge, @@ -16,7 +16,7 @@ const schema = Joi.object({ .default([]), }).required() -class LibrariesIoProjectDependencies extends BaseJsonService { +class LibrariesIoProjectDependencies extends LibrariesIoBase { static category = 'dependencies' static route = { @@ -82,7 +82,7 @@ class LibrariesIoProjectDependencies extends BaseJsonService { ] async handle({ platform, scope, packageName, version = 'latest' }) { - const url = `https://libraries.io/api/${encodeURIComponent(platform)}/${ + const url = `/${encodeURIComponent(platform)}/${ scope ? encodeURIComponent(`${scope}/`) : '' }${encodeURIComponent(packageName)}/${encodeURIComponent( version @@ -97,7 +97,7 @@ class LibrariesIoProjectDependencies extends BaseJsonService { } } -class LibrariesIoRepoDependencies extends BaseJsonService { +class LibrariesIoRepoDependencies extends LibrariesIoBase { static category = 'dependencies' static route = { @@ -117,9 +117,9 @@ class LibrariesIoRepoDependencies extends BaseJsonService { ] async handle({ user, repo }) { - const url = `https://libraries.io/api/github/${encodeURIComponent( - user - )}/${encodeURIComponent(repo)}/dependencies` + const url = `/github/${encodeURIComponent(user)}/${encodeURIComponent( + repo + )}/dependencies` const json = await this._requestJson({ url, schema, diff --git a/services/librariesio/librariesio-dependent-repos.service.js b/services/librariesio/librariesio-dependent-repos.service.js index 0f8217c11bc73..0c800157fab2f 100644 --- a/services/librariesio/librariesio-dependent-repos.service.js +++ b/services/librariesio/librariesio-dependent-repos.service.js @@ -1,9 +1,8 @@ import { metric } from '../text-formatters.js' -import { BaseJsonService } from '../index.js' -import { fetchProject } from './librariesio-common.js' +import LibrariesIoBase from './librariesio-base.js' // https://libraries.io/api#project-dependent-repositories -export default class LibrariesIoDependentRepos extends BaseJsonService { +export default class LibrariesIoDependentRepos extends LibrariesIoBase { static category = 'other' static route = { @@ -45,14 +44,12 @@ export default class LibrariesIoDependentRepos extends BaseJsonService { } async handle({ platform, scope, packageName }) { - const { dependent_repos_count: dependentReposCount } = await fetchProject( - this, - { + const { dependent_repos_count: dependentReposCount } = + await this.fetchProject({ platform, scope, packageName, - } - ) + }) return this.constructor.render({ dependentReposCount }) } } diff --git a/services/librariesio/librariesio-dependents.service.js b/services/librariesio/librariesio-dependents.service.js index ceaf4f5b27817..963a57e313782 100644 --- a/services/librariesio/librariesio-dependents.service.js +++ b/services/librariesio/librariesio-dependents.service.js @@ -1,9 +1,8 @@ import { metric } from '../text-formatters.js' -import { BaseJsonService } from '../index.js' -import { fetchProject } from './librariesio-common.js' +import LibrariesIoBase from './librariesio-base.js' // https://libraries.io/api#project-dependents -export default class LibrariesIoDependents extends BaseJsonService { +export default class LibrariesIoDependents extends LibrariesIoBase { static category = 'other' static route = { @@ -45,7 +44,7 @@ export default class LibrariesIoDependents extends BaseJsonService { } async handle({ platform, scope, packageName }) { - const { dependents_count: dependentCount } = await fetchProject(this, { + const { dependents_count: dependentCount } = await this.fetchProject({ platform, scope, packageName, diff --git a/services/librariesio/librariesio-sourcerank.service.js b/services/librariesio/librariesio-sourcerank.service.js index 351a668eeff7f..21055bf3b2dcc 100644 --- a/services/librariesio/librariesio-sourcerank.service.js +++ b/services/librariesio/librariesio-sourcerank.service.js @@ -1,10 +1,9 @@ import { colorScale } from '../color-formatters.js' -import { BaseJsonService } from '../index.js' -import { fetchProject } from './librariesio-common.js' +import LibrariesIoBase from './librariesio-base.js' const sourceRankColor = colorScale([10, 15, 20, 25, 30]) -export default class LibrariesIoSourcerank extends BaseJsonService { +export default class LibrariesIoSourcerank extends LibrariesIoBase { static category = 'rating' static route = { @@ -46,7 +45,7 @@ export default class LibrariesIoSourcerank extends BaseJsonService { } async handle({ platform, scope, packageName }) { - const { rank } = await fetchProject(this, { + const { rank } = await this.fetchProject({ platform, scope, packageName, diff --git a/services/librariesio/librariesio-sourcerank.spec.js b/services/librariesio/librariesio-sourcerank.spec.js new file mode 100644 index 0000000000000..3ddb815b16025 --- /dev/null +++ b/services/librariesio/librariesio-sourcerank.spec.js @@ -0,0 +1,52 @@ +import { expect } from 'chai' +import nock from 'nock' +import { cleanUpNockAfterEach, defaultContext } from '../test-helpers.js' +import LibrariesIoSourcerank from './librariesio-sourcerank.service.js' +import LibrariesIoApiProvider from './librariesio-api-provider.js' + +describe('LibrariesIoSourcerank', function () { + cleanUpNockAfterEach() + const fakeApiKey = 'fakeness' + const response = { + platform: 'npm', + dependents_count: 150, + dependent_repos_count: 191, + rank: 100, + } + const config = { + private: { + librariesio_tokens: fakeApiKey, + }, + } + const librariesIoApiProvider = new LibrariesIoApiProvider({ + baseUrl: 'https://libraries.io/api', + tokens: [fakeApiKey], + }) + + it('sends the auth information as configured', async function () { + const scope = nock('https://libraries.io/api') + // This ensures that the expected credentials are actually being sent with the HTTP request. + // Without this the request wouldn't match and the test would fail. + .get(`/npm/badge-maker?api_key=${fakeApiKey}`) + .reply(200, response) + + expect( + await LibrariesIoSourcerank.invoke( + { + ...defaultContext, + librariesIoApiProvider, + }, + config, + { + platform: 'npm', + packageName: 'badge-maker', + } + ) + ).to.deep.equal({ + message: 100, + color: 'brightgreen', + }) + + scope.done() + }) +})