From d9e8fee1a642898b68f841c1e313a9bdfa8d2abf Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 29 Jan 2025 17:52:19 +0000 Subject: [PATCH 1/5] Add friendly name to list embed --- src/helpers/EffectHelper.ts | 2 +- tests/helpers/EffectHelper.test.ts | 85 +++++++++ .../__snapshots__/EffectHelper.test.ts.snap | 169 ++++++++++++++++++ 3 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 tests/helpers/EffectHelper.test.ts create mode 100644 tests/helpers/__snapshots__/EffectHelper.test.ts.snap diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index d4673f4..bd86b15 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -82,7 +82,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() diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts new file mode 100644 index 0000000..6541653 --- /dev/null +++ b/tests/helpers/EffectHelper.test.ts @@ -0,0 +1,85 @@ +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: any[] = []; + + 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: any[] = []; + + 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(); + }); +}); \ 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..c3e6f55 --- /dev/null +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -0,0 +1,169 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +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, + }, +} +`; -- 2.45.2 From 0adf9c67c9f016f107eaadb8f811801bb08f50a1 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 29 Jan 2025 18:07:56 +0000 Subject: [PATCH 2/5] Add currently active effect to list --- src/database/entities/app/UserEffect.ts | 12 ++++++ src/helpers/EffectHelper.ts | 10 +++++ tests/helpers/EffectHelper.test.ts | 32 +++++++++++++-- .../__snapshots__/EffectHelper.test.ts.snap | 41 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts index 72fae5f..c962ff7 100644 --- a/src/database/entities/app/UserEffect.ts +++ b/src/database/entities/app/UserEffect.ts @@ -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 }) + .where("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 bd86b15..c44dfc4 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]; @@ -91,6 +92,15 @@ 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} (Exp. )`, + } + ]); + } + const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() diff --git a/tests/helpers/EffectHelper.test.ts b/tests/helpers/EffectHelper.test.ts index 6541653..e8dbef2 100644 --- a/tests/helpers/EffectHelper.test.ts +++ b/tests/helpers/EffectHelper.test.ts @@ -14,7 +14,7 @@ describe("GenerateEffectEmbed", () => { } ], 1, - ]) + ]); // Act const result = await EffectHelper.GenerateEffectEmbed("userId", 1); @@ -37,7 +37,7 @@ describe("GenerateEffectEmbed", () => { (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ effects, 15, - ]) + ]); // Act const result = await EffectHelper.GenerateEffectEmbed("userId", 1); @@ -60,7 +60,7 @@ describe("GenerateEffectEmbed", () => { (UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([ effects, 15, - ]) + ]); // Act const result = await EffectHelper.GenerateEffectEmbed("userId", 2); @@ -74,7 +74,31 @@ describe("GenerateEffectEmbed", () => { (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); diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap index c3e6f55..a78f16d 100644 --- a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -1,5 +1,46 @@ // 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": [ + { + "name": "Active", + "value": "Unclaimed Chance Up (Exp. )", + }, + ], + "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": { -- 2.45.2 From 37346aaeded413b2dfb4e226efb8564cf4ef185c Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Wed, 29 Jan 2025 18:09:30 +0000 Subject: [PATCH 3/5] Fix linter --- .../GetUnclaimedCardsHelper.test.ts | 19 ------------------- tests/helpers/EffectHelper.test.ts | 10 ++++++++-- 2 files changed, 8 insertions(+), 21 deletions(-) delete mode 100644 tests/helpers/DropHelpers/GetUnclaimedCardsHelper.test.ts 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 index e8dbef2..b0dd12d 100644 --- a/tests/helpers/EffectHelper.test.ts +++ b/tests/helpers/EffectHelper.test.ts @@ -24,7 +24,10 @@ describe("GenerateEffectEmbed", () => { }); test("GIVEN user has more than 1 page of effects, EXPECT pagination enabled", async () => { - const effects: any[] = []; + const effects: { + Name: string, + Unused: number, + }[] = []; for (let i = 0; i < 15; i++) { effects.push({ @@ -47,7 +50,10 @@ describe("GenerateEffectEmbed", () => { }); test("GIVEN user is on a page other than 1, EXPECT pagination enabled", async () => { - const effects: any[] = []; + const effects: { + Name: string, + Unused: number, + }[] = []; for (let i = 0; i < 15; i++) { effects.push({ -- 2.45.2 From 7c17e1d0d05d49d5239ebd6c9cbd6f3cd8c21227 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sat, 1 Feb 2025 16:40:14 +0000 Subject: [PATCH 4/5] Fix changes requested --- src/database/entities/app/UserEffect.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database/entities/app/UserEffect.ts b/src/database/entities/app/UserEffect.ts index c962ff7..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) @@ -77,8 +77,8 @@ export default class UserEffect extends AppBaseEntity { const query = await repository.createQueryBuilder("effect") .where("effect.UserId = :userId", { userId }) - .where("effect.WhenExpires IS NOT NULL") - .andWhere("effect.WhenExpires > :now", { now: new Date() }) + .andWhere("effect.WhenExpires IS NOT NULL") + .andWhere("effect.WhenExpires > :now", { now: new Date() }) .getOne(); return query; -- 2.45.2 From a050dd713128f7bcc18e62e72aa6749bfb076ff7 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Mon, 3 Feb 2025 18:23:29 +0000 Subject: [PATCH 5/5] Split expiry date to its own field --- src/helpers/EffectHelper.ts | 10 ++++++++-- tests/helpers/__snapshots__/EffectHelper.test.ts.snap | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/helpers/EffectHelper.ts b/src/helpers/EffectHelper.ts index c44dfc4..6c38cac 100644 --- a/src/helpers/EffectHelper.ts +++ b/src/helpers/EffectHelper.ts @@ -96,8 +96,14 @@ export default class EffectHelper { embed.addFields([ { name: "Active", - value: `${EffectDetails.get(activeEffect.Name)?.friendlyName} (Exp. )`, - } + value: `${EffectDetails.get(activeEffect.Name)?.friendlyName}`, + inline: true, + }, + { + name: "Expires", + value: ``, + inline: true, + }, ]); } diff --git a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap index a78f16d..f6e5e8e 100644 --- a/tests/helpers/__snapshots__/EffectHelper.test.ts.snap +++ b/tests/helpers/__snapshots__/EffectHelper.test.ts.snap @@ -7,8 +7,14 @@ exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added "description": "Unclaimed Chance Up x1", "fields": [ { + "inline": true, "name": "Active", - "value": "Unclaimed Chance Up (Exp. )", + "value": "Unclaimed Chance Up", + }, + { + "inline": true, + "name": "Expires", + "value": "", }, ], "footer": { -- 2.45.2