From cee1a4c084be35bb9a7517da5a3a02221c079f06 Mon Sep 17 00:00:00 2001 From: Edward Jones Date: Sat, 28 Apr 2018 19:33:18 +0100 Subject: [PATCH] Test emojiPrompt --- lib/harmony.js | 18 ++-- test/stubs/discord-stub.js | 8 ++ test/test-actions.js | 164 +++++++++++++++++++++++++++++++++++-- 3 files changed, 174 insertions(+), 16 deletions(-) diff --git a/lib/harmony.js b/lib/harmony.js index 87f8e29..ff6ef89 100644 --- a/lib/harmony.js +++ b/lib/harmony.js @@ -60,17 +60,19 @@ class Harmony { return formattedMessage; } - emojiPrompt(message, options, target) { + async emojiPrompt(message, options, target) { // TODO: work on messages when can't react - const filter = (reaction, user) => ((!target && user !== this.client.user) || user === target) && options.indexOf(reaction.emoji.name) >= 0; - let prompt = Promise.all([ + const filter = (reaction, user) => { + if (options.indexOf(reaction.emoji.name) < 0) return false; + if (target) return user === target; + return user !== this.client.user; + }; + let [reactions, response] = await Promise.all([ this.performReactions(message, options), message.awaitReactions(filter, { max: 1, time: 15000 }), - ]) - .then(([reactions, response]) => { - return Promise.all(reactions.map(x => x.remove())).then(_ => response); - }); - return prompt; + ]); + await Promise.all(reactions.map(x => x.remove())); + return response; } // returns a promised [addressesMe, optional text]: respectively, a boolean for if the text seems to address the bot, and the string of the relevant text diff --git a/test/stubs/discord-stub.js b/test/stubs/discord-stub.js index 4b4bdcc..717efcf 100644 --- a/test/stubs/discord-stub.js +++ b/test/stubs/discord-stub.js @@ -90,6 +90,14 @@ class MessageStub extends Discord.Message { this.embeds.push(embed); return embed; } + + newReaction(name, count, me) { + const emoji = new Discord.ReactionEmoji(null, name); + const reaction = new Discord.MessageReaction(this, emoji, count, me); + emoji.reaction = reaction; + this.reactions.set(reaction.id, reaction); + return reaction; + } } class DataManagerStub { diff --git a/test/test-actions.js b/test/test-actions.js index 29a8804..9770db7 100644 --- a/test/test-actions.js +++ b/test/test-actions.js @@ -28,7 +28,7 @@ describe('Harmony', function() { }); const messageReactStub = sinon.stub(); message.react = messageReactStub; - const reaction = new Discord.MessageReaction(message, '👍', 1, true); + const reaction = message.newReaction('👍', 1, true); messageReactStub.resolves(reaction); return bot.performReactions(message, ['👍']).then(reacts => { expect(reacts).to.deep.equal([reaction]); @@ -47,9 +47,9 @@ describe('Harmony', function() { }); const messageReactStub = sinon.stub(); message.react = messageReactStub; - const reaction1 = new Discord.MessageReaction(message, '👍', 1, true); - const reaction2 = new Discord.MessageReaction(message, '👎', 1, true); - const reaction3 = new Discord.MessageReaction(message, '❗', 1, true); + const reaction1 = message.newReaction('👍', 1, true); + const reaction2 = message.newReaction('👎', 1, true); + const reaction3 = message.newReaction('❗', 1, true); function quickPromise(count, reaction) { return new Promise(function(resolve) { @@ -82,10 +82,10 @@ describe('Harmony', function() { }); const messageReactStub = sinon.stub(); message.react = messageReactStub; - const reaction1 = new Discord.MessageReaction(message, '👍', 1, true); - const reaction2 = new Discord.MessageReaction(message, '👎', 1, true); - const removeStub1 = sinon.stub(reaction1, 'remove'); - const removeStub2 = sinon.stub(reaction2, 'remove'); + const reaction1 = message.newReaction('👍', 1, true); + const reaction2 = message.newReaction('👎', 1, true); + const removeStub1 = reaction1.remove = sinon.stub(); + const removeStub2 = reaction2.remove = sinon.stub(); removeStub1.resolves(reaction1); removeStub2.resolves(reaction2); @@ -178,5 +178,153 @@ describe('Harmony', function() { }); }); }); + + describe('emojiPrompt', function() { + beforeEach(function() { + this.message = this.bot.client.channel.newMessage({ + content: 'Message', + mentions: new Discord.Collection() + }); + }); + + it('offers reactions to press on message', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([]); + message.awaitReactions = sinon.stub().resolves(); + + await bot.emojiPrompt(message, reactionList); + + expect(bot.performReactions.callCount).to.equal(1); + }); + + it('returns selection', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([]); + message.awaitReactions = sinon.stub().resolves('test'); + + const resp = await bot.emojiPrompt(message, reactionList); + + expect(bot.performReactions.callCount).to.equal(1); + expect(message.awaitReactions.callCount).to.equal(1); + expect(resp).to.equal('test'); + }); + + it('removes own reactions on selection', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + const reaction1 = message.newReaction('✅', 1, true); + reaction1.remove = sinon.stub(); + + const reaction2 = message.newReaction('❎', 1, true); + reaction2.remove = sinon.stub(); + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([reaction1, reaction2]); + message.awaitReactions = sinon.stub().resolves(); + + await bot.emojiPrompt(message, reactionList); + + expect(bot.performReactions.callCount).to.equal(1); + expect(message.awaitReactions.callCount).to.equal(1); + expect(reaction1.remove.args).to.deep.equal([[]]); + expect(reaction2.remove.args).to.deep.equal([[]]); + }); + + it('awaits reactions correctly with no target', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + const reaction1 = message.newReaction('✅', 1, true); + const reaction2 = message.newReaction('❎', 1, true); + reaction1.remove = reaction2.remove = sinon.stub(); + + const botUser = bot.client.user; + const otherUser = bot.client.newUser(); + const otherUser2 = bot.client.newUser(); + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([reaction1, reaction2]); + message.awaitReactions = sinon.stub().callsFake(function(filter, opts) { + expect(opts).to.deep.equal({ max: 1, time: 15000 }); + expect(filter(reaction1, botUser)).to.equal(false); + expect(filter(reaction2, botUser)).to.equal(false); + + reaction1.count = 2; + expect(filter(reaction1, otherUser)).to.equal(true); + reaction1.count = 3; + expect(filter(reaction1, otherUser2)).to.equal(true); + + const lateBotReaction = message.newReaction('❓', 1, true); + const lateOtherReaction = message.newReaction('❗', 1, true); + expect(filter(lateBotReaction, botUser)).to.equal(false); + expect(filter(lateOtherReaction, otherUser)).to.equal(false); + return Promise.resolve(); + }); + + await bot.emojiPrompt(message, reactionList); + + expect(bot.performReactions.callCount).to.equal(1); + expect(message.awaitReactions.callCount).to.equal(1); + }); + + it('awaits reactions correctly with target', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + const reaction1 = message.newReaction('✅', 1, true); + const reaction2 = message.newReaction('❎', 1, true); + reaction1.remove = reaction2.remove = sinon.stub(); + + const botUser = bot.client.user; + const otherUser = bot.client.newUser(); + const otherUser2 = bot.client.newUser(); + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([reaction1, reaction2]); + message.awaitReactions = sinon.stub().callsFake(function(filter, opts) { + expect(opts).to.deep.equal({ max: 1, time: 15000 }); + expect(filter(reaction1, botUser)).to.equal(false); + expect(filter(reaction2, botUser)).to.equal(false); + + reaction1.count = 2; + expect(filter(reaction1, otherUser)).to.equal(true); + reaction1.count = 3; + expect(filter(reaction1, otherUser2)).to.equal(false); + return Promise.resolve(); + }); + + await bot.emojiPrompt(message, reactionList, otherUser); + + expect(bot.performReactions.callCount).to.equal(1); + expect(message.awaitReactions.callCount).to.equal(1); + }); + + it('does not perform extraneous actions', async function() { + const { bot, message } = this; + const reactionList = ['✅', '❎']; + + const reaction1 = message.newReaction('✅', 1, true); + reaction1.remove = sinon.stub(); + + const reaction2 = message.newReaction('❎', 1, true); + reaction2.remove = sinon.stub(); + + bot.performReactions = sinon.stub().withArgs(message, reactionList).resolves([reaction1, reaction2]); + message.awaitReactions = sinon.stub().resolves('test'); + + const resp = await bot.emojiPrompt(message, reactionList); + + expect(bot.performReactions.callCount).to.equal(1); + expect(message.awaitReactions.callCount).to.equal(1); + expect(resp).to.equal('test'); + expect(reaction1.remove.args).to.deep.equal([[]]); + expect(reaction2.remove.args).to.deep.equal([[]]); + + expect(bot.client.sendMessageStub.callCount).to.equal(0); + expect(bot.client.sendReactionStub.callCount).to.equal(0); + }); + }); }); });