Feature/12 create tests (#102)
* Fix tests * Update coverage * Remove unrequired mock files * Add about command test * Update about tests * Ban command tests * eval command tests * Start help command tests * Add help command tests * Add kick command tests * Mute command tests * Poll command tests * Add role command tests Signed-off-by: Ethan Lane <ethan@vylpes.com> * Add rules command tests * Add unmute command tests * Add warn command tests * Add MemberEvents tests * Add GuildMemberUpdate tests Signed-off-by: Ethan Lane <ethan@vylpes.com> * Add MessageEvents tests * Add StringTools test Signed-off-by: Ethan Lane <ethan@vylpes.com> * Add embed tests Signed-off-by: Ethan Lane <ethan@vylpes.com> * Add GitHub Actions Signed-off-by: Ethan Lane <ethan@vylpes.com> * Move to tslint Signed-off-by: Ethan Lane <ethan@vylpes.com> * Remove tslint Signed-off-by: Ethan Lane <ethan@vylpes.com> * Remove linting script Signed-off-by: Ethan Lane <ethan@vylpes.com>
This commit is contained in:
parent
2cc12d91be
commit
f61c4c728a
58 changed files with 6749 additions and 833 deletions
49
.eslintrc
49
.eslintrc
|
@ -1,49 +0,0 @@
|
||||||
{
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 6
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"camelcase": "error",
|
|
||||||
"brace-style": [
|
|
||||||
"error",
|
|
||||||
"1tbs"
|
|
||||||
],
|
|
||||||
"comma-dangle": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"comma-spacing": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"before": false,
|
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"comma-style": [
|
|
||||||
"error",
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"arrow-body-style": [
|
|
||||||
"error",
|
|
||||||
"as-needed"
|
|
||||||
],
|
|
||||||
"arrow-parens": [
|
|
||||||
"error",
|
|
||||||
"as-needed"
|
|
||||||
],
|
|
||||||
"arrow-spacing": "error",
|
|
||||||
"no-var": "error",
|
|
||||||
"prefer-template": "error",
|
|
||||||
"prefer-const": "error"
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"exports": "writable",
|
|
||||||
"module": "writable",
|
|
||||||
"require": "writable",
|
|
||||||
"process": "writable",
|
|
||||||
"console": "writable"
|
|
||||||
}
|
|
||||||
}
|
|
27
.github/workflows/testing.yml
vendored
Normal file
27
.github/workflows/testing.yml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
name: Testing
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [12.x, 14.x, 16.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: yarn install
|
||||||
|
- run: yarn build
|
||||||
|
- run: yarn test --coverage
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -103,4 +103,5 @@ dist
|
||||||
# TernJS port file
|
# TernJS port file
|
||||||
.tern-port
|
.tern-port
|
||||||
|
|
||||||
config.json
|
config.json
|
||||||
|
.DS_Store
|
|
@ -2,4 +2,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
preset: 'ts-jest',
|
preset: 'ts-jest',
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
|
setupFiles: ["./jest.setup.js"]
|
||||||
};
|
};
|
3
jest.setup.js
Normal file
3
jest.setup.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
jest.setTimeout(1 * 1000); // 1 second
|
||||||
|
jest.resetModules();
|
||||||
|
jest.resetAllMocks();
|
|
@ -6,7 +6,7 @@
|
||||||
"typings": "./dist",
|
"typings": "./dist",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"start": "ts-node ./src/vylbot",
|
"start": "node ./dist/vylbot",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -29,8 +29,6 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.11.10",
|
"@types/node": "^16.11.10",
|
||||||
"eslint": "^7.17.0",
|
|
||||||
"ts-node": "^10.4.0",
|
|
||||||
"typescript": "^4.5.2"
|
"typescript": "^4.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,14 @@ export class CoreClient extends Client {
|
||||||
private _events: Events;
|
private _events: Events;
|
||||||
private _util: Util;
|
private _util: Util;
|
||||||
|
|
||||||
|
public get commandItems(): ICommandItem[] {
|
||||||
|
return this._commandItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get eventItems(): IEventItem[] {
|
||||||
|
return this._eventItems;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
|
||||||
|
@ -8,12 +9,17 @@ export default class About extends Command {
|
||||||
super._category = "General";
|
super._category = "General";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||||
const embed = new PublicEmbed(context, "About", "")
|
const embed = new PublicEmbed(context, "About", "")
|
||||||
.addField("Version", process.env.BOT_VER)
|
.addField("Version", process.env.BOT_VER)
|
||||||
.addField("Author", process.env.BOT_AUTHOR)
|
.addField("Author", process.env.BOT_AUTHOR)
|
||||||
.addField("Date", process.env.BOT_DATE);
|
.addField("Date", process.env.BOT_DATE);
|
||||||
|
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@ import LogEmbed from "../helpers/embeds/LogEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
|
|
||||||
export default class Ban extends Command {
|
export default class Ban extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -15,13 +16,16 @@ export default class Ban extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
const targetUser = context.message.mentions.users.first();
|
const targetUser = context.message.mentions.users.first();
|
||||||
|
|
||||||
if (!targetUser) {
|
if (!targetUser) {
|
||||||
const embed = new ErrorEmbed(context, "User does not exist");
|
const embed = new ErrorEmbed(context, "User does not exist");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetMember = context.message.guild?.member(targetUser);
|
const targetMember = context.message.guild?.member(targetUser);
|
||||||
|
@ -29,7 +33,10 @@ export default class Ban extends Command {
|
||||||
if (!targetMember) {
|
if (!targetMember) {
|
||||||
const embed = new ErrorEmbed(context, "User is not in this server");
|
const embed = new ErrorEmbed(context, "User is not in this server");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasonArgs = context.args;
|
const reasonArgs = context.args;
|
||||||
|
@ -38,13 +45,19 @@ export default class Ban extends Command {
|
||||||
const reason = reasonArgs.join(" ");
|
const reason = reasonArgs.join(" ");
|
||||||
|
|
||||||
if (!context.message.guild?.available) {
|
if (!context.message.guild?.available) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetMember.bannable) {
|
if (!targetMember.bannable) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const logEmbed = new LogEmbed(context, "Member Banned");
|
const logEmbed = new LogEmbed(context, "Member Banned");
|
||||||
|
@ -58,5 +71,10 @@ export default class Ban extends Command {
|
||||||
|
|
||||||
logEmbed.SendToModLogsChannel();
|
logEmbed.SendToModLogsChannel();
|
||||||
publicEmbed.SendToCurrentChannel();
|
publicEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [logEmbed, publicEmbed],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ import { TextChannel } from "discord.js";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
|
|
||||||
export default class Clear extends Command {
|
export default class Clear extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -14,11 +15,15 @@ export default class Clear extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
if (context.args.length == 0) {
|
if (context.args.length == 0) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100");
|
const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalToClear = Number.parseInt(context.args[0]);
|
const totalToClear = Number.parseInt(context.args[0]);
|
||||||
|
@ -26,12 +31,20 @@ export default class Clear extends Command {
|
||||||
if (!totalToClear || totalToClear <= 0 || totalToClear > 100) {
|
if (!totalToClear || totalToClear <= 0 || totalToClear > 100) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100");
|
const errorEmbed = new ErrorEmbed(context, "Please specify an amount between 1 and 100");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await (context.message.channel as TextChannel).bulkDelete(totalToClear);
|
await (context.message.channel as TextChannel).bulkDelete(totalToClear);
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "", `${totalToClear} message(s) were removed`);
|
const embed = new PublicEmbed(context, "", `${totalToClear} message(s) were removed`);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
@ -10,9 +11,12 @@ export default class Evaluate extends Command {
|
||||||
super._category = "Owner";
|
super._category = "Owner";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||||
if (context.message.author.id != process.env.BOT_OWNERID) {
|
if (context.message.author.id != process.env.BOT_OWNERID) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const stmt = context.args;
|
const stmt = context.args;
|
||||||
|
@ -24,10 +28,20 @@ export default class Evaluate extends Command {
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "", result);
|
const embed = new PublicEmbed(context, "", result);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
catch (err: any) {
|
catch (err: any) {
|
||||||
const errorEmbed = new ErrorEmbed(context, err);
|
const errorEmbed = new ErrorEmbed(context, err);
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,9 +3,10 @@ import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import StringTools from "../helpers/StringTools";
|
import StringTools from "../helpers/StringTools";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
|
||||||
interface ICommandData {
|
export interface ICommandData {
|
||||||
Exists: boolean;
|
Exists: boolean;
|
||||||
Name?: string;
|
Name?: string;
|
||||||
Category?: string;
|
Category?: string;
|
||||||
|
@ -19,17 +20,17 @@ export default class Help extends Command {
|
||||||
super._category = "General";
|
super._category = "General";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||||
if (context.args.length == 0) {
|
if (context.args.length == 0) {
|
||||||
this.SendAll(context);
|
return this.SendAll(context);
|
||||||
} else {
|
} else {
|
||||||
this.SendSingle(context);
|
return this.SendSingle(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendAll(context: ICommandContext) {
|
public SendAll(context: ICommandContext): ICommandReturnContext {
|
||||||
const allCommands = this.GetAllCommandData();
|
const allCommands = this.GetAllCommandData();
|
||||||
const cateogries = this.DetermineCategories(allCommands);
|
const cateogries = [...new Set(allCommands.map(x => x.Category!))];;
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "Commands", "");
|
const embed = new PublicEmbed(context, "Commands", "");
|
||||||
|
|
||||||
|
@ -40,15 +41,24 @@ export default class Help extends Command {
|
||||||
});
|
});
|
||||||
|
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [ embed ]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendSingle(context: ICommandContext) {
|
public SendSingle(context: ICommandContext): ICommandReturnContext {
|
||||||
const command = this.GetCommandData(context.args[0]);
|
const command = this.GetCommandData(context.args[0]);
|
||||||
|
|
||||||
if (!command.Exists) {
|
if (!command.Exists) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Command does not exist");
|
const errorEmbed = new ErrorEmbed(context, "Command does not exist");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [ errorEmbed ]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, StringTools.Capitalise(command.Name!), "");
|
const embed = new PublicEmbed(context, StringTools.Capitalise(command.Name!), "");
|
||||||
|
@ -56,9 +66,14 @@ export default class Help extends Command {
|
||||||
embed.addField("Required Roles", StringTools.Capitalise(command.Roles!.join(", ")) || "*none*");
|
embed.addField("Required Roles", StringTools.Capitalise(command.Roles!.join(", ")) || "*none*");
|
||||||
|
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [ embed ]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private GetAllCommandData(): ICommandData[] {
|
public GetAllCommandData(): ICommandData[] {
|
||||||
const result: ICommandData[] = [];
|
const result: ICommandData[] = [];
|
||||||
|
|
||||||
const folder = process.env.FOLDERS_COMMANDS!;
|
const folder = process.env.FOLDERS_COMMANDS!;
|
||||||
|
@ -82,7 +97,7 @@ export default class Help extends Command {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GetCommandData(name: string): ICommandData {
|
public GetCommandData(name: string): ICommandData {
|
||||||
const folder = process.env.FOLDERS_COMMANDS!;
|
const folder = process.env.FOLDERS_COMMANDS!;
|
||||||
const path = `${process.cwd()}/${folder}/${name}.ts`;
|
const path = `${process.cwd()}/${folder}/${name}.ts`;
|
||||||
|
|
||||||
|
@ -104,16 +119,4 @@ export default class Help extends Command {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private DetermineCategories(commands: ICommandData[]): string[] {
|
|
||||||
const result: string[] = [];
|
|
||||||
|
|
||||||
commands.forEach(cmd => {
|
|
||||||
if (!result.includes(cmd.Category!)) {
|
|
||||||
result.push(cmd.Category!);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import ErrorMessages from "../constants/ErrorMessages";
|
import ErrorMessages from "../constants/ErrorMessages";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import LogEmbed from "../helpers/embeds/LogEmbed";
|
import LogEmbed from "../helpers/embeds/LogEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
|
@ -15,13 +16,17 @@ export default class Kick extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
const targetUser = context.message.mentions.users.first();
|
const targetUser = context.message.mentions.users.first();
|
||||||
|
|
||||||
if (!targetUser) {
|
if (!targetUser) {
|
||||||
const embed = new ErrorEmbed(context, "User does not exist");
|
const embed = new ErrorEmbed(context, "User does not exist");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetMember = context.message.guild?.member(targetUser);
|
const targetMember = context.message.guild?.member(targetUser);
|
||||||
|
@ -29,7 +34,11 @@ export default class Kick extends Command {
|
||||||
if (!targetMember) {
|
if (!targetMember) {
|
||||||
const embed = new ErrorEmbed(context, "User is not in this server");
|
const embed = new ErrorEmbed(context, "User is not in this server");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasonArgs = context.args;
|
const reasonArgs = context.args;
|
||||||
|
@ -38,13 +47,20 @@ export default class Kick extends Command {
|
||||||
const reason = reasonArgs.join(" ");
|
const reason = reasonArgs.join(" ");
|
||||||
|
|
||||||
if (!context.message.guild?.available) {
|
if (!context.message.guild?.available) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetMember.kickable) {
|
if (!targetMember.kickable) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const logEmbed = new LogEmbed(context, "Member Kicked");
|
const logEmbed = new LogEmbed(context, "Member Kicked");
|
||||||
|
@ -58,5 +74,10 @@ export default class Kick extends Command {
|
||||||
|
|
||||||
logEmbed.SendToModLogsChannel();
|
logEmbed.SendToModLogsChannel();
|
||||||
publicEmbed.SendToCurrentChannel();
|
publicEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [logEmbed, publicEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import ErrorMessages from "../constants/ErrorMessages";
|
import ErrorMessages from "../constants/ErrorMessages";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import LogEmbed from "../helpers/embeds/LogEmbed";
|
import LogEmbed from "../helpers/embeds/LogEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
|
@ -15,13 +16,17 @@ export default class Mute extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
const targetUser = context.message.mentions.users.first();
|
const targetUser = context.message.mentions.users.first();
|
||||||
|
|
||||||
if (!targetUser) {
|
if (!targetUser) {
|
||||||
const embed = new ErrorEmbed(context, "User does not exist");
|
const embed = new ErrorEmbed(context, "User does not exist");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetMember = context.message.guild?.member(targetUser);
|
const targetMember = context.message.guild?.member(targetUser);
|
||||||
|
@ -29,7 +34,11 @@ export default class Mute extends Command {
|
||||||
if (!targetMember) {
|
if (!targetMember) {
|
||||||
const embed = new ErrorEmbed(context, "User is not in this server");
|
const embed = new ErrorEmbed(context, "User is not in this server");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasonArgs = context.args;
|
const reasonArgs = context.args;
|
||||||
|
@ -38,13 +47,20 @@ export default class Mute extends Command {
|
||||||
const reason = reasonArgs.join(" ");
|
const reason = reasonArgs.join(" ");
|
||||||
|
|
||||||
if (!context.message.guild?.available) {
|
if (!context.message.guild?.available) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetMember.manageable) {
|
if (!targetMember.manageable) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const logEmbed = new LogEmbed(context, "Member Muted");
|
const logEmbed = new LogEmbed(context, "Member Muted");
|
||||||
|
@ -60,12 +76,21 @@ export default class Mute extends Command {
|
||||||
if (!mutedRole) {
|
if (!mutedRole) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound);
|
const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await targetMember.roles.add(mutedRole, reason);
|
await targetMember.roles.add(mutedRole, reason);
|
||||||
|
|
||||||
logEmbed.SendToModLogsChannel();
|
logEmbed.SendToModLogsChannel();
|
||||||
publicEmbed.SendToCurrentChannel();
|
publicEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [logEmbed, publicEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
@ -10,14 +11,18 @@ export default class Poll extends Command {
|
||||||
super._category = "General";
|
super._category = "General";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
const argsJoined = context.args.join(" ");
|
const argsJoined = context.args.join(" ");
|
||||||
const argsSplit = argsJoined.split(";");
|
const argsSplit = argsJoined.split(";");
|
||||||
|
|
||||||
if (argsSplit.length < 3 || argsSplit.length > 10) {
|
if (argsSplit.length < 3 || argsSplit.length > 10) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Usage: <title>;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options");
|
const errorEmbed = new ErrorEmbed(context, "Usage: <title>;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = argsSplit[0];
|
const title = argsSplit[0];
|
||||||
|
@ -53,5 +58,10 @@ export default class Poll extends Command {
|
||||||
if (context.message.deletable) {
|
if (context.message.deletable) {
|
||||||
await context.message.delete({ reason: "Poll command" });
|
await context.message.delete({ reason: "Poll command" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Role as DiscordRole } from "discord.js";
|
import { Role as DiscordRole } from "discord.js";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
|
|
||||||
export default class Role extends Command {
|
export default class Role extends Command {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -11,30 +12,39 @@ export default class Role extends Command {
|
||||||
super._category = "General";
|
super._category = "General";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext) {
|
||||||
const roles = process.env.COMMANDS_ROLE_ROLES!.split(',');
|
const roles = process.env.COMMANDS_ROLE_ROLES!.split(',');
|
||||||
|
|
||||||
if (context.args.length == 0) {
|
if (context.args.length == 0) {
|
||||||
this.SendRolesList(context, roles);
|
this.SendRolesList(context, roles);
|
||||||
} else {
|
} else {
|
||||||
this.ToggleRole(context, roles);
|
await this.ToggleRole(context, roles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendRolesList(context: ICommandContext, roles: String[]) {
|
public SendRolesList(context: ICommandContext, roles: String[]): ICommandReturnContext {
|
||||||
const description = `Do ${process.env.BOT_PREFIX}role <role> to get the role!\n${roles.join('\n')}`;
|
const description = `Do ${process.env.BOT_PREFIX}role <role> to get the role!\n${roles.join('\n')}`;
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "Roles", description);
|
const embed = new PublicEmbed(context, "Roles", description);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private ToggleRole(context: ICommandContext, roles: String[]) {
|
public async ToggleRole(context: ICommandContext, roles: String[]): Promise<ICommandReturnContext> {
|
||||||
const requestedRole = context.args[0];
|
const requestedRole = context.args[0];
|
||||||
|
|
||||||
if (!roles.includes(requestedRole)) {
|
if (!roles.includes(requestedRole)) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "This role isn't marked as assignable, to see a list of assignable roles, run this command without any parameters");
|
const errorEmbed = new ErrorEmbed(context, "This role isn't marked as assignable, to see a list of assignable roles, run this command without any parameters");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignRole = context.message.guild?.roles.cache.find(x => x.name == requestedRole);
|
const assignRole = context.message.guild?.roles.cache.find(x => x.name == requestedRole);
|
||||||
|
@ -42,29 +52,48 @@ export default class Role extends Command {
|
||||||
if (!assignRole) {
|
if (!assignRole) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "The current server doesn't have this role. Please contact the server's moderators");
|
const errorEmbed = new ErrorEmbed(context, "The current server doesn't have this role. Please contact the server's moderators");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const role = context.message.member?.roles.cache.find(x => x.name == requestedRole)
|
const role = context.message.member?.roles.cache.find(x => x.name == requestedRole)
|
||||||
|
|
||||||
if (!role) {
|
if (!role) {
|
||||||
this.AddRole(context, assignRole);
|
await this.AddRole(context, assignRole);
|
||||||
} else {
|
} else {
|
||||||
this.RemoveRole(context, assignRole);
|
await this.RemoveRole(context, assignRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async AddRole(context: ICommandContext, role: DiscordRole) {
|
public async AddRole(context: ICommandContext, role: DiscordRole): Promise<ICommandReturnContext> {
|
||||||
await context.message.member?.roles.add(role);
|
await context.message.member?.roles.add(role);
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "", `Gave role: ${role.name}`);
|
const embed = new PublicEmbed(context, "", `Gave role: ${role.name}`);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async RemoveRole(context: ICommandContext, role: DiscordRole) {
|
public async RemoveRole(context: ICommandContext, role: DiscordRole): Promise<ICommandReturnContext> {
|
||||||
await context.message.member?.roles.remove(role);
|
await context.message.member?.roles.remove(role);
|
||||||
|
|
||||||
const embed = new PublicEmbed(context, "", `Removed role: ${role.name}`);
|
const embed = new PublicEmbed(context, "", `Removed role: ${role.name}`);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import { existsSync, readFileSync } from "fs";
|
import { existsSync, readFileSync } from "fs";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
import { Command } from "../type/command";
|
import { Command } from "../type/command";
|
||||||
|
@ -21,11 +22,15 @@ export default class Rules extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||||
if (!existsSync(process.env.COMMANDS_RULES_FILE!)) {
|
if (!existsSync(`${process.cwd()}/${process.env.COMMANDS_RULES_FILE!}`)) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Rules file doesn't exist");
|
const errorEmbed = new ErrorEmbed(context, "Rules file doesn't exist");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const rulesFile = readFileSync(`${process.cwd()}/${process.env.COMMANDS_RULES_FILE}`).toString();
|
const rulesFile = readFileSync(`${process.cwd()}/${process.env.COMMANDS_RULES_FILE}`).toString();
|
||||||
|
@ -43,5 +48,10 @@ export default class Rules extends Command {
|
||||||
});
|
});
|
||||||
|
|
||||||
embeds.forEach(x => x.SendToCurrentChannel());
|
embeds.forEach(x => x.SendToCurrentChannel());
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: embeds
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import ErrorMessages from "../constants/ErrorMessages";
|
import ErrorMessages from "../constants/ErrorMessages";
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import LogEmbed from "../helpers/embeds/LogEmbed";
|
import LogEmbed from "../helpers/embeds/LogEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
|
@ -15,13 +16,17 @@ export default class Unmute extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async execute(context: ICommandContext) {
|
public override async execute(context: ICommandContext): Promise<ICommandReturnContext> {
|
||||||
const targetUser = context.message.mentions.users.first();
|
const targetUser = context.message.mentions.users.first();
|
||||||
|
|
||||||
if (!targetUser) {
|
if (!targetUser) {
|
||||||
const embed = new ErrorEmbed(context, "User does not exist");
|
const embed = new ErrorEmbed(context, "User does not exist");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetMember = context.message.guild?.member(targetUser);
|
const targetMember = context.message.guild?.member(targetUser);
|
||||||
|
@ -29,7 +34,11 @@ export default class Unmute extends Command {
|
||||||
if (!targetMember) {
|
if (!targetMember) {
|
||||||
const embed = new ErrorEmbed(context, "User is not in this server");
|
const embed = new ErrorEmbed(context, "User is not in this server");
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasonArgs = context.args;
|
const reasonArgs = context.args;
|
||||||
|
@ -38,13 +47,20 @@ export default class Unmute extends Command {
|
||||||
const reason = reasonArgs.join(" ");
|
const reason = reasonArgs.join(" ");
|
||||||
|
|
||||||
if (!context.message.guild?.available) {
|
if (!context.message.guild?.available) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetMember.manageable) {
|
if (!targetMember.manageable) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
const embed = new ErrorEmbed(context, ErrorMessages.InsufficientBotPermissions);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const logEmbed = new LogEmbed(context, "Member Unmuted");
|
const logEmbed = new LogEmbed(context, "Member Unmuted");
|
||||||
|
@ -60,12 +76,21 @@ export default class Unmute extends Command {
|
||||||
if (!mutedRole) {
|
if (!mutedRole) {
|
||||||
const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound);
|
const embed = new ErrorEmbed(context, ErrorMessages.RoleNotFound);
|
||||||
embed.SendToCurrentChannel();
|
embed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await targetMember.roles.remove(mutedRole, reason);
|
await targetMember.roles.remove(mutedRole, reason);
|
||||||
|
|
||||||
logEmbed.SendToModLogsChannel();
|
logEmbed.SendToModLogsChannel();
|
||||||
publicEmbed.SendToCurrentChannel();
|
publicEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [logEmbed, publicEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { ICommandContext } from "../contracts/ICommandContext";
|
import { ICommandContext } from "../contracts/ICommandContext";
|
||||||
|
import ICommandReturnContext from "../contracts/ICommandReturnContext";
|
||||||
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
import ErrorEmbed from "../helpers/embeds/ErrorEmbed";
|
||||||
import LogEmbed from "../helpers/embeds/LogEmbed";
|
import LogEmbed from "../helpers/embeds/LogEmbed";
|
||||||
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
import PublicEmbed from "../helpers/embeds/PublicEmbed";
|
||||||
|
@ -14,21 +15,29 @@ export default class Warn extends Command {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override execute(context: ICommandContext) {
|
public override execute(context: ICommandContext): ICommandReturnContext {
|
||||||
const user = context.message.mentions.users.first();
|
const user = context.message.mentions.users.first();
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Please specify a valid user");
|
const errorEmbed = new ErrorEmbed(context, "User does not exist");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const member = context.message.guild?.member(user);
|
const member = context.message.guild?.member(user);
|
||||||
|
|
||||||
if (!member) {
|
if (!member) {
|
||||||
const errorEmbed = new ErrorEmbed(context, "Please specify a valid user");
|
const errorEmbed = new ErrorEmbed(context, "User is not in this server");
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [errorEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const reasonArgs = context.args;
|
const reasonArgs = context.args;
|
||||||
|
@ -37,7 +46,10 @@ export default class Warn extends Command {
|
||||||
const reason = reasonArgs.join(" ");
|
const reason = reasonArgs.join(" ");
|
||||||
|
|
||||||
if (!context.message.guild?.available) {
|
if (!context.message.guild?.available) {
|
||||||
return;
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const logEmbed = new LogEmbed(context, "Member Warned");
|
const logEmbed = new LogEmbed(context, "Member Warned");
|
||||||
|
@ -50,5 +62,10 @@ export default class Warn extends Command {
|
||||||
|
|
||||||
logEmbed.SendToModLogsChannel();
|
logEmbed.SendToModLogsChannel();
|
||||||
publicEmbed.SendToCurrentChannel();
|
publicEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
commandContext: context,
|
||||||
|
embeds: [logEmbed, publicEmbed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
7
src/contracts/ICommandReturnContext.ts
Normal file
7
src/contracts/ICommandReturnContext.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { MessageEmbed } from "discord.js";
|
||||||
|
import { ICommandContext } from "./ICommandContext";
|
||||||
|
|
||||||
|
export default interface ICommandReturnContext {
|
||||||
|
commandContext: ICommandContext,
|
||||||
|
embeds: MessageEmbed[]
|
||||||
|
}
|
6
src/contracts/IEventReturnContext.ts
Normal file
6
src/contracts/IEventReturnContext.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { MessageEmbed } from "discord.js";
|
||||||
|
import { ICommandContext } from "./ICommandContext";
|
||||||
|
|
||||||
|
export default interface ICommandReturnContext {
|
||||||
|
embeds: MessageEmbed[]
|
||||||
|
}
|
|
@ -2,35 +2,48 @@ import { Event } from "../type/event";
|
||||||
import { GuildMember } from "discord.js";
|
import { GuildMember } from "discord.js";
|
||||||
import EventEmbed from "../helpers/embeds/EventEmbed";
|
import EventEmbed from "../helpers/embeds/EventEmbed";
|
||||||
import GuildMemberUpdate from "./MemberEvents/GuildMemberUpdate";
|
import GuildMemberUpdate from "./MemberEvents/GuildMemberUpdate";
|
||||||
|
import IEventReturnContext from "../contracts/IEventReturnContext";
|
||||||
|
|
||||||
export default class MemberEvents extends Event {
|
export default class MemberEvents extends Event {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override guildMemberAdd(member: GuildMember) {
|
public override guildMemberAdd(member: GuildMember): IEventReturnContext {
|
||||||
const embed = new EventEmbed(member.guild, "Member Joined");
|
const embed = new EventEmbed(member.guild, "Member Joined");
|
||||||
embed.AddUser("User", member.user, true);
|
embed.AddUser("User", member.user, true);
|
||||||
embed.addField("Created", member.user.createdAt);
|
embed.addField("Created", member.user.createdAt);
|
||||||
embed.setFooter(`Id: ${member.user.id}`);
|
embed.setFooter(`Id: ${member.user.id}`);
|
||||||
|
|
||||||
embed.SendToMemberLogsChannel();
|
embed.SendToMemberLogsChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override guildMemberRemove(member: GuildMember) {
|
public override guildMemberRemove(member: GuildMember): IEventReturnContext {
|
||||||
const embed = new EventEmbed(member.guild, "Member Left");
|
const embed = new EventEmbed(member.guild, "Member Left");
|
||||||
embed.AddUser("User", member.user, true);
|
embed.AddUser("User", member.user, true);
|
||||||
embed.addField("Joined", member.joinedAt);
|
embed.addField("Joined", member.joinedAt);
|
||||||
embed.setFooter(`Id: ${member.user.id}`);
|
embed.setFooter(`Id: ${member.user.id}`);
|
||||||
|
|
||||||
embed.SendToMemberLogsChannel();
|
embed.SendToMemberLogsChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember) {
|
public override guildMemberUpdate(oldMember: GuildMember, newMember: GuildMember): IEventReturnContext {
|
||||||
const handler = new GuildMemberUpdate(oldMember, newMember);
|
const handler = new GuildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
if (oldMember.nickname != newMember.nickname) { // Nickname change
|
if (oldMember.nickname != newMember.nickname) { // Nickname change
|
||||||
handler.NicknameChanged();
|
handler.NicknameChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,30 @@
|
||||||
import { GuildMember } from "discord.js";
|
import { GuildMember } from "discord.js";
|
||||||
|
import IEventReturnContext from "../../contracts/IEventReturnContext";
|
||||||
import EventEmbed from "../../helpers/embeds/EventEmbed";
|
import EventEmbed from "../../helpers/embeds/EventEmbed";
|
||||||
|
|
||||||
export default class GuildMemberUpdate {
|
export default class GuildMemberUpdate {
|
||||||
private _oldMember: GuildMember;
|
public oldMember: GuildMember;
|
||||||
private _newMember: GuildMember;
|
public newMember: GuildMember;
|
||||||
|
|
||||||
constructor(oldMember: GuildMember, newMember: GuildMember) {
|
constructor(oldMember: GuildMember, newMember: GuildMember) {
|
||||||
this._oldMember = oldMember;
|
this.oldMember = oldMember;
|
||||||
this._newMember = newMember;
|
this.newMember = newMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NicknameChanged() {
|
public NicknameChanged(): IEventReturnContext {
|
||||||
const oldNickname = this._oldMember.nickname || "*none*";
|
const oldNickname = this.oldMember.nickname || "*none*";
|
||||||
const newNickname = this._newMember.nickname || "*none*";
|
const newNickname = this.newMember.nickname || "*none*";
|
||||||
|
|
||||||
const embed = new EventEmbed(this._newMember.guild, "Nickname Changed");
|
const embed = new EventEmbed(this.newMember.guild, "Nickname Changed");
|
||||||
embed.AddUser("User", this._newMember.user, true);
|
embed.AddUser("User", this.newMember.user, true);
|
||||||
embed.addField("Before", oldNickname, true);
|
embed.addField("Before", oldNickname, true);
|
||||||
embed.addField("After", newNickname, true);
|
embed.addField("After", newNickname, true);
|
||||||
embed.setFooter(`Id: ${this._newMember.user.id}`);
|
embed.setFooter(`Id: ${this.newMember.user.id}`);
|
||||||
|
|
||||||
embed.SendToMemberLogsChannel();
|
embed.SendToMemberLogsChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,29 +1,60 @@
|
||||||
import { Event } from "../type/event";
|
import { Event } from "../type/event";
|
||||||
import { Message } from "discord.js";
|
import { Message } from "discord.js";
|
||||||
import EventEmbed from "../helpers/embeds/EventEmbed";
|
import EventEmbed from "../helpers/embeds/EventEmbed";
|
||||||
|
import IEventReturnContext from "../contracts/IEventReturnContext";
|
||||||
|
|
||||||
export default class MessageEvents extends Event {
|
export default class MessageEvents extends Event {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override messageDelete(message: Message) {
|
public override messageDelete(message: Message): IEventReturnContext {
|
||||||
if (!message.guild) return;
|
if (!message.guild) {
|
||||||
if (message.author.bot) return;
|
return {
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.author.bot) {
|
||||||
|
return {
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const embed = new EventEmbed(message.guild, "Message Deleted");
|
const embed = new EventEmbed(message.guild, "Message Deleted");
|
||||||
embed.AddUser("User", message.author, true);
|
embed.AddUser("User", message.author, true);
|
||||||
embed.addField("Channel", message.channel, true);
|
embed.addField("Channel", message.channel, true);
|
||||||
embed.addField("Content", `\`\`\`${message.content || "*none*"}\`\`\``);
|
embed.addField("Content", `\`\`\`${message.content || "*none*"}\`\`\``);
|
||||||
embed.addField("Attachments", `\`\`\`${message.attachments.map(x => x.url).join("\n")}`);
|
|
||||||
|
if (message.attachments.size > 0) {
|
||||||
|
embed.addField("Attachments", `\`\`\`${message.attachments.map(x => x.url).join("\n")}\`\`\``);
|
||||||
|
}
|
||||||
|
|
||||||
embed.SendToMessageLogsChannel();
|
embed.SendToMessageLogsChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override messageUpdate(oldMessage: Message, newMessage: Message) {
|
public override messageUpdate(oldMessage: Message, newMessage: Message): IEventReturnContext {
|
||||||
if (!newMessage.guild) return;
|
if (!newMessage.guild){
|
||||||
if (newMessage.author.bot) return;
|
return {
|
||||||
if (oldMessage.content == newMessage.content) return;
|
embeds: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newMessage.author.bot) {
|
||||||
|
return {
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldMessage.content == newMessage.content) {
|
||||||
|
return {
|
||||||
|
embeds: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const embed = new EventEmbed(newMessage.guild, "Message Edited");
|
const embed = new EventEmbed(newMessage.guild, "Message Edited");
|
||||||
embed.AddUser("User", newMessage.author, true);
|
embed.AddUser("User", newMessage.author, true);
|
||||||
|
@ -32,5 +63,9 @@ export default class MessageEvents extends Event {
|
||||||
embed.addField("After", `\`\`\`${newMessage.content || "*none*"}\`\`\``);
|
embed.addField("After", `\`\`\`${newMessage.content || "*none*"}\`\`\``);
|
||||||
|
|
||||||
embed.SendToMessageLogsChannel();
|
embed.SendToMessageLogsChannel();
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [embed]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import { MessageEmbed } from "discord.js";
|
||||||
import { ICommandContext } from "../../contracts/ICommandContext";
|
import { ICommandContext } from "../../contracts/ICommandContext";
|
||||||
|
|
||||||
export default class ErrorEmbed extends MessageEmbed {
|
export default class ErrorEmbed extends MessageEmbed {
|
||||||
private _context: ICommandContext;
|
public context: ICommandContext;
|
||||||
|
|
||||||
constructor(context: ICommandContext, message: String) {
|
constructor(context: ICommandContext, message: String) {
|
||||||
super();
|
super();
|
||||||
|
@ -10,10 +10,10 @@ export default class ErrorEmbed extends MessageEmbed {
|
||||||
super.setColor(process.env.EMBED_COLOUR_ERROR!);
|
super.setColor(process.env.EMBED_COLOUR_ERROR!);
|
||||||
super.setDescription(message);
|
super.setDescription(message);
|
||||||
|
|
||||||
this._context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendToCurrentChannel() {
|
public SendToCurrentChannel() {
|
||||||
this._context.message.channel.send(this);
|
this.context.message.channel.send(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { MessageEmbed, TextChannel, User, Guild } from "discord.js";
|
import { MessageEmbed, TextChannel, User, Guild } from "discord.js";
|
||||||
|
|
||||||
export default class EventEmbed extends MessageEmbed {
|
export default class EventEmbed extends MessageEmbed {
|
||||||
private _guild: Guild;
|
public guild: Guild;
|
||||||
|
|
||||||
constructor(guild: Guild, title: string) {
|
constructor(guild: Guild, title: string) {
|
||||||
super();
|
super();
|
||||||
|
@ -9,25 +9,25 @@ export default class EventEmbed extends MessageEmbed {
|
||||||
super.setColor(process.env.EMBED_COLOUR!);
|
super.setColor(process.env.EMBED_COLOUR!);
|
||||||
super.setTitle(title);
|
super.setTitle(title);
|
||||||
|
|
||||||
this._guild = guild;
|
this.guild = guild;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail methods
|
// Detail methods
|
||||||
public AddUser(title: string, user: User, setThumbnail: boolean = false) {
|
public AddUser(title: string, user: User, setThumbnail: boolean = false) {
|
||||||
super.addField(title, `${user} \`${user.tag}\``, true);
|
this.addField(title, `${user} \`${user.tag}\``, true);
|
||||||
|
|
||||||
if (setThumbnail) {
|
if (setThumbnail) {
|
||||||
super.setThumbnail(user.displayAvatarURL());
|
this.setThumbnail(user.displayAvatarURL());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddReason(message: String) {
|
public AddReason(message: String) {
|
||||||
super.addField("Reason", message || "*none*");
|
this.addField("Reason", message || "*none*");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send methods
|
// Send methods
|
||||||
public SendToChannel(name: string) {
|
public SendToChannel(name: string) {
|
||||||
const channel = this._guild.channels.cache
|
const channel = this.guild.channels.cache
|
||||||
.find(channel => channel.name == name) as TextChannel;
|
.find(channel => channel.name == name) as TextChannel;
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { ICommandContext } from "../../contracts/ICommandContext";
|
||||||
import ErrorEmbed from "./ErrorEmbed";
|
import ErrorEmbed from "./ErrorEmbed";
|
||||||
|
|
||||||
export default class LogEmbed extends MessageEmbed {
|
export default class LogEmbed extends MessageEmbed {
|
||||||
private _context: ICommandContext;
|
public context: ICommandContext;
|
||||||
|
|
||||||
constructor(context: ICommandContext, title: string) {
|
constructor(context: ICommandContext, title: string) {
|
||||||
super();
|
super();
|
||||||
|
@ -12,33 +12,33 @@ export default class LogEmbed extends MessageEmbed {
|
||||||
super.setColor(process.env.EMBED_COLOUR!);
|
super.setColor(process.env.EMBED_COLOUR!);
|
||||||
super.setTitle(title);
|
super.setTitle(title);
|
||||||
|
|
||||||
this._context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail methods
|
// Detail methods
|
||||||
public AddUser(title: string, user: User, setThumbnail: boolean = false) {
|
public AddUser(title: string, user: User, setThumbnail: boolean = false) {
|
||||||
super.addField(title, `${user} \`${user.tag}\``, true);
|
this.addField(title, `${user} \`${user.tag}\``, true);
|
||||||
|
|
||||||
if (setThumbnail) {
|
if (setThumbnail) {
|
||||||
super.setThumbnail(user.displayAvatarURL());
|
this.setThumbnail(user.displayAvatarURL());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddReason(message: String) {
|
public AddReason(message: String) {
|
||||||
super.addField("Reason", message || "*none*");
|
this.addField("Reason", message || "*none*");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send methods
|
// Send methods
|
||||||
public SendToCurrentChannel() {
|
public SendToCurrentChannel() {
|
||||||
this._context.message.channel.send(this);
|
this.context.message.channel.send(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendToChannel(name: string) {
|
public SendToChannel(name: string) {
|
||||||
const channel = this._context.message.guild?.channels.cache
|
const channel = this.context.message.guild?.channels.cache
|
||||||
.find(channel => channel.name == name) as TextChannel;
|
.find(channel => channel.name == name) as TextChannel;
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
const errorEmbed = new ErrorEmbed(this._context, ErrorMessages.ChannelNotFound);
|
const errorEmbed = new ErrorEmbed(this.context, ErrorMessages.ChannelNotFound);
|
||||||
errorEmbed.SendToCurrentChannel();
|
errorEmbed.SendToCurrentChannel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { MessageEmbed } from "discord.js";
|
||||||
import { ICommandContext } from "../../contracts/ICommandContext";
|
import { ICommandContext } from "../../contracts/ICommandContext";
|
||||||
|
|
||||||
export default class PublicEmbed extends MessageEmbed {
|
export default class PublicEmbed extends MessageEmbed {
|
||||||
private _context: ICommandContext;
|
public context: ICommandContext;
|
||||||
|
|
||||||
constructor(context: ICommandContext, title: string, description: string) {
|
constructor(context: ICommandContext, title: string, description: string) {
|
||||||
super();
|
super();
|
||||||
|
@ -11,16 +11,16 @@ export default class PublicEmbed extends MessageEmbed {
|
||||||
super.setTitle(title);
|
super.setTitle(title);
|
||||||
super.setDescription(description);
|
super.setDescription(description);
|
||||||
|
|
||||||
this._context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail methods
|
// Detail methods
|
||||||
public AddReason(message: String) {
|
public AddReason(message: String) {
|
||||||
super.addField("Reason", message || "*none*");
|
this.addField("Reason", message || "*none*");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send methods
|
// Send methods
|
||||||
public SendToCurrentChannel() {
|
public SendToCurrentChannel() {
|
||||||
this._context.message.channel.send(this);
|
this.context.message.channel.send(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
import { Command } from "../../../src/type/command";
|
|
||||||
|
|
||||||
export default class noCategory extends Command {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { Command } from "../../../src/type/command";
|
|
||||||
|
|
||||||
export default class normal extends Command {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this._category = "General";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { Command } from "../../../src/type/command";
|
|
||||||
|
|
||||||
export default class roles extends Command {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this._roles = [ "Moderator" ];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
import { Event } from "../../../src/type/event";
|
|
||||||
|
|
||||||
export class normal extends Event {
|
|
||||||
public override channelCreate() {}
|
|
||||||
}
|
|
10
tests/_mocks/commands/mockCmd.ts
Normal file
10
tests/_mocks/commands/mockCmd.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { Command } from "../../../src/type/command";
|
||||||
|
|
||||||
|
export default class MockCmd extends Command {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
super._category = "General";
|
||||||
|
super._roles = ["Moderator"];
|
||||||
|
}
|
||||||
|
}
|
13
tests/_mocks/rules/rules.json
Normal file
13
tests/_mocks/rules/rules.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"image": "IMAGEURL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "TITLE 1",
|
||||||
|
"description": [
|
||||||
|
"DESCRIPTION 1A",
|
||||||
|
"DESCRIPTION 1B"
|
||||||
|
],
|
||||||
|
"footer": "FOOTER 1"
|
||||||
|
}
|
||||||
|
]
|
|
@ -4,6 +4,9 @@ import { Client } from "discord.js";
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
import { Events } from "../../src/client/events";
|
import { Events } from "../../src/client/events";
|
||||||
import { Util } from "../../src/client/util";
|
import { Util } from "../../src/client/util";
|
||||||
|
import { Command } from "../../src/type/command";
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
import { Event } from "../../src/type/event";
|
||||||
|
|
||||||
jest.mock("discord.js");
|
jest.mock("discord.js");
|
||||||
jest.mock("dotenv");
|
jest.mock("dotenv");
|
||||||
|
@ -136,4 +139,29 @@ describe('Start', () => {
|
||||||
|
|
||||||
expect(() => coreClient.start()).toThrow("FOLDERS_EVENTS is not defined in .env");
|
expect(() => coreClient.start()).toThrow("FOLDERS_EVENTS is not defined in .env");
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('RegisterCommand', () => {
|
||||||
|
test('Expect command added to register', () => {
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const client = new CoreClient();
|
||||||
|
client.RegisterCommand("test", cmd);
|
||||||
|
|
||||||
|
expect(client.commandItems.length).toBe(1);
|
||||||
|
expect(client.commandItems[0].Name).toBe("test");
|
||||||
|
expect(client.commandItems[0].Command).toBe(cmd);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('RegisterEvent', () => {
|
||||||
|
test('Expect event added to register', () => {
|
||||||
|
const evt = mock<Event>();
|
||||||
|
|
||||||
|
const client = new CoreClient();
|
||||||
|
client.RegisterEvent(evt);
|
||||||
|
|
||||||
|
expect(client.eventItems.length).toBe(1);
|
||||||
|
expect(client.eventItems[0].Event).toBe(evt);
|
||||||
|
});
|
||||||
});
|
});
|
|
@ -1,7 +1,9 @@
|
||||||
import { Events } from "../../src/client/events";
|
import { Events } from "../../src/client/events";
|
||||||
|
import { Message } from "discord.js";
|
||||||
import { Message, Client, TextChannel, Guild, SnowflakeUtil, DMChannel } from "discord.js";
|
|
||||||
import { Util } from "../../src/client/util";
|
import { Util } from "../../src/client/util";
|
||||||
|
import ICommandItem from "../../src/contracts/ICommandItem";
|
||||||
|
import { Command } from "../../src/type/command";
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
jest.mock("../../src/client/util");
|
jest.mock("../../src/client/util");
|
||||||
|
|
||||||
|
@ -27,10 +29,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "!test first",
|
content: "!test first",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
expect(result.valid).toBeTruthy();
|
||||||
|
|
||||||
|
@ -58,10 +69,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "!test first",
|
content: "!test first",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Message was not sent in a guild, ignoring.");
|
expect(result.message).toBe("Message was not sent in a guild, ignoring.");
|
||||||
|
@ -84,10 +104,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "!test first",
|
content: "!test first",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Message was sent by a bot, ignoring.");
|
expect(result.message).toBe("Message was sent by a bot, ignoring.");
|
||||||
|
@ -110,10 +139,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "This is a standard message",
|
content: "This is a standard message",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Message was not a command, ignoring.");
|
expect(result.message).toBe("Message was not a command, ignoring.");
|
||||||
|
@ -136,10 +174,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "!",
|
content: "!",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Command name was not found");
|
expect(result.message).toBe("Command name was not found");
|
||||||
|
@ -162,10 +209,19 @@ describe('OnMessage', () => {
|
||||||
},
|
},
|
||||||
content: "!test first",
|
content: "!test first",
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
const result = await events.onMessage(message);
|
const result = await events.onMessage(message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Command failed");
|
expect(result.message).toBe("Command failed");
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import { Util } from "../../src/client/util";
|
import { Util } from "../../src/client/util";
|
||||||
|
|
||||||
import { Client, Guild, Message, Role, SnowflakeUtil, TextChannel, User } from "discord.js";
|
import { Client, Message } from "discord.js";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
import { Command } from "../../src/type/command";
|
||||||
|
import ICommandItem from "../../src/contracts/ICommandItem";
|
||||||
|
import IEventItem from "../../src/contracts/IEventItem";
|
||||||
|
import { Event } from "../../src/type/event";
|
||||||
|
|
||||||
jest.mock("fs");
|
jest.mock("fs");
|
||||||
|
|
||||||
|
@ -17,9 +22,6 @@ describe('LoadCommand', () => {
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -31,12 +33,22 @@ describe('LoadCommand', () => {
|
||||||
},
|
},
|
||||||
reply: jest.fn(),
|
reply: jest.fn(),
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
expect(result.valid).toBeTruthy();
|
||||||
|
expect(cmd.execute).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given Member Is Null, Expect Failed Result', () => {
|
test('Given Member Is Null, Expect Failed Result', () => {
|
||||||
|
@ -46,81 +58,27 @@ describe('LoadCommand', () => {
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: null
|
member: null
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Member is not part of message");
|
expect(result.message).toBe("Member is not part of message");
|
||||||
});
|
expect(cmd.execute).not.toBeCalled();
|
||||||
|
|
||||||
test('Given Folder Does Not Exist, Expect Failed Result', () => {
|
|
||||||
process.env = {
|
|
||||||
BOT_TOKEN: 'TOKEN',
|
|
||||||
BOT_PREFIX: '!',
|
|
||||||
FOLDERS_COMMANDS: 'commands',
|
|
||||||
FOLDERS_EVENTS: 'events',
|
|
||||||
}
|
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(false);
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
member: {
|
|
||||||
roles: {
|
|
||||||
cache: {
|
|
||||||
find: jest.fn().mockReturnValue(true),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
reply: jest.fn(),
|
|
||||||
} as unknown as Message;
|
|
||||||
|
|
||||||
const util = new Util();
|
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
|
||||||
expect(result.message).toBe("Command folder does not exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Given File Does Not Exist, Expect Failed Result', () => {
|
|
||||||
process.env = {
|
|
||||||
BOT_TOKEN: 'TOKEN',
|
|
||||||
BOT_PREFIX: '!',
|
|
||||||
FOLDERS_COMMANDS: 'commands',
|
|
||||||
FOLDERS_EVENTS: 'events',
|
|
||||||
}
|
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValueOnce(true)
|
|
||||||
.mockReturnValue(false);
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
member: {
|
|
||||||
roles: {
|
|
||||||
cache: {
|
|
||||||
find: jest.fn().mockReturnValue(true),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
reply: jest.fn(),
|
|
||||||
} as unknown as Message;
|
|
||||||
|
|
||||||
const util = new Util();
|
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
|
||||||
expect(result.message).toBe("File does not exist");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given User Does Have Role, Expect Successful Result', () => {
|
test('Given User Does Have Role, Expect Successful Result', () => {
|
||||||
|
@ -130,9 +88,6 @@ describe('LoadCommand', () => {
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -144,12 +99,22 @@ describe('LoadCommand', () => {
|
||||||
},
|
},
|
||||||
reply: jest.fn(),
|
reply: jest.fn(),
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("roles", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
expect(result.valid).toBeTruthy();
|
||||||
|
expect(cmd.execute).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given User Does Not Have Role, Expect Failed Result', () => {
|
test('Given User Does Not Have Role, Expect Failed Result', () => {
|
||||||
|
@ -159,9 +124,6 @@ describe('LoadCommand', () => {
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -173,42 +135,24 @@ describe('LoadCommand', () => {
|
||||||
},
|
},
|
||||||
reply: jest.fn(),
|
reply: jest.fn(),
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
cmd._roles = [ "Moderator" ];
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("roles", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("You require the `Moderator` role to run this command");
|
expect(result.message).toBe("You require the `Moderator` role to run this command");
|
||||||
});
|
expect(cmd.execute).not.toBeCalled();
|
||||||
|
|
||||||
test('Given Command Category Is Null, Expect Successful Result', () => {
|
|
||||||
process.env = {
|
|
||||||
BOT_TOKEN: 'TOKEN',
|
|
||||||
BOT_PREFIX: '!',
|
|
||||||
FOLDERS_COMMANDS: 'commands',
|
|
||||||
FOLDERS_EVENTS: 'events',
|
|
||||||
}
|
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
|
||||||
member: {
|
|
||||||
roles: {
|
|
||||||
cache: {
|
|
||||||
find: jest.fn().mockReturnValue(true),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
reply: jest.fn(),
|
|
||||||
} as unknown as Message;
|
|
||||||
|
|
||||||
const util = new Util();
|
|
||||||
|
|
||||||
const result = util.loadCommand("noCategory", [ "first" ], message);
|
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given command is set to disabled, Expect command to not fire', () => {
|
test('Given command is set to disabled, Expect command to not fire', () => {
|
||||||
|
@ -217,12 +161,9 @@ describe('LoadCommand', () => {
|
||||||
BOT_PREFIX: '!',
|
BOT_PREFIX: '!',
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
COMMANDS_DISABLED: 'normal',
|
COMMANDS_DISABLED: 'test',
|
||||||
COMMANDS_DISABLED_MESSAGE: 'disabled',
|
COMMANDS_DISABLED_MESSAGE: 'disabled',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -236,14 +177,24 @@ describe('LoadCommand', () => {
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
const messageReply = jest.spyOn(message, 'reply');
|
const messageReply = jest.spyOn(message, 'reply');
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Command is disabled");
|
expect(result.message).toBe("Command is disabled");
|
||||||
expect(messageReply).toBeCalledWith("disabled");
|
expect(messageReply).toBeCalledWith("disabled");
|
||||||
|
expect(cmd.execute).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given command COMMANDS_DISABLED_MESSAGE is empty, Expect default message sent', () => {
|
test('Given command COMMANDS_DISABLED_MESSAGE is empty, Expect default message sent', () => {
|
||||||
|
@ -252,11 +203,8 @@ describe('LoadCommand', () => {
|
||||||
BOT_PREFIX: '!',
|
BOT_PREFIX: '!',
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
COMMANDS_DISABLED: 'normal',
|
COMMANDS_DISABLED: 'test',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -270,14 +218,24 @@ describe('LoadCommand', () => {
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
const messageReply = jest.spyOn(message, 'reply');
|
const messageReply = jest.spyOn(message, 'reply');
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Command is disabled");
|
expect(result.message).toBe("Command is disabled");
|
||||||
expect(messageReply).toBeCalledWith("This command is disabled.");
|
expect(messageReply).toBeCalledWith("This command is disabled.");
|
||||||
|
expect(cmd.execute).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given a different command is disabled, Expect command to still fire', () => {
|
test('Given a different command is disabled, Expect command to still fire', () => {
|
||||||
|
@ -286,11 +244,8 @@ describe('LoadCommand', () => {
|
||||||
BOT_PREFIX: '!',
|
BOT_PREFIX: '!',
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
COMMANDS_DISABLED: 'anything',
|
COMMANDS_DISABLED: 'other',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -302,25 +257,38 @@ describe('LoadCommand', () => {
|
||||||
},
|
},
|
||||||
reply: jest.fn(),
|
reply: jest.fn(),
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const cmd = mock<Command>();
|
||||||
|
const otherCmd = mock<Command>();
|
||||||
|
|
||||||
|
const commandItem: ICommandItem = {
|
||||||
|
Name: "test",
|
||||||
|
Command: cmd
|
||||||
|
};
|
||||||
|
|
||||||
|
const otherCommandItem: ICommandItem = {
|
||||||
|
Name: "other",
|
||||||
|
Command: otherCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [ commandItem, otherCommandItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
expect(result.valid).toBeTruthy();
|
||||||
|
expect(cmd.execute).toBeCalled();
|
||||||
|
expect(otherCmd.execute).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given a different command is disabled with this one, Expect command to not fire', () => {
|
test('Given command is not found in register, expect command not found error', () => {
|
||||||
process.env = {
|
process.env = {
|
||||||
BOT_TOKEN: 'TOKEN',
|
BOT_TOKEN: 'TOKEN',
|
||||||
BOT_PREFIX: '!',
|
BOT_PREFIX: '!',
|
||||||
FOLDERS_COMMANDS: 'commands',
|
FOLDERS_COMMANDS: 'commands',
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
COMMANDS_DISABLED: 'normal,anything,',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
member: {
|
member: {
|
||||||
|
@ -332,13 +300,16 @@ describe('LoadCommand', () => {
|
||||||
},
|
},
|
||||||
reply: jest.fn(),
|
reply: jest.fn(),
|
||||||
} as unknown as Message;
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const commands: ICommandItem[] = [];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadCommand("normal", [ "first" ], message);
|
const result = util.loadCommand("test", [ "first" ], message, commands);
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
expect(result.valid).toBeFalsy();
|
||||||
expect(result.message).toBe("Command is disabled");
|
expect(result.message).toBe('Command not found');
|
||||||
|
expect(message.reply).toBeCalledWith('Command not found');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -351,17 +322,21 @@ describe('LoadEvents', () => {
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
fs.readdirSync = jest.fn().mockReturnValue(["normal.ts"]);
|
|
||||||
|
|
||||||
const client = {
|
const client = {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
} as unknown as Client;
|
} as unknown as Client;
|
||||||
|
|
||||||
|
const evt = mock<Event>();
|
||||||
|
|
||||||
|
const eventItem: IEventItem = {
|
||||||
|
Event: evt
|
||||||
|
};
|
||||||
|
|
||||||
|
const eventItems: IEventItem[] = [ eventItem ];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadEvents(client);
|
const result = util.loadEvents(client, eventItems);
|
||||||
|
|
||||||
const clientOn = jest.spyOn(client, 'on');
|
const clientOn = jest.spyOn(client, 'on');
|
||||||
|
|
||||||
|
@ -377,45 +352,19 @@ describe('LoadEvents', () => {
|
||||||
FOLDERS_EVENTS: 'events',
|
FOLDERS_EVENTS: 'events',
|
||||||
}
|
}
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(true);
|
|
||||||
fs.readdirSync = jest.fn().mockReturnValue(["normal"]);
|
|
||||||
|
|
||||||
const client = {
|
const client = {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
} as unknown as Client;
|
} as unknown as Client;
|
||||||
|
|
||||||
|
const eventItems: IEventItem[] = [];
|
||||||
|
|
||||||
const util = new Util();
|
const util = new Util();
|
||||||
|
|
||||||
const result = util.loadEvents(client);
|
const result = util.loadEvents(client, eventItems);
|
||||||
|
|
||||||
const clientOn = jest.spyOn(client, 'on');
|
const clientOn = jest.spyOn(client, 'on');
|
||||||
|
|
||||||
expect(result.valid).toBeTruthy();
|
expect(result.valid).toBeTruthy();
|
||||||
expect(clientOn).toBeCalledTimes(0);
|
expect(clientOn).toBeCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Given Event Folder Does Not Exist, Expect Failed Result', () => {
|
|
||||||
process.env = {
|
|
||||||
BOT_TOKEN: 'TOKEN',
|
|
||||||
BOT_PREFIX: '!',
|
|
||||||
FOLDERS_COMMANDS: 'commands',
|
|
||||||
FOLDERS_EVENTS: 'events',
|
|
||||||
}
|
|
||||||
|
|
||||||
process.cwd = jest.fn().mockReturnValue("../../tests/__mocks");
|
|
||||||
fs.existsSync = jest.fn().mockReturnValue(false);
|
|
||||||
fs.readdirSync = jest.fn().mockReturnValue(["normal.ts"]);
|
|
||||||
|
|
||||||
const client = {
|
|
||||||
on: jest.fn(),
|
|
||||||
} as unknown as Client;
|
|
||||||
|
|
||||||
const util = new Util();
|
|
||||||
|
|
||||||
const result = util.loadEvents(client);
|
|
||||||
|
|
||||||
expect(result.valid).toBeFalsy();
|
|
||||||
expect(result.message).toBe("Event folder does not exist");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
152
tests/commands/about.test.ts
Normal file
152
tests/commands/about.test.ts
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
import About from "../../src/commands/about";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
import PublicEmbed from "../../src/helpers/embeds/PublicEmbed";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect values set', () => {
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
expect(about._category).toBe("General");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Expect embed to be made and sent to the current channel', async () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_VER: "BOT_VER",
|
||||||
|
BOT_AUTHOR: "BOT_AUTHOR",
|
||||||
|
BOT_DATE: "BOT_DATE"
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = mock<Message>();
|
||||||
|
message.channel.send = jest.fn();
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "about",
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
const result = await about.execute(context);
|
||||||
|
|
||||||
|
expect(message.channel.send).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Expect embed send to have values', async () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_VER: "BOT_VER",
|
||||||
|
BOT_AUTHOR: "BOT_AUTHOR",
|
||||||
|
BOT_DATE: "BOT_DATE"
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = mock<Message>();
|
||||||
|
message.channel.send = jest.fn();
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "about",
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
const result = await about.execute(context);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('About');
|
||||||
|
expect(embed.description).toBe('');
|
||||||
|
expect(embed.fields.length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Expect version field to have values', async () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_VER: "BOT_VER",
|
||||||
|
BOT_AUTHOR: "BOT_AUTHOR",
|
||||||
|
BOT_DATE: "BOT_DATE"
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = mock<Message>();
|
||||||
|
message.channel.send = jest.fn();
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "about",
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
const result = await about.execute(context);
|
||||||
|
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
const field = embed.fields[0];
|
||||||
|
|
||||||
|
expect(field.name).toBe('Version');
|
||||||
|
expect(field.value).toBe('BOT_VER');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Expect author field to have values', async () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_VER: "BOT_VER",
|
||||||
|
BOT_AUTHOR: "BOT_AUTHOR",
|
||||||
|
BOT_DATE: "BOT_DATE"
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = mock<Message>();
|
||||||
|
message.channel.send = jest.fn();
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "about",
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
const result = await about.execute(context);
|
||||||
|
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
const field = embed.fields[1];
|
||||||
|
|
||||||
|
expect(field.name).toBe('Author');
|
||||||
|
expect(field.value).toBe('BOT_AUTHOR');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Expect version field to have values', async () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_VER: "BOT_VER",
|
||||||
|
BOT_AUTHOR: "BOT_AUTHOR",
|
||||||
|
BOT_DATE: "BOT_DATE"
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = mock<Message>();
|
||||||
|
message.channel.send = jest.fn();
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "about",
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const about = new About();
|
||||||
|
|
||||||
|
const result = await about.execute(context);
|
||||||
|
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
const field = embed.fields[2];
|
||||||
|
|
||||||
|
expect(field.name).toBe('Date');
|
||||||
|
expect(field.value).toBe('BOT_DATE');
|
||||||
|
});
|
||||||
|
});
|
566
tests/commands/ban.test.ts
Normal file
566
tests/commands/ban.test.ts
Normal file
|
@ -0,0 +1,566 @@
|
||||||
|
import { GuildMember, Message, TextChannel, User } from "discord.js";
|
||||||
|
import Ban from "../../src/commands/ban";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect values to be set', () => {
|
||||||
|
process.env.ROLES_MODERATOR = 'Moderator';
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
expect(ban._category).toBe('Moderation');
|
||||||
|
expect(ban._roles.length).toBe(1);
|
||||||
|
expect(ban._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect user to be banned', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).toBeCalledTimes(1);
|
||||||
|
expect(mentionedMember.ban).toBeCalledWith({ reason: 'Test Reason' });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user has permissions, expect embeds to be correct', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
const publicEmbed = result.embeds[1];
|
||||||
|
|
||||||
|
expect(logEmbed.title).toBe('Member Banned');
|
||||||
|
expect(publicEmbed.title).toBe("");
|
||||||
|
expect(publicEmbed.description).toBe('[object Object] has been banned');
|
||||||
|
expect(logEmbed.fields.length).toBe(3);
|
||||||
|
expect(publicEmbed.fields.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user has permission, expect logEmbed fields to be correct', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn().mockReturnValue('URL'),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
const fieldUser = logEmbed.fields[0];
|
||||||
|
const fieldModerator = logEmbed.fields[1];
|
||||||
|
const fieldReason = logEmbed.fields[2];
|
||||||
|
|
||||||
|
expect(fieldUser.name).toBe("User");
|
||||||
|
expect(fieldUser.value).toBe("[object Object] `USERTAG`");
|
||||||
|
expect(logEmbed.thumbnail?.url).toBe("URL");
|
||||||
|
|
||||||
|
expect(fieldModerator.name).toBe('Moderator');
|
||||||
|
expect(fieldModerator.value).toBe('[object Object] `AUTHORTAG`');
|
||||||
|
|
||||||
|
expect(fieldReason.name).toBe('Reason');
|
||||||
|
expect(fieldReason.value).toBe('Test Reason');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user is not mentioned, expect error embed to be sent', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(mentionedMember.ban).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embedError = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedError.description).toBe('User does not exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given member is not in server, expect error embed to be sent', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(mentionedMember.ban).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embedError = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedError.description).toBe('User is not in this server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given guild is unavailable, expect return and do nothing', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: true,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: false
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(mentionedMember.ban).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given bot cant ban user, expect error embed to be sent', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
bannable: false,
|
||||||
|
ban: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'ban',
|
||||||
|
args: ['ban', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const ban = new Ban();
|
||||||
|
|
||||||
|
const result = await ban.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(mentionedMember.ban).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embedError = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedError.description).toBe('Unable to do this action, am I missing permissions?');
|
||||||
|
});
|
||||||
|
});
|
178
tests/commands/clear.test.ts
Normal file
178
tests/commands/clear.test.ts
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import Clear from "../../src/commands/clear";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect values to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: "Moderator"
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
|
||||||
|
expect(clear._category).toBe('Moderation');
|
||||||
|
expect(clear._roles.length).toBe(1);
|
||||||
|
expect(clear._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given valid arguments, expect messages to be cleared', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageChannelBulkDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend,
|
||||||
|
bulkDelete: messageChannelBulkDelete
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'clear',
|
||||||
|
args: ['5'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
const result = await clear.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelBulkDelete).toBeCalledWith(5);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// PublicEmbed
|
||||||
|
const publicEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(publicEmbed.title).toBe('');
|
||||||
|
expect(publicEmbed.description).toBe('5 message(s) were removed');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given argument is not given, expect error embed to be sent', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageChannelBulkDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend,
|
||||||
|
bulkDelete: messageChannelBulkDelete
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'clear',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
const result = await clear.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelBulkDelete).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.title).toBeNull();
|
||||||
|
expect(errorEmbed.description).toBe('Please specify an amount between 1 and 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given argument is not a number, expect error embed to be sent', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageChannelBulkDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend,
|
||||||
|
bulkDelete: messageChannelBulkDelete
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'clear',
|
||||||
|
args: ['A'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
const result = await clear.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelBulkDelete).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.title).toBeNull();
|
||||||
|
expect(errorEmbed.description).toBe('Please specify an amount between 1 and 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given argument is less than 1, expect error embed to be sent', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageChannelBulkDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend,
|
||||||
|
bulkDelete: messageChannelBulkDelete
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'clear',
|
||||||
|
args: ['0'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
const result = await clear.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelBulkDelete).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.title).toBeNull();
|
||||||
|
expect(errorEmbed.description).toBe('Please specify an amount between 1 and 100');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given argument is more than 100, expect error embed to be sent', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageChannelBulkDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend,
|
||||||
|
bulkDelete: messageChannelBulkDelete
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'clear',
|
||||||
|
args: ['101'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = new Clear();
|
||||||
|
const result = await clear.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelBulkDelete).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.title).toBeNull();
|
||||||
|
expect(errorEmbed.description).toBe('Please specify an amount between 1 and 100');
|
||||||
|
});
|
||||||
|
});
|
136
tests/commands/eval.test.ts
Normal file
136
tests/commands/eval.test.ts
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import Evaluate from "../../src/commands/eval";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect values to be set', () => {
|
||||||
|
const evaluate = new Evaluate();
|
||||||
|
|
||||||
|
expect(evaluate._category).toBe('Owner');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect eval statement ran', () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_OWNERID: 'OWNERID'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log = jest.fn();
|
||||||
|
global.eval = jest.fn()
|
||||||
|
.mockReturnValue('General Kenobi');
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
author: {
|
||||||
|
id: 'OWNERID'
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'eval',
|
||||||
|
args: ['echo', 'Hello', 'there'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const evaluate = new Evaluate();
|
||||||
|
|
||||||
|
const result = evaluate.execute(context);
|
||||||
|
|
||||||
|
expect(console.log).toBeCalledWith('Eval Statement: echo Hello there');
|
||||||
|
expect(global.eval).toBeCalledWith('echo Hello there');
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// PublicEmbed
|
||||||
|
const publicEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(publicEmbed.title).toBe('');
|
||||||
|
expect(publicEmbed.description).toBe('General Kenobi');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user does not have permission, expect nothing to occur', () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_OWNERID: 'DIFFERENT'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log = jest.fn();
|
||||||
|
global.eval = jest.fn()
|
||||||
|
.mockReturnValue('General Kenobi');
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
author: {
|
||||||
|
id: 'OWNERID'
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'eval',
|
||||||
|
args: ['echo', 'Hello', 'there'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const evaluate = new Evaluate();
|
||||||
|
|
||||||
|
const result = evaluate.execute(context);
|
||||||
|
|
||||||
|
expect(console.log).not.toBeCalled();
|
||||||
|
expect(global.eval).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given eval failed, expect error embed to be sent', () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_OWNERID: 'OWNERID'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log = jest.fn();
|
||||||
|
global.eval = jest.fn()
|
||||||
|
.mockImplementation(() => {
|
||||||
|
throw new Error('Error message');
|
||||||
|
});
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
author: {
|
||||||
|
id: 'OWNERID'
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'eval',
|
||||||
|
args: ['echo', 'Hello', 'there'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const evaluate = new Evaluate();
|
||||||
|
|
||||||
|
const result = evaluate.execute(context);
|
||||||
|
|
||||||
|
expect(console.log).toBeCalledWith('Eval Statement: echo Hello there');
|
||||||
|
expect(global.eval).toBeCalledWith('echo Hello there');
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.title).toBeNull();
|
||||||
|
expect(errorEmbed.description).toBe('Error: Error message');
|
||||||
|
});
|
||||||
|
});
|
267
tests/commands/help.test.ts
Normal file
267
tests/commands/help.test.ts
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
import Help, { ICommandData } from "../../src/commands/help";
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
const oldCwd = process.cwd();
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
expect(help._category).toBe('General');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given no arguments were given, expect SendAll to be executed', () => {
|
||||||
|
const message = {} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'help',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
help.SendAll = jest.fn();
|
||||||
|
help.SendSingle = jest.fn();
|
||||||
|
|
||||||
|
help.execute(context);
|
||||||
|
|
||||||
|
expect(help.SendAll).toBeCalled();
|
||||||
|
expect(help.SendSingle).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given an argument was given, expect SendSingle to be executed', () => {
|
||||||
|
const message = {} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'help',
|
||||||
|
args: ['about'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
help.SendAll = jest.fn();
|
||||||
|
help.SendSingle = jest.fn();
|
||||||
|
|
||||||
|
help.execute(context);
|
||||||
|
|
||||||
|
expect(help.SendAll).not.toBeCalled();
|
||||||
|
expect(help.SendSingle).toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendAll', () => {
|
||||||
|
test('Expect embed with all commands to be sent', () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'help',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
const commandData0: ICommandData = {
|
||||||
|
Exists: true,
|
||||||
|
Name: 'about',
|
||||||
|
Category: 'general',
|
||||||
|
Roles: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const commandData1: ICommandData = {
|
||||||
|
Exists: true,
|
||||||
|
Name: 'role',
|
||||||
|
Category: 'general',
|
||||||
|
Roles: []
|
||||||
|
};
|
||||||
|
|
||||||
|
help.GetAllCommandData = jest.fn()
|
||||||
|
.mockReturnValue([commandData0, commandData1]);
|
||||||
|
|
||||||
|
const result = help.SendAll(context);
|
||||||
|
|
||||||
|
expect(help.GetAllCommandData).toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// PublicEmbed
|
||||||
|
const publicEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(publicEmbed.fields.length).toBe(1);
|
||||||
|
|
||||||
|
// PublicEmbed -> GeneralCategory Field
|
||||||
|
const publicEmbedFieldGeneral = publicEmbed.fields[0];
|
||||||
|
|
||||||
|
expect(publicEmbedFieldGeneral.name).toBe('General');
|
||||||
|
expect(publicEmbedFieldGeneral.value).toBe('about, role');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendSingle', () => {
|
||||||
|
test('Given command exists, expect embed to be sent with command fields', () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'help',
|
||||||
|
args: ['about'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const commandData: ICommandData = {
|
||||||
|
Exists: true,
|
||||||
|
Name: 'about',
|
||||||
|
Category: 'general',
|
||||||
|
Roles: ['role1', 'role2']
|
||||||
|
};
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
help.GetCommandData = jest.fn()
|
||||||
|
.mockReturnValue(commandData);
|
||||||
|
|
||||||
|
const result = help.SendSingle(context);
|
||||||
|
|
||||||
|
expect(help.GetCommandData).toBeCalledWith('about');
|
||||||
|
expect(messageChannelSend).toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// PublicEmbed
|
||||||
|
const publicEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(publicEmbed.title).toBe('About');
|
||||||
|
expect(publicEmbed.description).toBe('');
|
||||||
|
expect(publicEmbed.fields.length).toBe(2);
|
||||||
|
|
||||||
|
// PublicEmbed -> Category Field
|
||||||
|
const fieldCategory = publicEmbed.fields[0];
|
||||||
|
|
||||||
|
expect(fieldCategory.name).toBe('Category');
|
||||||
|
expect(fieldCategory.value).toBe('General');
|
||||||
|
|
||||||
|
// PublicEmbed -> RequiredRoles Field
|
||||||
|
const fieldRoles = publicEmbed.fields[1];
|
||||||
|
|
||||||
|
expect(fieldRoles.name).toBe('Required Roles');
|
||||||
|
expect(fieldRoles.value).toBe('Role1, Role2');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given command does not exist, expect error embed to be sent', () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'help',
|
||||||
|
args: ['about'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const commandData: ICommandData = {
|
||||||
|
Exists: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
help.GetCommandData = jest.fn()
|
||||||
|
.mockReturnValue(commandData);
|
||||||
|
|
||||||
|
const result = help.SendSingle(context);
|
||||||
|
|
||||||
|
expect(help.GetCommandData).toBeCalledWith('about');
|
||||||
|
expect(messageChannelSend).toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// ErrorEmbed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Command does not exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GetAllCommandData', () => {
|
||||||
|
test('Expect array of command data to be returned', () => {
|
||||||
|
process.env = {
|
||||||
|
FOLDERS_COMMANDS: "commands"
|
||||||
|
};
|
||||||
|
|
||||||
|
process.cwd = jest.fn()
|
||||||
|
.mockReturnValue(`${oldCwd}/tests/_mocks`);
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
const result = help.GetAllCommandData();
|
||||||
|
|
||||||
|
expect(result.length).toBe(1);
|
||||||
|
|
||||||
|
// Mock Command
|
||||||
|
const mockCommand = result[0];
|
||||||
|
|
||||||
|
expect(mockCommand.Exists).toBeTruthy();
|
||||||
|
expect(mockCommand.Name).toBe("mockCmd");
|
||||||
|
expect(mockCommand.Category).toBe("General");
|
||||||
|
|
||||||
|
expect(mockCommand.Roles!.length).toBe(1);
|
||||||
|
expect(mockCommand.Roles![0]).toBe("Moderator");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GetCommandData', () => {
|
||||||
|
test('Given command exists, expect data to be returned', () => {
|
||||||
|
process.env = {
|
||||||
|
FOLDERS_COMMANDS: "commands"
|
||||||
|
};
|
||||||
|
|
||||||
|
process.cwd = jest.fn()
|
||||||
|
.mockReturnValue(`${oldCwd}/tests/_mocks`);
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
const result = help.GetCommandData('mockCmd');
|
||||||
|
|
||||||
|
expect(result.Exists).toBeTruthy();
|
||||||
|
expect(result.Name).toBe("mockCmd");
|
||||||
|
expect(result.Category).toBe("General");
|
||||||
|
|
||||||
|
expect(result.Roles!.length).toBe(1);
|
||||||
|
expect(result.Roles![0]).toBe("Moderator");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given command does not exist, expect exists false to be returned', () => {
|
||||||
|
process.env = {
|
||||||
|
FOLDERS_COMMANDS: "commands"
|
||||||
|
};
|
||||||
|
|
||||||
|
const oldCwd = process.cwd();
|
||||||
|
|
||||||
|
process.cwd = jest.fn()
|
||||||
|
.mockReturnValue(`${oldCwd}/tests/_mocks`);
|
||||||
|
|
||||||
|
const help = new Help();
|
||||||
|
|
||||||
|
const result = help.GetCommandData('none');
|
||||||
|
|
||||||
|
expect(result.Exists).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
448
tests/commands/kick.test.ts
Normal file
448
tests/commands/kick.test.ts
Normal file
|
@ -0,0 +1,448 @@
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { GuildMember, Message, TextChannel, User } from "discord.js";
|
||||||
|
import Kick from "../../src/commands/kick";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: "Moderator"
|
||||||
|
};
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
expect(kick._category).toBe('Moderation');
|
||||||
|
expect(kick._roles.length).toBe(1);
|
||||||
|
expect(kick._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect user to be kicked', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
kickable: true,
|
||||||
|
kick: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "kick",
|
||||||
|
args: ["USER", "Test", "Reason"],
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
const result = await kick.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).toBeCalledTimes(1);
|
||||||
|
expect(member.kick).toBeCalledWith('Test Reason');
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
// Log Embed
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(logEmbed.title).toBe('Member Kicked');
|
||||||
|
expect(logEmbed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Log Embed -> User Field
|
||||||
|
const logEmbedFieldUser = logEmbed.fields[0];
|
||||||
|
|
||||||
|
expect(logEmbedFieldUser.name).toBe('User');
|
||||||
|
expect(logEmbedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(logEmbedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Log Embed -> Moderator Field
|
||||||
|
const logEmbedFieldModerator = logEmbed.fields[1];
|
||||||
|
|
||||||
|
expect(logEmbedFieldModerator.name).toBe('Moderator');
|
||||||
|
expect(logEmbedFieldModerator.value).toBe('[object Object] `AUTHORTAG`');
|
||||||
|
|
||||||
|
// Log Embed -> Reason Field
|
||||||
|
const logEmbedFieldReason = logEmbed.fields[2];
|
||||||
|
|
||||||
|
expect(logEmbedFieldReason.name).toBe('Reason');
|
||||||
|
expect(logEmbedFieldReason.value).toBe('Test Reason');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given target user is not found, expect user does not exist error', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
kickable: true,
|
||||||
|
kick: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "kick",
|
||||||
|
args: ["USER", "Test", "Reason"],
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
const result = await kick.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(member.kick).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe(null);
|
||||||
|
expect(embed.description).toBe('User does not exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given target member is not found, expect user is not in this server error', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
kickable: true,
|
||||||
|
kick: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "kick",
|
||||||
|
args: ["USER", "Test", "Reason"],
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
const result = await kick.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(member.kick).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe(null);
|
||||||
|
expect(embed.description).toBe('User is not in this server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given guild is not available, expect to stop', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
kickable: true,
|
||||||
|
kick: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: false
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "kick",
|
||||||
|
args: ["USER", "Test", "Reason"],
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
const result = await kick.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(member.kick).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given client can not kick member, expect error', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
kickable: false,
|
||||||
|
kick: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: "kick",
|
||||||
|
args: ["USER", "Test", "Reason"],
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
|
||||||
|
const kick = new Kick();
|
||||||
|
|
||||||
|
const result = await kick.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(member.kick).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe(null);
|
||||||
|
expect(embed.description).toBe('Unable to do this action, am I missing permissions?');
|
||||||
|
});
|
||||||
|
});
|
675
tests/commands/mute.test.ts
Normal file
675
tests/commands/mute.test.ts
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { GuildMember, Message, Role, TextChannel, User } from "discord.js";
|
||||||
|
import Mute from "../../src/commands/mute";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
expect(mute._category).toBe("Moderation");
|
||||||
|
expect(mute._roles.length).toBe(1);
|
||||||
|
expect(mute._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect user to be given muted role', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(member.roles.add).toBeCalledWith(role, 'Test Reason');
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
// Log Embed
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(logEmbed.title).toBe('Member Muted');
|
||||||
|
expect(logEmbed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Log Embed -> User Field
|
||||||
|
const logEmbedUserField = logEmbed.fields[0];
|
||||||
|
|
||||||
|
expect(logEmbedUserField.name).toBe('User');
|
||||||
|
expect(logEmbedUserField.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(logEmbedUserField.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Log Embed -> Moderator Field
|
||||||
|
const logEmbedModeratorField = logEmbed.fields[1];
|
||||||
|
|
||||||
|
expect(logEmbedModeratorField.name).toBe('Moderator');
|
||||||
|
expect(logEmbedModeratorField.value).toBe('[object Object] `AUTHORTAG`');
|
||||||
|
|
||||||
|
// Public Embed
|
||||||
|
const publicEmbed = result.embeds[1];
|
||||||
|
|
||||||
|
expect(publicEmbed.title).toBe('');
|
||||||
|
expect(publicEmbed.description).toBe('[object Object] has been muted');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user did not mention a user, expect user not to exist', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).not.toBeCalled();
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('User does not exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given member can not be found from user, expect user to not be in server', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('User is not in this server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given guild is unavailable, expect execution to stop', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: false,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given client can not manage user, expect insufficient permissions', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: false,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Unable to do this action, am I missing permissions?');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given muted role can not be found, expect role not found', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
add: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Mute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Unable to find role');
|
||||||
|
});
|
||||||
|
});
|
262
tests/commands/poll.test.ts
Normal file
262
tests/commands/poll.test.ts
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
import { Message, MessageEmbed } from "discord.js";
|
||||||
|
import Poll from "../../src/commands/poll";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
expect(poll._category).toBe('General');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given input is valid, expect poll to be generated', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: true
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: ['Test', 'title;', 'one;', 'two'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).toBeCalledTimes(1);
|
||||||
|
expect(returnMessageReact).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Test title');
|
||||||
|
expect(embed.description).toBe(':one: one\n:two: two');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given message is not deletable by client, expect it not to attempt deletion', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: false
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: ['Test', 'title;', 'one;', 'two'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).not.toBeCalled();
|
||||||
|
expect(returnMessageReact).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Test title');
|
||||||
|
expect(embed.description).toBe(':one: one\n:two: two');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given no arguments, expect error embed', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: true
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).not.toBeCalled();
|
||||||
|
expect(returnMessageReact).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Usage: <title>;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given only 1 option, expect error embed', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: true
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: ['Test', 'title;', 'one'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).not.toBeCalled();
|
||||||
|
expect(returnMessageReact).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Usage: <title>;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given 9 options, expect poll to be generated', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: true
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: ['Test', 'title;', 'one;', 'two;', 'three;', 'four;', 'five;', 'six;', 'seven;', 'eight;', 'nine'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).toBeCalledTimes(1);
|
||||||
|
expect(returnMessageReact).toBeCalledTimes(9);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Test title');
|
||||||
|
expect(embed.description).toBe(':one: one\n:two: two\n:three: three\n:four: four\n:five: five\n:six: six\n:seven: seven\n:eight: eight\n:nine: nine');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given 10 options, expect error embed', async () => {
|
||||||
|
const returnMessageReact = jest.fn();
|
||||||
|
|
||||||
|
const returnMessage = {
|
||||||
|
react: returnMessageReact
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn()
|
||||||
|
.mockReturnValue(returnMessage);
|
||||||
|
const messageDelete = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
delete: messageDelete,
|
||||||
|
deletable: true
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'poll',
|
||||||
|
args: ['Test', 'title;', 'one;', 'two;', 'three;', 'four;', 'five;', 'six;', 'seven;', 'eight;', 'nine;', 'ten'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const poll = new Poll();
|
||||||
|
|
||||||
|
const result = await poll.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(messageDelete).not.toBeCalled();
|
||||||
|
expect(returnMessageReact).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Usage: <title>;<option 1>;<option 2>... (separate options with semicolons), maximum of 9 options');
|
||||||
|
});
|
||||||
|
});
|
411
tests/commands/role.test.ts
Normal file
411
tests/commands/role.test.ts
Normal file
|
@ -0,0 +1,411 @@
|
||||||
|
import { GuildMemberRoleManager, Message, Role as DiscordRole } from "discord.js";
|
||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
import Role from "../../src/commands/role";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties are set', () => {
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
expect(role._category).toBe("General");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given no arguments were given, expect SendRolesList to be executed', async () => {
|
||||||
|
process.env = {
|
||||||
|
COMMANDS_ROLE_ROLES: 'One,Two'
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = {} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.SendRolesList = jest.fn();
|
||||||
|
role.ToggleRole = jest.fn();
|
||||||
|
|
||||||
|
await role.execute(context);
|
||||||
|
|
||||||
|
expect(role.SendRolesList).toBeCalledWith(context, ['One', 'Two']);
|
||||||
|
expect(role.ToggleRole).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given an argument was given, expect ToggleRole to be executed', async () => {
|
||||||
|
process.env = {
|
||||||
|
COMMANDS_ROLE_ROLES: 'One,Two'
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = {} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.SendRolesList = jest.fn();
|
||||||
|
role.ToggleRole = jest.fn();
|
||||||
|
|
||||||
|
await role.execute(context);
|
||||||
|
|
||||||
|
expect(role.SendRolesList).not.toBeCalled();
|
||||||
|
expect(role.ToggleRole).toBeCalledWith(context, ['One', 'Two']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendRolesList', () => {
|
||||||
|
test('Expect embed with roles to be sent to the current channel', () => {
|
||||||
|
process.env = {
|
||||||
|
BOT_PREFIX: '!'
|
||||||
|
};
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles = ['One', 'Two'];
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
const result = role.SendRolesList(context, roles);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Roles');
|
||||||
|
expect(embed.description).toBe('Do !role <role> to get the role!\nOne\nTwo');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ToggleRole', () => {
|
||||||
|
test('Given role name is a valid role AND user does not have the role, expect role to be added', async () => {
|
||||||
|
const discordRole = {} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const messageMemberRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(discordRole);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageMemberRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles = ['One', 'Two'];
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.AddRole = jest.fn();
|
||||||
|
role.RemoveRole = jest.fn();
|
||||||
|
|
||||||
|
const result = await role.ToggleRole(context, roles);
|
||||||
|
|
||||||
|
expect(messageMemberRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
expect(role.AddRole).toBeCalledWith(context, discordRole);
|
||||||
|
expect(role.RemoveRole).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given role name is a valid role AND user has the role, expect role to be removed', async () => {
|
||||||
|
const discordRole = {} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const messageMemberRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(discordRole);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(discordRole);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageMemberRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles = ['One', 'Two'];
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.AddRole = jest.fn();
|
||||||
|
role.RemoveRole = jest.fn();
|
||||||
|
|
||||||
|
const result = await role.ToggleRole(context, roles);
|
||||||
|
|
||||||
|
expect(messageMemberRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
expect(role.AddRole).not.toBeCalled();
|
||||||
|
expect(role.RemoveRole).toBeCalledWith(context, discordRole);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given role requested is not in the roles array, expect role not assignable error', async () => {
|
||||||
|
const discordRole = {} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const messageMemberRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(discordRole);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageMemberRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['Three'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles = ['One', 'Two'];
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.AddRole = jest.fn();
|
||||||
|
role.RemoveRole = jest.fn();
|
||||||
|
|
||||||
|
const result = await role.ToggleRole(context, roles);
|
||||||
|
|
||||||
|
expect(messageMemberRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(role.AddRole).not.toBeCalled();
|
||||||
|
expect(role.RemoveRole).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe("This role isn't marked as assignable, to see a list of assignable roles, run this command without any parameters");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given the role is not in the guild, expect error', async () => {
|
||||||
|
const discordRole = {} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const messageMemberRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageMemberRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles = ['One', 'Two'];
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
role.AddRole = jest.fn();
|
||||||
|
role.RemoveRole = jest.fn();
|
||||||
|
|
||||||
|
const result = await role.ToggleRole(context, roles);
|
||||||
|
|
||||||
|
expect(messageMemberRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(role.AddRole).not.toBeCalled();
|
||||||
|
expect(role.RemoveRole).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe("The current server doesn't have this role. Please contact the server's moderators");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('AddRole', () => {
|
||||||
|
test('Expect role to be added to user', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const guildMemberRoleManager = mock<GuildMemberRoleManager>();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: guildMemberRoleManager
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const discordRole = {
|
||||||
|
name: 'One'
|
||||||
|
} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
const result = await role.AddRole(context, discordRole);
|
||||||
|
|
||||||
|
expect(guildMemberRoleManager.add).toBeCalledWith(discordRole);
|
||||||
|
expect(messageChannelSend).toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('');
|
||||||
|
expect(embed.description).toBe('Gave role: One');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('RemoveRole', () => {
|
||||||
|
test('Expect role to be removed from user', async () => {
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const guildMemberRoleManager = mock<GuildMemberRoleManager>();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
member: {
|
||||||
|
roles: guildMemberRoleManager
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'role',
|
||||||
|
args: ['One'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const discordRole = {
|
||||||
|
name: 'One'
|
||||||
|
} as unknown as DiscordRole;
|
||||||
|
|
||||||
|
const role = new Role();
|
||||||
|
|
||||||
|
const result = await role.RemoveRole(context, discordRole);
|
||||||
|
|
||||||
|
expect(guildMemberRoleManager.remove).toBeCalledWith(discordRole);
|
||||||
|
expect(messageChannelSend).toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('');
|
||||||
|
expect(embed.description).toBe('Removed role: One');
|
||||||
|
});
|
||||||
|
});
|
106
tests/commands/rules.test.ts
Normal file
106
tests/commands/rules.test.ts
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import Rules from "../../src/commands/rules";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
const oldCwd = process.cwd();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: "Moderator"
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = new Rules();
|
||||||
|
|
||||||
|
expect(rules._category).toBe("Admin");
|
||||||
|
expect(rules._roles.length).toBe(1);
|
||||||
|
expect(rules._roles[0]).toBe("Moderator");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given rules exist, expect rules to be sent to current channel', () => {
|
||||||
|
process.env = {
|
||||||
|
COMMANDS_RULES_FILE: 'rules/rules.json'
|
||||||
|
};
|
||||||
|
|
||||||
|
process.cwd = jest.fn()
|
||||||
|
.mockReturnValue(`${oldCwd}/tests/_mocks`);
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'rules',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = new Rules();
|
||||||
|
|
||||||
|
const result = rules.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(2);
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
// Header Embed
|
||||||
|
const embedHeader = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedHeader.title).toBe("");
|
||||||
|
expect(embedHeader.description).toBe("");
|
||||||
|
expect(embedHeader.image?.url).toBe("IMAGEURL");
|
||||||
|
expect(embedHeader.footer?.text).toBe("");
|
||||||
|
|
||||||
|
// Main Embed
|
||||||
|
const embedMain = result.embeds[1];
|
||||||
|
|
||||||
|
expect(embedMain.title).toBe("TITLE 1");
|
||||||
|
expect(embedMain.description).toBe("DESCRIPTION 1A\nDESCRIPTION 1B");
|
||||||
|
expect(embedMain.image?.url).toBe("");
|
||||||
|
expect(embedMain.footer?.text).toBe("FOOTER 1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given rules file does not exist, expect does not exist error', () => {
|
||||||
|
process.env = {
|
||||||
|
COMMANDS_RULES_FILE: 'rules/none.json'
|
||||||
|
};
|
||||||
|
|
||||||
|
process.cwd = jest.fn()
|
||||||
|
.mockReturnValue(`${oldCwd}/tests/_mocks`);
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'rules',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = new Rules();
|
||||||
|
|
||||||
|
const result = rules.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe("Rules file doesn't exist");
|
||||||
|
});
|
||||||
|
});
|
673
tests/commands/unmute.test.ts
Normal file
673
tests/commands/unmute.test.ts
Normal file
|
@ -0,0 +1,673 @@
|
||||||
|
import { GuildMember, Message, Role, TextChannel, User } from "discord.js";
|
||||||
|
import Unmute from "../../src/commands/unmute";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
expect(mute._category).toBe("Moderation");
|
||||||
|
expect(mute._roles.length).toBe(1);
|
||||||
|
expect(mute._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect user to be given muted role', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(member.roles.remove).toBeCalledWith(role, 'Test Reason');
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
// Log Embed
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(logEmbed.title).toBe('Member Unmuted');
|
||||||
|
expect(logEmbed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Log Embed -> User Field
|
||||||
|
const logEmbedUserField = logEmbed.fields[0];
|
||||||
|
|
||||||
|
expect(logEmbedUserField.name).toBe('User');
|
||||||
|
expect(logEmbedUserField.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(logEmbedUserField.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Log Embed -> Moderator Field
|
||||||
|
const logEmbedModeratorField = logEmbed.fields[1];
|
||||||
|
|
||||||
|
expect(logEmbedModeratorField.name).toBe('Moderator');
|
||||||
|
expect(logEmbedModeratorField.value).toBe('[object Object] `AUTHORTAG`');
|
||||||
|
|
||||||
|
// Public Embed
|
||||||
|
const publicEmbed = result.embeds[1];
|
||||||
|
|
||||||
|
expect(publicEmbed.title).toBe('');
|
||||||
|
expect(publicEmbed.description).toBe('[object Object] has been unmuted');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user did not mention a user, expect user not to exist', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).not.toBeCalled();
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('User does not exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given member can not be found from user, expect user to not be in server', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('User is not in this server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given guild is unavailable, expect execution to stop', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: false,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given client can not manage user, expect insufficient permissions', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: false,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): Role | undefined => {
|
||||||
|
const result = callback(role);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
});
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).not.toBeCalled();
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Unable to do this action, am I missing permissions?');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given muted role can not be found, expect role not found', async () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs',
|
||||||
|
ROLES_MUTED: 'Muted'
|
||||||
|
};
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageAuthor = {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const member = {
|
||||||
|
manageable: true,
|
||||||
|
roles: {
|
||||||
|
remove: jest.fn()
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const role = {
|
||||||
|
name: 'Muted'
|
||||||
|
} as unknown as Role;
|
||||||
|
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(user);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(member);
|
||||||
|
const messageGuildRolesCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(undefined);
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember,
|
||||||
|
available: true,
|
||||||
|
roles: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildRolesCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: messageAuthor
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'mute',
|
||||||
|
args: ['USER', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const mute = new Unmute();
|
||||||
|
|
||||||
|
const result = await mute.execute(context);
|
||||||
|
|
||||||
|
expect(messageMentionsUsersFirst).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildMember).toBeCalledWith(user);
|
||||||
|
expect(messageGuildRolesCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Error Embed
|
||||||
|
const errorEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(errorEmbed.description).toBe('Unable to find role');
|
||||||
|
});
|
||||||
|
});
|
485
tests/commands/warn.test.ts
Normal file
485
tests/commands/warn.test.ts
Normal file
|
@ -0,0 +1,485 @@
|
||||||
|
import { GuildMember, Message, TextChannel, User } from "discord.js";
|
||||||
|
import Warn from "../../src/commands/warn";
|
||||||
|
import { ICommandContext } from "../../src/contracts/ICommandContext";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect values to be set', () => {
|
||||||
|
process.env.ROLES_MODERATOR = 'Moderator';
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
expect(warn._category).toBe('Moderation');
|
||||||
|
expect(warn._roles.length).toBe(1);
|
||||||
|
expect(warn._roles[0]).toBe('Moderator');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Execute', () => {
|
||||||
|
test('Given user has permission, expect user to be warnned', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user has permissions, expect embeds to be correct', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(2);
|
||||||
|
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
const publicEmbed = result.embeds[1];
|
||||||
|
|
||||||
|
expect(logEmbed.title).toBe('Member Warned');
|
||||||
|
expect(publicEmbed.title).toBe("");
|
||||||
|
expect(publicEmbed.description).toBe('[object Object] has been warned');
|
||||||
|
expect(logEmbed.fields.length).toBe(3);
|
||||||
|
expect(publicEmbed.fields.length).toBe(1);
|
||||||
|
expect(publicEmbed.fields[0].name).toBe('Reason');
|
||||||
|
expect(publicEmbed.fields[0].value).toBe('Test Reason');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user has permission, expect logEmbed fields to be correct', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn().mockReturnValue('URL'),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
const logEmbed = result.embeds[0];
|
||||||
|
|
||||||
|
const fieldUser = logEmbed.fields[0];
|
||||||
|
const fieldModerator = logEmbed.fields[1];
|
||||||
|
const fieldReason = logEmbed.fields[2];
|
||||||
|
|
||||||
|
expect(fieldUser.name).toBe("User");
|
||||||
|
expect(fieldUser.value).toBe("[object Object] `USERTAG`");
|
||||||
|
expect(logEmbed.thumbnail?.url).toBe("URL");
|
||||||
|
|
||||||
|
expect(fieldModerator.name).toBe('Moderator');
|
||||||
|
expect(fieldModerator.value).toBe('[object Object] `AUTHORTAG`');
|
||||||
|
|
||||||
|
expect(fieldReason.name).toBe('Reason');
|
||||||
|
expect(fieldReason.value).toBe('Test Reason');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given user is not mentioned, expect error embed to be sent', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embedError = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedError.description).toBe('User does not exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given member is not in server, expect error embed to be sent', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: true
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledTimes(1);
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
const embedError = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embedError.description).toBe('User is not in this server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given guild is unavailable, expect return and do nothing', async () => {
|
||||||
|
process.env = {
|
||||||
|
ROLES_MODERATOR: 'Moderator',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mentionedUser = {
|
||||||
|
displayAvatarURL: jest.fn(),
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
const mentionedMember = {
|
||||||
|
warnnable: true,
|
||||||
|
warn: jest.fn()
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
const logChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
const messageMentionsUsersFirst = jest.fn()
|
||||||
|
.mockReturnValue(mentionedUser);
|
||||||
|
const messageGuildMember = jest.fn()
|
||||||
|
.mockReturnValue(mentionedMember);
|
||||||
|
const messageGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockImplementation((callback): TextChannel | undefined => {
|
||||||
|
const result = callback(logChannel);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
mentions: {
|
||||||
|
users: {
|
||||||
|
first: messageMentionsUsersFirst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guild: {
|
||||||
|
member: messageGuildMember ,
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: messageGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
},
|
||||||
|
available: false
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
tag: 'AUTHORTAG'
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'warn',
|
||||||
|
args: ['warn', 'Test', 'Reason'],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const warn = new Warn();
|
||||||
|
|
||||||
|
const result = await warn.execute(context);
|
||||||
|
|
||||||
|
expect(messageChannelSend).not.toBeCalled();
|
||||||
|
expect(logChannel.send).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
164
tests/events/MemberEvents.test.ts
Normal file
164
tests/events/MemberEvents.test.ts
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
import { GuildMember, TextChannel, User } from "discord.js";
|
||||||
|
import MemberEvents from "../../src/events/MemberEvents";
|
||||||
|
import GuildMemberUpdate from "../../src/events/MemberEvents/GuildMemberUpdate";
|
||||||
|
|
||||||
|
describe('GuildMemberAdd', () => {
|
||||||
|
test('When event is fired, expect embed to be sent to logs channel', () => {
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const userDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const guildUser = {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
createdAt: currentDate,
|
||||||
|
id: 'USERID',
|
||||||
|
displayAvatarURL: userDisplayAvatarURL
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const guildMember = {
|
||||||
|
user: guildUser,
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const memberEvents = new MemberEvents();
|
||||||
|
|
||||||
|
const result = memberEvents.guildMemberAdd(guildMember);
|
||||||
|
|
||||||
|
expect(textChannel.send).toBeCalledTimes(1);
|
||||||
|
expect(userDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe("Member Joined");
|
||||||
|
expect(embed.footer?.text).toBe("Id: USERID");
|
||||||
|
expect(embed.fields.length).toBe(2);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe("User");
|
||||||
|
expect(embedFieldUser.value).toBe("[object Object] `USERTAG`");
|
||||||
|
expect(embedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Created Field
|
||||||
|
const embedFieldCreated = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldCreated.name).toBe("Created");
|
||||||
|
expect(embedFieldCreated.value).toBe(currentDate.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GuildMemberRemove', () => {
|
||||||
|
test('When event is fired, expect embed to be sent to logs channel', () => {
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
send: jest.fn()
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const userDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const guildUser = {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
createdAt: currentDate,
|
||||||
|
id: 'USERID',
|
||||||
|
displayAvatarURL: userDisplayAvatarURL
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const guildMember = {
|
||||||
|
user: guildUser,
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
joinedAt: currentDate
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const memberEvents = new MemberEvents();
|
||||||
|
|
||||||
|
const result = memberEvents.guildMemberRemove(guildMember);
|
||||||
|
|
||||||
|
expect(textChannel.send).toBeCalledTimes(1);
|
||||||
|
expect(userDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe("Member Left");
|
||||||
|
expect(embed.footer?.text).toBe("Id: USERID");
|
||||||
|
expect(embed.fields.length).toBe(2);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe("User");
|
||||||
|
expect(embedFieldUser.value).toBe("[object Object] `USERTAG`");
|
||||||
|
expect(embedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Joined Field
|
||||||
|
const embedFieldJoined = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldJoined.name).toBe("Joined");
|
||||||
|
expect(embedFieldJoined.value).toBe(currentDate.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('GuildMemberUpdate', () => {
|
||||||
|
test('Given nicknames are the same, expect NicknameChanged NOT to be called', () => {
|
||||||
|
const member = {
|
||||||
|
nickname: 'member'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const nicknameChanged = jest.fn();
|
||||||
|
|
||||||
|
GuildMemberUpdate.prototype.NicknameChanged = nicknameChanged;
|
||||||
|
|
||||||
|
const memberEvents = new MemberEvents();
|
||||||
|
|
||||||
|
const result = memberEvents.guildMemberUpdate(member, member);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
expect(nicknameChanged).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given nicknames are the different, expect NicknameChanged to be called', () => {
|
||||||
|
const oldMember = {
|
||||||
|
nickname: 'oldMember'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const newMember = {
|
||||||
|
nickname: 'newMember'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const nicknameChanged = jest.fn();
|
||||||
|
|
||||||
|
GuildMemberUpdate.prototype.NicknameChanged = nicknameChanged;
|
||||||
|
|
||||||
|
const memberEvents = new MemberEvents();
|
||||||
|
|
||||||
|
const result = memberEvents.guildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
expect(nicknameChanged).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
235
tests/events/MemberEvents/GuildMemberUpdate.test.ts
Normal file
235
tests/events/MemberEvents/GuildMemberUpdate.test.ts
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
import { GuildMember, TextChannel } from "discord.js";
|
||||||
|
import GuildMemberUpdate from "../../../src/events/MemberEvents/GuildMemberUpdate";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties are set', () => {
|
||||||
|
const oldMember = {
|
||||||
|
nickname: 'Old Nickname'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const newMember = {
|
||||||
|
nickname: 'New Nickname'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const guildMemberUpdate = new GuildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
|
expect(guildMemberUpdate.oldMember).toBe(oldMember);
|
||||||
|
expect(guildMemberUpdate.newMember).toBe(newMember);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('NicknameChanged', () => {
|
||||||
|
test('Given nickname has changed from one to another, expect embed to be sent with both', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const memberUserDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMember = {
|
||||||
|
nickname: 'Old Nickname'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const newMember = {
|
||||||
|
nickname: 'New Nickname',
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
id: 'USERID',
|
||||||
|
displayAvatarURL: memberUserDisplayAvatarURL
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const guildMemberUpdate = new GuildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
|
const result = guildMemberUpdate.NicknameChanged();
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(memberUserDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Nickname Changed');
|
||||||
|
expect(embed.footer?.text).toBe('Id: USERID');
|
||||||
|
expect(embed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('Old Nickname');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('New Nickname');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given old nickname was null, expect embed to say old nickname was none', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const memberUserDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMember = {} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const newMember = {
|
||||||
|
nickname: 'New Nickname',
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
id: 'USERID',
|
||||||
|
displayAvatarURL: memberUserDisplayAvatarURL
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const guildMemberUpdate = new GuildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
|
const result = guildMemberUpdate.NicknameChanged();
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(memberUserDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Nickname Changed');
|
||||||
|
expect(embed.footer?.text).toBe('Id: USERID');
|
||||||
|
expect(embed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('*none*');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('New Nickname');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given new nickname was null, expect embed to say new nickname was none', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const memberUserDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMember = {
|
||||||
|
nickname: 'Old Nickname'
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const newMember = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
id: 'USERID',
|
||||||
|
displayAvatarURL: memberUserDisplayAvatarURL
|
||||||
|
}
|
||||||
|
} as unknown as GuildMember;
|
||||||
|
|
||||||
|
const guildMemberUpdate = new GuildMemberUpdate(oldMember, newMember);
|
||||||
|
|
||||||
|
const result = guildMemberUpdate.NicknameChanged();
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(memberUserDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Nickname Changed');
|
||||||
|
expect(embed.footer?.text).toBe('Id: USERID');
|
||||||
|
expect(embed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('Old Nickname');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('*none*');
|
||||||
|
});
|
||||||
|
});
|
648
tests/events/MessageEvents.test.ts
Normal file
648
tests/events/MessageEvents.test.ts
Normal file
|
@ -0,0 +1,648 @@
|
||||||
|
import { Collection, Message, MessageAttachment, TextChannel } from "discord.js";
|
||||||
|
import MessageEvents from "../../src/events/MessageEvents";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('MessageDelete', () => {
|
||||||
|
test('Given message was in a guild AND user was NOT a bot, expect message deleted embed to be sent', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const messageAttachments = new Collection<string, MessageAttachment>([
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
{
|
||||||
|
url: 'image0.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
{
|
||||||
|
url: 'image1.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
channel: {},
|
||||||
|
content: 'Message Content',
|
||||||
|
attachments: messageAttachments
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageDelete(message);
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageAuthorDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Message Deleted');
|
||||||
|
expect(embed.fields.length).toBe(4);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
|
||||||
|
// Embed -> Channel Field
|
||||||
|
const embedFieldChannel = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldChannel.name).toBe('Channel');
|
||||||
|
expect(embedFieldChannel.value).toBe('[object Object]');
|
||||||
|
|
||||||
|
// Embed -> Content Field
|
||||||
|
const embedFieldContent = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldContent.name).toBe('Content');
|
||||||
|
expect(embedFieldContent.value).toBe('```Message Content```');
|
||||||
|
|
||||||
|
// Embed -> Attachments Field
|
||||||
|
const embedFieldAttachments = embed.fields[3];
|
||||||
|
|
||||||
|
expect(embedFieldAttachments.name).toBe('Attachments');
|
||||||
|
expect(embedFieldAttachments.value).toBe('```image0.png\nimage1.png```');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given message was not sent in a guild, expect execution stopped', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const messageAttachments = new Collection<string, MessageAttachment>([
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
{
|
||||||
|
url: 'image0.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
{
|
||||||
|
url: 'image1.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
channel: {},
|
||||||
|
content: 'Message Content',
|
||||||
|
attachments: messageAttachments
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageDelete(message);
|
||||||
|
|
||||||
|
expect(channelSend).not.toBeCalled();
|
||||||
|
expect(memberGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageAuthorDisplayAvatarURL).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given author is a bot, expect execution stopped', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const messageAttachments = new Collection<string, MessageAttachment>([
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
{
|
||||||
|
url: 'image0.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
{
|
||||||
|
url: 'image1.png'
|
||||||
|
} as unknown as MessageAttachment
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: true,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
channel: {},
|
||||||
|
content: 'Message Content',
|
||||||
|
attachments: messageAttachments
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageDelete(message);
|
||||||
|
|
||||||
|
expect(channelSend).not.toBeCalled();
|
||||||
|
expect(memberGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageAuthorDisplayAvatarURL).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given message does not contain any attachments, expect attachments field to be omitted', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const messageAttachments = new Collection<string, MessageAttachment>([]);
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
channel: {},
|
||||||
|
content: 'Message Content',
|
||||||
|
attachments: messageAttachments
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageDelete(message);
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageAuthorDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Message Deleted');
|
||||||
|
expect(embed.fields.length).toBe(3);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
|
||||||
|
// Embed -> Channel Field
|
||||||
|
const embedFieldChannel = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldChannel.name).toBe('Channel');
|
||||||
|
expect(embedFieldChannel.value).toBe('[object Object]');
|
||||||
|
|
||||||
|
// Embed -> Content Field
|
||||||
|
const embedFieldContent = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldContent.name).toBe('Content');
|
||||||
|
expect(embedFieldContent.value).toBe('```Message Content```');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('MessageUpdate', () => {
|
||||||
|
test('Given message is in a guild AND user is not a bot AND the content has actually changed, e xpect log embed to be sent', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {
|
||||||
|
content: 'Old Message'
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
content: 'New Message',
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageAuthorDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Message Edited');
|
||||||
|
expect(embed.fields.length).toBe(4);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(embedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Channel Field
|
||||||
|
const embedFieldChannel = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldChannel.name).toBe('Channel');
|
||||||
|
expect(embedFieldChannel.value).toBe('[object Object]');
|
||||||
|
expect(embedFieldChannel.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('```Old Message```');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[3];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('```New Message```');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given message was not in a guild, expect execution stopped', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {
|
||||||
|
content: 'Old Message'
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
content: 'New Message',
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).not.toBeCalled();
|
||||||
|
expect(memberGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageAuthorDisplayAvatarURL).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given author is a bot, expect execution stopped', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {
|
||||||
|
content: 'Old Message'
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: true,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
content: 'New Message',
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).not.toBeCalled();
|
||||||
|
expect(memberGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageAuthorDisplayAvatarURL).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given the message contents are the same, expect execution stopped', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {
|
||||||
|
content: 'Message'
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
content: 'Message',
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).not.toBeCalled();
|
||||||
|
expect(memberGuildChannelsCacheFind).not.toBeCalled();
|
||||||
|
expect(messageAuthorDisplayAvatarURL).not.toBeCalled();
|
||||||
|
expect(result.embeds.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given Old Message did not have a content, expect field to account for this', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
content: 'New Message',
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageAuthorDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Message Edited');
|
||||||
|
expect(embed.fields.length).toBe(4);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(embedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Channel Field
|
||||||
|
const embedFieldChannel = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldChannel.name).toBe('Channel');
|
||||||
|
expect(embedFieldChannel.value).toBe('[object Object]');
|
||||||
|
expect(embedFieldChannel.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('```*none*```');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[3];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('```New Message```');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given New Message does not have a content, expect field to account for this', () => {
|
||||||
|
process.env = {
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const textChannel = {
|
||||||
|
name: 'mod-logs',
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const memberGuildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(textChannel);
|
||||||
|
const messageAuthorDisplayAvatarURL = jest.fn();
|
||||||
|
|
||||||
|
const oldMessage = {
|
||||||
|
content: 'Old Message'
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const newMessage = {
|
||||||
|
guild: {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: memberGuildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
bot: false,
|
||||||
|
displayAvatarURL: messageAuthorDisplayAvatarURL,
|
||||||
|
tag: 'USERTAG'
|
||||||
|
},
|
||||||
|
channel: {},
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const messageEvents = new MessageEvents();
|
||||||
|
|
||||||
|
const result = messageEvents.messageUpdate(oldMessage, newMessage);
|
||||||
|
|
||||||
|
expect(channelSend).toBeCalledTimes(1);
|
||||||
|
expect(memberGuildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(messageAuthorDisplayAvatarURL).toBeCalledTimes(1);
|
||||||
|
expect(result.embeds.length).toBe(1);
|
||||||
|
|
||||||
|
// Embed
|
||||||
|
const embed = result.embeds[0];
|
||||||
|
|
||||||
|
expect(embed.title).toBe('Message Edited');
|
||||||
|
expect(embed.fields.length).toBe(4);
|
||||||
|
|
||||||
|
// Embed -> User Field
|
||||||
|
const embedFieldUser = embed.fields[0];
|
||||||
|
|
||||||
|
expect(embedFieldUser.name).toBe('User');
|
||||||
|
expect(embedFieldUser.value).toBe('[object Object] `USERTAG`');
|
||||||
|
expect(embedFieldUser.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Channel Field
|
||||||
|
const embedFieldChannel = embed.fields[1];
|
||||||
|
|
||||||
|
expect(embedFieldChannel.name).toBe('Channel');
|
||||||
|
expect(embedFieldChannel.value).toBe('[object Object]');
|
||||||
|
expect(embedFieldChannel.inline).toBeTruthy();
|
||||||
|
|
||||||
|
// Embed -> Before Field
|
||||||
|
const embedFieldBefore = embed.fields[2];
|
||||||
|
|
||||||
|
expect(embedFieldBefore.name).toBe('Before');
|
||||||
|
expect(embedFieldBefore.value).toBe('```Old Message```');
|
||||||
|
|
||||||
|
// Embed -> After Field
|
||||||
|
const embedFieldAfter = embed.fields[3];
|
||||||
|
|
||||||
|
expect(embedFieldAfter.name).toBe('After');
|
||||||
|
expect(embedFieldAfter.value).toBe('```*none*```');
|
||||||
|
});
|
||||||
|
});
|
11
tests/helpers/StringTools.test.ts
Normal file
11
tests/helpers/StringTools.test.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import StringTools from "../../src/helpers/StringTools";
|
||||||
|
|
||||||
|
describe('Capitalise', () => {
|
||||||
|
test('Expect sentence to be captilised', () => {
|
||||||
|
const inputString = 'the big brown fox jumps over the lazy dog';
|
||||||
|
|
||||||
|
const result = StringTools.Capitalise(inputString);
|
||||||
|
|
||||||
|
expect(result).toBe('The Big Brown Fox Jumps Over The Lazy Dog');
|
||||||
|
});
|
||||||
|
});
|
57
tests/helpers/embeds/ErrorEmbed.test.ts
Normal file
57
tests/helpers/embeds/ErrorEmbed.test.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { Message } from "discord.js";
|
||||||
|
import { ICommandContext } from "../../../src/contracts/ICommandContext";
|
||||||
|
import ErrorEmbed from "../../../src/helpers/embeds/ErrorEmbed";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR_ERROR: '0xd52803'
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = {} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new ErrorEmbed(context, 'Error Message');
|
||||||
|
|
||||||
|
expect(errorEmbed.color?.toString()).toBe('13969411'); // 0xd52803 in decimal
|
||||||
|
expect(errorEmbed.description).toBe('Error Message');
|
||||||
|
expect(errorEmbed.context).toBe(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToCurrentChannel', () => {
|
||||||
|
test('Expect embed to be sent to the current channel in context', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR_ERROR: '0xd52803'
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new ErrorEmbed(context, 'Error Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledWith(errorEmbed);
|
||||||
|
});
|
||||||
|
});
|
222
tests/helpers/embeds/EventEmbed.test.ts
Normal file
222
tests/helpers/embeds/EventEmbed.test.ts
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
import { Guild, Message, TextChannel, User } from "discord.js";
|
||||||
|
import { ICommandContext } from "../../../src/contracts/ICommandContext";
|
||||||
|
import EventEmbed from "../../../src/helpers/embeds/EventEmbed";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
expect(errorEmbed.color?.toString()).toBe('13969411'); // 0xd52803 in decimal
|
||||||
|
expect(errorEmbed.title).toBe('Event Message');
|
||||||
|
expect(errorEmbed.guild).toBe(guild);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('AddUser', () => {
|
||||||
|
test('Given setThumbnail is false, add field WITHOUT user thumbnail', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const addField = jest.fn();
|
||||||
|
const setThumbnail = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.addField = addField;
|
||||||
|
errorEmbed.setThumbnail = setThumbnail;
|
||||||
|
|
||||||
|
errorEmbed.AddUser('User', user);
|
||||||
|
|
||||||
|
expect(addField).toBeCalledWith('User', '[object Object] `USERTAG`', true);
|
||||||
|
expect(setThumbnail).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given setThumbnail is true, add field WITH user thumbnail', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const addField = jest.fn();
|
||||||
|
const setThumbnail = jest.fn();
|
||||||
|
const displayAvatarURL = jest.fn()
|
||||||
|
.mockReturnValue('image0.png');
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
displayAvatarURL: displayAvatarURL
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.addField = addField;
|
||||||
|
errorEmbed.setThumbnail = setThumbnail;
|
||||||
|
|
||||||
|
errorEmbed.AddUser('User', user, true);
|
||||||
|
|
||||||
|
expect(addField).toBeCalledWith('User', '[object Object] `USERTAG`', true);
|
||||||
|
expect(setThumbnail).toBeCalledWith('image0.png');
|
||||||
|
expect(displayAvatarURL).toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToChannel', () => {
|
||||||
|
test('Given channel can be found, expect embed to be sent to that channel', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const channel = {
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const guildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(channel);
|
||||||
|
|
||||||
|
const guild = {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: guildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as Guild;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel('channel-name');
|
||||||
|
|
||||||
|
expect(guildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(channelSend).toBeCalledWith(errorEmbed);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given channel can NOT be found, expect error logged', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const guildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
|
||||||
|
const guild = {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: guildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as Guild;
|
||||||
|
|
||||||
|
console.error = jest.fn();
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel('channel-name');
|
||||||
|
|
||||||
|
expect(guildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(console.error).toBeCalledWith('Unable to find channel channel-name');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToMessageLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MESSAGE as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToMessageLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('message-logs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToMemberLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MEMBER as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToMemberLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('member-logs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToModLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MOD as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const errorEmbed = new EventEmbed(guild, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToModLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('mod-logs');
|
||||||
|
});
|
||||||
|
});
|
331
tests/helpers/embeds/LogEmbed.test.ts
Normal file
331
tests/helpers/embeds/LogEmbed.test.ts
Normal file
|
@ -0,0 +1,331 @@
|
||||||
|
import { Guild, Message, TextChannel, User } from "discord.js";
|
||||||
|
import { ICommandContext } from "../../../src/contracts/ICommandContext";
|
||||||
|
import LogEmbed from "../../../src/helpers/embeds/LogEmbed";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Log Message');
|
||||||
|
|
||||||
|
expect(errorEmbed.color?.toString()).toBe('13969411'); // 0xd52803 in decimal
|
||||||
|
expect(errorEmbed.title).toBe('Log Message');
|
||||||
|
expect(errorEmbed.context).toBe(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('AddUser', () => {
|
||||||
|
test('Given setThumbnail is false, add field WITHOUT user thumbnail', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const addField = jest.fn();
|
||||||
|
const setThumbnail = jest.fn();
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
tag: 'USERTAG'
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: user
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.addField = addField;
|
||||||
|
errorEmbed.setThumbnail = setThumbnail;
|
||||||
|
|
||||||
|
errorEmbed.AddUser('User', user);
|
||||||
|
|
||||||
|
expect(addField).toBeCalledWith('User', '[object Object] `USERTAG`', true);
|
||||||
|
expect(setThumbnail).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given setThumbnail is true, add field WITH user thumbnail', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const addField = jest.fn();
|
||||||
|
const setThumbnail = jest.fn();
|
||||||
|
const displayAvatarURL = jest.fn()
|
||||||
|
.mockReturnValue('image0.png');
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
tag: 'USERTAG',
|
||||||
|
displayAvatarURL: displayAvatarURL
|
||||||
|
} as unknown as User;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
author: user
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.addField = addField;
|
||||||
|
errorEmbed.setThumbnail = setThumbnail;
|
||||||
|
|
||||||
|
errorEmbed.AddUser('User', user, true);
|
||||||
|
|
||||||
|
expect(addField).toBeCalledWith('User', '[object Object] `USERTAG`', true);
|
||||||
|
expect(setThumbnail).toBeCalledWith('image0.png');
|
||||||
|
expect(displayAvatarURL).toBeCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToChannel', () => {
|
||||||
|
test('Given channel can be found, expect embed to be sent to that channel', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelSend = jest.fn();
|
||||||
|
|
||||||
|
const channel = {
|
||||||
|
send: channelSend
|
||||||
|
} as unknown as TextChannel;
|
||||||
|
|
||||||
|
const guildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(channel);
|
||||||
|
|
||||||
|
const guild = {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: guildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as Guild;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
guild: guild
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel('channel-name');
|
||||||
|
|
||||||
|
expect(guildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
expect(channelSend).toBeCalledWith(errorEmbed);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Given channel can NOT be found, expect error logged', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const guildChannelsCacheFind = jest.fn()
|
||||||
|
.mockReturnValue(null);
|
||||||
|
|
||||||
|
const guild = {
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
find: guildChannelsCacheFind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as Guild;
|
||||||
|
|
||||||
|
console.error = jest.fn();
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
},
|
||||||
|
guild: guild
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel('channel-name');
|
||||||
|
|
||||||
|
expect(guildChannelsCacheFind).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToMessageLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MESSAGE as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToMessageLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('message-logs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToMemberLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MEMBER as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToMemberLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('member-logs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToModLogsChannel', () => {
|
||||||
|
describe('Expect SendToChannel caleld with CHANNELS_LOGS_MOD as parameter', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendToChannel = jest.fn();
|
||||||
|
|
||||||
|
const guild = {} as unknown as Guild;
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new LogEmbed(context, 'Event Message');
|
||||||
|
|
||||||
|
errorEmbed.SendToChannel = sendToChannel;
|
||||||
|
|
||||||
|
errorEmbed.SendToModLogsChannel();
|
||||||
|
|
||||||
|
expect(sendToChannel).toBeCalledWith('mod-logs');
|
||||||
|
});
|
||||||
|
});
|
67
tests/helpers/embeds/PublicEmbed.test.ts
Normal file
67
tests/helpers/embeds/PublicEmbed.test.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import { Guild, Message, TextChannel, User } from "discord.js";
|
||||||
|
import { ICommandContext } from "../../../src/contracts/ICommandContext";
|
||||||
|
import PublicEmbed from "../../../src/helpers/embeds/PublicEmbed";
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Constructor', () => {
|
||||||
|
test('Expect properties to be set', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR: '0xd52803',
|
||||||
|
CHANNELS_LOGS_MESSAGE: 'message-logs',
|
||||||
|
CHANNELS_LOGS_MEMBER: 'member-logs',
|
||||||
|
CHANNELS_LOGS_MOD: 'mod-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new PublicEmbed(context, 'Log Message', 'Log Description');
|
||||||
|
|
||||||
|
expect(errorEmbed.color?.toString()).toBe('13969411'); // 0xd52803 in decimal
|
||||||
|
expect(errorEmbed.title).toBe('Log Message');
|
||||||
|
expect(errorEmbed.description).toBe('Log Description');
|
||||||
|
expect(errorEmbed.context).toBe(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SendToCurrentChannel', () => {
|
||||||
|
test('Expect embed to be sent to the current channel in context', () => {
|
||||||
|
process.env = {
|
||||||
|
EMBED_COLOUR_ERROR: '0xd52803'
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageChannelSend = jest.fn();
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
channel: {
|
||||||
|
send: messageChannelSend
|
||||||
|
}
|
||||||
|
} as unknown as Message;
|
||||||
|
|
||||||
|
const context: ICommandContext = {
|
||||||
|
name: 'command',
|
||||||
|
args: [],
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorEmbed = new PublicEmbed(context, 'Message', 'Description');
|
||||||
|
|
||||||
|
errorEmbed.SendToCurrentChannel();
|
||||||
|
|
||||||
|
expect(messageChannelSend).toBeCalledWith(errorEmbed);
|
||||||
|
});
|
||||||
|
});
|
482
yarn.lock
482
yarn.lock
|
@ -2,13 +2,6 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@babel/code-frame@7.12.11":
|
|
||||||
version "7.12.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
|
|
||||||
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
|
|
||||||
dependencies:
|
|
||||||
"@babel/highlight" "^7.10.4"
|
|
||||||
|
|
||||||
"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0":
|
"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0":
|
||||||
version "7.16.0"
|
version "7.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
|
||||||
|
@ -150,7 +143,7 @@
|
||||||
"@babel/traverse" "^7.16.5"
|
"@babel/traverse" "^7.16.5"
|
||||||
"@babel/types" "^7.16.0"
|
"@babel/types" "^7.16.0"
|
||||||
|
|
||||||
"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0":
|
"@babel/highlight@^7.16.0":
|
||||||
version "7.16.0"
|
version "7.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
|
||||||
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
|
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
|
||||||
|
@ -293,18 +286,6 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@cspotcode/source-map-consumer@0.8.0":
|
|
||||||
version "0.8.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
|
|
||||||
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
|
|
||||||
|
|
||||||
"@cspotcode/source-map-support@0.7.0":
|
|
||||||
version "0.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
|
|
||||||
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
|
|
||||||
dependencies:
|
|
||||||
"@cspotcode/source-map-consumer" "0.8.0"
|
|
||||||
|
|
||||||
"@discordjs/collection@^0.1.6":
|
"@discordjs/collection@^0.1.6":
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c"
|
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c"
|
||||||
|
@ -319,35 +300,6 @@
|
||||||
combined-stream "^1.0.8"
|
combined-stream "^1.0.8"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
"@eslint/eslintrc@^0.4.3":
|
|
||||||
version "0.4.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
|
||||||
integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
|
|
||||||
dependencies:
|
|
||||||
ajv "^6.12.4"
|
|
||||||
debug "^4.1.1"
|
|
||||||
espree "^7.3.0"
|
|
||||||
globals "^13.9.0"
|
|
||||||
ignore "^4.0.6"
|
|
||||||
import-fresh "^3.2.1"
|
|
||||||
js-yaml "^3.13.1"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
strip-json-comments "^3.1.1"
|
|
||||||
|
|
||||||
"@humanwhocodes/config-array@^0.5.0":
|
|
||||||
version "0.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
|
|
||||||
integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
|
|
||||||
dependencies:
|
|
||||||
"@humanwhocodes/object-schema" "^1.2.0"
|
|
||||||
debug "^4.1.1"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
|
|
||||||
"@humanwhocodes/object-schema@^1.2.0":
|
|
||||||
version "1.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
|
||||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
|
||||||
|
|
||||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||||
|
@ -564,26 +516,6 @@
|
||||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
||||||
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
|
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
|
||||||
|
|
||||||
"@tsconfig/node10@^1.0.7":
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
|
|
||||||
integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
|
|
||||||
|
|
||||||
"@tsconfig/node12@^1.0.7":
|
|
||||||
version "1.0.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
|
|
||||||
integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
|
|
||||||
|
|
||||||
"@tsconfig/node14@^1.0.0":
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
|
|
||||||
integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
|
|
||||||
|
|
||||||
"@tsconfig/node16@^1.0.2":
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
|
||||||
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
|
||||||
|
|
||||||
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
|
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
|
||||||
version "7.1.17"
|
version "7.1.17"
|
||||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64"
|
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64"
|
||||||
|
@ -732,27 +664,17 @@ acorn-globals@^6.0.0:
|
||||||
acorn "^7.1.1"
|
acorn "^7.1.1"
|
||||||
acorn-walk "^7.1.1"
|
acorn-walk "^7.1.1"
|
||||||
|
|
||||||
acorn-jsx@^5.3.1:
|
|
||||||
version "5.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
|
||||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
|
||||||
|
|
||||||
acorn-walk@^7.1.1:
|
acorn-walk@^7.1.1:
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||||
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
||||||
|
|
||||||
acorn-walk@^8.1.1:
|
acorn@^7.1.1:
|
||||||
version "8.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
|
||||||
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
|
||||||
|
|
||||||
acorn@^7.1.1, acorn@^7.4.0:
|
|
||||||
version "7.4.1"
|
version "7.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||||
|
|
||||||
acorn@^8.2.4, acorn@^8.4.1:
|
acorn@^8.2.4:
|
||||||
version "8.6.0"
|
version "8.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
|
||||||
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
|
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
|
||||||
|
@ -764,31 +686,6 @@ agent-base@6:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "4"
|
debug "4"
|
||||||
|
|
||||||
ajv@^6.10.0, ajv@^6.12.4:
|
|
||||||
version "6.12.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
|
||||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal "^3.1.1"
|
|
||||||
fast-json-stable-stringify "^2.0.0"
|
|
||||||
json-schema-traverse "^0.4.1"
|
|
||||||
uri-js "^4.2.2"
|
|
||||||
|
|
||||||
ajv@^8.0.1:
|
|
||||||
version "8.8.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb"
|
|
||||||
integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal "^3.1.1"
|
|
||||||
json-schema-traverse "^1.0.0"
|
|
||||||
require-from-string "^2.0.2"
|
|
||||||
uri-js "^4.2.2"
|
|
||||||
|
|
||||||
ansi-colors@^4.1.1:
|
|
||||||
version "4.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
|
||||||
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
|
||||||
|
|
||||||
ansi-escapes@^4.2.1:
|
ansi-escapes@^4.2.1:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
||||||
|
@ -828,11 +725,6 @@ anymatch@^3.0.3:
|
||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
arg@^4.1.0:
|
|
||||||
version "4.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
|
||||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||||
|
@ -840,11 +732,6 @@ argparse@^1.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
sprintf-js "~1.0.2"
|
sprintf-js "~1.0.2"
|
||||||
|
|
||||||
astral-regex@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
|
||||||
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
|
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
@ -1105,12 +992,7 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.1"
|
safe-buffer "~5.1.1"
|
||||||
|
|
||||||
create-require@^1.1.0:
|
cross-spawn@^7.0.3:
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
|
||||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
|
||||||
|
|
||||||
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
|
@ -1152,7 +1034,7 @@ debug@4, debug@^4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "2.1.2"
|
ms "2.1.2"
|
||||||
|
|
||||||
debug@^4.0.1, debug@^4.1.1:
|
debug@^4.1.1:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
||||||
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
|
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
|
||||||
|
@ -1176,7 +1058,7 @@ dedent@^0.7.0:
|
||||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
||||||
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
||||||
|
|
||||||
deep-is@^0.1.3, deep-is@~0.1.3:
|
deep-is@~0.1.3:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||||
|
@ -1206,11 +1088,6 @@ diff-sequences@^27.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5"
|
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5"
|
||||||
integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==
|
integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==
|
||||||
|
|
||||||
diff@^4.0.1:
|
|
||||||
version "4.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
|
||||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
|
||||||
|
|
||||||
discord.js@12.5.3:
|
discord.js@12.5.3:
|
||||||
version "12.5.3"
|
version "12.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.5.3.tgz#56820d473c24320871df9ea0bbc6b462f21cf85c"
|
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.5.3.tgz#56820d473c24320871df9ea0bbc6b462f21cf85c"
|
||||||
|
@ -1225,13 +1102,6 @@ discord.js@12.5.3:
|
||||||
tweetnacl "^1.0.3"
|
tweetnacl "^1.0.3"
|
||||||
ws "^7.4.4"
|
ws "^7.4.4"
|
||||||
|
|
||||||
doctrine@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
|
||||||
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
|
|
||||||
dependencies:
|
|
||||||
esutils "^2.0.2"
|
|
||||||
|
|
||||||
domexception@^2.0.1:
|
domexception@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
||||||
|
@ -1271,13 +1141,6 @@ end-of-stream@^1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
once "^1.4.0"
|
once "^1.4.0"
|
||||||
|
|
||||||
enquirer@^2.3.5:
|
|
||||||
version "2.3.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
|
||||||
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
|
||||||
dependencies:
|
|
||||||
ansi-colors "^4.1.1"
|
|
||||||
|
|
||||||
escalade@^3.1.1:
|
escalade@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||||
|
@ -1293,11 +1156,6 @@ escape-string-regexp@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
||||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||||
|
|
||||||
escape-string-regexp@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
|
||||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
|
||||||
|
|
||||||
escodegen@^2.0.0:
|
escodegen@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
|
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
|
||||||
|
@ -1310,111 +1168,12 @@ escodegen@^2.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-scope@^5.1.1:
|
|
||||||
version "5.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
|
||||||
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
|
||||||
dependencies:
|
|
||||||
esrecurse "^4.3.0"
|
|
||||||
estraverse "^4.1.1"
|
|
||||||
|
|
||||||
eslint-utils@^2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
|
|
||||||
integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
|
|
||||||
dependencies:
|
|
||||||
eslint-visitor-keys "^1.1.0"
|
|
||||||
|
|
||||||
eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
|
|
||||||
integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
|
|
||||||
|
|
||||||
eslint-visitor-keys@^2.0.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
|
||||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
|
||||||
|
|
||||||
eslint@^7.17.0:
|
|
||||||
version "7.32.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
|
|
||||||
integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
|
|
||||||
dependencies:
|
|
||||||
"@babel/code-frame" "7.12.11"
|
|
||||||
"@eslint/eslintrc" "^0.4.3"
|
|
||||||
"@humanwhocodes/config-array" "^0.5.0"
|
|
||||||
ajv "^6.10.0"
|
|
||||||
chalk "^4.0.0"
|
|
||||||
cross-spawn "^7.0.2"
|
|
||||||
debug "^4.0.1"
|
|
||||||
doctrine "^3.0.0"
|
|
||||||
enquirer "^2.3.5"
|
|
||||||
escape-string-regexp "^4.0.0"
|
|
||||||
eslint-scope "^5.1.1"
|
|
||||||
eslint-utils "^2.1.0"
|
|
||||||
eslint-visitor-keys "^2.0.0"
|
|
||||||
espree "^7.3.1"
|
|
||||||
esquery "^1.4.0"
|
|
||||||
esutils "^2.0.2"
|
|
||||||
fast-deep-equal "^3.1.3"
|
|
||||||
file-entry-cache "^6.0.1"
|
|
||||||
functional-red-black-tree "^1.0.1"
|
|
||||||
glob-parent "^5.1.2"
|
|
||||||
globals "^13.6.0"
|
|
||||||
ignore "^4.0.6"
|
|
||||||
import-fresh "^3.0.0"
|
|
||||||
imurmurhash "^0.1.4"
|
|
||||||
is-glob "^4.0.0"
|
|
||||||
js-yaml "^3.13.1"
|
|
||||||
json-stable-stringify-without-jsonify "^1.0.1"
|
|
||||||
levn "^0.4.1"
|
|
||||||
lodash.merge "^4.6.2"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
natural-compare "^1.4.0"
|
|
||||||
optionator "^0.9.1"
|
|
||||||
progress "^2.0.0"
|
|
||||||
regexpp "^3.1.0"
|
|
||||||
semver "^7.2.1"
|
|
||||||
strip-ansi "^6.0.0"
|
|
||||||
strip-json-comments "^3.1.0"
|
|
||||||
table "^6.0.9"
|
|
||||||
text-table "^0.2.0"
|
|
||||||
v8-compile-cache "^2.0.3"
|
|
||||||
|
|
||||||
espree@^7.3.0, espree@^7.3.1:
|
|
||||||
version "7.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
|
|
||||||
integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
|
|
||||||
dependencies:
|
|
||||||
acorn "^7.4.0"
|
|
||||||
acorn-jsx "^5.3.1"
|
|
||||||
eslint-visitor-keys "^1.3.0"
|
|
||||||
|
|
||||||
esprima@^4.0.0, esprima@^4.0.1:
|
esprima@^4.0.0, esprima@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||||
|
|
||||||
esquery@^1.4.0:
|
estraverse@^5.2.0:
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
|
|
||||||
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
|
|
||||||
dependencies:
|
|
||||||
estraverse "^5.1.0"
|
|
||||||
|
|
||||||
esrecurse@^4.3.0:
|
|
||||||
version "4.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
|
||||||
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
|
|
||||||
dependencies:
|
|
||||||
estraverse "^5.2.0"
|
|
||||||
|
|
||||||
estraverse@^4.1.1:
|
|
||||||
version "4.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
|
||||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
|
||||||
|
|
||||||
estraverse@^5.1.0, estraverse@^5.2.0:
|
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||||
|
@ -1461,17 +1220,12 @@ expect@^27.4.2:
|
||||||
jest-message-util "^27.4.2"
|
jest-message-util "^27.4.2"
|
||||||
jest-regex-util "^27.4.0"
|
jest-regex-util "^27.4.0"
|
||||||
|
|
||||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|
||||||
version "3.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
|
||||||
|
|
||||||
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||||
|
|
||||||
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
fast-levenshtein@~2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||||
|
@ -1483,13 +1237,6 @@ fb-watchman@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
bser "2.1.1"
|
bser "2.1.1"
|
||||||
|
|
||||||
file-entry-cache@^6.0.1:
|
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
|
|
||||||
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
|
|
||||||
dependencies:
|
|
||||||
flat-cache "^3.0.4"
|
|
||||||
|
|
||||||
fill-range@^7.0.1:
|
fill-range@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||||
|
@ -1505,19 +1252,6 @@ find-up@^4.0.0, find-up@^4.1.0:
|
||||||
locate-path "^5.0.0"
|
locate-path "^5.0.0"
|
||||||
path-exists "^4.0.0"
|
path-exists "^4.0.0"
|
||||||
|
|
||||||
flat-cache@^3.0.4:
|
|
||||||
version "3.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
|
|
||||||
integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
|
|
||||||
dependencies:
|
|
||||||
flatted "^3.1.0"
|
|
||||||
rimraf "^3.0.2"
|
|
||||||
|
|
||||||
flatted@^3.1.0:
|
|
||||||
version "3.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2"
|
|
||||||
integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==
|
|
||||||
|
|
||||||
form-data@^3.0.0:
|
form-data@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
|
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
|
||||||
|
@ -1542,11 +1276,6 @@ function-bind@^1.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
functional-red-black-tree@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
|
||||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
|
||||||
|
|
||||||
gensync@^1.0.0-beta.2:
|
gensync@^1.0.0-beta.2:
|
||||||
version "1.0.0-beta.2"
|
version "1.0.0-beta.2"
|
||||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||||
|
@ -1574,13 +1303,6 @@ get-stream@^6.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||||
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
||||||
|
|
||||||
glob-parent@^5.1.2:
|
|
||||||
version "5.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
|
||||||
dependencies:
|
|
||||||
is-glob "^4.0.1"
|
|
||||||
|
|
||||||
glob-parent@^6.0.0:
|
glob-parent@^6.0.0:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||||
|
@ -1605,13 +1327,6 @@ globals@^11.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||||
|
|
||||||
globals@^13.6.0, globals@^13.9.0:
|
|
||||||
version "13.12.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e"
|
|
||||||
integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==
|
|
||||||
dependencies:
|
|
||||||
type-fest "^0.20.2"
|
|
||||||
|
|
||||||
got@^11.8.3:
|
got@^11.8.3:
|
||||||
version "11.8.3"
|
version "11.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770"
|
resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770"
|
||||||
|
@ -1705,19 +1420,6 @@ iconv-lite@0.4.24:
|
||||||
dependencies:
|
dependencies:
|
||||||
safer-buffer ">= 2.1.2 < 3"
|
safer-buffer ">= 2.1.2 < 3"
|
||||||
|
|
||||||
ignore@^4.0.6:
|
|
||||||
version "4.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
|
||||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
|
||||||
|
|
||||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
|
||||||
version "3.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
|
||||||
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
|
|
||||||
dependencies:
|
|
||||||
parent-module "^1.0.0"
|
|
||||||
resolve-from "^4.0.0"
|
|
||||||
|
|
||||||
import-local@^3.0.2:
|
import-local@^3.0.2:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0"
|
resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0"
|
||||||
|
@ -1766,7 +1468,7 @@ is-generator-fn@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
|
resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
|
||||||
integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
|
integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
|
||||||
|
|
||||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
|
is-glob@^4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||||
|
@ -2324,21 +2026,6 @@ json-buffer@3.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
|
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
|
||||||
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
|
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
|
||||||
|
|
||||||
json-schema-traverse@^0.4.1:
|
|
||||||
version "0.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
|
||||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
|
||||||
|
|
||||||
json-schema-traverse@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
|
||||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
|
||||||
|
|
||||||
json-stable-stringify-without-jsonify@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
|
||||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
|
||||||
|
|
||||||
json5@2.x, json5@^2.1.2:
|
json5@2.x, json5@^2.1.2:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
||||||
|
@ -2363,14 +2050,6 @@ leven@^3.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
||||||
integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
|
integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
|
||||||
|
|
||||||
levn@^0.4.1:
|
|
||||||
version "0.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
|
||||||
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
|
|
||||||
dependencies:
|
|
||||||
prelude-ls "^1.2.1"
|
|
||||||
type-check "~0.4.0"
|
|
||||||
|
|
||||||
levn@~0.3.0:
|
levn@~0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||||
|
@ -2391,16 +2070,6 @@ lodash.memoize@4.x:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
lodash.merge@^4.6.2:
|
|
||||||
version "4.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
|
||||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
|
||||||
|
|
||||||
lodash.truncate@^4.4.2:
|
|
||||||
version "4.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
|
|
||||||
integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
|
|
||||||
|
|
||||||
lodash@^4.7.0:
|
lodash@^4.7.0:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
|
@ -2425,7 +2094,7 @@ make-dir@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
semver "^6.0.0"
|
semver "^6.0.0"
|
||||||
|
|
||||||
make-error@1.x, make-error@^1.1.1:
|
make-error@1.x:
|
||||||
version "1.3.6"
|
version "1.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||||
|
@ -2564,18 +2233,6 @@ optionator@^0.8.1:
|
||||||
type-check "~0.3.2"
|
type-check "~0.3.2"
|
||||||
word-wrap "~1.2.3"
|
word-wrap "~1.2.3"
|
||||||
|
|
||||||
optionator@^0.9.1:
|
|
||||||
version "0.9.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
|
|
||||||
integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
|
|
||||||
dependencies:
|
|
||||||
deep-is "^0.1.3"
|
|
||||||
fast-levenshtein "^2.0.6"
|
|
||||||
levn "^0.4.1"
|
|
||||||
prelude-ls "^1.2.1"
|
|
||||||
type-check "^0.4.0"
|
|
||||||
word-wrap "^1.2.3"
|
|
||||||
|
|
||||||
p-cancelable@^2.0.0:
|
p-cancelable@^2.0.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
|
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
|
||||||
|
@ -2600,13 +2257,6 @@ p-try@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||||
|
|
||||||
parent-module@^1.0.0:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
|
||||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
|
||||||
dependencies:
|
|
||||||
callsites "^3.0.0"
|
|
||||||
|
|
||||||
parse5@6.0.1:
|
parse5@6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||||
|
@ -2654,11 +2304,6 @@ pkg-dir@^4.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^4.0.0"
|
find-up "^4.0.0"
|
||||||
|
|
||||||
prelude-ls@^1.2.1:
|
|
||||||
version "1.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
|
||||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
|
||||||
|
|
||||||
prelude-ls@~1.1.2:
|
prelude-ls@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
|
@ -2679,11 +2324,6 @@ prism-media@^1.2.9:
|
||||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
||||||
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
||||||
|
|
||||||
progress@^2.0.0:
|
|
||||||
version "2.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
|
||||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
|
||||||
|
|
||||||
prompts@^2.0.1:
|
prompts@^2.0.1:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
|
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
|
||||||
|
@ -2705,7 +2345,7 @@ pump@^3.0.0:
|
||||||
end-of-stream "^1.1.0"
|
end-of-stream "^1.1.0"
|
||||||
once "^1.3.1"
|
once "^1.3.1"
|
||||||
|
|
||||||
punycode@^2.1.0, punycode@^2.1.1:
|
punycode@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
@ -2728,21 +2368,11 @@ react-is@^17.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
|
|
||||||
regexpp@^3.1.0:
|
|
||||||
version "3.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
|
||||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
|
||||||
|
|
||||||
require-directory@^2.1.1:
|
require-directory@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||||
|
|
||||||
require-from-string@^2.0.2:
|
|
||||||
version "2.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
|
||||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
|
||||||
|
|
||||||
resolve-alpn@^1.0.0:
|
resolve-alpn@^1.0.0:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
|
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
|
||||||
|
@ -2755,11 +2385,6 @@ resolve-cwd@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
resolve-from "^5.0.0"
|
resolve-from "^5.0.0"
|
||||||
|
|
||||||
resolve-from@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
|
||||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
|
||||||
|
|
||||||
resolve-from@^5.0.0:
|
resolve-from@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||||
|
@ -2785,7 +2410,7 @@ responselike@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
lowercase-keys "^2.0.0"
|
lowercase-keys "^2.0.0"
|
||||||
|
|
||||||
rimraf@^3.0.0, rimraf@^3.0.2:
|
rimraf@^3.0.0:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||||
|
@ -2809,7 +2434,7 @@ saxes@^5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
xmlchars "^2.2.0"
|
xmlchars "^2.2.0"
|
||||||
|
|
||||||
semver@7.x, semver@^7.2.1, semver@^7.3.2:
|
semver@7.x, semver@^7.3.2:
|
||||||
version "7.3.5"
|
version "7.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||||
|
@ -2853,15 +2478,6 @@ slash@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
slice-ansi@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
|
|
||||||
integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
astral-regex "^2.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
|
|
||||||
source-map-support@^0.5.6:
|
source-map-support@^0.5.6:
|
||||||
version "0.5.21"
|
version "0.5.21"
|
||||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||||
|
@ -2905,7 +2521,7 @@ string-length@^4.0.1:
|
||||||
char-regex "^1.0.2"
|
char-regex "^1.0.2"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
string-width@^4.1.0, string-width@^4.2.0:
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
@ -2931,11 +2547,6 @@ strip-final-newline@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
|
||||||
version "3.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
|
||||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||||
|
@ -2970,17 +2581,6 @@ symbol-tree@^3.2.4:
|
||||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||||
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
||||||
|
|
||||||
table@^6.0.9:
|
|
||||||
version "6.7.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/table/-/table-6.7.3.tgz#255388439715a738391bd2ee4cbca89a4d05a9b7"
|
|
||||||
integrity sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==
|
|
||||||
dependencies:
|
|
||||||
ajv "^8.0.1"
|
|
||||||
lodash.truncate "^4.4.2"
|
|
||||||
slice-ansi "^4.0.0"
|
|
||||||
string-width "^4.2.3"
|
|
||||||
strip-ansi "^6.0.1"
|
|
||||||
|
|
||||||
terminal-link@^2.0.0:
|
terminal-link@^2.0.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
|
resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
|
||||||
|
@ -2998,11 +2598,6 @@ test-exclude@^6.0.0:
|
||||||
glob "^7.1.4"
|
glob "^7.1.4"
|
||||||
minimatch "^3.0.4"
|
minimatch "^3.0.4"
|
||||||
|
|
||||||
text-table@^0.2.0:
|
|
||||||
version "0.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
|
||||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
|
||||||
|
|
||||||
throat@^6.0.1:
|
throat@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
|
resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
|
||||||
|
@ -3065,36 +2660,11 @@ ts-jest@^27.1.2:
|
||||||
semver "7.x"
|
semver "7.x"
|
||||||
yargs-parser "20.x"
|
yargs-parser "20.x"
|
||||||
|
|
||||||
ts-node@^10.4.0:
|
|
||||||
version "10.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
|
||||||
integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
|
|
||||||
dependencies:
|
|
||||||
"@cspotcode/source-map-support" "0.7.0"
|
|
||||||
"@tsconfig/node10" "^1.0.7"
|
|
||||||
"@tsconfig/node12" "^1.0.7"
|
|
||||||
"@tsconfig/node14" "^1.0.0"
|
|
||||||
"@tsconfig/node16" "^1.0.2"
|
|
||||||
acorn "^8.4.1"
|
|
||||||
acorn-walk "^8.1.1"
|
|
||||||
arg "^4.1.0"
|
|
||||||
create-require "^1.1.0"
|
|
||||||
diff "^4.0.1"
|
|
||||||
make-error "^1.1.1"
|
|
||||||
yn "3.1.1"
|
|
||||||
|
|
||||||
tweetnacl@^1.0.3:
|
tweetnacl@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
|
||||||
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
||||||
|
|
||||||
type-check@^0.4.0, type-check@~0.4.0:
|
|
||||||
version "0.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
|
||||||
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
|
|
||||||
dependencies:
|
|
||||||
prelude-ls "^1.2.1"
|
|
||||||
|
|
||||||
type-check@~0.3.2:
|
type-check@~0.3.2:
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
|
||||||
|
@ -3107,11 +2677,6 @@ type-detect@4.0.8:
|
||||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
||||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||||
|
|
||||||
type-fest@^0.20.2:
|
|
||||||
version "0.20.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
|
||||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
|
||||||
|
|
||||||
type-fest@^0.21.3:
|
type-fest@^0.21.3:
|
||||||
version "0.21.3"
|
version "0.21.3"
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||||
|
@ -3134,18 +2699,6 @@ universalify@^0.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||||
|
|
||||||
uri-js@^4.2.2:
|
|
||||||
version "4.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
|
||||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
|
||||||
dependencies:
|
|
||||||
punycode "^2.1.0"
|
|
||||||
|
|
||||||
v8-compile-cache@^2.0.3:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
|
||||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
|
||||||
|
|
||||||
v8-to-istanbul@^8.1.0:
|
v8-to-istanbul@^8.1.0:
|
||||||
version "8.1.0"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c"
|
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c"
|
||||||
|
@ -3227,7 +2780,7 @@ which@^2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe "^2.0.0"
|
isexe "^2.0.0"
|
||||||
|
|
||||||
word-wrap@^1.2.3, word-wrap@~1.2.3:
|
word-wrap@~1.2.3:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||||
|
@ -3298,8 +2851,3 @@ yargs@^16.2.0:
|
||||||
string-width "^4.2.0"
|
string-width "^4.2.0"
|
||||||
y18n "^5.0.5"
|
y18n "^5.0.5"
|
||||||
yargs-parser "^20.2.2"
|
yargs-parser "^20.2.2"
|
||||||
|
|
||||||
yn@3.1.1:
|
|
||||||
version "3.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
|
||||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
|
||||||
|
|
Loading…
Reference in a new issue