WIP: Split up moon counter from the database #489
21 changed files with 1114 additions and 21 deletions
225
3
Normal file
225
3
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
import {ButtonInteraction} from "discord.js";
|
||||||
|
import List from "../../../../src/buttonEvents/304276391837302787/moons/list";
|
||||||
|
import UserSetting from "../../../../src/database/entities/UserSetting";
|
||||||
|
import Moon from "../../../../src/database/entities/304276391837302787/Moon";
|
||||||
|
|
||||||
|
describe("GIVEN interaction.guild is null", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: null,
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN userId parameter is undefined", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN page parameter is undefined", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN no moons for the user is returned", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT moons function to be called", () => {
|
||||||
|
expect(Moon.FetchPaginatedMoonsByUserId).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("username does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN member is not in cache", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue(undefined),
|
||||||
|
},
|
||||||
|
fetch: jest.fn().mockResolvedValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT API to be called", () => {
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledWith("userId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied with username", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("username does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN member can not be found", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue(undefined),
|
||||||
|
},
|
||||||
|
fetch: jest.fn().mockResolvedValue(undefined),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT API to be called", () => {
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledWith("userId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied with username", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("This user does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN no moons on current page", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
test.todo("EXPECT description to say so");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN happy flow", () => {
|
||||||
|
test.todo("EXPECT moons to be fetched");
|
||||||
|
|
||||||
|
test.todo("EXPECT embed to be updated");
|
||||||
|
|
||||||
|
test.todo("EXPECT row to be updated");
|
||||||
|
|
||||||
|
describe("GIVEN it is the first page", () => {
|
||||||
|
test.todo("EXPECT Previous button to be disabled");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN it is the last page", () => {
|
||||||
|
test.todo("EXPECT Next button to be disabled");
|
||||||
|
|
||||||
|
describe("GIVEN there are more moons in the counter than in the database", () => {
|
||||||
|
test.todo("EXPECT untracked counter to be present");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN no moons on the current page", () => {
|
||||||
|
test.todo("EXPECT Next button to be disabled");
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE `user_setting` (
|
||||||
|
`Id` varchar(255) NOT NULL,
|
||||||
|
`WhenCreated` datetime NOT NULL,
|
||||||
|
`WhenUpdated` datetime NOT NULL,
|
||||||
|
`UserId` varchar(255) NOT NULL,
|
||||||
|
`Key` varchar(255) NOT NULL,
|
||||||
|
`Value` varchar(255) NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE user_setting
|
||||||
|
ADD PRIMARY KEY (Id);
|
|
@ -8,7 +8,7 @@
|
||||||
"clean": "rm -rf node_modules/ dist/",
|
"clean": "rm -rf node_modules/ dist/",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"start": "node ./dist/vylbot",
|
"start": "node ./dist/vylbot",
|
||||||
"test": "jest . --passWithNoTests",
|
"test": "jest",
|
||||||
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
|
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
|
||||||
"db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js",
|
"db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js",
|
||||||
"db:create": "typeorm migration:create ./src/database/migrations",
|
"db:create": "typeorm migration:create ./src/database/migrations",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ButtonInteraction} from "discord.js";
|
import {ButtonInteraction} from "discord.js";
|
||||||
import {ButtonEvent} from "../type/buttonEvent";
|
import {ButtonEvent} from "../../type/buttonEvent";
|
||||||
import List from "./moons/list";
|
import List from "./moons/list";
|
||||||
|
|
||||||
export default class Moons extends ButtonEvent {
|
export default class Moons extends ButtonEvent {
|
|
@ -1,6 +1,7 @@
|
||||||
import {ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder} from "discord.js";
|
import {ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, EmbedBuilder} from "discord.js";
|
||||||
import Moon from "../../database/entities/304276391837302787/Moon";
|
import Moon from "../../../database/entities/304276391837302787/Moon";
|
||||||
import EmbedColours from "../../constants/EmbedColours";
|
import EmbedColours from "../../../constants/EmbedColours";
|
||||||
|
import UserSetting from "../../../database/entities/UserSetting";
|
||||||
|
|
||||||
export default async function List(interaction: ButtonInteraction) {
|
export default async function List(interaction: ButtonInteraction) {
|
||||||
if (!interaction.guild) return;
|
if (!interaction.guild) return;
|
||||||
|
@ -12,26 +13,40 @@ export default async function List(interaction: ButtonInteraction) {
|
||||||
|
|
||||||
const pageNumber = Number(page);
|
const pageNumber = Number(page);
|
||||||
|
|
||||||
const member = interaction.guild.members.cache.find(x => x.user.id == userId);
|
const member = interaction.guild.members.cache.find(x => x.user.id == userId) || await interaction.guild.members.fetch(userId);
|
||||||
|
|
||||||
const pageLength = 10;
|
const pageLength = 10;
|
||||||
|
|
||||||
const moons = await Moon.FetchPaginatedMoonsByUserId(userId, pageLength, pageNumber);
|
const moons = await Moon.FetchPaginatedMoonsByUserId(userId, pageLength, pageNumber);
|
||||||
|
|
||||||
if (!moons || moons[0].length == 0) {
|
if (!moons) {
|
||||||
await interaction.reply(`${member?.user.username ?? "This user"} does not have any moons or page is invalid.`);
|
await interaction.reply(`${member?.user.username ?? "This user"} does not have any moons or page is invalid.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moonSetting = await UserSetting.FetchOneByKey(userId, "moons");
|
||||||
|
const totalMoons = moonSetting && Number(moonSetting.Value) ? Number(moonSetting.Value) : 0;
|
||||||
|
|
||||||
const totalPages = Math.ceil(moons[1] / pageLength);
|
const totalPages = Math.ceil(moons[1] / pageLength);
|
||||||
|
|
||||||
const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
let description = ["*none*"];
|
||||||
|
|
||||||
|
if (moons[0].length > 0) {
|
||||||
|
description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moonDifference = totalMoons - moons[1];
|
||||||
|
const isLastPage = pageNumber + 1 == totalPages || moons[0].length == 0;
|
||||||
|
|
||||||
|
if (isLastPage && moonDifference > 0) {
|
||||||
|
description.push(`...plus ${moonDifference} more untracked`);
|
||||||
|
}
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setTitle(`${member?.user.username}'s Moons`)
|
.setTitle(`${member.user.username}'s Moons`)
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setDescription(description.join("\n"))
|
.setDescription(description.join("\n"))
|
||||||
.setFooter({ text: `Page ${page + 1} of ${totalPages} · ${moons[1]} moons` });
|
.setFooter({ text: `Page ${pageNumber + 1} of ${totalPages} · ${totalMoons} moons` });
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
.addComponents(
|
.addComponents(
|
||||||
|
@ -44,7 +59,7 @@ export default async function List(interaction: ButtonInteraction) {
|
||||||
.setCustomId(`moons list ${userId} ${pageNumber + 1}`)
|
.setCustomId(`moons list ${userId} ${pageNumber + 1}`)
|
||||||
.setLabel("Next")
|
.setLabel("Next")
|
||||||
.setStyle(ButtonStyle.Primary)
|
.setStyle(ButtonStyle.Primary)
|
||||||
.setDisabled(pageNumber + 1 == totalPages));
|
.setDisabled(isLastPage));
|
||||||
|
|
||||||
await interaction.update({
|
await interaction.update({
|
||||||
embeds: [ embed ],
|
embeds: [ embed ],
|
|
@ -1,6 +1,7 @@
|
||||||
import {CommandInteraction, EmbedBuilder} from "discord.js";
|
import {CommandInteraction, EmbedBuilder} from "discord.js";
|
||||||
import Moon from "../../../database/entities/304276391837302787/Moon";
|
import Moon from "../../../database/entities/304276391837302787/Moon";
|
||||||
import EmbedColours from "../../../constants/EmbedColours";
|
import EmbedColours from "../../../constants/EmbedColours";
|
||||||
|
import UserSetting from "../../../database/entities/UserSetting";
|
||||||
|
|
||||||
export default async function AddMoon(interaction: CommandInteraction) {
|
export default async function AddMoon(interaction: CommandInteraction) {
|
||||||
const description = interaction.options.get("description", true).value?.toString();
|
const description = interaction.options.get("description", true).value?.toString();
|
||||||
|
@ -10,9 +11,22 @@ export default async function AddMoon(interaction: CommandInteraction) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const moonCount = await Moon.FetchMoonCountByUserId(interaction.user.id);
|
let moonSetting = await UserSetting.FetchOneByKey(interaction.user.id, "moons");
|
||||||
|
const moonCount = moonSetting && Number(moonSetting.Value) ? Number(moonSetting.Value) : 0;
|
||||||
|
|
||||||
const moon = new Moon(moonCount + 1, description, interaction.user.id);
|
if (moonSetting) {
|
||||||
|
moonSetting.UpdateValue(`${moonCount + 1}`);
|
||||||
|
} else {
|
||||||
|
moonSetting = new UserSetting(interaction.user.id, "moons", `${moonCount + 1}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await moonSetting.Save(UserSetting, moonSetting);
|
||||||
|
|
||||||
|
const allMoons = await Moon.FetchMoonCountByUserId(interaction.user.id);
|
||||||
|
|
||||||
|
const moonNumber = allMoons + 1;
|
||||||
|
|
||||||
|
const moon = new Moon(moonNumber, description, interaction.user.id);
|
||||||
|
|
||||||
await moon.Save(Moon, moon);
|
await moon.Save(Moon, moon);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder} from "discord.js";
|
import {ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder} from "discord.js";
|
||||||
import Moon from "../../../database/entities/304276391837302787/Moon";
|
import Moon from "../../../database/entities/304276391837302787/Moon";
|
||||||
import EmbedColours from "../../../constants/EmbedColours";
|
import EmbedColours from "../../../constants/EmbedColours";
|
||||||
|
import UserSetting from "../../../database/entities/UserSetting";
|
||||||
|
|
||||||
export default async function ListMoons(interaction: CommandInteraction) {
|
export default async function ListMoons(interaction: CommandInteraction) {
|
||||||
const user = interaction.options.get("user")?.user ?? interaction.user;
|
const user = interaction.options.get("user")?.user ?? interaction.user;
|
||||||
|
@ -10,20 +11,29 @@ export default async function ListMoons(interaction: CommandInteraction) {
|
||||||
|
|
||||||
const moons = await Moon.FetchPaginatedMoonsByUserId(user.id, pageLength, page);
|
const moons = await Moon.FetchPaginatedMoonsByUserId(user.id, pageLength, page);
|
||||||
|
|
||||||
if (!moons || moons[0].length == 0) {
|
const moonSetting = await UserSetting.FetchOneByKey(interaction.user.id, "moons");
|
||||||
await interaction.reply(`${user.username} does not have any moons or page is invalid.`);
|
const totalMoons = moonSetting && Number(moonSetting.Value) ? Number(moonSetting.Value) : 0;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalPages = Math.ceil(moons[1] / pageLength);
|
const totalPages = Math.ceil(moons[1] / pageLength);
|
||||||
|
|
||||||
const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
let description = ["*none*"];
|
||||||
|
|
||||||
|
if (moons[0].length > 0) {
|
||||||
|
description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moonDifference = totalMoons - moons[1];
|
||||||
|
const isLastPage = page + 1 == totalPages || moons[0].length == 0;
|
||||||
|
|
||||||
|
if (isLastPage && moonDifference > 0) {
|
||||||
|
description.push(`...plus ${moonDifference} more untracked`);
|
||||||
|
}
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setTitle(`${user.username}'s Moons`)
|
.setTitle(`${user.username}'s Moons`)
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setDescription(description.join("\n"))
|
.setDescription(description.join("\n"))
|
||||||
.setFooter({ text: `Page ${page + 1} of ${totalPages} · ${moons[1]} moons` });
|
.setFooter({ text: `Page ${page + 1} of ${totalPages} · ${totalMoons} moons` });
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
.addComponents(
|
.addComponents(
|
||||||
|
@ -36,7 +46,7 @@ export default async function ListMoons(interaction: CommandInteraction) {
|
||||||
.setCustomId(`moons list ${user.id} ${page + 1}`)
|
.setCustomId(`moons list ${user.id} ${page + 1}`)
|
||||||
.setLabel("Next")
|
.setLabel("Next")
|
||||||
.setStyle(ButtonStyle.Primary)
|
.setStyle(ButtonStyle.Primary)
|
||||||
.setDisabled(page + 1 == totalPages));
|
.setDisabled(isLastPage));
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [ embed ],
|
embeds: [ embed ],
|
||||||
|
|
35
src/database/entities/UserSetting.ts
Normal file
35
src/database/entities/UserSetting.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { Column, Entity} from "typeorm";
|
||||||
|
import AppDataSource from "../dataSources/appDataSource";
|
||||||
|
import BaseEntity from "../../contracts/BaseEntity";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export default class UserSetting extends BaseEntity {
|
||||||
|
constructor(userId: string, key: string, value: string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.UserId = userId;
|
||||||
|
this.Key = key;
|
||||||
|
this.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
UserId: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
Key: string;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
Value: string;
|
||||||
|
|
||||||
|
public UpdateValue(value: string) {
|
||||||
|
this.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async FetchOneByKey(userId: string, key: string, relations?: string[]): Promise<UserSetting | null> {
|
||||||
|
const repository = AppDataSource.getRepository(UserSetting);
|
||||||
|
|
||||||
|
const single = await repository.findOne({ where: { UserId: userId, Key: key }, relations: relations || {} });
|
||||||
|
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
import MigrationHelper from "../../../helpers/MigrationHelper";
|
||||||
|
|
||||||
|
export class CreateUserSetting1727286976268 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
MigrationHelper.Up('1727286976268-CreateUserSetting', '3.3.0', [
|
||||||
|
"01-UserSetting",
|
||||||
|
"02-UserSettingKey",
|
||||||
|
], queryRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ import MessageCreate from "./events/MessageEvents/MessageCreate";
|
||||||
|
|
||||||
// Button Event Imports
|
// Button Event Imports
|
||||||
import Verify from "./buttonEvents/verify";
|
import Verify from "./buttonEvents/verify";
|
||||||
import MoonsButtonEvent from "./buttonEvents/moons";
|
import MoonsButtonEvent from "./buttonEvents/304276391837302787/moons";
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
|
|
21
tests/buttonEvents/304276391837302787/moons.test.ts
Normal file
21
tests/buttonEvents/304276391837302787/moons.test.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { ButtonInteraction } from "discord.js";
|
||||||
|
import Moons from "../../../src/buttonEvents/304276391837302787/moons";
|
||||||
|
import * as List from "../../../src/buttonEvents/304276391837302787/moons/list";
|
||||||
|
|
||||||
|
describe("GIVEN interaction action is list", () => {
|
||||||
|
const interaction = {
|
||||||
|
customId: "moons list",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
const listSpy = jest.spyOn(List, "default");
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const moons = new Moons();
|
||||||
|
await moons.execute(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT List function to be called", () => {
|
||||||
|
expect(listSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(listSpy).toHaveBeenCalledWith(interaction);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GIVEN happy flow EXPECT embed to be updated 1`] = `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "**1 -** Test Descriptio",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 1 of 1 · 0 moons",
|
||||||
|
},
|
||||||
|
"title": "username's Moons",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GIVEN happy flow EXPECT row to be updated 1`] = `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "moons list userId -1",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "moons list userId 1",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
268
tests/buttonEvents/304276391837302787/moons/list.test.ts
Normal file
268
tests/buttonEvents/304276391837302787/moons/list.test.ts
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
import {ActionRowBuilder, ButtonBuilder, ButtonInteraction, EmbedBuilder} from "discord.js";
|
||||||
|
import List from "../../../../src/buttonEvents/304276391837302787/moons/list";
|
||||||
|
import UserSetting from "../../../../src/database/entities/UserSetting";
|
||||||
|
import Moon from "../../../../src/database/entities/304276391837302787/Moon";
|
||||||
|
|
||||||
|
describe("GIVEN happy flow", () => {
|
||||||
|
let updatedWithEmbeds: EmbedBuilder[] | undefined;
|
||||||
|
let updatedWithRows: ActionRowBuilder<ButtonBuilder>[] | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn((options: any) => {
|
||||||
|
updatedWithEmbeds = options.embeds;
|
||||||
|
updatedWithRows = options.components;
|
||||||
|
}),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
MoonNumber: 1,
|
||||||
|
Description: "Test Description",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT moons to be fetched", () => {
|
||||||
|
expect(Moon.FetchPaginatedMoonsByUserId).toHaveBeenCalledTimes(1);
|
||||||
|
expect(Moon.FetchPaginatedMoonsByUserId).toHaveBeenCalledWith("userId", 10, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT interaction.update to be called", () => {
|
||||||
|
expect(interaction.update).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT embed to be updated", () => {
|
||||||
|
expect(updatedWithEmbeds).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT row to be updated", () => {
|
||||||
|
expect(updatedWithRows).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN interaction.guild is null", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: null,
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN userId parameter is undefined", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN page parameter is undefined", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT function to return", () => {
|
||||||
|
expect(interaction.reply).not.toHaveBeenCalled();
|
||||||
|
expect(interaction.update).not.toHaveBeenCalled();
|
||||||
|
expect(UserSetting.FetchOneByKey).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN no moons for the user is returned", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT moons function to be called", () => {
|
||||||
|
expect(Moon.FetchPaginatedMoonsByUserId).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("username does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN member is not in cache", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue(undefined),
|
||||||
|
},
|
||||||
|
fetch: jest.fn().mockResolvedValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT API to be called", () => {
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledWith("userId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied with username", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("username does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN member can not be found", () => {
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue(undefined),
|
||||||
|
},
|
||||||
|
fetch: jest.fn().mockResolvedValue(undefined),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue(undefined)
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT API to be called", () => {
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.guild?.members.fetch).toHaveBeenCalledWith("userId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT error replied with username", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.reply).toHaveBeenCalledWith("This user does not have any moons or page is invalid.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN no moons on current page", () => {
|
||||||
|
let updatedWith: EmbedBuilder[] | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
guild: {
|
||||||
|
members: {
|
||||||
|
cache: {
|
||||||
|
find: jest.fn().mockReturnValue({
|
||||||
|
user: {
|
||||||
|
username: "username",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reply: jest.fn(),
|
||||||
|
update: jest.fn((options: any) => {
|
||||||
|
updatedWith = options.embeds;
|
||||||
|
}),
|
||||||
|
customId: "moons list userId 0",
|
||||||
|
} as unknown as ButtonInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn();
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT description to say so", () => {
|
||||||
|
expect(updatedWith).toBeDefined();
|
||||||
|
expect(updatedWith?.length).toBe(1);
|
||||||
|
|
||||||
|
expect(updatedWith![0].data.description).toBe("*none*");
|
||||||
|
});
|
||||||
|
});
|
17
tests/commands/304276391837302787/moons.test.ts
Normal file
17
tests/commands/304276391837302787/moons.test.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
describe("constructor", () => {
|
||||||
|
test.todo("EXPECT CommandBuilder to be defined correctly");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("execute", () => {
|
||||||
|
describe("GIVEN interaction is not a chat input command", () => {
|
||||||
|
test.todo("EXPECT nothing to happen");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN interaction subcommand is list", () => {
|
||||||
|
test.todo("EXPECT ListMoons to be called");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN interaction subcommand is add", () => {
|
||||||
|
test.todo("EXPECT AddMoon to be called");
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GIVEN happy flow EXPECT embed to be replied 1`] = `
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"color": 5294200,
|
||||||
|
"description": "**2 -** Test Description",
|
||||||
|
"thumbnail": {
|
||||||
|
"url": "https://cdn.discordapp.com/emojis/374131312182689793.webp?size=96&quality=lossless",
|
||||||
|
},
|
||||||
|
"title": "undefined Got A Moon!",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GIVEN happy flow EXPECT moon to be saved 1`] = `
|
||||||
|
{
|
||||||
|
"Description": "Test Description",
|
||||||
|
"Id": Any<String>,
|
||||||
|
"MoonNumber": 2,
|
||||||
|
"UserId": "userId",
|
||||||
|
"WhenCreated": Any<Date>,
|
||||||
|
"WhenUpdated": Any<Date>,
|
||||||
|
}
|
||||||
|
`;
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GIVEN happy flow EXPECT interaction to be replied 1`] = `
|
||||||
|
{
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "moons list userId -1",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "moons list userId 01",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"embeds": [
|
||||||
|
{
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "**1 -** Test Descriptio",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 01 of 1 · 0 moons",
|
||||||
|
},
|
||||||
|
"title": "undefined's Moons",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
96
tests/commands/304276391837302787/moons/add.test.ts
Normal file
96
tests/commands/304276391837302787/moons/add.test.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import { CommandInteraction, EmbedBuilder } from "discord.js";
|
||||||
|
import AddMoon from "../../../../src/commands/304276391837302787/moons/add";
|
||||||
|
import Moon from "../../../../src/database/entities/304276391837302787/Moon";
|
||||||
|
import UserSetting from "../../../../src/database/entities/UserSetting";
|
||||||
|
|
||||||
|
describe("GIVEN happy flow", () => {
|
||||||
|
let repliedWithEmbed: EmbedBuilder[] | undefined;
|
||||||
|
let savedMoon: Moon | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options: any) => {
|
||||||
|
repliedWithEmbed = options.embeds;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce({
|
||||||
|
value: "Test Description",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
},
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
const userSetting = {
|
||||||
|
Value: 1,
|
||||||
|
UpdateValue: jest.fn(),
|
||||||
|
Save: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchMoonCountByUserId = jest.fn().mockResolvedValue(1);
|
||||||
|
Moon.prototype.Save = jest.fn().mockImplementation((_, entity: Moon) => {
|
||||||
|
savedMoon = entity;
|
||||||
|
});
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue(userSetting);
|
||||||
|
|
||||||
|
await AddMoon(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT description option to have been fetched", () => {
|
||||||
|
expect(interaction.options.get).toHaveBeenCalledTimes(1);
|
||||||
|
expect(interaction.options.get).toHaveBeenCalledWith("description", true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT UserSetting to have been fetched", () => {
|
||||||
|
expect(UserSetting.FetchOneByKey).toHaveBeenCalledTimes(1);
|
||||||
|
expect(UserSetting.FetchOneByKey).toHaveBeenCalledWith("userId", "moons");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT moonCount to be updated +1", () => {
|
||||||
|
expect(userSetting.UpdateValue).toHaveBeenCalledTimes(1);
|
||||||
|
expect(userSetting.UpdateValue).toHaveBeenCalledWith("2");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT setting to be saved", () => {
|
||||||
|
expect(userSetting.Save).toHaveBeenCalledTimes(1);
|
||||||
|
expect(userSetting.Save).toHaveBeenCalledWith(UserSetting, userSetting);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT moon to be saved", () => {
|
||||||
|
expect(Moon.prototype.Save).toHaveBeenCalledTimes(1);
|
||||||
|
expect(Moon.prototype.Save).toHaveBeenCalledWith(Moon, expect.any(Moon));
|
||||||
|
|
||||||
|
expect(savedMoon).toBeDefined();
|
||||||
|
expect(savedMoon).toMatchSnapshot({
|
||||||
|
Id: expect.any(String),
|
||||||
|
WhenCreated: expect.any(Date),
|
||||||
|
WhenUpdated: expect.any(Date),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT embed to be replied", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(repliedWithEmbed).toBeDefined();
|
||||||
|
expect(repliedWithEmbed).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN description is null", () => {
|
||||||
|
test.todo("EXPECT error replied");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN description is greater than 255 characters", () => {
|
||||||
|
test.todo("EXPECT error replied");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN moon count setting exists", () => {
|
||||||
|
test.todo("EXPECT existing entity to be updated");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN moon count setting does not exist", () => {
|
||||||
|
test.todo("EXPECT new entity to be created");
|
||||||
|
});
|
249
tests/commands/304276391837302787/moons/list.test.ts
Normal file
249
tests/commands/304276391837302787/moons/list.test.ts
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
import { ActionRowBuilder, APIEmbed, ButtonBuilder, CommandInteraction, EmbedBuilder, InteractionReplyOptions } from "discord.js";
|
||||||
|
import List from "../../../../src/commands/304276391837302787/moons/list";
|
||||||
|
import Moon from "../../../../src/database/entities/304276391837302787/Moon";
|
||||||
|
import UserSetting from "../../../../src/database/entities/UserSetting";
|
||||||
|
|
||||||
|
describe("GIVEN happy flow", () => {
|
||||||
|
let repliedWith: InteractionReplyOptions | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options) => {
|
||||||
|
repliedWith = options;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(undefined) // User
|
||||||
|
.mockReturnValue({
|
||||||
|
value: "0",
|
||||||
|
}), // Page
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
}
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
MoonNumber: 1,
|
||||||
|
Description: "Test Description",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "0",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT interaction to be replied", () => {
|
||||||
|
expect(interaction.reply).toHaveBeenCalledTimes(1);
|
||||||
|
expect(repliedWith).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN moons returned is empty", () => {
|
||||||
|
let repliedWith: InteractionReplyOptions | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options) => {
|
||||||
|
repliedWith = options;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(undefined) // User
|
||||||
|
.mockReturnValue({
|
||||||
|
value: "0",
|
||||||
|
}), // Page
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
}
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "0",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT none description", () => {
|
||||||
|
expect(repliedWith).toBeDefined();
|
||||||
|
|
||||||
|
expect(repliedWith!.embeds).toBeDefined();
|
||||||
|
expect(repliedWith!.embeds!.length).toBe(1);
|
||||||
|
|
||||||
|
const repliedWithEmbed = repliedWith!.embeds![0] as EmbedBuilder;
|
||||||
|
|
||||||
|
expect(repliedWithEmbed.data.description).toBe("*none*");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN it is the first page", () => {
|
||||||
|
let repliedWith: InteractionReplyOptions | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options) => {
|
||||||
|
repliedWith = options;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(undefined) // User
|
||||||
|
.mockReturnValue({
|
||||||
|
value: "0",
|
||||||
|
}), // Page
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
}
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
MoonNumber: 1,
|
||||||
|
Description: "Test Description",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "0",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT Previous button to be disabled", () => {
|
||||||
|
expect(repliedWith).toBeDefined();
|
||||||
|
|
||||||
|
expect(repliedWith!.components).toBeDefined();
|
||||||
|
expect(repliedWith!.components!.length).toBe(1);
|
||||||
|
|
||||||
|
const repliedWithRow = repliedWith!.components![0] as ActionRowBuilder<ButtonBuilder>;
|
||||||
|
|
||||||
|
expect(repliedWithRow.components[0].data.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN it is the last page", () => {
|
||||||
|
let repliedWith: InteractionReplyOptions | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options) => {
|
||||||
|
repliedWith = options;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(undefined) // User
|
||||||
|
.mockReturnValue({
|
||||||
|
value: "0",
|
||||||
|
}), // Page
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
}
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
MoonNumber: 1,
|
||||||
|
Description: "Test Description",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "0",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT Next button to be disabled", () => {
|
||||||
|
expect(repliedWith).toBeDefined();
|
||||||
|
|
||||||
|
expect(repliedWith!.components).toBeDefined();
|
||||||
|
expect(repliedWith!.components!.length).toBe(1);
|
||||||
|
|
||||||
|
const repliedWithRow = repliedWith!.components![0] as ActionRowBuilder<ButtonBuilder>;
|
||||||
|
|
||||||
|
expect(repliedWithRow.components[1].data.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN moon count is greater than the amount of moons in the database", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "2",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT untracked counter to be shown", () => {
|
||||||
|
const repliedWithEmbed = repliedWith!.embeds![0] as EmbedBuilder;
|
||||||
|
|
||||||
|
expect(repliedWithEmbed.data.description).toContain("...plus 1 more untracked");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("GIVEN moon count is empty", () => {
|
||||||
|
let repliedWith: InteractionReplyOptions | undefined;
|
||||||
|
|
||||||
|
const interaction = {
|
||||||
|
reply: jest.fn((options) => {
|
||||||
|
repliedWith = options;
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
get: jest.fn()
|
||||||
|
.mockReturnValueOnce(undefined) // User
|
||||||
|
.mockReturnValue({
|
||||||
|
value: "0",
|
||||||
|
}), // Page
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
id: "userId",
|
||||||
|
}
|
||||||
|
} as unknown as CommandInteraction;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
Moon.FetchPaginatedMoonsByUserId = jest.fn().mockResolvedValue([
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
UserSetting.FetchOneByKey = jest.fn().mockResolvedValue({
|
||||||
|
Value: "0",
|
||||||
|
});
|
||||||
|
|
||||||
|
await List(interaction);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("EXPECT Next button to be disabled", () => {
|
||||||
|
expect(repliedWith).toBeDefined();
|
||||||
|
|
||||||
|
expect(repliedWith!.components).toBeDefined();
|
||||||
|
expect(repliedWith!.components!.length).toBe(1);
|
||||||
|
|
||||||
|
const repliedWithRow = repliedWith!.components![0] as ActionRowBuilder<ButtonBuilder>;
|
||||||
|
|
||||||
|
expect(repliedWithRow.components[1].data.disabled).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
11
tests/database/entites/UserSetting.test.ts
Normal file
11
tests/database/entites/UserSetting.test.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
describe("constructor", () => {
|
||||||
|
test.todo("EXPECT settings to be configured");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("UpdateValue", () => {
|
||||||
|
test.todo("EXPECT value to be updated");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("FetchOneByKey", () => {
|
||||||
|
test.todo("EXPECT single entity returned");
|
||||||
|
});
|
Loading…
Reference in a new issue