Skip to content

Commit

Permalink
Merge pull request #29 from moonstar-x/defer-removal
Browse files Browse the repository at this point in the history
Removed deferred replies.
  • Loading branch information
moonstar-x authored Nov 20, 2024
2 parents 8832230 + 3b3dcae commit 0d0ea2d
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 89 deletions.
23 changes: 23 additions & 0 deletions src/base/presence/PresenceManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ describe('Base > Presence > PresenceManager', () => {
expect(clearIntervalSpy).toHaveBeenCalledWith(oldHandle);
expect((manager as unknown as { intervalHandle: number }).intervalHandle).not.toBe(oldHandle);
});

it('should call manager.update on an interval.', async () => {
jest.useFakeTimers();
const updateSpy = jest.spyOn(manager, 'update');
updateSpy.mockImplementation(() => Promise.resolve());

await manager.setRefreshInterval(1000);
jest.advanceTimersByTime(3000);

expect(manager.update).toHaveBeenCalled();
jest.clearAllTimers();
jest.useRealTimers();
});
});

describe('setPresence()', () => {
Expand All @@ -117,6 +130,16 @@ describe('Base > Presence > PresenceManager', () => {
expect(logger.info).toHaveBeenCalledWith('Presence changed to: something');
});

it('should log presence change even if no user exists.', () => {
const oldUser = client.user;
client.user = null;

manager.setPresence('something');
expect(logger.info).toHaveBeenCalledWith('Presence changed to: something');

client.user = oldUser;
});

it('should log error if presence change fails.', () => {
const expectedError = new Error('Oops');
(client.user!.setPresence as jest.Mock).mockImplementationOnce(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/base/presence/PresenceResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class PresenceResolver {
case 'uptime':
return this.getUptime();
default:
throw new Error('Invalid presence name provided.');
return Promise.resolve('');
}
}

Expand Down
54 changes: 18 additions & 36 deletions src/commands/ConfigureCommand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ describe('Commands > ConfigureCommand', () => {

describe('runChannel()', () => {
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
locale: 'en-US',
guildId: '1267881983548063785',
options: {
Expand All @@ -64,16 +63,11 @@ describe('Commands > ConfigureCommand', () => {
}
} as unknown as GuildChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with pre check message if no channel is provided.', async () => {
(interaction.options.getChannel as jest.Mock).mockReturnValueOnce(null);
await command.run(interaction);

expect(interaction.editReply).toHaveBeenCalledWith({ content: 'No channel provided.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'No channel provided.' });
});

it('should update guild channel.', async () => {
Expand All @@ -83,7 +77,7 @@ describe('Commands > ConfigureCommand', () => {

it('should reply with channel update message.', async () => {
await command.run(interaction);
expect(interaction.editReply).toHaveBeenCalledWith({ content: 'Successfully updated notifications channel to Channel.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'Successfully updated notifications channel to Channel.' });
});
});

Expand All @@ -93,34 +87,34 @@ describe('Commands > ConfigureCommand', () => {
update: jest.fn().mockImplementation(() => Promise.resolve())
};
const followUpResponseMock = {
awaitMessageComponent: jest.fn().mockResolvedValue(userResponseMock)
awaitMessageComponent: jest.fn().mockImplementation(({ filter }) => {
filter({ user: { id: 1 }, customId: 'configure-storefronts-enable' });
return userResponseMock;
})
};
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
followUp: jest.fn().mockResolvedValue(followUpResponseMock),
locale: 'en-US',
guildId: '1267881983548063785',
options: {
getSubcommand: jest.fn().mockReturnValue('storefronts')
},
user: {
id: 1
}
} as unknown as GuildChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with empty storefronts message if no storefronts exist.', async () => {
(getStorefronts as jest.Mock).mockResolvedValueOnce([]);
await command.run(interaction);

expect(interaction.editReply).toHaveBeenCalledWith({ content: 'No storefronts are available right now.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'No storefronts are available right now.' });
});

it('should reply with start message.', async () => {
await command.run(interaction);
expect(interaction.editReply).toHaveBeenCalledWith({ content: 'You will receive a follow up for each storefront available. Please, click on the buttons as they appear to enable or disable notifications for each storefront.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'You will receive a follow up for each storefront available. Please, click on the buttons as they appear to enable or disable notifications for each storefront.' });
});

it('should send follow up with correct components for each storefront.', async () => {
Expand Down Expand Up @@ -181,8 +175,7 @@ describe('Commands > ConfigureCommand', () => {

describe('runLanguage()', () => {
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
locale: 'en-US',
guildId: '1267881983548063785',
options: {
Expand All @@ -191,16 +184,11 @@ describe('Commands > ConfigureCommand', () => {
}
} as unknown as GuildChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with pre check message if no locale is provided.', async () => {
(interaction.options.getString as jest.Mock).mockReturnValueOnce(null);
await command.run(interaction);

expect(interaction.editReply).toHaveBeenCalledWith({ content: 'No language provided.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'No language provided.' });
});

it('should update guild locale.', async () => {
Expand All @@ -210,29 +198,23 @@ describe('Commands > ConfigureCommand', () => {

it('should reply with language update message.', async () => {
await command.run(interaction);
expect(interaction.editReply).toHaveBeenCalledWith({ content: 'Successfully updated notifications language to **English**.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'Successfully updated notifications language to **English**.' });
});
});

describe('runDefault()', () => {
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
locale: 'en-US',
guildId: '1267881983548063785',
options: {
getSubcommand: jest.fn().mockReturnValue('unknown')
}
} as unknown as GuildChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with unknown subcommand message.', async () => {
await command.run(interaction);
expect(interaction.editReply).toHaveBeenCalledWith({ content: 'Unknown subcommand received.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'Unknown subcommand received.' });
});
});
});
Expand Down
16 changes: 7 additions & 9 deletions src/commands/ConfigureCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ export default class ConfigureCommand extends Command {
}

public override async run(interaction: GuildChatInputCommandInteraction): Promise<void> {
await interaction.deferReply();

const subCommand = interaction.options.getSubcommand();

switch (subCommand) {
Expand All @@ -89,24 +87,24 @@ export default class ConfigureCommand extends Command {
const channel = interaction.options.getChannel('channel');

if (!channel) {
await interaction.editReply({ content: t('commands.configure.run.channel.pre_check.text') });
await interaction.reply({ content: t('commands.configure.run.channel.pre_check.text') });
return;
}

await updateOrCreateGuildChannel(interaction.guildId, channel.id);
await interaction.editReply({ content: t('commands.configure.run.channel.success.text', { channel: channel.toString() }) });
await interaction.reply({ content: t('commands.configure.run.channel.success.text', { channel: channel.toString() }) });
}

private async runStorefronts(interaction: GuildChatInputCommandInteraction): Promise<void> {
const t = getInteractionTranslator(interaction);
const storefronts = await getStorefronts();

if (!storefronts.length) {
await interaction.editReply({ content: t('commands.configure.run.storefronts.empty.text') });
await interaction.reply({ content: t('commands.configure.run.storefronts.empty.text') });
return;
}

await interaction.editReply({ content: t('commands.configure.run.storefronts.start.text') });
await interaction.reply({ content: t('commands.configure.run.storefronts.start.text') });

const buttonIds = {
enable: 'configure-storefronts-enable',
Expand Down Expand Up @@ -153,19 +151,19 @@ export default class ConfigureCommand extends Command {
const locale = interaction.options.getString('language') as Locale | null;

if (!locale) {
await interaction.editReply({ content: t('commands.configure.run.language.pre_check.text') });
await interaction.reply({ content: t('commands.configure.run.language.pre_check.text') });
return;
}

const language = t(AVAILABLE_LOCALES[locale]);
await updateOrCreateGuildLocale(interaction.guildId, locale);

await interaction.editReply({ content: t('commands.configure.run.language.success.text', { language }) });
await interaction.reply({ content: t('commands.configure.run.language.success.text', { language }) });
}

private async runDefault(interaction: ChatInputCommandInteraction): Promise<void> {
const t = getInteractionTranslator(interaction);

await interaction.editReply({ content: t('commands.configure.run.default.response.text') });
await interaction.reply({ content: t('commands.configure.run.default.response.text') });
}
}
10 changes: 2 additions & 8 deletions src/commands/HelpCommand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,10 @@ describe('Commands > HelpCommand', () => {
describe('run()', () => {
const command = new HelpCommand(client);
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
locale: 'en-US'
} as unknown as ChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with the embed.', async () => {
await command.run(interaction);

Expand All @@ -60,7 +54,7 @@ describe('Commands > HelpCommand', () => {
)
];

expect(interaction.editReply).toHaveBeenCalledWith({ embeds: expectedEmbeds, components: expectedComponents });
expect(interaction.reply).toHaveBeenCalledWith({ embeds: expectedEmbeds, components: expectedComponents });
});
});
});
3 changes: 1 addition & 2 deletions src/commands/HelpCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default class HelpCommand extends Command {
}

public override async run(interaction: ChatInputCommandInteraction): Promise<void> {
await interaction.deferReply();
const t = getInteractionTranslator(interaction);

const embed = new EmbedBuilder()
Expand All @@ -40,6 +39,6 @@ export default class HelpCommand extends Command {
new ButtonBuilder().setEmoji('🌎').setStyle(ButtonStyle.Link).setURL(BOT_WEBSITE_URL).setLabel(t('commands.help.run.buttons.bot_website.label')),
);

await interaction.editReply({ embeds: [embed], components: [row1, row2] });
await interaction.reply({ embeds: [embed], components: [row1, row2] });
}
}
16 changes: 5 additions & 11 deletions src/commands/InfoCommand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,16 @@ describe('Commands > InfoCommand', () => {
describe('run()', () => {
const command = new InfoCommand(client);
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
locale: 'en-US',
guildId: '1267881983548063785'
} as unknown as GuildChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with configure message if no settings are found.', async () => {
(getGuild as jest.Mock).mockResolvedValueOnce(null);
await command.run(interaction);

expect(interaction.editReply).toHaveBeenCalledWith({ content: 'No settings have been found for this server. Please use **/configure channel** command to set up the subscription channel.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'No settings have been found for this server. Please use **/configure channel** command to set up the subscription channel.' });
});

it('should reply with the correct embed if channel exists.', async () => {
Expand All @@ -91,7 +85,7 @@ describe('Commands > InfoCommand', () => {
})
];

expect(interaction.editReply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
expect(interaction.reply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
});

it('should reply with the correct embed if no channel is set.', async () => {
Expand Down Expand Up @@ -128,7 +122,7 @@ describe('Commands > InfoCommand', () => {
})
];

expect(interaction.editReply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
expect(interaction.reply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
});

it('should reply with the correct embed if channel set does not exist.', async () => {
Expand All @@ -152,7 +146,7 @@ describe('Commands > InfoCommand', () => {
})
];

expect(interaction.editReply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
expect(interaction.reply).toHaveBeenCalledWith({ embeds: expectedEmbeds });
});
});
});
5 changes: 2 additions & 3 deletions src/commands/InfoCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ export default class InfoCommand extends Command {
}

public override async run(interaction: GuildChatInputCommandInteraction): Promise<void> {
await interaction.deferReply();
const t = getInteractionTranslator(interaction);
const guildInfo = await getGuild(interaction.guildId);

if (!guildInfo) {
await interaction.editReply({ content: t('commands.info.run.pre_check.text') });
await interaction.reply({ content: t('commands.info.run.pre_check.text') });
return;
}

Expand All @@ -52,7 +51,7 @@ export default class InfoCommand extends Command {
text: t('commands.info.run.embed.footer', { createdAt, updatedAt })
});

await interaction.editReply({ embeds: [embed] });
await interaction.reply({ embeds: [embed] });
}

private async getChannel(channelId: string | null): Promise<Channel | null> {
Expand Down
12 changes: 3 additions & 9 deletions src/commands/OffersCommand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,21 @@ describe('Commands > OffersCommand', () => {
describe('run()', () => {
const command = new OffersCommand(client);
const interaction = {
deferReply: jest.fn(),
editReply: jest.fn(),
reply: jest.fn(),
followUp: jest.fn(),
locale: 'en-US'
} as unknown as ChatInputCommandInteraction;

it('should defer the reply.', async () => {
await command.run(interaction);
expect(interaction.deferReply).toHaveBeenCalled();
});

it('should reply with the empty message if no offers are available.', async () => {
(getCurrentGameOffers as jest.Mock).mockResolvedValueOnce([]);
await command.run(interaction);

expect(interaction.editReply).toHaveBeenCalledWith({ content: 'There are currently no offers in any of the following storefronts: Steam, EpicGames.' });
expect(interaction.reply).toHaveBeenCalledWith({ content: 'There are currently no offers in any of the following storefronts: Steam, EpicGames.' });
});

it('should reply with start message.', async () => {
await command.run(interaction);
expect(interaction.editReply).toHaveBeenCalledWith({ content: "Here's a list of the currently available offers." });
expect(interaction.reply).toHaveBeenCalledWith({ content: "Here's a list of the currently available offers." });
});

it('should send an embed and component for each game.', async () => {
Expand Down
Loading

0 comments on commit 0d0ea2d

Please sign in to comment.