throw if given invalid version, refactor [apm] (#1785)

* throw if given invalid version

* refactor service

* add test

* fixup

* move service

* split up module

* update test

* add keywords

* remove from all-badge-examples

* update category [license → miscellaneous]

* Error → InvalidResponse

* minor style fix

* InvalidResponse

* reduce some code duplication

* fixup

* update category

* invalid → unparseable json response
This commit is contained in:
Danial
2018-07-30 14:46:47 +12:00
committed by GitHub
parent 409bcd1870
commit c974b1b931
4 changed files with 206 additions and 101 deletions

136
services/apm/apm.js Normal file
View File

@@ -0,0 +1,136 @@
'use strict';
const { BaseJsonService } = require('../base');
const { InvalidResponse } = require('../errors');
const { version: versionColor } = require('../../lib/color-formatters');
const {
metric,
addv
} = require('../../lib/text-formatters');
class BaseAPMService extends BaseJsonService {
async fetch(repo) {
const apiUrl = 'https://atom.io/api/packages/' + repo;
return this._requestJson(apiUrl, {}, 'package not found');
}
static get defaultBadgeData() {
return { label: 'apm' };
}
}
class APMDownloads extends BaseAPMService {
async handle({repo}) {
const json = await this.fetch(repo);
const downloads = json.downloads;
return {message: metric(downloads), color: 'green'};
}
static get category() {
return 'downloads';
}
static get defaultBadgeData() {
return { label: 'downloads' };
}
static get url() {
return {
base: 'apm/dm',
format: '(.+)',
capture: ['repo']
};
}
static get examples() {
return [
{
previewUrl: 'dm/vim-mode',
keywords: [
'atom'
]
},
];
}
};
class APMVersion extends BaseAPMService {
async handle({repo}) {
const json = await this.fetch(repo);
const version = json.releases.latest;
if (!version)
throw new InvalidResponse({ underlyingError: new Error('version is invalid') });
return {message: addv(version), color: versionColor(version)};
}
static get category() {
return 'version';
}
static get url() {
return {
base: 'apm/v',
format: '(.+)',
capture: ['repo']
};
}
static get examples() {
return [
{
previewUrl: 'v/vim-mode',
keywords: [
'atom'
]
},
];
}
};
class APMLicense extends BaseAPMService {
async handle({repo}) {
const json = await this.fetch(repo);
const license = json.metadata.license;
if (!license)
throw new InvalidResponse({ underlyingError: new Error('licence is invalid') });
return {message: license, color: 'blue'};
}
static get defaultBadgeData() {
return { label: 'license' };
}
static get category() {
return 'license';
}
static get url() {
return {
base: 'apm/l',
format: '(.+)',
capture: ['repo']
};
}
static get examples() {
return [
{
previewUrl: 'l/vim-mode',
keywords: [
'atom'
]
},
];
}
};
module.exports = {
APMDownloads,
APMVersion,
APMLicense,
}

View File

@@ -0,0 +1,70 @@
'use strict';
const Joi = require('joi');
const ServiceTester = require('../service-tester');
const t = new ServiceTester({ id: 'apm', title: 'Atom Package Manager' });
const { invalidJSON } = require('../response-fixtures');
const {
isMetric,
isVPlusTripleDottedVersion
} = require('../test-validators');
module.exports = t;
t.create('Downloads')
.get('/dm/vim-mode.json')
.expectJSONTypes(Joi.object().keys({ name: 'downloads', value: isMetric }));
t.create('Version')
.get('/v/vim-mode.json')
.expectJSONTypes(Joi.object().keys({ name: 'apm', value: isVPlusTripleDottedVersion }));
t.create('License')
.get('/l/vim-mode.json')
.expectJSON({ name: 'license', value: 'MIT' });
t.create('Downloads | Package not found')
.get('/dm/notapackage.json')
.expectJSON({ name: 'downloads', value: 'package not found' });
t.create('Version | Package not found')
.get('/v/notapackage.json')
.expectJSON({ name: 'apm', value: 'package not found' });
t.create('License | Package not found')
.get('/l/notapackage.json')
.expectJSON({ name: 'license', value: 'package not found' });
t.create('Connection error')
.get('/v/vim-mode.json')
.networkOff()
.expectJSON({ name: 'apm', value: 'inaccessible' });
t.create('Invalid version')
.get('/dm/vim-mode.json')
.intercept(nock => nock('https://atom.io')
.get('/api/packages/vim-mode')
.reply([
200,
'{"releases":{}}'
])
)
.expectJSON({name: 'downloads', value: 'unparseable json response'});
t.create('Invalid License')
.get('/l/vim-mode.json')
.intercept(nock => nock('https://atom.io')
.get('/api/packages/vim-mode')
.reply([
200,
'{"metadata":{}}'
])
)
.expectJSON({name: 'license', value: 'unparseable json response'});
t.create('Unexpected response')
.get('/dm/vim-mode.json')
.intercept(nock => nock('https://atom.io')
.get('/api/packages/vim-mode')
.reply(invalidJSON)
)
.expectJSON({name: 'downloads', value: 'unparseable json response'});