From 06ac40a6d7d2b0f32fcaa98744e70e9ba7041868 Mon Sep 17 00:00:00 2001 From: Luis Bauza Date: Thu, 25 Dec 2025 10:28:44 -0500 Subject: [PATCH] refactor: update command tests to use require syntax and improve error handling --- __tests__/commands/ask.test.js | 16 ++++++++-------- __tests__/commands/help.test.js | 3 ++- __tests__/commands/kick.test.js | 18 ++++++++++-------- __tests__/commands/ping.test.js | 5 +++-- __tests__/commands/prune.test.js | 7 ++++--- jest.config.js | 3 +++ utils/command.js | 6 +++--- 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/__tests__/commands/ask.test.js b/__tests__/commands/ask.test.js index 773a5da..f3c9736 100644 --- a/__tests__/commands/ask.test.js +++ b/__tests__/commands/ask.test.js @@ -1,14 +1,16 @@ -import { jest } from '@jest/globals'; +const { createMockInteraction } = require('../utils/testUtils'); // Mock axios -jest.unstable_mockModule('axios', () => ({ +jest.mock('axios', () => ({ + __esModule: true, default: { post: jest.fn(), }, })); +const axios = require('axios').default; -// Mock the discord.js module -jest.unstable_mockModule('discord.js', () => ({ +// Mock discord.js +jest.mock('discord.js', () => ({ SlashCommandBuilder: jest.fn().mockReturnValue({ setName: jest.fn().mockReturnThis(), setDescription: jest.fn().mockReturnThis(), @@ -38,9 +40,7 @@ jest.unstable_mockModule('discord.js', () => ({ }), })); -const axios = (await import('axios')).default; -const { createMockInteraction } = await import('../utils/testUtils.js'); -const AskCommand = (await import('../../commands/ask.js')).default; +const AskCommand = require('../../commands/ask').default; const askCommand = new AskCommand(); describe('Ask Command', () => { @@ -258,4 +258,4 @@ describe('Ask Command', () => { await expect(askCommand.run(interaction)).rejects.toThrow('Failed to follow up'); }); }); -}); +}); \ No newline at end of file diff --git a/__tests__/commands/help.test.js b/__tests__/commands/help.test.js index 0b073cc..4f57403 100644 --- a/__tests__/commands/help.test.js +++ b/__tests__/commands/help.test.js @@ -19,7 +19,8 @@ jest.mock('discord.js', () => ({ }), })); -const helpCommand = require('../../commands/help'); +const HelpCommand = require('../../commands/help').default; +const helpCommand = new HelpCommand(); describe('Help Command', () => { describe('Command Structure', () => { diff --git a/__tests__/commands/kick.test.js b/__tests__/commands/kick.test.js index 6aec8b2..c422379 100644 --- a/__tests__/commands/kick.test.js +++ b/__tests__/commands/kick.test.js @@ -13,12 +13,13 @@ jest.mock('discord.js', () => ({ }; callback(option); return { - addStringOption: jest.fn().mockImplementation(callback => { - const option = { + addStringOption: jest.fn().mockImplementation(cb => { + const strOption = { setName: jest.fn().mockReturnThis(), setDescription: jest.fn().mockReturnThis(), + setRequired: jest.fn().mockReturnThis(), }; - callback(option); + cb(strOption); return { setDefaultMemberPermissions: jest.fn().mockReturnThis(), toJSON: jest.fn().mockReturnValue({ @@ -46,11 +47,12 @@ jest.mock('discord.js', () => ({ toJSON: jest.fn(), }), PermissionFlagsBits: { - KickMembers: 0x2n, + KickMembers: 0x0000000000000002n, }, })); -const kickCommand = require('../../commands/kick'); +const KickCommand = require('../../commands/kick').default; +const kickCommand = new KickCommand(); describe('Kick Command', () => { describe('Command Structure', () => { @@ -152,7 +154,7 @@ describe('Kick Command', () => { expect(mockKick).not.toHaveBeenCalled(); expect(interaction.reply).toHaveBeenCalledWith({ - content: 'That user is not in this server!', + content: 'Command failed: That user is not in this server!', ephemeral: true, }); }); @@ -173,7 +175,7 @@ describe('Kick Command', () => { expect(mockKick).not.toHaveBeenCalled(); expect(interaction.reply).toHaveBeenCalledWith({ content: - 'I cannot kick this user! They may have higher permissions than me.', + 'Command failed: I cannot kick this user! They may have higher permissions than me.', ephemeral: true, }); }); @@ -195,7 +197,7 @@ describe('Kick Command', () => { await kickCommand.execute(interaction); expect(interaction.reply).toHaveBeenCalledWith({ - content: 'There was an error trying to kick this user!', + content: 'Command failed: Failed to kick user', ephemeral: true, }); }); diff --git a/__tests__/commands/ping.test.js b/__tests__/commands/ping.test.js index 60a656e..13f66e2 100644 --- a/__tests__/commands/ping.test.js +++ b/__tests__/commands/ping.test.js @@ -12,7 +12,8 @@ jest.mock('discord.js', () => ({ }), })); -const pingCommand = require('../../commands/ping'); +const PingCommand = require('../../commands/ping').default; +const pingCommand = new PingCommand(); describe('Ping Command', () => { describe('Command Structure', () => { @@ -47,7 +48,7 @@ describe('Ping Command', () => { it('should handle interaction reply failure', async () => { // Mock a failed reply - interaction.reply.mockRejectedValueOnce(new Error('Failed to reply')); + interaction.reply.mockRejectedValue(new Error('Failed to reply')); await expect(pingCommand.execute(interaction)).rejects.toThrow( 'Failed to reply', diff --git a/__tests__/commands/prune.test.js b/__tests__/commands/prune.test.js index 9755108..a0bb3a2 100644 --- a/__tests__/commands/prune.test.js +++ b/__tests__/commands/prune.test.js @@ -39,7 +39,8 @@ jest.mock('discord.js', () => ({ }, })); -const pruneCommand = require('../../commands/prune'); +const PruneCommand = require('../../commands/prune').default; +const pruneCommand = new PruneCommand(); describe('Prune Command', () => { describe('Command Structure', () => { @@ -103,7 +104,7 @@ describe('Prune Command', () => { await pruneCommand.execute(interaction); expect(interaction.reply).toHaveBeenCalledWith({ - content: 'There was an error trying to prune messages in this channel!', + content: 'Command failed: Failed to delete messages', ephemeral: true, }); }); @@ -116,7 +117,7 @@ describe('Prune Command', () => { await pruneCommand.execute(interaction); expect(interaction.reply).toHaveBeenCalledWith({ - content: 'There was an error trying to prune messages in this channel!', + content: 'Command failed: Messages older than 14 days cannot be deleted', ephemeral: true, }); }); diff --git a/jest.config.js b/jest.config.js index 6826768..2a65061 100644 --- a/jest.config.js +++ b/jest.config.js @@ -23,6 +23,9 @@ export default { '^.+\\.jsx?$': 'babel-jest', }, + // Ignore node_modules except for chalk (which is ESM only) + transformIgnorePatterns: ['/node_modules/(?!(chalk)/)'], + // An array of regexp pattern strings that are matched against all test files testPathIgnorePatterns: ['/node_modules/'], }; diff --git a/utils/command.js b/utils/command.js index 40ed4e3..1bc3a90 100644 --- a/utils/command.js +++ b/utils/command.js @@ -34,7 +34,7 @@ export default class Command { this._logger.info(`Executing command: ${interaction.commandName}`); await this.run(interaction); } catch (error) { - this.handleError(interaction, error); + await this.handleError(interaction, error); } } @@ -44,13 +44,13 @@ export default class Command { } // Standardized error handling - handleError(interaction, error) { + async handleError(interaction, error) { this._logger.error(`Command ${interaction.commandName} failed:`, error); const response = interaction.deferred ? 'followUp' : 'reply'; const errorMessage = this.getErrorMessage(error); - interaction[response]({ + await interaction[response]({ content: errorMessage, ephemeral: true, });