import { expect } from "chai"; import { Collection, Constants, Guild, Message, MessageEmbed, MessageMentions, MessageReference } from "discord.js"; import { SinonSandbox, createSandbox } from "sinon"; import { BaseMocks, CustomMocks } from "@lambocreeper/mock-discord.js"; import EventHandler from "../../../src/abstracts/EventHandler"; import GhostPingHandler from "../../../src/event/handlers/GhostPingHandler"; describe("GhostPingHandler", () => { describe("constructor()", () => { it("creates a handler for MESSAGE_DELETE", () => { const handler = new GhostPingHandler(); expect(handler.getEvent()).to.equal(Constants.Events.MESSAGE_DELETE); }); }); describe("handle()", () => { let sandbox: SinonSandbox; let handler: EventHandler; beforeEach(() => { sandbox = createSandbox(); handler = new GhostPingHandler(); }); it("sends a message when a message is deleted that pinged a user", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); message.mentions = new MessageMentions(message, [CustomMocks.getUser({ id: "328194044587147278" })], [], false); message.content = "Hey <@328194044587147278>!"; await handler.handle(message); expect(messageMock.calledOnce).to.be.true; }); it("does not send a message when a message is deleted that didn't ping a user", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); message.mentions = new MessageMentions(message, [], [], false); message.content = "Hey everybody!"; await handler.handle(message); expect(messageMock.calledOnce).to.be.false; }); it("does not send a message when it's author is a bot", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); const author = BaseMocks.getUser(); author.bot = true; message.author = author; message.mentions = new MessageMentions(message, [BaseMocks.getUser()], [], false); message.content = "Hey <@328194044587147278>, stop spamming or we'll arrest you!"; await handler.handle(message); expect(messageMock.called).to.be.false; }); it("does not send a message when author only mentions himself", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); message.author = BaseMocks.getUser(); message.mentions = new MessageMentions(message, [CustomMocks.getUser()], [], false); message.content = `<@${message.author.id}>`; await handler.handle(message); expect(messageMock.called).to.be.false; }); it("sends a message when message author and someone else is being mentioned", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); const author = CustomMocks.getUser(); message.author = author; message.mentions = new MessageMentions(message, [author, CustomMocks.getUser({ id: "328194044587147278" })], [], false); message.content = `<@${message.author.id}> <@328194044587147278>`; await handler.handle(message); expect(messageMock.called).to.be.true; }); it("provides additional info if message is a reply to another message", async () => { const message = CustomMocks.getMessage({guild: CustomMocks.getGuild()}); const messageMock = sandbox.stub(message.channel, "send"); const channelMock = CustomMocks.getTextChannel(); const repliedToMessage = CustomMocks.getMessage({ id: "328194044587147280", guild: CustomMocks.getGuild()}, { channel: CustomMocks.getTextChannel({ id: "328194044587147278"}) }); const resolveChannelStub = sandbox.stub(message.guild.channels, "resolve").returns(channelMock); const fetchMessageStub = sandbox.stub(channelMock.messages, "fetch").returns(Promise.resolve(repliedToMessage)); const author = CustomMocks.getUser(); message.author = author; message.mentions = new MessageMentions(message, [CustomMocks.getUser({ id: "328194044587147278" })], [], false); message.guild.id = "328194044587147279"; message.content = "this is a reply"; message.reference = { channelId: "328194044587147278", guildId: "328194044587147279", messageId: "328194044587147280" }; await handler.handle(message); expect(messageMock.called).to.be.true; expect(resolveChannelStub.called).to.be.true; expect(fetchMessageStub.called).to.be.true; const sentEmbed = messageMock.getCall(0).args[0].embeds[0]; expect(sentEmbed).to.be.an.instanceOf(MessageEmbed); if (sentEmbed instanceof MessageEmbed) { const replyToField = sentEmbed.fields.find(field => field.name === "Reply to"); expect(replyToField).to.not.be.null; const messageLinkField = sentEmbed.fields.find(field => field.name === "Message replied to"); expect(messageLinkField).to.not.be.null; expect(messageLinkField.value).to.equal("https://discord.com/channels/328194044587147279/328194044587147278/328194044587147280"); } }); it("does not send a message when author only mentions himself and bots", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); const botUser = CustomMocks.getUser({id: "328194044587147278"}); botUser.bot = true; message.author = BaseMocks.getUser(); message.mentions = new MessageMentions(message, [message.author, botUser], [], false); message.content = `<@${message.author.id}> <@${botUser.id}>`; await handler.handle(message); expect(messageMock.called).to.be.false; }); it("does not send a message when author only mentions bots", async () => { const message = CustomMocks.getMessage(); const messageMock = sandbox.stub(message.channel, "send"); const botUser = CustomMocks.getUser({id: "328194044587147278"}); const botUser2 = CustomMocks.getUser({id: "328194044587147279"}); botUser.bot = true; botUser2.bot = true; message.author = BaseMocks.getUser(); message.mentions = new MessageMentions(message, [botUser, botUser2], [], false); message.content = `<@${botUser.id}> <@${botUser2.id}>`; await handler.handle(message); expect(messageMock.called).to.be.false; }); it("does not send a message when author replies to a bot", async () => { const message = CustomMocks.getMessage({guild: CustomMocks.getGuild()}); const messageMock = sandbox.stub(message.channel, "send"); const channelMock = CustomMocks.getTextChannel(); const repliedToMessage = CustomMocks.getMessage({ id: "328194044587147280", guild: CustomMocks.getGuild() }, { channel: CustomMocks.getTextChannel({ id: "328194044587147278"}) }); const resolveChannelStub = sandbox.stub(message.guild.channels, "resolve").returns(channelMock); const fetchMessageStub = sandbox.stub(channelMock.messages, "fetch").returns(Promise.resolve(repliedToMessage)); const author = BaseMocks.getUser(); const botUser = CustomMocks.getUser({id: "328194044587147276"}); botUser.bot = true; message.author = author; message.mentions = new MessageMentions(message, [botUser], [], false); message.guild.id = "328194044587147279"; message.content = "this is a reply"; message.reference = { channelId: "328194044587147278", guildId: "328194044587147279", messageId: "328194044587147280" }; await handler.handle(message); expect(messageMock.called).to.be.false; expect(resolveChannelStub.called).to.be.false; expect(fetchMessageStub.called).to.be.false; }); afterEach(() => { sandbox.restore(); }); }); });