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: '★★★★½' })