refactor [redmine] plugin rating services (#2491)

This commit is contained in:
chris48s
2018-12-10 20:02:38 +00:00
committed by GitHub
parent 66623644c3
commit b74fe4ed6f
2 changed files with 75 additions and 90 deletions

View File

@@ -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 }

View File

@@ -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',
})