From 416e30c042429f26c6ab75b529ebc878ef23a237 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 19 Feb 2025 18:17:16 +0000
Subject: [PATCH 1/2] Update tests

---
 tests/buttonEvents/Effects/Buy.test.ts | 70 ++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 4 deletions(-)

diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts
index f094e0c..cdf60f1 100644
--- a/tests/buttonEvents/Effects/Buy.test.ts
+++ b/tests/buttonEvents/Effects/Buy.test.ts
@@ -1,7 +1,69 @@
-describe("Execute", () => {
-    test.todo("GIVEN subaction is confirm, EXPECT confirm function executed");
+import {ButtonInteraction} from "discord.js";
+import Buy from "../../../src/buttonEvents/Effects/Buy";
+import GenerateButtonInteractionMock from "../../__functions__/discord.js/GenerateButtonInteractionMock";
+import { ButtonInteraction as ButtonInteractionType } from "../../__types__/discord.js";
+import AppLogger from "../../../src/client/appLogger";
 
-    test.todo("GIVEN subaction is cancel, EXPECT cancel function executed");
+jest.mock("../../../src/client/appLogger");
+
+let interaction: ButtonInteractionType;
+
+beforeEach(() => {
+    jest.resetAllMocks();
+
+    interaction = GenerateButtonInteractionMock();
+    interaction.customId = "effects buy";
 
-    test.todo("GIVEN subaction is invalid, EXPECT error logged");
+});
+
+describe("Execute", () => {
+    test("GIVEN subaction is confirm, EXPECT confirm function executed", async () => {
+        // Arrange
+        interaction.customId += " confirm";
+
+        const confirmSpy = jest.spyOn(Buy as any, "Confirm");
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(confirmSpy).toHaveBeenCalledTimes(1);
+        expect(confirmSpy).toHaveBeenCalledWith(interaction);
+
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN subaction is cancel, EXPECT cancel function executed", async () => {
+        // Arrange
+        interaction.customId += " cancel";
+
+        const cancelSpy = jest.spyOn(Buy as any, "Cancel");
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(cancelSpy).toHaveBeenCalledTimes(1);
+        expect(cancelSpy).toHaveBeenCalledWith(interaction);
+
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
+
+    test("GIVEN subaction is invalid, EXPECT error logged", async () => {
+        // Arrange
+        interaction.customId += " invalid";
+
+        const confirmSpy = jest.spyOn(Buy as any, "Confirm");
+        const cancelSpy = jest.spyOn(Buy as any, "Cancel");
+
+        // Act
+        await Buy.Execute(interaction as unknown as ButtonInteraction);
+
+        // Assert
+        expect(AppLogger.LogError).toHaveBeenCalledTimes(1);
+        expect(AppLogger.LogError).toHaveBeenCalledWith("Buy", "Unknown subaction, effects invalid");
+
+        expect(confirmSpy).not.toHaveBeenCalled();
+        expect(cancelSpy).not.toHaveBeenCalled();
+    });
 });

From f745fdfbca80ec1d00d3bc0ccb6eb71605601a60 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 19 Feb 2025 18:40:59 +0000
Subject: [PATCH 2/2] WIP: Start creating tests for confirmation button event

---
 src/buttonEvents/Effects/Buy.ts               | 31 +++++++++
 .../GenerateButtonInteractionMock.ts          |  2 +
 tests/__types__/discord.js.ts                 |  2 +
 tests/buttonEvents/Effects/Buy.test.ts        | 65 +++++++++++++++++--
 4 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/src/buttonEvents/Effects/Buy.ts b/src/buttonEvents/Effects/Buy.ts
index a7fc2c4..1dad272 100644
--- a/src/buttonEvents/Effects/Buy.ts
+++ b/src/buttonEvents/Effects/Buy.ts
@@ -1,5 +1,7 @@
 import {ButtonInteraction} from "discord.js";
 import AppLogger from "../../client/appLogger";
+import EffectHelper from "../../helpers/EffectHelper";
+import EmbedColours from "../../constants/EmbedColours";
 
 export default class Buy {
     public static async Execute(interaction: ButtonInteraction) {
@@ -18,6 +20,35 @@ export default class Buy {
     }
 
     private static async Confirm(interaction: ButtonInteraction) {
+        const id = interaction.customId.split(" ")[3];
+        const quantity = interaction.customId.split(" ")[4];
+
+        if (!id || !quantity) {
+            AppLogger.LogError("Buy Confirm", "Not enough parameters");
+            return;
+        }
+
+        const quantityNumber = Number(quantity);
+        
+        if (!quantityNumber || quantityNumber < 1) {
+            AppLogger.LogError("Buy Confirm", "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.Success);
+        generatedEmbed.embed.setFooter({ text: "Purchased" });
+
+        await interaction.update({
+            embeds: [ generatedEmbed.embed ],
+            components: [ generatedEmbed.row ],
+        });
     }
 
     private static async Cancel(interaction: ButtonInteraction) {
diff --git a/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts
index a1024ee..2199477 100644
--- a/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts
+++ b/tests/__functions__/discord.js/GenerateButtonInteractionMock.ts
@@ -17,5 +17,7 @@ export default function GenerateButtonInteractionMock(): ButtonInteraction {
             id: "userId",
         },
         customId: "customId",
+        update: jest.fn(),
+        reply: jest.fn(),
     };
 }
\ No newline at end of file
diff --git a/tests/__types__/discord.js.ts b/tests/__types__/discord.js.ts
index e1f5961..afd1469 100644
--- a/tests/__types__/discord.js.ts
+++ b/tests/__types__/discord.js.ts
@@ -14,6 +14,8 @@ export type ButtonInteraction = {
         id: string,
     } | null,
     customId: string,
+    update: jest.Func,
+    reply: jest.Func,
 }
 
 export type CommandInteraction = {
diff --git a/tests/buttonEvents/Effects/Buy.test.ts b/tests/buttonEvents/Effects/Buy.test.ts
index cdf60f1..10f4daf 100644
--- a/tests/buttonEvents/Effects/Buy.test.ts
+++ b/tests/buttonEvents/Effects/Buy.test.ts
@@ -3,8 +3,10 @@ import Buy from "../../../src/buttonEvents/Effects/Buy";
 import GenerateButtonInteractionMock from "../../__functions__/discord.js/GenerateButtonInteractionMock";
 import { ButtonInteraction as ButtonInteractionType } from "../../__types__/discord.js";
 import AppLogger from "../../../src/client/appLogger";
+import EffectHelper from "../../../src/helpers/EffectHelper";
 
 jest.mock("../../../src/client/appLogger");
+jest.mock("../../../src/helpers/EffectHelper");
 
 let interaction: ButtonInteractionType;
 
@@ -21,7 +23,8 @@ describe("Execute", () => {
         // Arrange
         interaction.customId += " confirm";
 
-        const confirmSpy = jest.spyOn(Buy as any, "Confirm");
+        const confirmSpy = jest.spyOn(Buy as any, "Confirm")
+            .mockImplementation();
 
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
@@ -37,13 +40,14 @@ describe("Execute", () => {
         // Arrange
         interaction.customId += " cancel";
 
-        const cancelSpy = jest.spyOn(Buy as any, "Cancel");
+        const cancelSpy = jest.spyOn(Buy as any, "Cancel")
+            .mockImplementation();
 
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
 
         // Assert
-        expect(cancelSpy).toHaveBeenCalledTimes(1);
+        expect(cancelSpy).toHaveBeenCalledTimes(1)
         expect(cancelSpy).toHaveBeenCalledWith(interaction);
 
         expect(AppLogger.LogError).not.toHaveBeenCalled();
@@ -53,8 +57,10 @@ describe("Execute", () => {
         // Arrange
         interaction.customId += " invalid";
 
-        const confirmSpy = jest.spyOn(Buy as any, "Confirm");
-        const cancelSpy = jest.spyOn(Buy as any, "Cancel");
+        const confirmSpy = jest.spyOn(Buy as any, "Confirm")
+            .mockImplementation();
+        const cancelSpy = jest.spyOn(Buy as any, "Cancel")
+            .mockImplementation();
 
         // Act
         await Buy.Execute(interaction as unknown as ButtonInteraction);
@@ -67,3 +73,52 @@ describe("Execute", () => {
         expect(cancelSpy).not.toHaveBeenCalled();
     });
 });
+
+describe("Confirm", () => {
+    beforeEach(() => {
+        interaction.customId += " confirm";
+    });
+
+    test("EXPECT success embed generated", async () => {
+        // Assert
+        interaction.customId += " id 1";
+
+        const embed = {
+            id: "embed",
+        };
+        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", "id", 1, true);
+
+        expect(interaction.reply).not.toHaveBeenCalled();
+        expect(AppLogger.LogError).not.toHaveBeenCalled();
+    });
+
+    test.todo("GIVEN id is not supplied, EXPECT error");
+
+    test.todo("GIVEN quantity is not supplied, EXPECT error");
+
+    test.todo("GIVEN quantity is not a number, EXPECT error");
+
+    test.todo("GIVEN quantity is 0, EXPECT error");
+
+    test.todo("GIVEN GenerateEffectBuyEmbed returns with a string, EXPECT error replied");
+});