Compare commits
2 commits
97bd3d675b
...
451c53f2cd
Author | SHA1 | Date | |
---|---|---|---|
451c53f2cd | |||
345a9efbc2 |
3 changed files with 400 additions and 27 deletions
|
@ -27,21 +27,16 @@ export default class Warn extends Command {
|
||||||
public override async execute(interaction: CommandInteraction) {
|
public override async execute(interaction: CommandInteraction) {
|
||||||
if (!interaction.guild || !interaction.guildId) return;
|
if (!interaction.guild || !interaction.guildId) return;
|
||||||
|
|
||||||
const targetUser = interaction.options.get('target');
|
const targetUser = interaction.options.get('target', true).user!;
|
||||||
const reasonInput = interaction.options.get('reason');
|
const reasonInput = interaction.options.get('reason');
|
||||||
|
|
||||||
if (!targetUser || !targetUser.user || !targetUser.member) {
|
|
||||||
await interaction.reply('Fields are required.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*";
|
const reason = reasonInput && reasonInput.value ? reasonInput.value.toString() : "*none*";
|
||||||
|
|
||||||
const logEmbed = new EmbedBuilder()
|
const logEmbed = new EmbedBuilder()
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setTitle("Member Warned")
|
.setTitle("Member Warned")
|
||||||
.setDescription(`<@${targetUser.user.id}> \`${targetUser.user.tag}\``)
|
.setDescription(`<@${targetUser.id}> \`${targetUser.tag}\``)
|
||||||
.setThumbnail(targetUser.user.avatarURL())
|
.setThumbnail(targetUser.avatarURL())
|
||||||
.addFields([
|
.addFields([
|
||||||
{
|
{
|
||||||
name: "Moderator",
|
name: "Moderator",
|
||||||
|
@ -55,15 +50,15 @@ export default class Warn extends Command {
|
||||||
|
|
||||||
const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId);
|
const channelName = await SettingsHelper.GetSetting('channels.logs.mod', interaction.guildId);
|
||||||
|
|
||||||
if (!channelName) return;
|
if (channelName) {
|
||||||
|
|
||||||
const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel;
|
const channel = interaction.guild.channels.cache.find(x => x.name == channelName) as TextChannel;
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
await channel.send({ embeds: [ logEmbed ]});
|
await channel.send({ embeds: [ logEmbed ]});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const audit = new Audit(targetUser.user.id, AuditType.Warn, reason, interaction.user.id, interaction.guildId);
|
const audit = new Audit(targetUser.id, AuditType.Warn, reason, interaction.user.id, interaction.guildId);
|
||||||
await audit.Save(Audit, audit);
|
await audit.Save(Audit, audit);
|
||||||
|
|
||||||
await interaction.reply('Successfully warned user.');
|
await interaction.reply('Successfully warned user.');
|
||||||
|
|
|
@ -95,7 +95,7 @@ describe('Execute', () => {
|
||||||
expect(interaction.reply).toHaveBeenCalledWith("Successfully warned user.");
|
expect(interaction.reply).toHaveBeenCalledWith("Successfully warned user.");
|
||||||
|
|
||||||
expect(interaction.options.get).toHaveBeenCalledTimes(2);
|
expect(interaction.options.get).toHaveBeenCalledTimes(2);
|
||||||
expect(interaction.options.get).toHaveBeenCalledWith("target");
|
expect(interaction.options.get).toHaveBeenCalledWith("target", true);
|
||||||
expect(interaction.options.get).toHaveBeenCalledWith("reason");
|
expect(interaction.options.get).toHaveBeenCalledWith("reason");
|
||||||
|
|
||||||
expect(interaction.guild!.channels.cache.find).toHaveBeenCalledTimes(1);
|
expect(interaction.guild!.channels.cache.find).toHaveBeenCalledTimes(1);
|
||||||
|
@ -120,21 +120,375 @@ describe('Execute', () => {
|
||||||
}, "savedAudit");
|
}, "savedAudit");
|
||||||
});
|
});
|
||||||
|
|
||||||
test.todo("GIVEN interaction.guild is null, EXPECT nothing to happen");
|
test("GIVEN interaction.guild is null, EXPECT nothing to happen", async () => {
|
||||||
|
let sentEmbeds: EmbedBuilder[] | undefined;
|
||||||
|
let savedAudit: Audit | undefined;
|
||||||
|
|
||||||
test.todo("GIVEN interaction.guildId is null, EXPECT nothing to happen");
|
// Arrange
|
||||||
|
const targetUser = {
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
tag: "userTag",
|
||||||
|
avatarURL: jest.fn().mockReturnValue("https://google.com/avatar.png"),
|
||||||
|
},
|
||||||
|
member: {},
|
||||||
|
};
|
||||||
|
|
||||||
test.todo("GIVEN targetUser is null, EXPECT error");
|
const reason = {
|
||||||
|
value: "Test reason",
|
||||||
|
};
|
||||||
|
|
||||||
test.todo("GIVEN targetUser.user is undefined, EXPECT error");
|
const logChannel = {
|
||||||
|
send: jest.fn().mockImplementation((opts: any) => {
|
||||||
|
sentEmbeds = opts.embeds;
|
||||||
|
}),
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
test.todo("GIVEN targetUser.member is undefined, EXPECT error");
|
const interaction = {
|
||||||
|
reply: jest.fn(),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(targetUser)
|
||||||
|
.mockReturnValue(reason),
|
||||||
|
},
|
||||||
|
guildId: "guildId",
|
||||||
|
user: {
|
||||||
|
id: "moderatorId",
|
||||||
|
},
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
test.todo("GIVEN reasonInput is null, EXPECT reason to be defaulted");
|
SettingsHelper.GetSetting = jest.fn().mockResolvedValue("mod-logs");
|
||||||
|
|
||||||
test.todo("GIVEN reasonInput.value is undefined, EXPECT reason to be defaulted");
|
Audit.prototype.Save = jest.fn().mockImplementation((_, audit: Audit) => {
|
||||||
|
savedAudit = audit;
|
||||||
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");
|
// Act
|
||||||
|
const command = new Warn();
|
||||||
|
await command.execute(interaction);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(Audit.prototype.Save).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN interaction.guildId is null, EXPECT nothing to happen", 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),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(Audit.prototype.Save).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN reasonInput is null, EXPECT reason to be defaulted", 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(null),
|
||||||
|
},
|
||||||
|
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(sentEmbeds).toBeDefined();
|
||||||
|
|
||||||
|
expect(sentEmbeds![0].data.fields).toBeDefined();
|
||||||
|
expect(sentEmbeds![0].data.fields!.length).toBe(2);
|
||||||
|
|
||||||
|
const logEmbedReasonField = sentEmbeds![0].data.fields!.find(x => x.name == "Reason");
|
||||||
|
|
||||||
|
expect(logEmbedReasonField).toBeDefined();
|
||||||
|
expect(logEmbedReasonField!.value).toBe("*none*");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN reasonInput.value is undefined, EXPECT reason to be defaulted", 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: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
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(sentEmbeds).toBeDefined();
|
||||||
|
|
||||||
|
expect(sentEmbeds![0].data.fields).toBeDefined();
|
||||||
|
expect(sentEmbeds![0].data.fields!.length).toBe(2);
|
||||||
|
|
||||||
|
const logEmbedReasonField = sentEmbeds![0].data.fields!.find(x => x.name == "Reason");
|
||||||
|
|
||||||
|
expect(logEmbedReasonField).toBeDefined();
|
||||||
|
expect(logEmbedReasonField!.value).toBe("*none*");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN channels.logs.mod setting is not found, EXPECT command to return", 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(undefined);
|
||||||
|
|
||||||
|
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(Audit.prototype.Save).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(logChannel.send).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN channel is not found, EXPECT logEmbed to not be sent", 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(undefined),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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(Audit.prototype.Save).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(interaction.guild!.channels.cache.find).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(logChannel.send).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,29 @@
|
||||||
|
import BaseEntity from "../../src/contracts/BaseEntity";
|
||||||
|
import uuid from "uuid";
|
||||||
|
|
||||||
|
jest.mock("uuid", () => {
|
||||||
|
return {
|
||||||
|
v4: () => "uuidv4",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
test.todo("EXPECT properties to be set");
|
test("EXPECT properties to be set", () => {
|
||||||
|
// Arrange
|
||||||
|
const systemTime = new Date("2024-06-29T00:00:00.000Z");
|
||||||
|
|
||||||
|
jest.setSystemTime(systemTime);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const entity = new BaseEntity();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(entity.Id).toBe("uuidv4");
|
||||||
|
expect(entity.WhenCreated).toStrictEqual(systemTime);
|
||||||
|
expect(entity.WhenUpdated).toStrictEqual(systemTime);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Save", () => {
|
describe("Save", () => {
|
||||||
|
|
Loading…
Reference in a new issue