From 2bf6dfdeeaf69072391fc493cff5f2d75795ad25 Mon Sep 17 00:00:00 2001 From: ChrisCarini <6374067+ChrisCarini@users.noreply.github.com> Date: Sun, 12 Apr 2020 10:05:49 -0700 Subject: [PATCH] Adding badges for JetBrains Plugin Ratings, run [JetBrainsRating]. #4897 (#4898) * Adding badges for JetBrains Plugin Ratings. Addresses feature request #4897 * Removing unnecessary undefined label and improving variable name in tests. --- .../jetbrains/jetbrains-rating.service.js | 86 +++++++++++++++++++ services/jetbrains/jetbrains-rating.tester.js | 84 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 services/jetbrains/jetbrains-rating.service.js create mode 100644 services/jetbrains/jetbrains-rating.tester.js diff --git a/services/jetbrains/jetbrains-rating.service.js b/services/jetbrains/jetbrains-rating.service.js new file mode 100644 index 0000000000000..c57512cba06ff --- /dev/null +++ b/services/jetbrains/jetbrains-rating.service.js @@ -0,0 +1,86 @@ +'use strict' + +const Joi = require('@hapi/joi') +const { starRating } = require('../text-formatters') +const { colorScale } = require('../color-formatters') +const JetbrainsBase = require('./jetbrains-base') + +const pluginRatingColor = colorScale([2, 3, 4]) + +const schema = Joi.object({ + 'plugin-repository': Joi.object({ + category: Joi.object({ + 'idea-plugin': Joi.array() + .min(1) + .items( + Joi.object({ + rating: Joi.string().required(), + }) + ) + .single() + .required(), + }), + }).required(), +}).required() + +module.exports = class JetbrainsRating extends JetbrainsBase { + static get category() { + return 'rating' + } + + static get route() { + return { + base: 'jetbrains/plugin/r', + pattern: ':format(rating|stars)/:pluginId', + } + } + + static get examples() { + return [ + { + title: 'JetBrains IntelliJ Plugins', + pattern: 'rating/:pluginId', + namedParams: { + pluginId: '11941-automatic-power-saver', + }, + staticPreview: this.render({ + rating: '4.5', + format: 'rating', + }), + }, + { + title: 'JetBrains IntelliJ Plugins', + pattern: 'stars/:pluginId', + namedParams: { + pluginId: '11941-automatic-power-saver', + }, + staticPreview: this.render({ + rating: '4.5', + format: 'stars', + }), + }, + ] + } + + static get defaultBadgeData() { + return { label: 'rating' } + } + + static render({ rating, format }) { + const message = + format === 'rating' + ? `${+parseFloat(rating).toFixed(1)}/5` + : starRating(rating) + return { + message, + color: pluginRatingColor(rating), + } + } + + async handle({ format, pluginId }) { + const pluginData = await this.fetchPackageData({ pluginId, schema }) + const pluginRating = + pluginData['plugin-repository'].category['idea-plugin'][0].rating + return this.constructor.render({ rating: pluginRating, format }) + } +} diff --git a/services/jetbrains/jetbrains-rating.tester.js b/services/jetbrains/jetbrains-rating.tester.js new file mode 100644 index 0000000000000..1388905f5eb08 --- /dev/null +++ b/services/jetbrains/jetbrains-rating.tester.js @@ -0,0 +1,84 @@ +'use strict' + +const { withRegex, isStarRating } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +const isRating = withRegex(/^(([0-4](.?([0-9]))?)|5)\/5$/) + +t.create('rating number (user friendly plugin id)') + .get('/rating/11941-automatic-power-saver.json') + .expectBadge({ label: 'rating', message: isRating }) + +t.create('rating number (plugin id from plugin.xml)') + .get('/rating/com.chriscarini.jetbrains.jetbrains-auto-power-saver.json') + .expectBadge({ label: 'rating', message: isRating }) + +t.create('rating number (number as a plugin id)') + .get('/rating/11941.json') + .expectBadge({ label: 'rating', message: isRating }) + +t.create('rating number for unknown plugin') + .get('/rating/unknown-plugin.json') + .expectBadge({ label: 'rating', message: 'not found' }) + +t.create('rating stars (user friendly plugin id)') + .get('/stars/11941-automatic-power-saver.json') + .expectBadge({ label: 'rating', message: isStarRating }) + +t.create('rating stars (plugin id from plugin.xml)') + .get('/stars/com.chriscarini.jetbrains.jetbrains-auto-power-saver.json') + .expectBadge({ label: 'rating', message: isStarRating }) + +t.create('rating stars (number as a plugin id)') + .get('/stars/11941.json') + .expectBadge({ label: 'rating', message: isStarRating }) + +t.create('rating stars for unknown plugin') + .get('/stars/unknown-plugin.json') + .expectBadge({ label: 'rating', message: 'not found' }) + +t.create('rating number') + .get('/rating/11941.json') + .intercept( + nock => + nock('https://plugins.jetbrains.com') + .get('/plugins/list?pluginId=11941') + .reply( + 200, + ` + + + + 4.5 + + + ` + ), + { + 'Content-Type': 'text/xml;charset=UTF-8', + } + ) + .expectBadge({ label: 'rating', message: '4.5/5' }) + +t.create('rating stars') + .get('/stars/11941.json') + .intercept( + nock => + nock('https://plugins.jetbrains.com') + .get('/plugins/list?pluginId=11941') + .reply( + 200, + ` + + + + 4.5 + + + ` + ), + { + 'Content-Type': 'text/xml;charset=UTF-8', + } + ) + .expectBadge({ label: 'rating', message: '★★★★½' })