Add client tests
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Ethan Lane 2024-03-20 18:30:58 +00:00
parent 0f0dbee7de
commit 9c13ee6099
3 changed files with 282 additions and 15 deletions

View file

@ -1,6 +1,5 @@
import { Client, Partials } from "discord.js"; import { Client, Partials } from "discord.js";
import * as dotenv from "dotenv"; import * as dotenv from "dotenv";
import { createConnection } from "typeorm";
import { EventType } from "../constants/EventType"; import { EventType } from "../constants/EventType";
import ICommandItem from "../contracts/ICommandItem"; import ICommandItem from "../contracts/ICommandItem";
import IEventItem from "../contracts/IEventItem"; import IEventItem from "../contracts/IEventItem";
@ -39,9 +38,12 @@ export class CoreClient extends Client {
return; return;
} }
await AppDataSource.initialize() try {
.then(() => console.log("Data Source Initialized")) await AppDataSource.initialize();
.catch((err) => console.error("Error Initialising Data Source", err)); } catch (err) {
console.error("Error Initialising Data Source", err);
return;
}
super.on("interactionCreate", this._events.onInteractionCreate); super.on("interactionCreate", this._events.onInteractionCreate);
super.on("ready", this._events.onReady); super.on("ready", this._events.onReady);

View file

@ -1,23 +1,129 @@
import { Partials, Client } from "discord.js";
import { CoreClient } from "../../src/client/client";
import * as dotenv from "dotenv";
import AppDataSource from "../../src/database/dataSources/appDataSource";
import { Util } from "../../src/client/util";
import { Command } from "../../src/type/command";
import { EventType } from "../../src/constants/EventType";
import { ButtonEvent } from "../../src/type/buttonEvent";
jest.mock("dotenv");
beforeEach(() => {
jest.clearAllMocks();
process.env = {};
});
describe('constructor', () => { describe('constructor', () => {
test.todo("EXPECT properties to be set"); test("EXPECT properties to be set", () => {
const client = new CoreClient([1, 2, 3], [Partials.User]);
expect(dotenv.config).toHaveBeenCalledTimes(1);
expect(client).toBeDefined();
expect(CoreClient.commandItems).toEqual([]);
expect(CoreClient.eventItems).toEqual([]);
expect(CoreClient.buttonEvents).toEqual([]);
expect(client).toHaveProperty("_events");
expect(client).toHaveProperty("_util");
});
}); });
describe('start', () => { describe('start', () => {
test.todo("EXPECT bot to start"); test("EXPECT bot to start", async () => {
process.env.BOT_TOKEN = "token";
console.error = jest.fn();
AppDataSource.initialize = jest.fn().mockResolvedValue(undefined);
test.todo("GIVEN BOT_TOKEN is not in env var, EXPECT error"); const client = new CoreClient([1, 2, 3], [Partials.User]);
test.todo("GIVEN database connection can not be initialised, EXPECT error"); const loadSlashCommands = jest.spyOn(Util.prototype, "loadSlashCommands").mockImplementation();
const loadEvents = jest.spyOn(Util.prototype, "loadEvents").mockImplementation();
Client.prototype.login = jest.fn();
Client.prototype.on = jest.fn();
await client.start();
expect(AppDataSource.initialize).toHaveBeenCalledTimes(1);
expect(console.error).not.toHaveBeenCalled();
expect(client.login).toHaveBeenCalledTimes(1);
expect(client.login).toHaveBeenCalledWith("token");
expect(client.on).toHaveBeenCalledTimes(2);
expect(client.on).toHaveBeenCalledWith("interactionCreate", expect.any(Function));
expect(client.on).toHaveBeenCalledWith("ready", expect.any(Function))
expect(loadSlashCommands).toHaveBeenCalledTimes(1);
expect(loadSlashCommands).toHaveBeenCalledWith(client);
expect(loadEvents).toHaveBeenCalledTimes(1);
expect(loadEvents).toHaveBeenCalledWith(client, []);
});
test("GIVEN BOT_TOKEN is not in env var, EXPECT error", async () => {
console.error = jest.fn();
const client = new CoreClient([1, 2, 3], [ Partials.User ]);
await client.start();
expect(console.error).toHaveBeenCalledWith("BOT_TOKEN is not defined in .env");
});
test("GIVEN database connection can not be initialised, EXPECT error", async () => {
process.env.BOT_TOKEN = "token";
console.log = jest.fn();
console.error = jest.fn();
AppDataSource.initialize = jest.fn().mockRejectedValue("error");
const client = new CoreClient([1, 2, 3], [Partials.User]);
await client.start();
expect(console.log).not.toHaveBeenCalled();
expect(console.error).toHaveBeenCalledWith("Error Initialising Data Source", "error");
});
}); });
describe('RegisterCommand', () => { describe('RegisterCommand', () => {
test.todo("EXPECT command to be added to list"); test("EXPECT command to be added to list", () => {
CoreClient.RegisterCommand("name", {} as Command, "serverId");
expect(CoreClient.commandItems).toStrictEqual([
{
Name: "name",
Command: {},
ServerId: "serverId",
}
])
});
}); });
describe("RegisterEvent", () => { describe("RegisterEvent", () => {
test.todo("EXPECT event to be added to list"); test("EXPECT event to be added to list", () => {
CoreClient.RegisterEvent(EventType.ChannelCreate, () => {});
expect(CoreClient.eventItems).toStrictEqual([
{
EventType: EventType.ChannelCreate,
ExecutionFunction: expect.any(Function),
}
]);
});
}); });
describe("RegisterButtonEvent", () => { describe("RegisterButtonEvent", () => {
test.todo("EXPECT button event to be added to list"); test("EXPECT button event to be added to list", () => {
CoreClient.RegisterButtonEvent("buttonId", {} as ButtonEvent);
expect(CoreClient.buttonEvents).toStrictEqual([
{
ButtonId: "buttonId",
Event: {},
}
])
});
}); });

