From 665fc293b5b43e57481f0e92bbc054c341a7148e Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Tue, 10 Dec 2024 10:07:23 +0000
Subject: [PATCH 1/5] Use rsync

---
 .forgejo/workflows/production.yml | 2 +-
 .forgejo/workflows/stage.yml      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml
index fa080ee..922968c 100644
--- a/.forgejo/workflows/production.yml
+++ b/.forgejo/workflows/production.yml
@@ -22,7 +22,7 @@ jobs:
     - run: yarn test
 
     - name: "Copy files over to location"
-      run: cp -r . ${{ secrets.PROD_REPO_PATH }}
+      run: rsync -r . ${{ secrets.PROD_REPO_PATH }}
 
   deploy:
     environment: prod
diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml
index e8157b8..34af3a2 100644
--- a/.forgejo/workflows/stage.yml
+++ b/.forgejo/workflows/stage.yml
@@ -22,7 +22,7 @@ jobs:
     - run: yarn test
 
     - name: "Copy files over to location"
-      run: cp -r . ${{ secrets.STAGE_REPO_PATH }}
+      run: rsync -r . ${{ secrets.STAGE_REPO_PATH }}
 
   deploy:
     environment: prod

From 0cc43567931e7a947c3a6afb1c47707b1060ed06 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Tue, 10 Dec 2024 10:10:13 +0000
Subject: [PATCH 2/5] Use rsync -rvzP

---
 .forgejo/workflows/production.yml | 2 +-
 .forgejo/workflows/stage.yml      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml
index 922968c..584bd56 100644
--- a/.forgejo/workflows/production.yml
+++ b/.forgejo/workflows/production.yml
@@ -22,7 +22,7 @@ jobs:
     - run: yarn test
 
     - name: "Copy files over to location"
-      run: rsync -r . ${{ secrets.PROD_REPO_PATH }}
+      run: rsync -rvzP . ${{ secrets.PROD_REPO_PATH }}
 
   deploy:
     environment: prod
diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml
index 34af3a2..fbf46d6 100644
--- a/.forgejo/workflows/stage.yml
+++ b/.forgejo/workflows/stage.yml
@@ -22,7 +22,7 @@ jobs:
     - run: yarn test
 
     - name: "Copy files over to location"
-      run: rsync -r . ${{ secrets.STAGE_REPO_PATH }}
+      run: rsync -rvzP . ${{ secrets.STAGE_REPO_PATH }}
 
   deploy:
     environment: prod

From 725f3ee869499b6ed667531f1d70be35de75d1b5 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Tue, 10 Dec 2024 10:19:40 +0000
Subject: [PATCH 3/5] Use password secret

---
 .forgejo/workflows/production.yml | 2 +-
 .forgejo/workflows/stage.yml      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml
index 584bd56..6ccad47 100644
--- a/.forgejo/workflows/production.yml
+++ b/.forgejo/workflows/production.yml
@@ -52,7 +52,7 @@ jobs:
       with:
         host: ${{ secrets.PROD_SSH_HOST }}
         username: ${{ secrets.PROD_SSH_USER }}
-        key: ${{ secrets.PROD_SSH_KEY }}
+        password: ${{ secrets.PROD_SSH_PASS }}
         port: ${{ secrets.PROD_SSH_PORT }}
         envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
         script: |
diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml
index fbf46d6..e14da4e 100644
--- a/.forgejo/workflows/stage.yml
+++ b/.forgejo/workflows/stage.yml
@@ -52,7 +52,7 @@ jobs:
       with:
         host: ${{ secrets.STAGE_SSH_HOST }}
         username: ${{ secrets.STAGE_SSH_USER }}
-        key: ${{ secrets.STAGE_SSH_KEY }}
+        password: ${{ secrets.STAGE_SSH_PASS }}
         port: ${{ secrets.STAGE_SSH_PORT }}
         envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
         script: |

From e081ff78028beb53bea297926a686e04dd132193 Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Tue, 10 Dec 2024 10:21:03 +0000
Subject: [PATCH 4/5] Revert "Use password secret"

This reverts commit 725f3ee869499b6ed667531f1d70be35de75d1b5.
---
 .forgejo/workflows/production.yml | 2 +-
 .forgejo/workflows/stage.yml      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.forgejo/workflows/production.yml b/.forgejo/workflows/production.yml
index 6ccad47..584bd56 100644
--- a/.forgejo/workflows/production.yml
+++ b/.forgejo/workflows/production.yml
@@ -52,7 +52,7 @@ jobs:
       with:
         host: ${{ secrets.PROD_SSH_HOST }}
         username: ${{ secrets.PROD_SSH_USER }}
-        password: ${{ secrets.PROD_SSH_PASS }}
+        key: ${{ secrets.PROD_SSH_KEY }}
         port: ${{ secrets.PROD_SSH_PORT }}
         envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
         script: |
diff --git a/.forgejo/workflows/stage.yml b/.forgejo/workflows/stage.yml
index e14da4e..fbf46d6 100644
--- a/.forgejo/workflows/stage.yml
+++ b/.forgejo/workflows/stage.yml
@@ -52,7 +52,7 @@ jobs:
       with:
         host: ${{ secrets.STAGE_SSH_HOST }}
         username: ${{ secrets.STAGE_SSH_USER }}
