refactor [redmine] plugin rating services (#2491)
This commit is contained in:
@@ -1,19 +1,77 @@
|
||||
'use strict'
|
||||
|
||||
const xml2js = require('xml2js')
|
||||
const LegacyService = require('../legacy-service')
|
||||
const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
|
||||
const { starRating } = require('../../lib/text-formatters')
|
||||
const { floorCount: floorCountColor } = require('../../lib/color-formatters')
|
||||
|
||||
module.exports = class Redmine extends LegacyService {
|
||||
const Joi = require('joi')
|
||||
const BaseXmlService = require('../base-xml')
|
||||
|
||||
const schema = Joi.object({
|
||||
'redmine-plugin': Joi.object({
|
||||
'ratings-average': Joi.number()
|
||||
.min(0)
|
||||
.required(),
|
||||
}).required(),
|
||||
})
|
||||
|
||||
class BaseRedminePluginRating extends BaseXmlService {
|
||||
async fetch({ plugin }) {
|
||||
const url = `https://www.redmine.org/plugins/${plugin}.xml`
|
||||
return this._requestXml({ schema, url })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
|
||||
static render({ rating }) {
|
||||
throw new Error(`render() function not implemented for ${this.name}`)
|
||||
}
|
||||
|
||||
async handle({ plugin }) {
|
||||
const data = await this.fetch({ plugin })
|
||||
const rating = data['redmine-plugin']['ratings-average']
|
||||
return this.constructor.render({ rating })
|
||||
}
|
||||
}
|
||||
|
||||
class RedminePluginRating extends BaseRedminePluginRating {
|
||||
static get route() {
|
||||
return {
|
||||
base: 'redmine/plugin',
|
||||
base: 'redmine/plugin/rating',
|
||||
pattern: ':plugin',
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'redmine' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Plugin on redmine.org',
|
||||
namedParams: { plugin: 'redmine_xlsx_format_issue_exporter' },
|
||||
staticExample: this.render({ rating: 5 }),
|
||||
keywords: ['redmine', 'plugin'],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static render({ rating }) {
|
||||
return {
|
||||
label: 'rating',
|
||||
message: `${rating.toFixed(1)}/5.0`,
|
||||
color: floorCountColor(rating, 2, 3, 4),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RedminePluginStars extends BaseRedminePluginRating {
|
||||
static get route() {
|
||||
return {
|
||||
base: 'redmine/plugin/stars',
|
||||
pattern: ':plugin',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,60 +79,20 @@ module.exports = class Redmine extends LegacyService {
|
||||
return [
|
||||
{
|
||||
title: 'Plugin on redmine.org',
|
||||
previewUrl: 'rating/redmine_xlsx_format_issue_exporter',
|
||||
keywords: ['redmine', 'plugin'],
|
||||
},
|
||||
{
|
||||
title: 'Plugin on redmine.org',
|
||||
previewUrl: 'stars/redmine_xlsx_format_issue_exporter',
|
||||
namedParams: { plugin: 'redmine_xlsx_format_issue_exporter' },
|
||||
staticExample: this.render({ rating: 5 }),
|
||||
keywords: ['redmine', 'plugin'],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static registerLegacyRouteHandler({ camp, cache }) {
|
||||
camp.route(
|
||||
/^\/redmine\/plugin\/(rating|stars)\/(.*)\.(svg|png|gif|jpg|json)$/,
|
||||
cache((data, match, sendBadge, request) => {
|
||||
const type = match[1]
|
||||
const plugin = match[2]
|
||||
const format = match[3]
|
||||
const options = {
|
||||
method: 'GET',
|
||||
uri: `https://www.redmine.org/plugins/${plugin}.xml`,
|
||||
}
|
||||
|
||||
const badgeData = getBadgeData(type, data)
|
||||
request(options, (err, res, buffer) => {
|
||||
if (err != null) {
|
||||
badgeData.text[1] = 'inaccessible'
|
||||
sendBadge(format, badgeData)
|
||||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line handle-callback-err
|
||||
xml2js.parseString(buffer.toString(), (err, data) => {
|
||||
try {
|
||||
const rating = data['redmine-plugin']['ratings-average'][0]._
|
||||
badgeData.colorscheme = floorCountColor(rating, 2, 3, 4)
|
||||
|
||||
switch (type) {
|
||||
case 'rating':
|
||||
badgeData.text[1] = `${rating}/5.0`
|
||||
break
|
||||
case 'stars':
|
||||
badgeData.text[1] = starRating(Math.round(rating))
|
||||
break
|
||||
}
|
||||
|
||||
sendBadge(format, badgeData)
|
||||
} catch (e) {
|
||||
badgeData.text[1] = 'invalid'
|
||||
sendBadge(format, badgeData)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
)
|
||||
static render({ rating }) {
|
||||
return {
|
||||
label: 'stars',
|
||||
message: starRating(Math.round(rating)),
|
||||
color: floorCountColor(rating, 2, 3, 4),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { RedminePluginRating, RedminePluginStars }
|
||||
|
||||
@@ -9,16 +9,6 @@ module.exports = t
|
||||
|
||||
t.create('plugin rating')
|
||||
.get('/plugin/rating/redmine_xlsx_format_issue_exporter.json')
|
||||
.intercept(nock =>
|
||||
nock('https://www.redmine.org')
|
||||
.get('/plugins/redmine_xlsx_format_issue_exporter.xml')
|
||||
.reply(
|
||||
200,
|
||||
'<redmine-plugin>' +
|
||||
'<ratings-average type="float">1.23456</ratings-average>' +
|
||||
'</redmine-plugin>'
|
||||
)
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'rating',
|
||||
@@ -28,16 +18,6 @@ t.create('plugin rating')
|
||||
|
||||
t.create('plugin stars')
|
||||
.get('/plugin/stars/redmine_xlsx_format_issue_exporter.json')
|
||||
.intercept(nock =>
|
||||
nock('https://www.redmine.org')
|
||||
.get('/plugins/redmine_xlsx_format_issue_exporter.xml')
|
||||
.reply(
|
||||
200,
|
||||
'<redmine-plugin>' +
|
||||
'<ratings-average type="float">1.23456</ratings-average>' +
|
||||
'</redmine-plugin>'
|
||||
)
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'stars',
|
||||
@@ -47,22 +27,9 @@ t.create('plugin stars')
|
||||
|
||||
t.create('plugin not found')
|
||||
.get('/plugin/rating/plugin_not_found.json')
|
||||
.intercept(nock =>
|
||||
nock('https://www.redmine.org')
|
||||
.get('/plugins/plugin_not_found.xml')
|
||||
.reply(404, '')
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'rating',
|
||||
value: 'invalid',
|
||||
name: 'redmine',
|
||||
value: 'not found',
|
||||
})
|
||||
)
|
||||
|
||||
t.create('connection error')
|
||||
.get('/plugin/rating/redmine_xlsx_format_issue_exporter.json')
|
||||
.networkOff()
|
||||
.expectJSON({
|
||||
name: 'rating',
|
||||
value: 'inaccessible',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user