From 89b0b02ef4be316e9fabfba72ec54a1852b75d9c Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 12 Mar 2025 17:55:51 +0000
Subject: [PATCH 1/4] Add tests for effects buy confirm button event

---
 tests/buttonEvents/Effects/Buy.test.ts | 75 +++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 8 deletions(-)

diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts
index 6c7ae6b..01c3f89 100644
--- a/tests/buttonEvents/Effects/Buy.test.ts
+++ b/tests/buttonEvents/Effects/Buy.test.ts
@@ -5,9 +5,11 @@ import { ButtonInteraction as ButtonInteractionType } from "../../__types__/disc
 import AppLogger from "../../../src/client/appLogger";
 import EffectHelper from "../../../src/helpers/EffectHelper";
 import EmbedColours from "../../../src/constants/EmbedColours";
+import User from "../../../src/database/entities/app/User";
 
 jest.mock("../../../src/client/appLogger");
 jest.mock("../../../src/helpers/EffectHelper");
+jest.mock("../../../src/database/entities/app/User");
 
 let interaction: ButtonInteractionType;
 
@@ -81,13 +83,23 @@ describe("Execute", () => {
 });
 
 describe("Confirm", () => {
+    let user: User;
+
     beforeEach(() => {
         interaction.customId += " confirm";
+
+        user = {
+            Currency: 1000,
+            Save: jest.fn(),
+            RemoveCurrency: jest.fn(),
+        } as unknown as User;
+
+        (User.FetchOneById as jest.Mock).mockResolvedValue(user);
     });
 
     test("EXPECT success embed generated", async () => {
         // Assert
-        interaction.customId += " id 1";
+        interaction.customId += " unclaimed 1";
 
         const embed = {
             id: "embed",
@@ -114,7 +126,7 @@ describe("Confirm", () => {
         });
 
         expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1);
-        expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledWith("userId", "id", 1, true);
+        expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledWith("userId", "unclaimed", 1, true);
 
         expect(embed.setColor).toHaveBeenCalledTimes(1);
         expect(embed.setColor).toHaveBeenCalledWith(EmbedColours.Success);
@@ -124,6 +136,18 @@ describe("Confirm", () => {
 
         expect(interaction.reply).not.toHaveBeenCalled();
         expect(AppLogger.LogError).not.toHaveBeenCalled();
+
+        expect(User.FetchOneById).toHaveBeenCalledTimes(1);
+        expect(User.FetchOneById).toHaveBeenCalledWith(User, "userId");
+
+        expect(user.RemoveCurrency).toHaveBeenCalledTimes(1);
+        expect(user.RemoveCurrency).toHaveBeenCalledWith(100);
+
+        expect(user.Save).toHaveBeenCalledTimes(1);
+        expect(user.Save).toHaveBeenCalledWith(User, user);
+
+        expect(EffectHelper.AddEffectToUserInventory).toHaveBeenCalledTimes(1);
+        expect(EffectHelper.AddEffectToUserInventory).toHaveBeenCalledWith("userId", "unclaimed", 1);
     });
 
     test("GIVEN id is not supplied, EXPECT error", async () => {
@@ -156,7 +180,7 @@ describe("Confirm", () => {
 
     test("GIVEN quantity is not supplied, EXPECT error", async () => {
         // Assert
-        interaction.customId += " id";
+        interaction.customId += " unclaimed";
 
         const embed = {
             id: "embed",
@@ -186,7 +210,7 @@ describe("Confirm", () => {
 
     test("GIVEN quantity is not a number, EXPECT error", async () => {
         // Assert
-        interaction.customId += " id invalid";
+        interaction.customId += " unclaimed invalid";
 
         const embed = {
             id: "embed",
@@ -216,7 +240,7 @@ describe("Confirm", () => {
 
     test("GIVEN quantity is 0, EXPECT error", async () => {
         // Assert
-        interaction.customId += " id 0";
+        interaction.customId += " unclaimed 0";
 
         const embed = {
             id: "embed",
@@ -244,13 +268,48 @@ describe("Confirm", () => {
         expect(interaction.update).not.toHaveBeenCalled();
     });
 
-    test.todo("GIVEN user is not found, EXPECT error");
+    test("GIVEN user is not found, EXPECT error", async () => {
+        // Assert
+        interaction.customId += " unclaimed 1";
 
-    test.todo("GIVEN user does not have enough currency, EXPECT error");
+        (User.FetchOneById as jest.Mock).mockResolvedValue(undefined);
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Confirm", "Unable to find user");
+
+        expect(EffectHelper.AddEffectToUserInventory).not.toHaveBeenCalled();
+
+        expect(interaction.update).not.toHaveBeenCalled();
+        expect(interaction.reply).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN user does not have enough currency, EXPECT error", async () => {
+        // Assert
+        interaction.customId += " unclaimed 1";
+
+        user.Currency = 0;
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(interaction.reply).toHaveBeenCalledTimes(1);
+        expect(interaction.reply).toHaveBeenCalledWith("You don't have enough currency to buy this! You have `0 Currency` and need `100 Currency`!");
+        
+        expect(EffectHelper.AddEffectToUserInventory).not.toHaveBeenCalled();
+
+        expect(interaction.update).not.toHaveBeenCalled();
+
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
 
     test("GIVEN GenerateEffectBuyEmbed returns with a string, EXPECT error replied", async () => {
         // Assert
-        interaction.customId += " id 1";
+        interaction.customId += " unclaimed 1";
         
         (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue("Test error");
 

From b49bc67fe10b9c5ee4559add8b5882b11df9b062 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 12 Mar 2025 18:00:56 +0000
Subject: [PATCH 2/4] Create buy cancel button event

---
 src/buttonEvents/Effects/Buy.ts | 36 +++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/buttonEvents/Effects/Buy.ts b/src/buttonEvents/Effects/Buy.ts
index 473eb08..49cc75f 100644
--- a/src/buttonEvents/Effects/Buy.ts
+++ b/src/buttonEvents/Effects/Buy.ts
@@ -80,5 +80,41 @@ export default class Buy {
     }
 
     private static async Cancel(interaction: ButtonInteraction) {
+        const id = interaction.customId.split(" ")[3];
+        const quantity = interaction.customId.split(" ")[4];
+
+        if (!id || !quantity) {
+            AppLogger.LogError("Buy Cancel", "Not enough parameters");
+            return;
+        }
+        
+        const effectDetail = EffectDetails.get(id);
+
+        if (!effectDetail) {
+            AppLogger.LogError("Buy Cancel", "Effect detail not found!");
+            return;
+        }
+
+        const quantityNumber = Number(quantity);
+        
+        if (!quantityNumber || quantityNumber < 1) {
+            AppLogger.LogError("Buy Cancel", "Invalid number");
+            return;
+        }
+
+        const generatedEmbed = await EffectHelper.GenerateEffectBuyEmbed(interaction.user.id, id, quantityNumber, true);
+
+        if (typeof generatedEmbed == "string") {
+            await interaction.reply(generatedEmbed);
+            return;
+        }
+
+        generatedEmbed.embed.setColor(EmbedColours.Error);
+        generatedEmbed.embed.setFooter({ text: "Cancelled" });
+
+        await interaction.update({
+            embeds: [ generatedEmbed.embed ],
+            components: [ generatedEmbed.row ],
+        });
     }
 }

From 926567c9cd93a11de7c3182fa1abc10e275d19b1 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 12 Mar 2025 18:05:34 +0000
Subject: [PATCH 3/4] Add tests

---
 tests/buttonEvents/Effects/Buy.test.ts | 126 +++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts
index 01c3f89..70f1ebf 100644
--- a/tests/buttonEvents/Effects/Buy.test.ts
+++ b/tests/buttonEvents/Effects/Buy.test.ts
@@ -326,3 +326,129 @@ describe("Confirm", () => {
         expect(AppLogger.LogError).not.toHaveBeenCalled();
     });
 });
+
+describe("Cancel", () => {
+    beforeEach(() => {
+        interaction.customId += " cancel";
+    });
+
+    test("EXPECT embed generated", async () => {
+        // Assert
+        interaction.customId += " unclaimed 1";
+
+        const embed = {
+            id: "embed",
+            setColor: jest.fn(),
+            setFooter: jest.fn(),
+        };
+        const row = {
+            id: "row",
+        };
+        
+        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({
+            embed,
+            row,
+        });
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(interaction.update).toHaveBeenCalledTimes(1);
+        expect(interaction.update).toHaveBeenCalledWith({
+            embeds: [ embed ],
+            components: [ row ],
+        });
+
+        expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1);
+        expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledWith("userId", "unclaimed", 1, true);
+
+        expect(embed.setColor).toHaveBeenCalledTimes(1);
+        expect(embed.setColor).toHaveBeenCalledWith(EmbedColours.Error);
+
+        expect(embed.setFooter).toHaveBeenCalledTimes(1);
+        expect(embed.setFooter).toHaveBeenCalledWith({ text: "Cancelled" });
+
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN id is not supplied, EXPECT error", async () => {
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Not enough parameters");
+
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(interaction.update).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN quantity is not supplied, EXPECT error", async () => {
+        // Assert
+        interaction.customId += " unclaimed";
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Not enough parameters");
+
+        expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled();
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(interaction.update).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN quantity is not a number, EXPECT error", async () => {
+        // Assert
+        interaction.customId += " unclaimed invalid";
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Invalid number");
+
+        expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled();
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(interaction.update).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN quantity is 0, EXPECT error", async () => {
+        // Assert
+        interaction.customId += " unclaimed 0";
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy Cancel", "Invalid number");
+
+        expect(EffectHelper.GenerateEffectBuyEmbed).not.toHaveBeenCalled();
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(interaction.update).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN GenerateEffectBuyEmbed returns with a string, EXPECT error replied", async () => {
+        // Assert
+        interaction.customId += " unclaimed 1";
+        
+        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue("Test error");
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(interaction.reply).toHaveBeenCalledTimes(1);
+        expect(interaction.reply).toHaveBeenCalledWith("Test error");
+
+        expect(EffectHelper.GenerateEffectBuyEmbed).toHaveBeenCalledTimes(1);
+
+        expect(interaction.update).not.toHaveBeenCalled();
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
+});

From bc98d6ba752f669e52987abbe794277686f05029 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 12 Mar 2025 18:07:05 +0000
Subject: [PATCH 4/4] Update tests

---
 tests/buttonEvents/Effects/Buy.test.ts | 57 --------------------------
 1 file changed, 57 deletions(-)

diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts
index 70f1ebf..2a4b902 100644
--- a/tests/buttonEvents/Effects/Buy.test.ts
+++ b/tests/buttonEvents/Effects/Buy.test.ts
@@ -151,21 +151,6 @@ describe("Confirm", () => {
     });
 
     test("GIVEN id is not supplied, EXPECT error", async () => {
-        // Assert
-        const embed = {
-            id: "embed",
-            setColor: jest.fn(),
-            setFooter: jest.fn(),
-        };
-        const row = {
-            id: "row",
-        };
-        
-        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({
-            embed,
-            row,
-        });
-
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
 
@@ -182,20 +167,6 @@ describe("Confirm", () => {
         // Assert
         interaction.customId += " unclaimed";
 
-        const embed = {
-            id: "embed",
-            setColor: jest.fn(),
-            setFooter: jest.fn(),
-        };
-        const row = {
-            id: "row",
-        };
-        
-        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({
-            embed,
-            row,
-        });
-
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
 
@@ -212,20 +183,6 @@ describe("Confirm", () => {
         // Assert
         interaction.customId += " unclaimed invalid";
 
-        const embed = {
-            id: "embed",
-            setColor: jest.fn(),
-            setFooter: jest.fn(),
-        };
-        const row = {
-            id: "row",
-        };
-        
-        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({
-            embed,
-            row,
-        });
-
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
 
@@ -242,20 +199,6 @@ describe("Confirm", () => {
         // Assert
         interaction.customId += " unclaimed 0";
 
-        const embed = {
-            id: "embed",
-            setColor: jest.fn(),
-            setFooter: jest.fn(),
-        };
-        const row = {
-            id: "row",
-        };
-        
-        (EffectHelper.GenerateEffectBuyEmbed as jest.Mock).mockResolvedValue({
-            embed,
-            row,
-        });
-
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);