From 67fbc8e2677bfcc97bf0ee277a3b2e718c96e708 Mon Sep 17 00:00:00 2001 From: Calvin Montgomery Date: Sat, 6 Jan 2018 10:31:59 -0800 Subject: [PATCH] Add more information to the voteskip passed log message --- src/channel/voteskip.js | 37 ++++++++++++++++++------------- test/channel/voteskip.js | 47 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/channel/voteskip.js b/src/channel/voteskip.js index 445fe79f..374641f8 100644 --- a/src/channel/voteskip.js +++ b/src/channel/voteskip.js @@ -75,10 +75,14 @@ VoteskipModule.prototype.update = function () { return; } - var max = this.calcVoteskipMax(); - var need = Math.ceil(max * this.channel.modules.options.get("voteskip_ratio")); + const { total, eligible, noPermission, afk } = this.calcUsercounts(); + const need = Math.ceil(eligible * this.channel.modules.options.get("voteskip_ratio")); if (this.poll.counts[0] >= need) { - this.channel.logger.log("[playlist] Voteskip passed."); + const info = `${this.poll.counts[0]}/${eligible} skipped; ` + + `eligible voters: ${eligible} = total (${total}) - AFK (${afk}) ` + + `- no permission (${noPermission}); ` + + `ratio = ${this.channel.modules.options.get("voteskip_ratio")}`; + this.channel.logger.log(`[playlist] Voteskip passed: ${info}`); this.reset(); this.channel.modules.playlist._playNext(); } else { @@ -87,10 +91,10 @@ VoteskipModule.prototype.update = function () { }; VoteskipModule.prototype.sendVoteskipData = function (users) { - var max = this.calcVoteskipMax(); + const { eligible } = this.calcUsercounts(); var data = { count: this.poll ? this.poll.counts[0] : 0, - need: this.poll ? Math.ceil(max * this.channel.modules.options.get("voteskip_ratio")) + need: this.poll ? Math.ceil(eligible * this.channel.modules.options.get("voteskip_ratio")) : 0 }; @@ -103,17 +107,20 @@ VoteskipModule.prototype.sendVoteskipData = function (users) { }); }; -VoteskipModule.prototype.calcVoteskipMax = function () { - var perms = this.channel.modules.permissions; - return this.channel.users.map(function (u) { - if (!perms.canVoteskip(u)) { - return 0; - } +VoteskipModule.prototype.calcUsercounts = function () { + const perms = this.channel.modules.permissions; + const counts = { total: 0, noPermission: 0, afk: 0 }; - return u.is(Flags.U_AFK) ? 0 : 1; - }).reduce(function (a, b) { - return a + b; - }, 0); + this.channel.users.forEach(u => { + counts.total++; + + if (!perms.canVoteskip(u)) counts.noPermission++; + else if (u.is(Flags.U_AFK)) counts.afk++; + }); + + counts.eligible = counts.total - (counts.noPermission + counts.afk); + + return counts; }; VoteskipModule.prototype.reset = function reset() { diff --git a/test/channel/voteskip.js b/test/channel/voteskip.js index 17f6f004..02997306 100644 --- a/test/channel/voteskip.js +++ b/test/channel/voteskip.js @@ -1,9 +1,14 @@ const VoteskipModule = require('../../lib/channel/voteskip'); const assert = require('assert'); +const Flags = require('../../lib/flags'); describe('VoteskipModule', () => { - describe('#update', () => { - let fakeUser = { + let fakeUser; + let fakeChannel; + let voteskipModule; + + beforeEach(() => { + fakeUser = { socket: { emit() { @@ -13,7 +18,7 @@ describe('VoteskipModule', () => { return false } }; - let fakeChannel = { + fakeChannel = { logger: { log() { @@ -46,8 +51,10 @@ describe('VoteskipModule', () => { users: [fakeUser] }; - let voteskipModule = new VoteskipModule(fakeChannel); + voteskipModule = new VoteskipModule(fakeChannel); + }); + describe('#update', () => { it('resets the vote before changing to the next video', () => { let reset = false, playNext = false; fakeChannel.modules.playlist._playNext = () => { @@ -73,4 +80,36 @@ describe('VoteskipModule', () => { assert(playNext, 'Expected playlist to be advanced'); }); }); + + describe('#calcUsercounts', () => { + it('calculates correctly', () => { + fakeChannel.users = [ + // 1 with permission and not AFK + { is(f) { return false; }, _has_permission: true }, + // 1 without permission and not AFK + { is(f) { return false; }, _has_permission: false }, + // 1 afk with permission + { is(f) { return f === Flags.U_AFK; }, _has_permission: true }, + // 1 afk without permission + { is(f) { return f === Flags.U_AFK; }, _has_permission: false } + ] + + fakeChannel.modules.permissions.canVoteskip = u => u._has_permission; + + const { + total, + eligible, + afk, + noPermission + } = voteskipModule.calcUsercounts(); + + assert.strictEqual(total, 4, 'mismatch: total'); + assert.strictEqual(eligible, 1, 'mismatch: eligible'); + // Permission is checked before AFK; if user is AFK and also does + // not have permission, they should be counted in noPermission + // but not afk + assert.strictEqual(afk, 1, 'mismatch: afk'); + assert.strictEqual(noPermission, 2, 'mismatch: noPermission'); + }); + }); });