From 42ec4a99dbcb69abcb71094aed3fc87e6e0cc85c Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Fri, 28 Jun 2024 18:21:28 +0100 Subject: [PATCH] WIP: Start of warn command tests --- .../commands/__snapshots__/warn.test.ts.snap | 38 ++++++ tests/commands/timeout.test.ts | 10 +- tests/commands/warn.test.ts | 117 +++++++++++++++++- 3 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 tests/commands/__snapshots__/warn.test.ts.snap diff --git a/tests/commands/__snapshots__/warn.test.ts.snap b/tests/commands/__snapshots__/warn.test.ts.snap new file mode 100644 index 0000000..c6685d0 --- /dev/null +++ b/tests/commands/__snapshots__/warn.test.ts.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Execute EXPECT user to be warned 1`] = ` +[ + { + "color": 3166394, + "description": "<@userId> \`userTag\`", + "fields": [ + { + "name": "Moderator", + "value": "<@moderatorId>", + }, + { + "name": "Reason", + "value": "Test reason", + }, + ], + "thumbnail": { + "url": "https://google.com/avatar.png", + }, + "title": "Member Warned", + }, +] +`; + +exports[`Execute EXPECT user to be warned 2`] = ` +{ + "AuditId": Any, + "AuditType": 1, + "Id": Any, + "ModeratorId": "moderatorId", + "Reason": "Test reason", + "ServerId": "guildId", + "UserId": "userId", + "WhenCreated": Any, + "WhenUpdated": Any, +} +`; diff --git a/tests/commands/timeout.test.ts b/tests/commands/timeout.test.ts index b8037c6..9bb7ad1 100644 --- a/tests/commands/timeout.test.ts +++ b/tests/commands/timeout.test.ts @@ -44,8 +44,8 @@ describe('execute', () => { const timeoutFunc = jest.fn(); - let dmChannelSentEmbeds: (APIEmbed | JSONEncodable)[] | undefined; - let logsChannelSentEmbeds: (APIEmbed | JSONEncodable)[] | undefined; + let dmChannelSentEmbeds: readonly (APIEmbed | JSONEncodable)[] | undefined; + let logsChannelSentEmbeds: readonly (APIEmbed | JSONEncodable)[] | undefined; const dmChannel = { send: jest.fn().mockImplementation((options: MessageCreateOptions) => { @@ -697,8 +697,8 @@ describe('execute', () => { const timeoutFunc = jest.fn(); - let dmChannelSentEmbeds: (APIEmbed | JSONEncodable)[] | undefined; - let logsChannelSentEmbeds: (APIEmbed | JSONEncodable)[] | undefined; + let dmChannelSentEmbeds: readonly (APIEmbed | JSONEncodable)[] | undefined; + let logsChannelSentEmbeds: readonly (APIEmbed | JSONEncodable)[] | undefined; const dmChannel = { send: jest.fn().mockImplementation((options: MessageCreateOptions) => { @@ -771,4 +771,4 @@ describe('execute', () => { expect(resultEmbedDMField.name).toBe("DM Sent"); expect(resultEmbedDMField.value).toBe("false"); }); -}); \ No newline at end of file +}); diff --git a/tests/commands/warn.test.ts b/tests/commands/warn.test.ts index edaca28..32d1eff 100644 --- a/tests/commands/warn.test.ts +++ b/tests/commands/warn.test.ts @@ -1,13 +1,124 @@ +import {APIEmbed, APIEmbedField, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, SlashCommandStringOption, SlashCommandUserOption, TextChannel} from "discord.js"; +import Warn from "../../src/commands/warn"; +import SettingsHelper from "../../src/helpers/SettingsHelper"; +import EmbedColours from "../../src/constants/EmbedColours"; +import Audit from "../../src/database/entities/Audit"; +import {AuditType} from "../../src/constants/AuditType"; + beforeEach(() => { process.env = {}; }); describe('Constructor', () => { - test.todo('EXPECT values to be set'); + test('EXPECT values to be set', () => { + const command = new Warn(); + + expect(command.CommandBuilder).toBeDefined(); + + const commandBuilder = command.CommandBuilder as SlashCommandBuilder; + + expect(commandBuilder.name).toBe("warn"); + expect(commandBuilder.description).toBe("Warns a member in the server with an optional reason") + expect(commandBuilder.default_member_permissions).toBe(PermissionsBitField.Flags.ModerateMembers.toString()); + expect(commandBuilder.options.length).toBe(2); + + const commandBuilderUserOption = commandBuilder.options[0] as SlashCommandUserOption; + + expect(commandBuilderUserOption.name).toBe("target"); + expect(commandBuilderUserOption.description).toBe("The user"); + expect(commandBuilderUserOption.required).toBe(true); + + const commandBuilderReasonOption = commandBuilder.options[1] as SlashCommandStringOption; + + expect(commandBuilderReasonOption.name).toBe("reason"); + expect(commandBuilderReasonOption.description).toBe("The reason"); + }); }); describe('Execute', () => { - test.todo("EXPECT user to be warned"); + test("EXPECT user to be warned", async () => { + let sentEmbeds: EmbedBuilder[] | undefined; + let savedAudit: Audit | undefined; + + // Arrange + const targetUser = { + user: { + id: "userId", + tag: "userTag", + avatarURL: jest.fn().mockReturnValue("https://google.com/avatar.png"), + }, + member: {}, + }; + + const reason = { + value: "Test reason", + }; + + const logChannel = { + send: jest.fn().mockImplementation((opts: any) => { + sentEmbeds = opts.embeds; + }), + } as unknown as TextChannel; + + const interaction = { + reply: jest.fn(), + options: { + get: jest.fn() + .mockReturnValueOnce(targetUser) + .mockReturnValue(reason), + }, + guild: { + channels: { + cache: { + find: jest.fn().mockReturnValue(logChannel), + }, + }, + }, + guildId: "guildId", + user: { + id: "moderatorId", + }, + } as unknown as CommandInteraction; + + SettingsHelper.GetSetting = jest.fn().mockResolvedValue("mod-logs"); + + Audit.prototype.Save = jest.fn().mockImplementation((_, audit: Audit) => { + savedAudit = audit; + }); + + // Act + const command = new Warn(); + await command.execute(interaction); + + // Assert + expect(interaction.reply).toHaveBeenCalledTimes(1); + expect(interaction.reply).toHaveBeenCalledWith("Successfully warned user."); + + expect(interaction.options.get).toHaveBeenCalledTimes(2); + expect(interaction.options.get).toHaveBeenCalledWith("target"); + expect(interaction.options.get).toHaveBeenCalledWith("reason"); + + expect(interaction.guild!.channels.cache.find).toHaveBeenCalledTimes(1); + + expect(SettingsHelper.GetSetting).toHaveBeenCalledTimes(1); + expect(SettingsHelper.GetSetting).toHaveBeenCalledWith("channels.logs.mod", "guildId"); + + expect(targetUser.user.avatarURL).toHaveBeenCalledTimes(1); + + expect(logChannel.send).toHaveBeenCalledTimes(1); + + expect(sentEmbeds).toBeDefined(); + expect(sentEmbeds).toMatchSnapshot(); + + expect(Audit.prototype.Save).toHaveBeenCalledWith(Audit, expect.any(Audit)); + + expect(savedAudit).toMatchSnapshot({ + Id: expect.any(String), + AuditId: expect.any(String), + WhenCreated: expect.any(Date), + WhenUpdated: expect.any(Date) + }); + }); test.todo("GIVEN interaction.guild is null, EXPECT nothing to happen"); @@ -26,4 +137,4 @@ describe('Execute', () => { test.todo("GIVEN channels.logs.mod setting is not found, EXPECT command to return"); test.todo("GIVEN channel is not found, EXPECT logEmbed to not be sent"); -}); \ No newline at end of file +});