diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts index 72fae5f..447b9c5 100644 --- a/src/database/entities/app/UserEffect.ts +++ b/src/database/entities/app/UserEffect.ts @@ -63,7 +63,7 @@ export default class UserEffect extends AppBaseEntity { const query = await repository.createQueryBuilder("effect") .where("effect.UserId = :userId", { userId }) - .where("effect.Unused > 0") + .andWhere("effect.Unused > 0") .orderBy("effect.Name", "ASC") .skip(page * itemsPerPage) .take(itemsPerPage) @@ -71,4 +71,16 @@ export default class UserEffect extends AppBaseEntity { return query; } + + public static async FetchActiveEffectByUserId(userId: string): Promise { + const repository = AppDataSource.getRepository(UserEffect); + + const query = await repository.createQueryBuilder("effect") + .where("effect.UserId = :userId", { userId }) + .andWhere("effect.WhenExpires IS NOT NULL") + .andWhere("effect.WhenExpires > :now", { now: new Date() }) + .getOne(); + + return query; + } } diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index d4673f4..6c38cac 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -73,6 +73,7 @@ export default class EffectHelper { const itemsPerPage = 10; const query = await UserEffect.FetchAllByUserIdPaginated(userId, page - 1, itemsPerPage); + const activeEffect = await UserEffect.FetchActiveEffectByUserId(userId); const effects = query[0]; const count = query[1]; @@ -82,7 +83,7 @@ export default class EffectHelper { let description = "*none*"; if (effects.length > 0) { - description = effects.map(x => `${x.Name} x${x.Unused}`).join("\n"); + description = effects.map(x => `${EffectDetails.get(x.Name)?.friendlyName} x${x.Unused}`).join("\n"); } const embed = new EmbedBuilder() @@ -91,6 +92,21 @@ export default class EffectHelper { .setColor(EmbedColours.Ok) .setFooter({ text: `Page ${page} of ${totalPages}` }); + if (activeEffect) { + embed.addFields([ + { + name: "Active", + value: `${EffectDetails.get(activeEffect.Name)?.friendlyName}`, + inline: true, + }, + { + name: "Expires", + value: ``, + inline: true, + }, + ]); + } + const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() diff --git a/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts b/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts deleted file mode 100644 index 04f76fc..0000000 --- a/tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -describe("GetRandomCardUnclaimed", () => { - test.todo("GIVEN chance is within bronze chance, EXPECT bronze card returned"); - - test.todo("GIVEN chance is within silver chance, EXPECT silver card"); - - test.todo("GIVEN chance is within gold chance, EXPECT gold card returned"); - - test.todo("GIVEN chance is within manga chance, EXPECT manga card returned"); -}); - -describe("GetRandomCardByRarityUnclaimed", () => { - test.todo("GIVEN user has no claimed cards, EXPECT random card returned"); - - test.todo("GIVEN no cards are found in memory, EXPECT undefined returned"); - - test.todo("GIVEN no series metadata is found for random card, EXPECT undefined returned"); - - test.todo("GIVEN user has claimed cards, EXPECT random card to NOT be this card"); -}); \ No newline at end of file diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts new file mode 100644 index 0000000..b0dd12d --- /dev/null +++ b/tests/helpers/EffectHelper.test.ts @@ -0,0 +1,115 @@ +import EffectHelper from "../../src/helpers/EffectHelper"; +import UserEffect from "../../src/database/entities/app/UserEffect"; + +jest.mock("../../src/database/entities/app/UserEffect"); + +describe("GenerateEffectEmbed", () => { + test("GIVEN user has an effect, EXPECT detailed embed to be returned", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [ + { + Name: "unclaimed", + Unused: 1, + } + ], + 1, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user has more than 1 page of effects, EXPECT pagination enabled", async () => { + const effects: { + Name: string, + Unused: number, + }[] = []; + + for (let i = 0; i < 15; i++) { + effects.push({ + Name: "unclaimed", + Unused: 1, + }); + } + + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + effects, + 15, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user is on a page other than 1, EXPECT pagination enabled", async () => { + const effects: { + Name: string, + Unused: number, + }[] = []; + + for (let i = 0; i < 15; i++) { + effects.push({ + Name: "unclaimed", + Unused: 1, + }); + } + + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + effects, + 15, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 2); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN user does NOT have an effect, EXPECT empty embed to be returned", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [], + 0, + ]); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); + + test("GIVEN there is an active effect, EXPECT field added", async () => { + // Arrange + (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ + [ + { + Name: "unclaimed", + Unused: 1, + } + ], + 1, + ]); + + (UserEffect.FetchActiveEffectByUserId as jest.Mock).mockResolvedValue({ + Name: "unclaimed", + WhenExpires: new Date(1738174052), + }); + + // Act + const result = await EffectHelper.GenerateEffectEmbed("userId", 1); + + // Assert + expect(result).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap new file mode 100644 index 0000000..f6e5e8e --- /dev/null +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -0,0 +1,216 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1", + "fields": [ + { + "inline": true, + "name": "Active", + "value": "Unclaimed Chance Up", + }, + { + "inline": true, + "name": "Expires", + "value": "", + }, + ], + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user does NOT have an effect, EXPECT empty embed to be returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "*none*", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user has an effect, EXPECT detailed embed to be returned 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 1", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user has more than 1 page of effects, EXPECT pagination enabled 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 1 of 2", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 0", + "disabled": true, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 2", + "disabled": false, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`; + +exports[`GenerateEffectEmbed GIVEN user is on a page other than 1, EXPECT pagination enabled 1`] = ` +{ + "embed": { + "color": 3166394, + "description": "Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1 +Unclaimed Chance Up x1", + "footer": { + "icon_url": undefined, + "text": "Page 2 of 2", + }, + "title": "Effects", + }, + "row": { + "components": [ + { + "custom_id": "effects list 1", + "disabled": false, + "emoji": undefined, + "label": "Previous", + "style": 1, + "type": 2, + }, + { + "custom_id": "effects list 3", + "disabled": true, + "emoji": undefined, + "label": "Next", + "style": 1, + "type": 2, + }, + ], + "type": 1, + }, +} +`;