From d097181a8dbaeaf96e34290b309af30688b7c6bc Mon Sep 17 00:00:00 2001 From: LamboCreeper <12111454+LamboCreeper@users.noreply.github.com> Date: Sun, 19 May 2024 12:25:11 +0100 Subject: [PATCH] Add handler which sends a log when a user recieves or loses the regular role --- .../handlers/RegularMemberChangesHandler.ts | 45 ++++++ .../RegularMemberChangesHandlerTest.ts | 139 ++++++++++++++++++ 2 files changed, 184 insertions(+) diff --git a/src/event/handlers/RegularMemberChangesHandler.ts b/src/event/handlers/RegularMemberChangesHandler.ts index e69de29b..44006538 100644 --- a/src/event/handlers/RegularMemberChangesHandler.ts +++ b/src/event/handlers/RegularMemberChangesHandler.ts @@ -0,0 +1,45 @@ +import { EmbedBuilder, Events, GuildMember, TextChannel } from "discord.js"; +import EventHandler from "../../abstracts/EventHandler"; +import getConfigValue from "../../utils/getConfigValue"; + +class RegularMemberChangesHandler extends EventHandler { + constructor() { + super(Events.GuildMemberUpdate); + } + + async handle(oldMember: GuildMember, newMember: GuildMember) { + if (oldMember.roles.cache.size === newMember.roles.cache.size) { + return; + } + + const roleId = getConfigValue("REGULAR_ROLE"); + const hadRoleBefore = oldMember.roles.cache.has(roleId); + const hasRoleNow = newMember.roles.cache.has(roleId); + + if ((hadRoleBefore && hasRoleNow) || (!hadRoleBefore && !hasRoleNow)) { + return; + } + + const channelId = getConfigValue("REGULAR_ROLE_CHANGE_CHANNEL"); + const logChannel = await newMember.guild.channels.fetch(channelId) as TextChannel; + + const embed = new EmbedBuilder(); + + embed.setThumbnail(newMember.user.avatarURL()); + embed.setDescription(`<@${newMember.user.id}>`); + + if (hadRoleBefore && !hasRoleNow) { + embed.setTitle("No Longer Regular"); + embed.setColor("#F71313"); + } + + if (!hadRoleBefore && hasRoleNow) { + embed.setTitle("New Regular Member"); + embed.setColor("#6CEF0E") + } + + logChannel?.send({ embeds: [embed] }); + } +} + +export default RegularMemberChangesHandler; diff --git a/test/event/handlers/RegularMemberChangesHandlerTest.ts b/test/event/handlers/RegularMemberChangesHandlerTest.ts index e69de29b..320e72c6 100644 --- a/test/event/handlers/RegularMemberChangesHandlerTest.ts +++ b/test/event/handlers/RegularMemberChangesHandlerTest.ts @@ -0,0 +1,139 @@ +import { expect } from "chai"; +import { + Collection, + Events, + GuildMember, + Role, +} from "discord.js"; +import { createSandbox, SinonSandbox } from "sinon"; +import { BaseMocks, CustomMocks } from "@lambocreeper/mock-discord.js"; +import RegularMemberChangesHandler from "../../../src/event/handlers/RegularMemberChangesHandler"; +import EventHandler from "../../../src/abstracts/EventHandler"; + +describe("RegularMemberChangesHandler", () => { + describe("constructor()", () => { + it("creates a handler for GuildMemberUpdate", () => { + const handler = new RegularMemberChangesHandler(); + + expect(handler.getEvent()).to.equal(Events.GuildMemberUpdate); + }); + }); + + describe("handle()", () => { + let sandbox: SinonSandbox; + let handler: EventHandler; + let oldMember: GuildMember; + let newMember: GuildMember; + + beforeEach(() => { + sandbox = createSandbox(); + handler = new RegularMemberChangesHandler(); + oldMember = BaseMocks.getGuildMember(); + newMember = CustomMocks.getGuildMember(); + }); + + afterEach(() => sandbox.restore()); + + it("does nothing if the user's roles have not changed", async () => { + const getChannelSpy = sandbox.spy(newMember.guild.channels, "fetch"); + + sandbox.stub(oldMember, "roles").get(() => ({ + cache: new Collection() + })); + + sandbox.stub(newMember, "roles").get(() => ({ + cache: new Collection() + })); + + await handler.handle(oldMember, newMember); + + expect(getChannelSpy.called).to.be.false; + }); + + it("sends a message saying the user has the role, if they now have it", async () => { + const channel = BaseMocks.getTextChannel() + const sendMessageSpy = sandbox.stub(channel, "send").resolves(); + + // @ts-ignore + const getChannelSpy = sandbox.stub(newMember.guild.channels, "fetch").resolves(channel); + + sandbox.stub(oldMember, "roles").get(() => ({ + cache: new Collection() + })); + + sandbox.stub(newMember, "roles").get(() => ({ + cache: new Collection([ + [ + "700614448846733402", + Reflect.construct(Role, + [ + BaseMocks.getClient(), + { + id: "700614448846733402", + name: "Regular" + }, + BaseMocks.getGuild() + ] + ) + ] + ]) + })); + + await handler.handle(oldMember, newMember); + + expect(getChannelSpy.called).to.be.true; + expect(sendMessageSpy.called).to.be.true; + + const embed = sendMessageSpy.getCall(0).firstArg.embeds[0]; + + + expect(embed.data.title).to.equal("New Regular Member"); + expect(embed.data.color).to.equal(7139086); + expect(embed.data.thumbnail.url).to.equal(newMember.user.avatar); + expect(embed.data.description).to.equal(`<@${newMember.user.id}>`); + }); + + it("sends a message saying the user does not have the role, if they no longer have it", async () => { + const channel = BaseMocks.getTextChannel() + const sendMessageSpy = sandbox.stub(channel, "send").resolves(); + + // @ts-ignore + const getChannelSpy = sandbox.stub(newMember.guild.channels, "fetch").resolves(channel); + + sandbox.stub(oldMember, "roles").get(() => ({ + cache: new Collection([ + [ + "700614448846733402", + Reflect.construct(Role, + [ + BaseMocks.getClient(), + { + id: "700614448846733402", + name: "Regular" + }, + BaseMocks.getGuild() + ] + ) + ] + ]) + })); + + sandbox.stub(newMember, "roles").get(() => ({ + cache: new Collection() + })); + + await handler.handle(oldMember, newMember); + + expect(getChannelSpy.called).to.be.true; + expect(sendMessageSpy.called).to.be.true; + + const embed = sendMessageSpy.getCall(0).firstArg.embeds[0]; + + + expect(embed.data.title).to.equal("No Longer Regular"); + expect(embed.data.color).to.equal(16192275); + expect(embed.data.thumbnail.url).to.equal(newMember.user.avatar); + expect(embed.data.description).to.equal(`<@${newMember.user.id}>`); + }); + }); +});