diff --git a/services/reddit/subreddit-subscribers.service.js b/services/reddit/subreddit-subscribers.service.js index e59273f478..83a0f6a719 100644 --- a/services/reddit/subreddit-subscribers.service.js +++ b/services/reddit/subreddit-subscribers.service.js @@ -11,7 +11,7 @@ const schema = Joi.object({ }).required(), }).required() -module.exports = class SubredditSubscribers extends BaseJsonService { +module.exports = class RedditSubredditSubscribers extends BaseJsonService { static get category() { return 'social' } @@ -60,6 +60,7 @@ module.exports = class SubredditSubscribers extends BaseJsonService { url: `https://www.reddit.com/r/${subreddit}/about.json`, errorMessages: { 404: 'subreddit not found', + 403: 'subreddit is private', }, }) } diff --git a/services/reddit/subreddit-subscribers.tester.js b/services/reddit/subreddit-subscribers.tester.js index 9e4d12e3c7..b9d4265d55 100644 --- a/services/reddit/subreddit-subscribers.tester.js +++ b/services/reddit/subreddit-subscribers.tester.js @@ -23,3 +23,22 @@ t.create('subreddit-subscribers (not existing subreddit)') label: 'reddit', message: 'subreddit not found', }) + +t.create('subreddit-subscribers (private sub)') + .get('/centuryclub.json') + .expectBadge({ + label: 'reddit', + message: 'subreddit is private', + }) + +t.create('subreddit-subscribers (private sub)') + .get('/centuryclub.json') + .intercept(nock => + nock('https://www.reddit.com/r') + .get('/centuryclub/about.json') + .reply(200, { kind: 't5', data: {} }) + ) + .expectBadge({ + label: 'reddit', + message: 'subreddit not found', + }) diff --git a/services/reddit/user-karma.service.js b/services/reddit/user-karma.service.js new file mode 100644 index 0000000000..d8e0d0fa7d --- /dev/null +++ b/services/reddit/user-karma.service.js @@ -0,0 +1,96 @@ +'use strict' + +const Joi = require('@hapi/joi') +const { nonNegativeInteger } = require('../validators') +const { metric } = require('../text-formatters') +const { BaseJsonService } = require('..') + +const schema = Joi.object({ + data: Joi.object({ + link_karma: nonNegativeInteger, + comment_karma: nonNegativeInteger, + }).required(), +}).required() + +module.exports = class RedditUserKarma extends BaseJsonService { + static get category() { + return 'social' + } + + static get route() { + return { + base: 'reddit/user-karma', + pattern: ':variant(link|comment|combined)/:user', + } + } + + static get examples() { + return [ + { + title: 'Reddit User Karma', + namedParams: { variant: 'combined', user: 'example' }, + staticPreview: { + label: 'combined karma', + message: 56, + color: 'red', + style: 'social', + }, + }, + ] + } + + static get defaultBadgeData() { + return { + label: 'reddit karma', + namedLogo: 'reddit', + } + } + + static render({ variant, karma, user }) { + const label = + variant === 'combined' + ? `u/${user} karma` + : `u/${user} karma (${variant})` + return { + label, + message: metric(karma), + color: 'red', + link: [`https://www.reddit.com/u/${user}`], + } + } + + async fetch({ user }) { + return this._requestJson({ + schema, + url: `https://www.reddit.com/u/${user}/about.json`, + errorMessages: { + 404: 'user not found', + }, + }) + } + + transform({ json, variant }) { + let karma + if (variant === 'link') { + karma = json.data.link_karma + } else if (variant === 'comment') { + karma = json.data.comment_karma + } else { + const total = json.data.link_karma + json.data.comment_karma + karma = total + } + + return { karma } + } + + async handle({ variant, user }) { + const json = await this.fetch({ user }) + const { karma } = this.transform({ json, variant }) + + return this.constructor.render({ + variant, + karma, + user, + }) + } +} diff --git a/services/reddit/user-karma.tester.js b/services/reddit/user-karma.tester.js new file mode 100644 index 0000000000..e02496e5f2 --- /dev/null +++ b/services/reddit/user-karma.tester.js @@ -0,0 +1,80 @@ +'use strict' + +const { isMetric } = require('../test-validators') +const t = (module.exports = require('../tester').createServiceTester()) + +t.create('user-karma (valid - link)') + .get('/link/user_simulator.json') + .expectBadge({ + label: 'u/user_simulator karma (link)', + message: isMetric, + }) + +t.create('user-karma (valid - comment') + .get('/comment/user_simulator.json') + .expectBadge({ + label: 'u/user_simulator karma (comment)', + message: isMetric, + }) + +t.create('user-karma (valid - combined)') + .get('/combined/user_simulator.json') + .expectBadge({ + label: 'u/user_simulator karma', + message: isMetric, + }) + +t.create('user-karma (non-existing user)') + .get('/combined/thisuserdoesnotexistandhopefullyneverwill.json') + .expectBadge({ + label: 'reddit karma', + message: 'user not found', + }) + +t.create('user-karma (link - math check)') + .get('/link/user_simulator.json') + .intercept(nock => + nock('https://www.reddit.com/u') + .get('/user_simulator/about.json') + .reply(200, { kind: 't2', data: { link_karma: 20, comment_karma: 80 } }) + ) + .expectBadge({ + label: 'u/user_simulator karma (link)', + message: '20', + }) + +t.create('user-karma (comment - math check)') + .get('/comment/user_simulator.json') + .intercept(nock => + nock('https://www.reddit.com/u') + .get('/user_simulator/about.json') + .reply(200, { kind: 't2', data: { link_karma: 20, comment_karma: 80 } }) + ) + .expectBadge({ + label: 'u/user_simulator karma (comment)', + message: '80', + }) + +t.create('user-karma (combined - math check)') + .get('/combined/user_simulator.json') + .intercept(nock => + nock('https://www.reddit.com/u') + .get('/user_simulator/about.json') + .reply(200, { kind: 't2', data: { link_karma: 20, comment_karma: 80 } }) + ) + .expectBadge({ + label: 'u/user_simulator karma', + message: '100', + }) + +t.create('user-karma (combined - missing data)') + .get('/combined/user_simulator.json') + .intercept(nock => + nock('https://www.reddit.com/u') + .get('/user_simulator/about.json') + .reply(200, { kind: 't2', data: { link_karma: 20 } }) + ) + .expectBadge({ + label: 'reddit karma', + message: 'invalid response data', + })