View file

@ -1,9 +1,168 @@
describe('onChatInput', () => { import { ChatInputCommandInteraction } from 'discord.js';
test.todo("GIVEN command is registered globally AND command is found, execute the global command"); import ChatInputComamnd from '../../../src/client/interactionCreate/chatInputCommand';
import { CoreClient } from '../../../src/client/client';
import ICommandItem from '../../../src/contracts/ICommandItem';
test.todo("GIVEN command is registered to a single server, execute the server command"); beforeEach(() => {
CoreClient.commandItems = [];
test.todo("GIVEN interaction is not a chat input command, EXPECT nothing to happen"); });
test.todo("GIVEN command is registered globally AND command is not found, EXPECT error"); describe('onChatInput', () => {
test("GIVEN command is registered globally AND command is found, execute the global command", async () => {
// Arrange
const interaction = {
reply: jest.fn(),
isChatInputCommand: jest.fn().mockReturnValue(true),
commandName: "test",
} as unknown as ChatInputCommandInteraction;
const testCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
};
const testServerCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
ServerId: "123",
};
CoreClient.commandItems = [ testCommand, testServerCommand ];
// Act
await ChatInputComamnd.onChatInput(interaction);
// Assert
expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1);
expect(interaction.reply).not.toHaveBeenCalled();
expect(testCommand.Command.execute).toHaveBeenCalledTimes(1);
expect(testCommand.Command.execute).toHaveBeenCalledWith(interaction);
expect(testServerCommand.Command.execute).not.toHaveBeenCalled();
});
test("GIVEN command is registered to a single server, execute the server command", async () => {
// Arrange
const interaction = {
reply: jest.fn(),
isChatInputCommand: jest.fn().mockReturnValue(true),
commandName: "test",
guildId: "123",
} as unknown as ChatInputCommandInteraction;
const testCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
};
const testServerCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
ServerId: "123",
};
CoreClient.commandItems = [ testCommand, testServerCommand ];
// Act
await ChatInputComamnd.onChatInput(interaction);
// Assert
expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1);
expect(interaction.reply).not.toHaveBeenCalled();
expect(testServerCommand.Command.execute).toHaveBeenCalledTimes(1);
expect(testServerCommand.Command.execute).toHaveBeenCalledWith(interaction);
expect(testCommand.Command.execute).not.toHaveBeenCalled();
});
test("GIVEN interaction is not a chat input command, EXPECT nothing to happen", async () => {
// Arrange
const interaction = {
reply: jest.fn(),
isChatInputCommand: jest.fn().mockReturnValue(false),
commandName: "test",
guildId: "123",
} as unknown as ChatInputCommandInteraction;
const testCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
};
const testServerCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
ServerId: "123",
};
CoreClient.commandItems = [ testCommand, testServerCommand ];
// Act
await ChatInputComamnd.onChatInput(interaction);
// Assert
expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1);
expect(interaction.reply).not.toHaveBeenCalled();
expect(testServerCommand.Command.execute).not.toHaveBeenCalled();
expect(testCommand.Command.execute).not.toHaveBeenCalled();
});
test("GIVEN command is registered globally AND command is not found, EXPECT error", async () => {
// Arrange
const interaction = {
reply: jest.fn(),
isChatInputCommand: jest.fn().mockReturnValue(true),
commandName: "other",
guildId: "123",
} as unknown as ChatInputCommandInteraction;
const testCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
};
const testServerCommand: ICommandItem = {
Name: "test",
Command: {
CommandBuilder: jest.fn(),
execute: jest.fn(),
},
ServerId: "123",
};
CoreClient.commandItems = [ testCommand, testServerCommand ];
// Act
await ChatInputComamnd.onChatInput(interaction);
// Assert
expect(interaction.isChatInputCommand).toHaveBeenCalledTimes(1);
expect(interaction.reply).toHaveBeenCalledTimes(1);
expect(interaction.reply).toHaveBeenCalledWith("Command not found.");
expect(testServerCommand.Command.execute).not.toHaveBeenCalled();
expect(testCommand.Command.execute).not.toHaveBeenCalled();
});
}); });