From f41194ba719f4fa392c205ec86ca05e705dbef2b Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 19:11:12 +0200 Subject: [PATCH 01/11] add base jest setup --- jest.config.js | 18 ++++++++++++++++++ package-lock.json | 27 ++++++++++++++++++++------- package.json | 7 +++++-- 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 jest.config.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..4086ac8 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,18 @@ +module.exports = { + 'roots': [ + '/tests', + '/server' + ], + 'transform': { + '^.+\\.tsx?$': 'ts-jest' + }, + 'testRegex': '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$', + 'moduleFileExtensions': [ + 'ts', + 'tsx', + 'js', + 'jsx', + 'json', + 'node' + ], +}; diff --git a/package-lock.json b/package-lock.json index f7c99e8..ef82566 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,12 +30,13 @@ "winston": "^3.8.2" }, "devDependencies": { - "@types/jest": "^29.5.0", + "@types/jest": "^29.5.2", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "eslint": "^8.38.0", "jest": "^29.5.0", "jest-cli": "^29.5.0", + "mockdate": "^3.0.5", "nodemon": "^2.0.22", "rimraf": "^5.0.0", "ts-jest": "^29.1.0" @@ -1568,9 +1569,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "version": "29.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", + "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -4989,6 +4990,12 @@ "node": ">=10" } }, + "node_modules/mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8139,9 +8146,9 @@ } }, "@types/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "version": "29.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", + "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", "dev": true, "requires": { "expect": "^29.0.0", @@ -10720,6 +10727,12 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, + "mockdate": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz", + "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/package.json b/package.json index d4f0a57..715ae52 100644 --- a/package.json +++ b/package.json @@ -33,15 +33,18 @@ "debuggable": "node build/index.js --inspect-brk", "monitor": "nodemon build/index.js", "lint": "eslint . --ext .ts", - "lint-fix": "eslint . --ext .ts --fix" + "lint-fix": "eslint . --ext .ts --fix", + "test": "jest", + "test-watch": "jest --watch" }, "devDependencies": { - "@types/jest": "^29.5.0", + "@types/jest": "^29.5.2", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "eslint": "^8.38.0", "jest": "^29.5.0", "jest-cli": "^29.5.0", + "mockdate": "^3.0.5", "nodemon": "^2.0.22", "rimraf": "^5.0.0", "ts-jest": "^29.1.0" From c39f9c6ee14b6700274ac60bf863afc8db2eb8c9 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 19:56:30 +0200 Subject: [PATCH 02/11] add first passing test --- tests/helpers/memberRoles.test.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/helpers/memberRoles.test.ts diff --git a/tests/helpers/memberRoles.test.ts b/tests/helpers/memberRoles.test.ts new file mode 100644 index 0000000..6ff3a9c --- /dev/null +++ b/tests/helpers/memberRoles.test.ts @@ -0,0 +1,28 @@ +import { Collection, GuildMember, Role } from "discord.js" +import { filterRolesFromMemberUpdate } from "../../server/helper/roleFilter" + +function buildFakeRole(id: string, name: string): Role { + return { id, name } + +} +test('filterRolesFromMemberUpdate', () => { + const oldMemberRoles: Collection = new Collection() + oldMemberRoles.set('1', buildFakeRole('01', 'Role01')) + oldMemberRoles.set('2', buildFakeRole('02', 'Role02')) + + const newMemberRoles: Collection = new Collection() + newMemberRoles.set('1', buildFakeRole('01', 'Role01')) + newMemberRoles.set('2', buildFakeRole('02', 'Role02')) + newMemberRoles.set('3', buildFakeRole('03', 'Role03')) + + const oldMember: GuildMember = { roles: { cache: oldMemberRoles }, guild: { id: "guildid" } } + const newMember: GuildMember = { roles: { cache: newMemberRoles }, guild: { id: "guildid" } } + const output = filterRolesFromMemberUpdate(oldMember, newMember) + + const expectedAddedRoles: Collection = new Collection() + expectedAddedRoles.set('3', buildFakeRole('03', 'Role03')) + const expectedRemovedRoles: Collection = new Collection() + + expect(output.addedRoles).toEqual(expectedAddedRoles) + expect(output.removedRoles).toEqual(expectedRemovedRoles) +}) From a6f19ccd2b1b0708fb294db7feda4526da51f26e Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 19:56:49 +0200 Subject: [PATCH 03/11] add date test (WIP) --- tests/helpers/date.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/helpers/date.test.ts diff --git a/tests/helpers/date.test.ts b/tests/helpers/date.test.ts new file mode 100644 index 0000000..e3f5d3e --- /dev/null +++ b/tests/helpers/date.test.ts @@ -0,0 +1,16 @@ +import { GuildScheduledEvent } from "discord.js" +import { createDateStringFromEvent } from "../../server/helper/dateHelper" +import MockDate from 'mockdate' + +beforeAll(() => { + MockDate.set('01-01-2023') +}) + +function getTestDate(date: string): GuildScheduledEvent { + return { scheduledStartAt: new Date(date) } +} +test('createDateStringFromEvent - correct formatting', () => { + expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 12:30') + expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01. um 12:30') + expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 12:30') +}) From dd72f8e165112d1eedf12206868337b668036247 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:09:00 +0200 Subject: [PATCH 04/11] add automatic jest test in docker build to workflows --- .gitea/workflows/test.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .gitea/workflows/test.yaml diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml new file mode 100644 index 0000000..d284415 --- /dev/null +++ b/.gitea/workflows/test.yaml @@ -0,0 +1,18 @@ +name: Compile the repository +on: [pull_request] +env: + REGISTRY: gitea.brudi.xyz + IMAGE_NAME: ${{ gitea.repository }} + USER: ${{ gitea.actor }} +jobs: + compile: + runs-on: ubuntu-latest + container: catthehacker/ubuntu:act-latest + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Run Tests + run: docker build --target test . + From 6b0e84669a70a30e9e6c4271dbda065ca1c0744e Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:09:09 +0200 Subject: [PATCH 05/11] update dockerfile to support test stage --- Dockerfile | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e765732..8b0b04b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,22 @@ -FROM node:alpine as Build -ENV NODE_ENV=production +FROM node:alpine as files WORKDIR /app COPY [ "package-lock.json", "package.json", "index.ts", "tsconfig.json", "./" ] COPY server ./server +FROM files as proddependencies +ENV NODE_ENV=production RUN npm ci --omit=dev +FROM proddependencies as compile RUN npm run build CMD ["npm","run","start"] + +FROM files as dependencies +RUN npm ci + +FROM dependencies as test +COPY jest.config.js . +COPY tests ./tests + +RUN npm run test From 65cdee36e9cb6abb880210bd7a83886532107697 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:09:52 +0200 Subject: [PATCH 06/11] update testcase --- tests/helpers/date.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/helpers/date.test.ts b/tests/helpers/date.test.ts index e3f5d3e..176ff88 100644 --- a/tests/helpers/date.test.ts +++ b/tests/helpers/date.test.ts @@ -10,7 +10,7 @@ function getTestDate(date: string): GuildScheduledEvent { return { scheduledStartAt: new Date(date) } } test('createDateStringFromEvent - correct formatting', () => { - expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 12:30') - expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01. um 12:30') - expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 12:30') + expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 13:30') + expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01 um 13:30') + expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 13:30') }) From c133570d8c49d173b495e174679d0226403804e4 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:11:39 +0200 Subject: [PATCH 07/11] update other workflows to use staged builds --- .gitea/workflows/compile.yaml | 2 +- .gitea/workflows/docker-build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/compile.yaml b/.gitea/workflows/compile.yaml index 2fa0821..457a567 100644 --- a/.gitea/workflows/compile.yaml +++ b/.gitea/workflows/compile.yaml @@ -14,4 +14,4 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - name: Build Container - run: docker build . + run: docker build --target compile . diff --git a/.gitea/workflows/docker-build.yaml b/.gitea/workflows/docker-build.yaml index 5700667..b474638 100644 --- a/.gitea/workflows/docker-build.yaml +++ b/.gitea/workflows/docker-build.yaml @@ -22,6 +22,6 @@ jobs: - name: Log in to the Container registry run: docker login -u ${{ env.USER }} -p ${{ secrets.TOKEN }} ${{ env.REGISTRY }} - name: Build Container - run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" . + run: docker build --target compile -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" . - name: Push Container run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" From c32434a7eb00927bc30cfa7a12f394d99c8f7338 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:16:03 +0200 Subject: [PATCH 08/11] rename test job --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index d284415..d738e00 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,7 +5,7 @@ env: IMAGE_NAME: ${{ gitea.repository }} USER: ${{ gitea.actor }} jobs: - compile: + test: runs-on: ubuntu-latest container: catthehacker/ubuntu:act-latest permissions: From af414d0bad1f89e871b6b35f81f27cd6a026307b Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:17:04 +0200 Subject: [PATCH 09/11] rename human facing name for test job --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index d738e00..0fadd23 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,4 +1,4 @@ -name: Compile the repository +name: Run unit tests on: [pull_request] env: REGISTRY: gitea.brudi.xyz From 37b798818c28d6f2193b3c58ab23d9a67b669e68 Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:31:37 +0200 Subject: [PATCH 10/11] handle timezone correctly in docker build --- Dockerfile | 3 +-- tests/helpers/date.test.ts | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8b0b04b..086648b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:alpine as files +ENV TZ="Europe/Berlin" WORKDIR /app - COPY [ "package-lock.json", "package.json", "index.ts", "tsconfig.json", "./" ] COPY server ./server @@ -18,5 +18,4 @@ RUN npm ci FROM dependencies as test COPY jest.config.js . COPY tests ./tests - RUN npm run test diff --git a/tests/helpers/date.test.ts b/tests/helpers/date.test.ts index 176ff88..52f7ff9 100644 --- a/tests/helpers/date.test.ts +++ b/tests/helpers/date.test.ts @@ -10,7 +10,7 @@ function getTestDate(date: string): GuildScheduledEvent { return { scheduledStartAt: new Date(date) } } test('createDateStringFromEvent - correct formatting', () => { - expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 13:30') - expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01 um 13:30') - expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 13:30') + expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 12:30') + expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01 um 12:30') + expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 12:30') }) From 25bb676fda1af1cfe9040671b36b9a5d99f77aac Mon Sep 17 00:00:00 2001 From: mightypanders Date: Sat, 24 Jun 2023 20:37:59 +0200 Subject: [PATCH 11/11] readd compile --- .gitea/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/docker-build.yaml b/.gitea/workflows/docker-build.yaml index c2abff3..09c917d 100644 --- a/.gitea/workflows/docker-build.yaml +++ b/.gitea/workflows/docker-build.yaml @@ -21,7 +21,7 @@ jobs: - name: Log in to the Container registry run: docker login -u ${{ env.USER }} -p ${{ secrets.TOKEN }} ${{ env.REGISTRY }} - name: Build Container - run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}" . + run: docker build --target compile -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}" . env: version: $(cat package.json | awk 'match($0, /version/) {print $2}' | sed 's/[\",]//g') # extracts the version number from the package.json with bash magic - name: Push Container