-        password: ${{ secrets.STAGE_SSH_PASS }}
+        key: ${{ secrets.STAGE_SSH_KEY }}
         port: ${{ secrets.STAGE_SSH_PORT }}
         envs: DB_NAME,DB_AUTH_USER,DB_AUTH_PASS,DB_HOST,DB_PORT,DB_ROOT_HOST,DB_SYNC,DB_LOGGING,DB_DATA_LOCATION,BOT_TOKEN,BOT_VER,BOT_AUTHOR,BOT_OWNERID,BOT_CLIENTID,ABOUT_FUNDING,ABOUT_REPO,CACHE_INTERVAL
         script: |

From e557540d703783bb1626d5d844e1b75285381fad Mon Sep 17 00:00:00 2001
From: Ethan Lane <ethan@vylpes.com>
Date: Wed, 11 Dec 2024 18:41:59 +0000
Subject: [PATCH 5/5] Create add moon command tests

---
 3                                             | 225 ------------------
 .../304276391837302787/moons/add.test.ts      | 106 ++++++++-
 2 files changed, 102 insertions(+), 229 deletions(-)
 delete mode 100644 3

diff --git a/3 b/3
deleted file mode 100644
index fe6eb2a..0000000
--- a/3
+++ /dev/null
@@ -1,225 +0,0 @@
-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");
-    });
-});
\ No newline at end of file
diff --git a/tests/commands/304276391837302787/moons/add.test.ts b/tests/commands/304276391837302787/moons/add.test.ts
index cf31842..a66eab3 100644
--- a/tests/commands/304276391837302787/moons/add.test.ts
+++ b/tests/commands/304276391837302787/moons/add.test.ts
@@ -80,17 +80,115 @@ describe("GIVEN happy flow", () => {
 });
 
 describe("GIVEN description is null", () => {
-    test.todo("EXPECT error replied");
+    const interaction = {
+        reply: jest.fn(),
+        options: {
+            get: jest.fn().mockReturnValue({
+                value: null,
+            }),
+        },
+    } as unknown as CommandInteraction;
+
+    beforeEach(async () => {
+        await AddMoon(interaction);
+    });
+
+    test("EXPECT error replied", () => {
+        expect(interaction.reply).toHaveBeenCalledTimes(1);
+        expect(interaction.reply).toHaveBeenCalledWith("Name must be less than 255 characters!");
+    });
 });
 
 describe("GIVEN description is greater than 255 characters", () => {
-    test.todo("EXPECT error replied");
+    const optionGet = jest.fn();
+
+    const interaction = {
+        reply: jest.fn(),
+        options: {
+            get: optionGet,
+        },
+    } as unknown as CommandInteraction;
+
+    beforeEach(async () => {
+        let longString = "";
+
+        for (let i = 0; i < 30; i++) {
+            longString += "1234567890";
+        }
+
+        optionGet.mockReturnValue({
+            value: longString,
+        });
+
+        await AddMoon(interaction);
+    });
+
+    test("EXPECT error replied", () => {
+        expect(interaction.reply).toHaveBeenCalledTimes(1);
+        expect(interaction.reply).toHaveBeenCalledWith("Name must be less than 255 characters!");
+    });
 });
 
 describe("GIVEN moon count setting exists", () => {
-    test.todo("EXPECT existing entity to be updated");
+    const moonSetting = {
+        Value: "1",
+        UpdateValue: jest.fn(),
+        Save: jest.fn(),
+    };
+
+    const interaction = {
+        reply: jest.fn(),
+        options: {
+            get: jest.fn().mockReturnValue({
+                value: "Test Description",
+            }),
+        },
+        user: {
+            id: "userId",
+        },
+    } as unknown as CommandInteraction;
+
+    beforeEach(async () => {
+        UserSetting.FetchOneByKey = jest.fn().mockResolvedValue(moonSetting);
+        
+        await AddMoon(interaction);
+    });
+
+    test("EXPECT existing entity to be updated", () => {
+        expect(moonSetting.UpdateValue).toHaveBeenCalledTimes(1);
+        expect(moonSetting.UpdateValue).toHaveBeenCalledWith("2");
+    });
 });
 
 describe("GIVEN moon count setting does not exist", () => {
-    test.todo("EXPECT new entity to be created");
+    let savedSetting: UserSetting | undefined;
+
+    const interaction = {
+        reply: jest.fn(),
+        options: {
+            get: jest.fn().mockReturnValue({
+                value: "Test Description",
+            }),
+        },
+        user: {
+            id: "userId",
+        },
+    } as unknown as CommandInteraction;
+
+    beforeEach(async () => {
+        UserSetting.FetchOneByKey = jest.fn().mockResolvedValue(null);
+        UserSetting.prototype.Save = jest.fn().mockImplementation((_, setting: UserSetting) => {
+            savedSetting = setting;
+        });
+        
+        await AddMoon(interaction);
+    });
+
+    test("EXPECT new entity to be created", () => {
+        // Expect the entity to have the new entity.
+        // Probably the best way we can really imply a new entity
+        // that I can think of
+        expect(savedSetting).toBeDefined();
+        expect(savedSetting?.Value).toBe("1");
+    });
 });
\ No newline at end of file