Add [pkgreview].dev service (#4660)

* Add pkgreview.dev services

* 🐛 FIX: Fix badges for pkgnames containing @ symbol

* 🐛 FIX: parseFloat the rating

* 🐛 FIX: Fix LGTM alerts

Alert: 2 for Incomplete string escaping or encoding

* Update services/pkgreview/package-rating.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* 🐛 FIX: Rollback to Joi.number() temporarily

* 👌 IMPROVE: Follow guidelines properly.

Not completely done, yet.

* 🐛 FIX: Handle response timed out error

* 👌 IMPROVE: Merge star and rating badge logic

* 🐛 FIX: Fix according to the maintainer's review

*  TEST: Write a test

*  TEST: Write one more dummy test

* 👌 IMPROVE: Improve message color scheme. Add logic to it. use color-formatters.

*  TEST: Complete Test Suitew

* 👌 IMPROVE: Make fixes according to the review

*  TEST: Write nice tests

*  TEST: Fix test regex

* 👌 IMPROVE: Do according to the review

*  TEST: Fix test regex and don't test Bad Requested Badge

*  TEST: Fix tests :)

Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>
This commit is contained in:
Kumar Abhirup
2020-02-22 22:41:20 +05:30
committed by GitHub
parent bb069b0492
commit ae4401ccb7
2 changed files with 118 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
'use strict'
const Joi = require('@hapi/joi')
const { starRating, metric } = require('../text-formatters')
const { colorScale } = require('../color-formatters')
const { nonNegativeInteger } = require('../validators')
const { BaseJsonService } = require('..')
const pkgReviewColor = colorScale([2, 3, 4])
const schema = Joi.object({
rating: Joi.number()
.min(0)
.max(1)
.precision(1)
.required()
.allow(null),
reviewsCount: nonNegativeInteger,
}).required()
module.exports = class PkgreviewRating extends BaseJsonService {
static get category() {
return 'rating'
}
static get route() {
return {
base: 'pkgreview',
pattern: ':format(rating|stars)/:pkgManager(npm)/:pkgSlug+',
}
}
static get examples() {
return [
{
title: 'pkgreview.dev Package Ratings',
pattern: 'rating/:pkgManager/:pkgSlug+',
namedParams: { pkgManager: 'npm', pkgSlug: 'react' },
staticPreview: this.render({
format: 'rating',
rating: 3.5,
reviewsCount: 237,
}),
},
{
title: 'pkgreview.dev Star Ratings',
pattern: 'stars/:pkgManager/:pkgSlug+',
namedParams: { pkgManager: 'npm', pkgSlug: 'react' },
staticPreview: this.render({
format: 'stars',
rating: 1.5,
reviewsCount: 200,
}),
},
]
}
static render({ rating, reviewsCount, format }) {
const message =
format === 'rating'
? `${+parseFloat(rating).toFixed(1)}/5 (${metric(reviewsCount)})`
: starRating(rating)
return {
message,
label: format,
color: pkgReviewColor(rating),
}
}
async fetch({ pkgManager, pkgSlug }) {
return this._requestJson({
schema,
url: `https://pkgreview.dev/api/v1/${pkgManager}/${encodeURIComponent(
pkgSlug
)}`,
errorMessages: {
404: 'package not found',
},
})
}
async handle({ format, pkgManager, pkgSlug }) {
const { reviewsCount, rating } = await this.fetch({
pkgManager,
pkgSlug,
})
return this.constructor.render({
reviewsCount,
format,
rating: rating * 5,
})
}
}

View File

@@ -0,0 +1,24 @@
'use strict'
const { withRegex, isStarRating } = require('../test-validators')
const t = (module.exports = require('../tester').createServiceTester())
const isRatingWithReviews = withRegex(
/^(([0-4](.?([0-9]))?)|5)\/5?\s*\([0-9]*\)$/
)
t.create('Stars Badge renders')
.get('/stars/npm/react.json')
.expectBadge({ label: 'stars', message: isStarRating })
t.create('Rating Badge renders')
.get('/rating/npm/react.json')
.expectBadge({ label: 'rating', message: isRatingWithReviews })
t.create('nonexistent package')
.get('/rating/npm/ohlolweallknowthispackagewontexist.json')
.expectBadge({
label: 'rating',
message: 'package not found',
color: 'red',
})