[Bintray] Downloads (Bintray Versions renamed and not changed) (#5316)

* Bintray Downloads (Bintray Versions renamed and not changed)

* Tests fix

* Tests fix

* Tests fix

* Refactoring

* PR suggestions

* PR suggestions

* PR suggestions

Co-authored-by: Martynas Petuška <petuska.m@cambridgeassessment.org.uk>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
Martynas Petuška
2020-08-11 15:52:56 +03:00
committed by GitHub
parent f55f00cfa7
commit 3dd163e2a7
7 changed files with 209 additions and 6 deletions

3
package-lock.json generated
View File

@@ -6869,8 +6869,7 @@
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true,
"optional": true
"dev": true
},
"@types/keyv": {
"version": "3.1.1",

View File

@@ -0,0 +1,125 @@
'use strict'
const Joi = require('@hapi/joi')
const { metric } = require('../text-formatters')
const { downloadCount } = require('../color-formatters')
const { BaseJsonService } = require('..')
const schema = Joi.object({
totalDownloads: Joi.number().required(),
}).required()
const versionSchema = Joi.object({
name: Joi.string().required(),
}).required()
const documentation = `
<p>
These badges utilize unofficial Bintray APIs to retrieve download data. <br />
As such, they may be unstable or intermittently unavailable.
</p>`
module.exports = class BintrayDownloads extends BaseJsonService {
static get category() {
return 'downloads'
}
static get route() {
return {
base: 'bintray',
pattern: ':interval(dt)/:subject/:repo/:packageName/:version*',
}
}
static get auth() {
return {
userKey: 'bintray_user',
passKey: 'bintray_apikey',
authorizedOrigins: ['https://bintray.com'],
}
}
static get examples() {
return [
{
title: 'Bintray',
staticPreview: this.render({ downloads: 69000 }),
namedParams: {
interval: 'dt',
subject: 'asciidoctor',
repo: 'maven',
packageName: 'asciidoctorj',
},
documentation,
},
{
title: 'Bintray (latest)',
staticPreview: this.render({ version: 'latest', downloads: 69000 }),
namedParams: {
interval: 'dt',
subject: 'asciidoctor',
repo: 'maven',
packageName: 'asciidoctorj',
version: 'latest',
},
documentation,
},
{
title: 'Bintray (version)',
staticPreview: this.render({ version: '1.6.0', downloads: 69000 }),
namedParams: {
interval: 'dt',
subject: 'asciidoctor',
repo: 'maven',
packageName: 'asciidoctorj',
version: '1.6.0',
},
documentation,
},
]
}
static get defaultBadgeData() {
return { label: 'downloads' }
}
static render({ version, downloads }) {
return {
label: version ? `downloads@${version}` : 'downloads',
message: metric(downloads),
color: downloadCount(downloads),
}
}
async fetch({ subject, repo, packageName, version }) {
let actualVersion = version
if (version === 'latest') {
actualVersion = (
await this._requestJson(
this.authHelper.withBasicAuth({
schema: versionSchema,
url: `https://bintray.com/api/v1/packages/${subject}/${repo}/${packageName}/versions/_latest`,
})
)
).name
}
return this._requestJson(
this.authHelper.withBasicAuth({
schema,
url: actualVersion
? `https://bintray.com/api/ui/version/${subject}/${repo}/${packageName}/${actualVersion}/total_downloads`
: `https://bintray.com/api/ui/package/${subject}/${repo}/${packageName}/total_downloads`,
})
)
}
async handle({ version, subject, repo, packageName }) {
const { totalDownloads } = await this.fetch({
subject,
repo,
packageName,
version,
})
return this.constructor.render({ version, downloads: totalDownloads })
}
}

View File

@@ -0,0 +1,47 @@
'use strict'
const { expect } = require('chai')
const nock = require('nock')
const { cleanUpNockAfterEach, defaultContext } = require('../test-helpers')
const BintrayDownloads = require('./bintray-downloads.service')
describe('BintrayDownloads', function () {
describe('auth', function () {
cleanUpNockAfterEach()
const user = 'admin'
const pass = 'password'
const config = {
private: {
bintray_user: user,
bintray_apikey: pass,
},
}
it('sends the auth information as configured', async function () {
const scope = nock('https://bintray.com')
.get('/api/ui/package/asciidoctor/maven/asciidoctorj/total_downloads')
// 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.
.basicAuth({ user, pass })
.reply(200, {
totalDownloads: 69,
})
expect(
await BintrayDownloads.invoke(defaultContext, config, {
interval: 'dt',
subject: 'asciidoctor',
repo: 'maven',
packageName: 'asciidoctorj',
})
).to.deep.equal({
color: 'yellowgreen',
label: 'downloads',
message: '69',
})
scope.done()
})
})
})

View File

@@ -0,0 +1,32 @@
'use strict'
const { isMetric } = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
t.create('downloads')
.get('/dt/asciidoctor/maven/asciidoctorj.json')
.expectBadge({
label: 'downloads',
message: isMetric,
})
t.create('downloads (not found)')
.get('/dt/asciidoctor/maven/not-a-real-package.json')
.expectBadge({
label: 'downloads',
message: 'not found',
})
t.create('downloads (mocked)')
.get('/dt/asciidoctor/maven/asciidoctorj.json')
.intercept(nock =>
nock('https://bintray.com')
.get('/api/ui/package/asciidoctor/maven/asciidoctorj/total_downloads')
.reply(200, {
totalDownloads: 420,
})
)
.expectBadge({
label: 'downloads',
message: '420',
})

View File

@@ -10,7 +10,7 @@ const schema = Joi.object()
})
.required()
module.exports = class Bintray extends BaseJsonService {
module.exports = class BintrayVersion extends BaseJsonService {
static get category() {
return 'version'
}

View File

@@ -3,9 +3,9 @@
const { expect } = require('chai')
const nock = require('nock')
const { cleanUpNockAfterEach, defaultContext } = require('../test-helpers')
const Bintray = require('./bintray.service')
const BintrayVersion = require('./bintray-version.service')
describe('Bintray', function () {
describe('BintrayVersion', function () {
describe('auth', function () {
cleanUpNockAfterEach()
@@ -29,7 +29,7 @@ describe('Bintray', function () {
})
expect(
await Bintray.invoke(defaultContext, config, {
await BintrayVersion.invoke(defaultContext, config, {
subject: 'asciidoctor',
repo: 'maven',
packageName: 'asciidoctorj',