From ae45ba7ca8a7edb60a347ee16827169615795115 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 17:31:39 +0200 Subject: [PATCH 01/26] actions: frontend test coverage wordt gereport door de workflow --- .github/workflows/frontend-testing.yml | 17 ++++++++++++++++- frontend/package.json | 1 + frontend/vitest.config.ts | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.github/workflows/frontend-testing.yml b/.github/workflows/frontend-testing.yml index ff7bde4d..23950914 100644 --- a/.github/workflows/frontend-testing.yml +++ b/.github/workflows/frontend-testing.yml @@ -38,6 +38,12 @@ jobs: if: '! github.event.pull_request.draft' runs-on: [self-hosted, Linux, X64] + permissions: + # Required to checkout the code + contents: read + # Required to put a comment into the pull-request + pull-requests: write + strategy: matrix: node-version: [22.x] @@ -51,4 +57,13 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - - run: npm run test:unit -w frontend + - run: npm run test:coverage -w frontend + - name: 'Report Frontend Coverage' + # Set if: always() to also generate the report if tests are failing + # Only works if you set `reportOnFailure: true` in your vite config as specified above + if: always() + uses: davelosert/vitest-coverage-report-action@v2 + with: + name: 'Frontend' + json-summary-path: './frontend/coverage/coverage-summary.json' + json-final-path: './frontend/coverage/coverage-final.json' diff --git a/frontend/package.json b/frontend/package.json index e6ce1426..105331f0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,6 +13,7 @@ "format-check": "prettier --check src/", "lint": "eslint . --fix", "test:unit": "vitest --run", + "test:coverage": "vitest --run --coverage.enabled true", "test:e2e": "playwright test" }, "dependencies": { diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index ba2d72b6..9f561462 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -9,6 +9,12 @@ export default mergeConfig( environment: "jsdom", exclude: [...configDefaults.exclude, "e2e/**"], root: fileURLToPath(new URL("./", import.meta.url)), + coverage: { + reporter: ['text', 'json-summary', 'json'], + // If you want a coverage reports even if your tests are failing, include the reportOnFailure option + reportOnFailure: true, + exclude: ['**/*config*'], + }, }, }), ); From 77d7eeba9f48d4b76582a7597fd95ee189012ce3 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 4 Apr 2025 17:48:12 +0200 Subject: [PATCH 02/26] style: fix linting issues met Prettier --- frontend/vitest.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 9f561462..2b4cbf51 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -10,11 +10,11 @@ export default mergeConfig( exclude: [...configDefaults.exclude, "e2e/**"], root: fileURLToPath(new URL("./", import.meta.url)), coverage: { - reporter: ['text', 'json-summary', 'json'], + reporter: ["text", "json-summary", "json"], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ['**/*config*'], - }, + exclude: ["**/*config*"], + }, }, }), ); From 9c02857718f38df02926209659bbcb509ad88a0f Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:03:37 +0200 Subject: [PATCH 03/26] actions: path naar vitest config toegevoegd voor coverage --- .github/workflows/frontend-testing.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/frontend-testing.yml b/.github/workflows/frontend-testing.yml index 23950914..025c66c3 100644 --- a/.github/workflows/frontend-testing.yml +++ b/.github/workflows/frontend-testing.yml @@ -67,3 +67,4 @@ jobs: name: 'Frontend' json-summary-path: './frontend/coverage/coverage-summary.json' json-final-path: './frontend/coverage/coverage-final.json' + vite-config-path: './frontend/vitest.config.ts' From 2a0d7e4626a941391380e268571021fc6cb9d0d0 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:04:14 +0200 Subject: [PATCH 04/26] actions: threshold voor coverage op 60% gezet --- frontend/vitest.config.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 9f561462..0611c658 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -14,6 +14,12 @@ export default mergeConfig( // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, exclude: ['**/*config*'], + thresholds: { + lines: 60, + branches: 60, + functions: 60, + statements: 60 + }, }, }, }), From 8766bd40c74aa5d737f5da1bc456dafdb1423947 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:08:34 +0200 Subject: [PATCH 05/26] actions: backend vitest geconfigureerd voor coverage --- backend/vitest.config.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index 29142c49..ac0e257e 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -5,5 +5,17 @@ export default defineConfig({ environment: 'node', globals: true, testTimeout: 100000, + coverage: { + reporter: ['text', 'json-summary', 'json'], + // If you want a coverage reports even if your tests are failing, include the reportOnFailure option + reportOnFailure: true, + exclude: ['**/*config*'], + thresholds: { + lines: 60, + branches: 60, + functions: 60, + statements: 60 + }, + }, }, }); From be2ef0c79d90a953a40e3b8ff69d26d9ed35099b Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:09:08 +0200 Subject: [PATCH 06/26] actions: nieuw npm script voor coverage toegevoegd --- backend/package.json | 3 ++- package.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/package.json b/backend/package.json index 83db321f..a49b4a1b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,7 +13,8 @@ "format-check": "prettier --check src/", "lint": "eslint . --fix", "pretest:unit": "npm run build", - "test:unit": "vitest --run" + "test:unit": "vitest --run", + "test:coverage": "vitest --run --coverage.enabled true" }, "dependencies": { "@mikro-orm/core": "6.4.9", diff --git a/package.json b/package.json index 64cfd665..abd18fcf 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "format-check": "npm run format-check --workspace=backend --workspace=common --workspace=frontend", "lint": "npm run lint --workspace=backend --workspace=common --workspace=frontend", "pretest:unit": "npm run build", - "test:unit": "npm run test:unit --workspace=backend --workspace=frontend" + "test:unit": "npm run test:unit --workspace=backend --workspace=frontend", + "test:coverage": "npm run test:coverage --workspace=backend --workspace=frontend" }, "workspaces": [ "backend", From e9215c50be5018965c64ab83fee8fe18227402c9 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:09:24 +0200 Subject: [PATCH 07/26] actions: backend testing workflow geeft nu ook een coverage report --- .github/workflows/backend-testing.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/backend-testing.yml b/.github/workflows/backend-testing.yml index 0d0b1f3f..242c6bf1 100644 --- a/.github/workflows/backend-testing.yml +++ b/.github/workflows/backend-testing.yml @@ -42,4 +42,14 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - - run: npm run test:unit -w backend + - run: npm run test:coverage -w backend + - name: 'Report Backend Coverage' + # Set if: always() to also generate the report if tests are failing + # Only works if you set `reportOnFailure: true` in your vite config as specified above + if: always() + uses: davelosert/vitest-coverage-report-action@v2 + with: + name: 'Backend' + json-summary-path: './backend/coverage/coverage-summary.json' + json-final-path: './backend/coverage/coverage-final.json' + vite-config-path: './backend/vitest.config.ts' From c016884dda43d5e2e3d9d7bf66c3720922eb3535 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 18:16:28 +0200 Subject: [PATCH 08/26] actions: backend testing workflow permissions aangepast --- .github/workflows/backend-testing.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/backend-testing.yml b/.github/workflows/backend-testing.yml index 242c6bf1..2a9bbec5 100644 --- a/.github/workflows/backend-testing.yml +++ b/.github/workflows/backend-testing.yml @@ -29,6 +29,12 @@ jobs: if: '! github.event.pull_request.draft' runs-on: [self-hosted, Linux, X64] + permissions: + # Required to checkout the code + contents: read + # Required to put a comment into the pull-request + pull-requests: write + strategy: matrix: node-version: [22.x] From 11b10eee01ed0ad74db1768420d4e9b44790fda3 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 4 Apr 2025 18:25:16 +0200 Subject: [PATCH 09/26] style: fix linting issues met Prettier --- backend/package.json | 2 +- backend/vitest.config.ts | 6 +++--- frontend/vitest.config.ts | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/package.json b/backend/package.json index a49b4a1b..a3060881 100644 --- a/backend/package.json +++ b/backend/package.json @@ -14,7 +14,7 @@ "lint": "eslint . --fix", "pretest:unit": "npm run build", "test:unit": "vitest --run", - "test:coverage": "vitest --run --coverage.enabled true" + "test:coverage": "vitest --run --coverage.enabled true" }, "dependencies": { "@mikro-orm/core": "6.4.9", diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index ac0e257e..e5663cf2 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -14,8 +14,8 @@ export default defineConfig({ lines: 60, branches: 60, functions: 60, - statements: 60 - }, - }, + statements: 60, + }, + }, }, }); diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 66de040e..be1b1762 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -18,9 +18,9 @@ export default mergeConfig( lines: 60, branches: 60, functions: 60, - statements: 60 - }, - }, + statements: 60, + }, + }, }, }), ); From cd7eb486eb64a930c155bb94c99b6bae521c89a0 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Fri, 4 Apr 2025 19:31:52 +0200 Subject: [PATCH 10/26] actions: coverage wordt berekend op alle bestanden die getest worden door vitest --- .github/workflows/backend-testing.yml | 1 + .github/workflows/frontend-testing.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/backend-testing.yml b/.github/workflows/backend-testing.yml index 2a9bbec5..a372da74 100644 --- a/.github/workflows/backend-testing.yml +++ b/.github/workflows/backend-testing.yml @@ -59,3 +59,4 @@ jobs: json-summary-path: './backend/coverage/coverage-summary.json' json-final-path: './backend/coverage/coverage-final.json' vite-config-path: './backend/vitest.config.ts' + file-coverage-mode: all diff --git a/.github/workflows/frontend-testing.yml b/.github/workflows/frontend-testing.yml index 025c66c3..b40f6915 100644 --- a/.github/workflows/frontend-testing.yml +++ b/.github/workflows/frontend-testing.yml @@ -68,3 +68,4 @@ jobs: json-summary-path: './frontend/coverage/coverage-summary.json' json-final-path: './frontend/coverage/coverage-final.json' vite-config-path: './frontend/vitest.config.ts' + file-coverage-mode: all From e3ba522a6c3db3bf282d62915671340675fafa33 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sat, 5 Apr 2025 10:53:25 +0200 Subject: [PATCH 11/26] test: coverage action test --- backend/src/test.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 backend/src/test.ts diff --git a/backend/src/test.ts b/backend/src/test.ts new file mode 100644 index 00000000..e69de29b From 3ca063a72135f84301f4630774b752261e02015b Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Sat, 5 Apr 2025 11:13:06 +0200 Subject: [PATCH 12/26] actions: backend coverage exclude aangepast test bestanden moeten niet gecovered worden Bestanden rechtstreeks onder de src folder moeten ook niet gecovered worden (deze binden heel het project samen maar hebben geen aparte functionaliteit om te testen) --- backend/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index ac0e257e..9b0971b6 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ reporter: ['text', 'json-summary', 'json'], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ['**/*config*'], + exclude: ['**/*config*', '**/tests/**', 'src/*.ts'], thresholds: { lines: 60, branches: 60, From 11f5592e2f6b533a96424f900a4e4005c30db0a0 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 8 Apr 2025 18:49:09 +0200 Subject: [PATCH 13/26] test: meer exclude paths toegevoegd --- backend/vitest.config.ts | 2 +- frontend/vitest.config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index 9b0971b6..41b3a483 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ reporter: ['text', 'json-summary', 'json'], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ['**/*config*', '**/tests/**', 'src/*.ts'], + exclude: ['**/*config*', '**/tests/**', 'src/*.ts', '**/dist/**', '**/node_modules/**'], thresholds: { lines: 60, branches: 60, diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 66de040e..24dcedc5 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -13,7 +13,7 @@ export default mergeConfig( reporter: ["text", "json-summary", "json"], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ["**/*config*"], + exclude: ["**/*config*", "**/tests/**", 'src/*.ts', '**/dist/**', '**/e2e/**', '**/*config*', '**/node_modules/**'], thresholds: { lines: 60, branches: 60, From 8f1184cb7153ae8b61bea32a1b2e82036c418024 Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 8 Apr 2025 18:50:12 +0200 Subject: [PATCH 14/26] actions: build project vooraleer te testen --- .github/workflows/backend-testing.yml | 1 + .github/workflows/frontend-testing.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/backend-testing.yml b/.github/workflows/backend-testing.yml index a372da74..ce7600e0 100644 --- a/.github/workflows/backend-testing.yml +++ b/.github/workflows/backend-testing.yml @@ -48,6 +48,7 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci + - run: npm run build - run: npm run test:coverage -w backend - name: 'Report Backend Coverage' # Set if: always() to also generate the report if tests are failing diff --git a/.github/workflows/frontend-testing.yml b/.github/workflows/frontend-testing.yml index b40f6915..053e66c3 100644 --- a/.github/workflows/frontend-testing.yml +++ b/.github/workflows/frontend-testing.yml @@ -57,6 +57,7 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci + - run: npm run build - run: npm run test:coverage -w frontend - name: 'Report Frontend Coverage' # Set if: always() to also generate the report if tests are failing From 14c52046fcee8a63abc15de43f95b673e7c42c7f Mon Sep 17 00:00:00 2001 From: Timo De Meyst Date: Tue, 8 Apr 2025 18:58:56 +0200 Subject: [PATCH 15/26] test: frontend exclude uitgebreidt --- frontend/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 72d3f8da..58c8ba0f 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -13,7 +13,7 @@ export default mergeConfig( reporter: ["text", "json-summary", "json"], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ["**/*config*", "**/tests/**", 'src/*.ts', '**/dist/**', '**/e2e/**', '**/*config*', '**/node_modules/**'], + exclude: ["**/*config*", "**/tests/**", 'src/*.ts', 'src/*.vue', '**/dist/**', '**/e2e/**', '**/*config*', '**/node_modules/**'], thresholds: { lines: 60, branches: 60, From d754ed44a03849da4d82470edc8a795132ff26b9 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Tue, 8 Apr 2025 17:04:16 +0000 Subject: [PATCH 16/26] style: fix linting issues met Prettier --- frontend/vitest.config.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 58c8ba0f..f5224465 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -13,7 +13,16 @@ export default mergeConfig( reporter: ["text", "json-summary", "json"], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ["**/*config*", "**/tests/**", 'src/*.ts', 'src/*.vue', '**/dist/**', '**/e2e/**', '**/*config*', '**/node_modules/**'], + exclude: [ + "**/*config*", + "**/tests/**", + "src/*.ts", + "src/*.vue", + "**/dist/**", + "**/e2e/**", + "**/*config*", + "**/node_modules/**", + ], thresholds: { lines: 60, branches: 60, From c0d37c154fe9b0b5963ced481d14d3d1d1bd4049 Mon Sep 17 00:00:00 2001 From: Timo De Meyst <58138112+kloep1@users.noreply.github.com> Date: Mon, 14 Apr 2025 10:36:52 +0200 Subject: [PATCH 17/26] actions: extra test exclusions --- backend/vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index ee810173..ec507c9b 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ reporter: ['text', 'json-summary', 'json'], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, - exclude: ['**/*config*', '**/tests/**', 'src/*.ts', '**/dist/**', '**/node_modules/**'], + exclude: ['**/*config*', '**/tests/**', 'src/*.ts', '**/dist/**', '**/node_modules/**', 'src/logging/**', 'src/routes/**'], thresholds: { lines: 60, branches: 60, From 9f2616856059428cfd41e9d5a705b2b1d8bc8a18 Mon Sep 17 00:00:00 2001 From: Timo De Meyst <58138112+kloep1@users.noreply.github.com> Date: Mon, 14 Apr 2025 10:42:27 +0200 Subject: [PATCH 18/26] actions: verwijder lege file --- backend/src/test.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 backend/src/test.ts diff --git a/backend/src/test.ts b/backend/src/test.ts deleted file mode 100644 index e69de29b..00000000 From b85d651a6511c55fe1a9be6979e7a9554e8246e1 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 14:55:25 +0200 Subject: [PATCH 19/26] chore(backend): Verlaag coverage threshold --- backend/vitest.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts index ec507c9b..cd281251 100644 --- a/backend/vitest.config.ts +++ b/backend/vitest.config.ts @@ -11,10 +11,10 @@ export default defineConfig({ reportOnFailure: true, exclude: ['**/*config*', '**/tests/**', 'src/*.ts', '**/dist/**', '**/node_modules/**', 'src/logging/**', 'src/routes/**'], thresholds: { - lines: 60, - branches: 60, - functions: 60, - statements: 60, + lines: 50, + branches: 50, + functions: 50, + statements: 50, }, }, }, From 1e4afa684690d568c7d715ad55e7fd39a784a4a5 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 14:59:02 +0200 Subject: [PATCH 20/26] test(frontend): Tweak excludes --- frontend/vitest.config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 851b7b00..e1ad10af 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -16,8 +16,9 @@ export default mergeConfig( exclude: [ "**/*config*", "**/tests/**", - "src/*.ts", - "src/*.vue", + "src/**/*.vue", + "src/**/*.d.ts", + "src/assets/**", "**/dist/**", "**/e2e/**", "**/*config*", From c47da0c826361dc1286dc7048d27649f16e09ba3 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 15:10:47 +0200 Subject: [PATCH 21/26] test(frontend): Verlaag coverage threshold --- frontend/vitest.config.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index e1ad10af..17c96938 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -19,16 +19,17 @@ export default mergeConfig( "src/**/*.vue", "src/**/*.d.ts", "src/assets/**", + "src/data-objects/**", "**/dist/**", "**/e2e/**", "**/*config*", "**/node_modules/**", ], thresholds: { - lines: 60, - branches: 60, - functions: 60, - statements: 60, + lines: 50, + branches: 50, + functions: 50, + statements: 50, }, }, From 4a6b6ee0612ee904010b1a87014353887df9171a Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 16:54:52 +0200 Subject: [PATCH 22/26] test(frontend): Coverage verbeteren --- .../assignments-controller.test.ts | 65 +++++++++++++++ .../controllers/classes-controller.test.ts | 10 +++ .../controllers/groups.controller.test.ts | 13 +++ .../learning-paths-controller.test.ts | 21 +++++ .../controllers/student-controller.test.ts | 35 +++++--- .../submissions-controller.test.ts | 15 ++++ .../controllers/teacher-controller.test.ts | 71 ++++++++++++++++ frontend/tests/utils/assingment-rules.test.ts | 82 +++++++++++++++++++ frontend/tests/utils/deep-equals.test.ts | 68 +++++++++++++++ frontend/vitest.config.ts | 23 +++++- 10 files changed, 387 insertions(+), 16 deletions(-) create mode 100644 frontend/tests/controllers/assignments-controller.test.ts create mode 100644 frontend/tests/controllers/classes-controller.test.ts create mode 100644 frontend/tests/controllers/groups.controller.test.ts create mode 100644 frontend/tests/controllers/learning-paths-controller.test.ts create mode 100644 frontend/tests/controllers/submissions-controller.test.ts create mode 100644 frontend/tests/controllers/teacher-controller.test.ts create mode 100644 frontend/tests/utils/assingment-rules.test.ts create mode 100644 frontend/tests/utils/deep-equals.test.ts diff --git a/frontend/tests/controllers/assignments-controller.test.ts b/frontend/tests/controllers/assignments-controller.test.ts new file mode 100644 index 00000000..4e765462 --- /dev/null +++ b/frontend/tests/controllers/assignments-controller.test.ts @@ -0,0 +1,65 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { AssignmentController } from '../../src/controllers/assignments'; +import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; + +describe('AssignmentController Tests', () => { + let controller: AssignmentController; + + beforeEach(() => { + controller = new AssignmentController('8764b861-90a6-42e5-9732-c0d9eb2f55f9'); // Example class ID + }); + + it('should fetch all assignments', async () => { + const result = await controller.getAll(true); + expect(result).toHaveProperty('assignments'); + expect(Array.isArray(result.assignments)).toBe(true); + expect(result.assignments.length).toBeGreaterThan(0); + }); + + it('should fetch an assignment by number', async () => { + const assignmentNumber = 21000; // Example assignment ID + const result = await controller.getByNumber(assignmentNumber); + expect(result).toHaveProperty('assignment'); + expect(result.assignment).toHaveProperty('id', assignmentNumber); + }); + + it('should update an existing assignment', async () => { + const assignmentNumber = 21000; + const updatedData = { title: 'Updated Assignment Title' }; + const result = await controller.updateAssignment(assignmentNumber, updatedData); + expect(result).toHaveProperty('assignment'); + expect(result.assignment).toHaveProperty('id', assignmentNumber); + expect(result.assignment).toHaveProperty('title', updatedData.title); + }); + + it('should fetch submissions for an assignment', async () => { + const assignmentNumber = 21000; + const result = await controller.getSubmissions(assignmentNumber, true); + expect(result).toHaveProperty('submissions'); + expect(Array.isArray(result.submissions)).toBe(true); + }); + + it('should fetch questions for an assignment', async () => { + const assignmentNumber = 21000; + const result = await controller.getQuestions(assignmentNumber, true); + expect(result).toHaveProperty('questions'); + expect(Array.isArray(result.questions)).toBe(true); + }); + + it('should fetch groups for an assignment', async () => { + const assignmentNumber = 21000; + const result = await controller.getGroups(assignmentNumber, true); + expect(result).toHaveProperty('groups'); + expect(Array.isArray(result.groups)).toBe(true); + }); + + it('should handle fetching a non-existent assignment', async () => { + const assignmentNumber = 99999; // Non-existent assignment ID + await expect(controller.getByNumber(assignmentNumber)).rejects.toThrow(); + }); + + it('should handle deleting a non-existent assignment', async () => { + const assignmentNumber = 99999; // Non-existent assignment ID + await expect(controller.deleteAssignment(assignmentNumber)).rejects.toThrow(); + }); +}); diff --git a/frontend/tests/controllers/classes-controller.test.ts b/frontend/tests/controllers/classes-controller.test.ts new file mode 100644 index 00000000..e8c07b12 --- /dev/null +++ b/frontend/tests/controllers/classes-controller.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from 'vitest'; +import { ClassController } from '../../src/controllers/classes'; + +describe('Test controller classes', () => { + it('Get classes', async () => { + const controller = new ClassController(); + const data = await controller.getAll(true); + expect(data.classes).to.have.length.greaterThan(0); + }); +}); diff --git a/frontend/tests/controllers/groups.controller.test.ts b/frontend/tests/controllers/groups.controller.test.ts new file mode 100644 index 00000000..30d90c09 --- /dev/null +++ b/frontend/tests/controllers/groups.controller.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from 'vitest'; +import { GroupController } from '../../src/controllers/groups'; + +describe('Test controller groups', () => { + it('Get groups', async () => { + const classId = '8764b861-90a6-42e5-9732-c0d9eb2f55f9'; + const assignmentNumber = 21000; + + const controller = new GroupController(classId, assignmentNumber); + const data = await controller.getAll(true); + expect(data.groups).to.have.length.greaterThan(0); + }); +}); diff --git a/frontend/tests/controllers/learning-paths-controller.test.ts b/frontend/tests/controllers/learning-paths-controller.test.ts new file mode 100644 index 00000000..d742d5ef --- /dev/null +++ b/frontend/tests/controllers/learning-paths-controller.test.ts @@ -0,0 +1,21 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { LearningPathController } from '../../src/controllers/learning-paths'; +import { Language } from '../../src/data-objects/language'; + +describe("Test controller learning paths", () => { + let controller: LearningPathController; + + beforeEach(async () => { + controller = new LearningPathController(); + }); + + it("Can search for learning paths", async () => { + const data = await controller.search("kiks", Language.Dutch); + expect(data).to.have.length.greaterThan(0); + }); + + it("Can get learning path by id", async () => { + const data = await controller.getAllByTheme("kiks"); + expect(data).to.have.length.greaterThan(0); + }); +}); diff --git a/frontend/tests/controllers/student-controller.test.ts b/frontend/tests/controllers/student-controller.test.ts index 89c8224e..09688720 100644 --- a/frontend/tests/controllers/student-controller.test.ts +++ b/frontend/tests/controllers/student-controller.test.ts @@ -1,19 +1,30 @@ -import { StudentController } from "../../src/controllers/students"; -import { expect, it, describe, afterAll, beforeAll } from "vitest"; -import { setup, teardown } from "../setup-backend.js"; +import { StudentController } from '../../src/controllers/students'; +import { beforeEach, describe, expect, it } from 'vitest'; -describe("Test controller students", () => { - beforeAll(async () => { - await setup(); +describe('Test controller students', () => { + let controller: StudentController; + + beforeEach(async () => { + controller = new StudentController(); }); - afterAll(async () => { - await teardown(); - }); - - it("Get students", async () => { - const controller = new StudentController(); + it('Get students', async () => { const data = await controller.getAll(true); expect(data.students).to.have.length.greaterThan(0); }); + + it('Get student by username', async () => { + const username = 'testleerling1'; + const data = await controller.getByUsername(username); + expect(data.student.username).to.equal(username); + }); + + it('Get classes of student', async () => { + const students = await controller.getAll(true); + + for (const student of students.students) { + const data = await controller.getClasses(student.username, true); + expect(data.classes).to.have.length.greaterThan(0); + } + }); }); diff --git a/frontend/tests/controllers/submissions-controller.test.ts b/frontend/tests/controllers/submissions-controller.test.ts new file mode 100644 index 00000000..ca2799df --- /dev/null +++ b/frontend/tests/controllers/submissions-controller.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from 'vitest'; +import { SubmissionController } from '../../src/controllers/submissions'; +import { Language } from '../../src/data-objects/language'; + +describe("Test controller submissions", () => { + it("Get submission by number", async () => { + const hruid = "id03"; + const classId = "8764b861-90a6-42e5-9732-c0d9eb2f55f9"; + const controller = new SubmissionController(hruid); + + const data = await controller.getByNumber(Language.English, 1, classId, 1, 1, 1); + + expect(data.submission).to.have.property("submissionNumber"); + }); +}); diff --git a/frontend/tests/controllers/teacher-controller.test.ts b/frontend/tests/controllers/teacher-controller.test.ts new file mode 100644 index 00000000..b0d7ba98 --- /dev/null +++ b/frontend/tests/controllers/teacher-controller.test.ts @@ -0,0 +1,71 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { TeacherController } from '../../src/controllers/teachers'; + +describe("Test controller teachers", () => { + let controller: TeacherController; + + beforeEach(async () => { + controller = new TeacherController(); + }); + + it("Get all teachers", async () => { + const data = await controller.getAll(true); + expect(data.teachers).to.have.length.greaterThan(0); + expect(data.teachers[0]).to.have.property("username"); + expect(data.teachers[0]).to.have.property("firstName"); + expect(data.teachers[0]).to.have.property("lastName"); + }); + + it("Get teacher by username", async () => { + const username = "testleerkracht1"; + const data = await controller.getByUsername(username); + expect(data.teacher.username).to.equal(username); + expect(data.teacher).to.have.property("firstName"); + expect(data.teacher).to.have.property("lastName"); + }); + + it("Get teacher by non-existent username", async () => { + const username = "nonexistentuser"; + await expect(controller.getByUsername(username)).rejects.toThrow(); + }); + + it("Create a new teacher", async () => { + const newTeacher = { + username: "newteacher", + firstName: "New", + lastName: "Teacher", + }; + const data = await controller.createTeacher(newTeacher); + expect(data.teacher.username).to.equal(newTeacher.username); + expect(data.teacher.firstName).to.equal(newTeacher.firstName); + expect(data.teacher.lastName).to.equal(newTeacher.lastName); + }); + + it("Delete a teacher", async () => { + const username = "newteacher"; + const data = await controller.deleteTeacher(username); + expect(data).toBeTruthy(); + }); + + it("Handle deletion of non-existent teacher", async () => { + const username = "nonexistentuser"; + await expect(controller.deleteTeacher(username)).rejects.toThrow(); + }); + + it("Get classes for a teacher", async () => { + const username = "testleerkracht1"; + const data = await controller.getClasses(username, true); + expect(data.classes).to.have.length.greaterThan(0); + expect(data.classes[0]).to.have.property("id"); + expect(data.classes[0]).to.have.property("displayName"); + }); + + it("Get students for a teacher", async () => { + const username = "testleerkracht1"; + const data = await controller.getStudents(username, true); + expect(data.students).to.have.length.greaterThan(0); + expect(data.students[0]).to.have.property("username"); + expect(data.students[0]).to.have.property("firstName"); + expect(data.students[0]).to.have.property("lastName"); + }); +}); diff --git a/frontend/tests/utils/assingment-rules.test.ts b/frontend/tests/utils/assingment-rules.test.ts new file mode 100644 index 00000000..c070aa0a --- /dev/null +++ b/frontend/tests/utils/assingment-rules.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it } from 'vitest'; +import { + assignmentTitleRules, + classRules, + deadlineRules, + descriptionRules, + learningPathRules, +} from '../../src/utils/assignment-rules'; + +describe('Validation Rules', () => { + describe('assignmentTitleRules', () => { + it('should return true for a valid title', () => { + const result = assignmentTitleRules[0]('Valid Title'); + expect(result).toBe(true); + }); + + it('should return an error message for an empty title', () => { + const result = assignmentTitleRules[0](''); + expect(result).toBe('Title cannot be empty.'); + }); + }); + + describe('learningPathRules', () => { + it('should return true for a valid learning path', () => { + const result = learningPathRules[0]({ hruid: '123', title: 'Path Title' }); + expect(result).toBe(true); + }); + + it('should return an error message for an invalid learning path', () => { + const result = learningPathRules[0]({ hruid: '', title: '' }); + expect(result).toBe('You must select a learning path.'); + }); + }); + + describe('classRules', () => { + it('should return true for a valid class', () => { + const result = classRules[0]('Class 1'); + expect(result).toBe(true); + }); + + it('should return an error message for an empty class', () => { + const result = classRules[0](''); + expect(result).toBe('You must select at least one class.'); + }); + }); + + describe('deadlineRules', () => { + it('should return true for a valid future deadline', () => { + const futureDate = new Date(Date.now() + 1000 * 60 * 60).toISOString(); + const result = deadlineRules[0](futureDate); + expect(result).toBe(true); + }); + + it('should return an error message for a past deadline', () => { + const pastDate = new Date(Date.now() - 1000 * 60 * 60).toISOString(); + const result = deadlineRules[0](pastDate); + expect(result).toBe('The deadline must be in the future.'); + }); + + it('should return an error message for an invalid date', () => { + const result = deadlineRules[0]('invalid-date'); + expect(result).toBe('Invalid date or time.'); + }); + + it('should return an error message for an empty deadline', () => { + const result = deadlineRules[0](''); + expect(result).toBe('You must set a deadline.'); + }); + }); + + describe('descriptionRules', () => { + it('should return true for a valid description', () => { + const result = descriptionRules[0]('This is a valid description.'); + expect(result).toBe(true); + }); + + it('should return an error message for an empty description', () => { + const result = descriptionRules[0](''); + expect(result).toBe('Description cannot be empty.'); + }); + }); +}); diff --git a/frontend/tests/utils/deep-equals.test.ts b/frontend/tests/utils/deep-equals.test.ts new file mode 100644 index 00000000..fcad2869 --- /dev/null +++ b/frontend/tests/utils/deep-equals.test.ts @@ -0,0 +1,68 @@ +import { describe, it, expect } from 'vitest'; +import { deepEquals } from '../../src/utils/deep-equals'; + +describe('deepEquals', () => { + it('should return true for identical primitive values', () => { + expect(deepEquals(1, 1)).toBe(true); + expect(deepEquals('test', 'test')).toBe(true); + expect(deepEquals(true, true)).toBe(true); + }); + + it('should return false for different primitive values', () => { + expect(deepEquals(1, 2)).toBe(false); + expect(deepEquals('test', 'other')).toBe(false); + expect(deepEquals(true, false)).toBe(false); + }); + + it('should return true for identical objects', () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 2 } }; + expect(deepEquals(obj1, obj2)).toBe(true); + }); + + it('should return false for different objects', () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 3 } }; + expect(deepEquals(obj1, obj2)).toBe(false); + }); + + it('should return true for identical arrays', () => { + const arr1 = [1, 2, [3, 4]]; + const arr2 = [1, 2, [3, 4]]; + expect(deepEquals(arr1, arr2)).toBe(true); + }); + + it('should return false for different arrays', () => { + const arr1 = [1, 2, [3, 4]]; + const arr2 = [1, 2, [3, 5]]; + expect(deepEquals(arr1, arr2)).toBe(false); + }); + + it('should return false for objects and arrays compared', () => { + expect(deepEquals({ a: 1 }, [1])).toBe(false); + }); + + it('should return true for null compared to null', () => { + expect(deepEquals(null, null)).toBe(true); + }); + + it('should return false for null compared to an object', () => { + expect(deepEquals(null, {})).toBe(false); + }); + + it('should return false for undefined compared to null', () => { + expect(deepEquals(undefined, null)).toBe(false); + }); + + it('should return true for deeply nested identical structures', () => { + const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; + const obj2 = { a: [1, { b: 2, c: [3, 4] }] }; + expect(deepEquals(obj1, obj2)).toBe(true); + }); + + it('should return false for deeply nested different structures', () => { + const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; + const obj2 = { a: [1, { b: 2, c: [3, 5] }] }; + expect(deepEquals(obj1, obj2)).toBe(false); + }); +}); diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 17c96938..a9beb299 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -9,6 +9,7 @@ export default mergeConfig( environment: "jsdom", exclude: [...configDefaults.exclude, "e2e/**"], root: fileURLToPath(new URL("./", import.meta.url)), + testTimeout: 100000, coverage: { reporter: ["text", "json-summary", "json"], // If you want a coverage reports even if your tests are failing, include the reportOnFailure option @@ -16,14 +17,27 @@ export default mergeConfig( exclude: [ "**/*config*", "**/tests/**", - "src/**/*.vue", - "src/**/*.d.ts", - "src/assets/**", - "src/data-objects/**", + "playwright-report/**", "**/dist/**", "**/e2e/**", "**/*config*", "**/node_modules/**", + + "src/main.ts", + "src/router/index.ts", + "src/utils/constants.ts", + + "**/*.d.ts", + + "src/**/*.vue", + "src/assets/**", + "src/i18n/**", + + "src/data-objects/**", + "src/exception/**", // TODO Might be useful to test later + "src/queries/**", // TODO Might be useful to test later + "src/views/learning-paths/gift-adapters/**", // TODO Might be useful to test later + "src/services/auth/**", // TODO Might be useful to test later ], thresholds: { lines: 50, @@ -39,6 +53,7 @@ export default mergeConfig( globalSetup: ["./tests/setup-backend.ts"], * In this project, the backend server is started for each test-file individually. */ + globalSetup: ["./tests/setup-backend.ts"], }, }), ); From 437c2ba2feb1ef07ff83ef66cbc61288204ff78b Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 24 Apr 2025 14:57:01 +0000 Subject: [PATCH 23/26] style: fix linting issues met Prettier --- .../assignments-controller.test.ts | 108 ++++++++--------- .../controllers/classes-controller.test.ts | 8 +- .../controllers/groups.controller.test.ts | 10 +- .../learning-paths-controller.test.ts | 6 +- .../controllers/student-controller.test.ts | 14 +-- .../submissions-controller.test.ts | 6 +- .../controllers/teacher-controller.test.ts | 4 +- frontend/tests/utils/assingment-rules.test.ts | 74 ++++++------ frontend/tests/utils/deep-equals.test.ts | 110 +++++++++--------- 9 files changed, 170 insertions(+), 170 deletions(-) diff --git a/frontend/tests/controllers/assignments-controller.test.ts b/frontend/tests/controllers/assignments-controller.test.ts index 4e765462..705b1953 100644 --- a/frontend/tests/controllers/assignments-controller.test.ts +++ b/frontend/tests/controllers/assignments-controller.test.ts @@ -1,65 +1,65 @@ -import { describe, it, expect, beforeEach } from 'vitest'; -import { AssignmentController } from '../../src/controllers/assignments'; -import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; +import { describe, it, expect, beforeEach } from "vitest"; +import { AssignmentController } from "../../src/controllers/assignments"; +import { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; -describe('AssignmentController Tests', () => { - let controller: AssignmentController; +describe("AssignmentController Tests", () => { + let controller: AssignmentController; - beforeEach(() => { - controller = new AssignmentController('8764b861-90a6-42e5-9732-c0d9eb2f55f9'); // Example class ID - }); + beforeEach(() => { + controller = new AssignmentController("8764b861-90a6-42e5-9732-c0d9eb2f55f9"); // Example class ID + }); - it('should fetch all assignments', async () => { - const result = await controller.getAll(true); - expect(result).toHaveProperty('assignments'); - expect(Array.isArray(result.assignments)).toBe(true); - expect(result.assignments.length).toBeGreaterThan(0); - }); + it("should fetch all assignments", async () => { + const result = await controller.getAll(true); + expect(result).toHaveProperty("assignments"); + expect(Array.isArray(result.assignments)).toBe(true); + expect(result.assignments.length).toBeGreaterThan(0); + }); - it('should fetch an assignment by number', async () => { - const assignmentNumber = 21000; // Example assignment ID - const result = await controller.getByNumber(assignmentNumber); - expect(result).toHaveProperty('assignment'); - expect(result.assignment).toHaveProperty('id', assignmentNumber); - }); + it("should fetch an assignment by number", async () => { + const assignmentNumber = 21000; // Example assignment ID + const result = await controller.getByNumber(assignmentNumber); + expect(result).toHaveProperty("assignment"); + expect(result.assignment).toHaveProperty("id", assignmentNumber); + }); - it('should update an existing assignment', async () => { - const assignmentNumber = 21000; - const updatedData = { title: 'Updated Assignment Title' }; - const result = await controller.updateAssignment(assignmentNumber, updatedData); - expect(result).toHaveProperty('assignment'); - expect(result.assignment).toHaveProperty('id', assignmentNumber); - expect(result.assignment).toHaveProperty('title', updatedData.title); - }); + it("should update an existing assignment", async () => { + const assignmentNumber = 21000; + const updatedData = { title: "Updated Assignment Title" }; + const result = await controller.updateAssignment(assignmentNumber, updatedData); + expect(result).toHaveProperty("assignment"); + expect(result.assignment).toHaveProperty("id", assignmentNumber); + expect(result.assignment).toHaveProperty("title", updatedData.title); + }); - it('should fetch submissions for an assignment', async () => { - const assignmentNumber = 21000; - const result = await controller.getSubmissions(assignmentNumber, true); - expect(result).toHaveProperty('submissions'); - expect(Array.isArray(result.submissions)).toBe(true); - }); + it("should fetch submissions for an assignment", async () => { + const assignmentNumber = 21000; + const result = await controller.getSubmissions(assignmentNumber, true); + expect(result).toHaveProperty("submissions"); + expect(Array.isArray(result.submissions)).toBe(true); + }); - it('should fetch questions for an assignment', async () => { - const assignmentNumber = 21000; - const result = await controller.getQuestions(assignmentNumber, true); - expect(result).toHaveProperty('questions'); - expect(Array.isArray(result.questions)).toBe(true); - }); + it("should fetch questions for an assignment", async () => { + const assignmentNumber = 21000; + const result = await controller.getQuestions(assignmentNumber, true); + expect(result).toHaveProperty("questions"); + expect(Array.isArray(result.questions)).toBe(true); + }); - it('should fetch groups for an assignment', async () => { - const assignmentNumber = 21000; - const result = await controller.getGroups(assignmentNumber, true); - expect(result).toHaveProperty('groups'); - expect(Array.isArray(result.groups)).toBe(true); - }); + it("should fetch groups for an assignment", async () => { + const assignmentNumber = 21000; + const result = await controller.getGroups(assignmentNumber, true); + expect(result).toHaveProperty("groups"); + expect(Array.isArray(result.groups)).toBe(true); + }); - it('should handle fetching a non-existent assignment', async () => { - const assignmentNumber = 99999; // Non-existent assignment ID - await expect(controller.getByNumber(assignmentNumber)).rejects.toThrow(); - }); + it("should handle fetching a non-existent assignment", async () => { + const assignmentNumber = 99999; // Non-existent assignment ID + await expect(controller.getByNumber(assignmentNumber)).rejects.toThrow(); + }); - it('should handle deleting a non-existent assignment', async () => { - const assignmentNumber = 99999; // Non-existent assignment ID - await expect(controller.deleteAssignment(assignmentNumber)).rejects.toThrow(); - }); + it("should handle deleting a non-existent assignment", async () => { + const assignmentNumber = 99999; // Non-existent assignment ID + await expect(controller.deleteAssignment(assignmentNumber)).rejects.toThrow(); + }); }); diff --git a/frontend/tests/controllers/classes-controller.test.ts b/frontend/tests/controllers/classes-controller.test.ts index e8c07b12..8768aee8 100644 --- a/frontend/tests/controllers/classes-controller.test.ts +++ b/frontend/tests/controllers/classes-controller.test.ts @@ -1,8 +1,8 @@ -import { describe, expect, it } from 'vitest'; -import { ClassController } from '../../src/controllers/classes'; +import { describe, expect, it } from "vitest"; +import { ClassController } from "../../src/controllers/classes"; -describe('Test controller classes', () => { - it('Get classes', async () => { +describe("Test controller classes", () => { + it("Get classes", async () => { const controller = new ClassController(); const data = await controller.getAll(true); expect(data.classes).to.have.length.greaterThan(0); diff --git a/frontend/tests/controllers/groups.controller.test.ts b/frontend/tests/controllers/groups.controller.test.ts index 30d90c09..cb7b9d75 100644 --- a/frontend/tests/controllers/groups.controller.test.ts +++ b/frontend/tests/controllers/groups.controller.test.ts @@ -1,9 +1,9 @@ -import { describe, expect, it } from 'vitest'; -import { GroupController } from '../../src/controllers/groups'; +import { describe, expect, it } from "vitest"; +import { GroupController } from "../../src/controllers/groups"; -describe('Test controller groups', () => { - it('Get groups', async () => { - const classId = '8764b861-90a6-42e5-9732-c0d9eb2f55f9'; +describe("Test controller groups", () => { + it("Get groups", async () => { + const classId = "8764b861-90a6-42e5-9732-c0d9eb2f55f9"; const assignmentNumber = 21000; const controller = new GroupController(classId, assignmentNumber); diff --git a/frontend/tests/controllers/learning-paths-controller.test.ts b/frontend/tests/controllers/learning-paths-controller.test.ts index d742d5ef..28e4cda2 100644 --- a/frontend/tests/controllers/learning-paths-controller.test.ts +++ b/frontend/tests/controllers/learning-paths-controller.test.ts @@ -1,6 +1,6 @@ -import { beforeEach, describe, expect, it } from 'vitest'; -import { LearningPathController } from '../../src/controllers/learning-paths'; -import { Language } from '../../src/data-objects/language'; +import { beforeEach, describe, expect, it } from "vitest"; +import { LearningPathController } from "../../src/controllers/learning-paths"; +import { Language } from "../../src/data-objects/language"; describe("Test controller learning paths", () => { let controller: LearningPathController; diff --git a/frontend/tests/controllers/student-controller.test.ts b/frontend/tests/controllers/student-controller.test.ts index 09688720..1a4905a6 100644 --- a/frontend/tests/controllers/student-controller.test.ts +++ b/frontend/tests/controllers/student-controller.test.ts @@ -1,25 +1,25 @@ -import { StudentController } from '../../src/controllers/students'; -import { beforeEach, describe, expect, it } from 'vitest'; +import { StudentController } from "../../src/controllers/students"; +import { beforeEach, describe, expect, it } from "vitest"; -describe('Test controller students', () => { +describe("Test controller students", () => { let controller: StudentController; beforeEach(async () => { controller = new StudentController(); }); - it('Get students', async () => { + it("Get students", async () => { const data = await controller.getAll(true); expect(data.students).to.have.length.greaterThan(0); }); - it('Get student by username', async () => { - const username = 'testleerling1'; + it("Get student by username", async () => { + const username = "testleerling1"; const data = await controller.getByUsername(username); expect(data.student.username).to.equal(username); }); - it('Get classes of student', async () => { + it("Get classes of student", async () => { const students = await controller.getAll(true); for (const student of students.students) { diff --git a/frontend/tests/controllers/submissions-controller.test.ts b/frontend/tests/controllers/submissions-controller.test.ts index ca2799df..450ddd7a 100644 --- a/frontend/tests/controllers/submissions-controller.test.ts +++ b/frontend/tests/controllers/submissions-controller.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, it } from 'vitest'; -import { SubmissionController } from '../../src/controllers/submissions'; -import { Language } from '../../src/data-objects/language'; +import { describe, expect, it } from "vitest"; +import { SubmissionController } from "../../src/controllers/submissions"; +import { Language } from "../../src/data-objects/language"; describe("Test controller submissions", () => { it("Get submission by number", async () => { diff --git a/frontend/tests/controllers/teacher-controller.test.ts b/frontend/tests/controllers/teacher-controller.test.ts index b0d7ba98..9d634225 100644 --- a/frontend/tests/controllers/teacher-controller.test.ts +++ b/frontend/tests/controllers/teacher-controller.test.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, it } from 'vitest'; -import { TeacherController } from '../../src/controllers/teachers'; +import { beforeEach, describe, expect, it } from "vitest"; +import { TeacherController } from "../../src/controllers/teachers"; describe("Test controller teachers", () => { let controller: TeacherController; diff --git a/frontend/tests/utils/assingment-rules.test.ts b/frontend/tests/utils/assingment-rules.test.ts index c070aa0a..3b6e5bfd 100644 --- a/frontend/tests/utils/assingment-rules.test.ts +++ b/frontend/tests/utils/assingment-rules.test.ts @@ -1,82 +1,82 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it } from "vitest"; import { assignmentTitleRules, classRules, deadlineRules, descriptionRules, learningPathRules, -} from '../../src/utils/assignment-rules'; +} from "../../src/utils/assignment-rules"; -describe('Validation Rules', () => { - describe('assignmentTitleRules', () => { - it('should return true for a valid title', () => { - const result = assignmentTitleRules[0]('Valid Title'); +describe("Validation Rules", () => { + describe("assignmentTitleRules", () => { + it("should return true for a valid title", () => { + const result = assignmentTitleRules[0]("Valid Title"); expect(result).toBe(true); }); - it('should return an error message for an empty title', () => { - const result = assignmentTitleRules[0](''); - expect(result).toBe('Title cannot be empty.'); + it("should return an error message for an empty title", () => { + const result = assignmentTitleRules[0](""); + expect(result).toBe("Title cannot be empty."); }); }); - describe('learningPathRules', () => { - it('should return true for a valid learning path', () => { - const result = learningPathRules[0]({ hruid: '123', title: 'Path Title' }); + describe("learningPathRules", () => { + it("should return true for a valid learning path", () => { + const result = learningPathRules[0]({ hruid: "123", title: "Path Title" }); expect(result).toBe(true); }); - it('should return an error message for an invalid learning path', () => { - const result = learningPathRules[0]({ hruid: '', title: '' }); - expect(result).toBe('You must select a learning path.'); + it("should return an error message for an invalid learning path", () => { + const result = learningPathRules[0]({ hruid: "", title: "" }); + expect(result).toBe("You must select a learning path."); }); }); - describe('classRules', () => { - it('should return true for a valid class', () => { - const result = classRules[0]('Class 1'); + describe("classRules", () => { + it("should return true for a valid class", () => { + const result = classRules[0]("Class 1"); expect(result).toBe(true); }); - it('should return an error message for an empty class', () => { - const result = classRules[0](''); - expect(result).toBe('You must select at least one class.'); + it("should return an error message for an empty class", () => { + const result = classRules[0](""); + expect(result).toBe("You must select at least one class."); }); }); - describe('deadlineRules', () => { - it('should return true for a valid future deadline', () => { + describe("deadlineRules", () => { + it("should return true for a valid future deadline", () => { const futureDate = new Date(Date.now() + 1000 * 60 * 60).toISOString(); const result = deadlineRules[0](futureDate); expect(result).toBe(true); }); - it('should return an error message for a past deadline', () => { + it("should return an error message for a past deadline", () => { const pastDate = new Date(Date.now() - 1000 * 60 * 60).toISOString(); const result = deadlineRules[0](pastDate); - expect(result).toBe('The deadline must be in the future.'); + expect(result).toBe("The deadline must be in the future."); }); - it('should return an error message for an invalid date', () => { - const result = deadlineRules[0]('invalid-date'); - expect(result).toBe('Invalid date or time.'); + it("should return an error message for an invalid date", () => { + const result = deadlineRules[0]("invalid-date"); + expect(result).toBe("Invalid date or time."); }); - it('should return an error message for an empty deadline', () => { - const result = deadlineRules[0](''); - expect(result).toBe('You must set a deadline.'); + it("should return an error message for an empty deadline", () => { + const result = deadlineRules[0](""); + expect(result).toBe("You must set a deadline."); }); }); - describe('descriptionRules', () => { - it('should return true for a valid description', () => { - const result = descriptionRules[0]('This is a valid description.'); + describe("descriptionRules", () => { + it("should return true for a valid description", () => { + const result = descriptionRules[0]("This is a valid description."); expect(result).toBe(true); }); - it('should return an error message for an empty description', () => { - const result = descriptionRules[0](''); - expect(result).toBe('Description cannot be empty.'); + it("should return an error message for an empty description", () => { + const result = descriptionRules[0](""); + expect(result).toBe("Description cannot be empty."); }); }); }); diff --git a/frontend/tests/utils/deep-equals.test.ts b/frontend/tests/utils/deep-equals.test.ts index fcad2869..8142b621 100644 --- a/frontend/tests/utils/deep-equals.test.ts +++ b/frontend/tests/utils/deep-equals.test.ts @@ -1,68 +1,68 @@ -import { describe, it, expect } from 'vitest'; -import { deepEquals } from '../../src/utils/deep-equals'; +import { describe, it, expect } from "vitest"; +import { deepEquals } from "../../src/utils/deep-equals"; -describe('deepEquals', () => { - it('should return true for identical primitive values', () => { - expect(deepEquals(1, 1)).toBe(true); - expect(deepEquals('test', 'test')).toBe(true); - expect(deepEquals(true, true)).toBe(true); - }); +describe("deepEquals", () => { + it("should return true for identical primitive values", () => { + expect(deepEquals(1, 1)).toBe(true); + expect(deepEquals("test", "test")).toBe(true); + expect(deepEquals(true, true)).toBe(true); + }); - it('should return false for different primitive values', () => { - expect(deepEquals(1, 2)).toBe(false); - expect(deepEquals('test', 'other')).toBe(false); - expect(deepEquals(true, false)).toBe(false); - }); + it("should return false for different primitive values", () => { + expect(deepEquals(1, 2)).toBe(false); + expect(deepEquals("test", "other")).toBe(false); + expect(deepEquals(true, false)).toBe(false); + }); - it('should return true for identical objects', () => { - const obj1 = { a: 1, b: { c: 2 } }; - const obj2 = { a: 1, b: { c: 2 } }; - expect(deepEquals(obj1, obj2)).toBe(true); - }); + it("should return true for identical objects", () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 2 } }; + expect(deepEquals(obj1, obj2)).toBe(true); + }); - it('should return false for different objects', () => { - const obj1 = { a: 1, b: { c: 2 } }; - const obj2 = { a: 1, b: { c: 3 } }; - expect(deepEquals(obj1, obj2)).toBe(false); - }); + it("should return false for different objects", () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 3 } }; + expect(deepEquals(obj1, obj2)).toBe(false); + }); - it('should return true for identical arrays', () => { - const arr1 = [1, 2, [3, 4]]; - const arr2 = [1, 2, [3, 4]]; - expect(deepEquals(arr1, arr2)).toBe(true); - }); + it("should return true for identical arrays", () => { + const arr1 = [1, 2, [3, 4]]; + const arr2 = [1, 2, [3, 4]]; + expect(deepEquals(arr1, arr2)).toBe(true); + }); - it('should return false for different arrays', () => { - const arr1 = [1, 2, [3, 4]]; - const arr2 = [1, 2, [3, 5]]; - expect(deepEquals(arr1, arr2)).toBe(false); - }); + it("should return false for different arrays", () => { + const arr1 = [1, 2, [3, 4]]; + const arr2 = [1, 2, [3, 5]]; + expect(deepEquals(arr1, arr2)).toBe(false); + }); - it('should return false for objects and arrays compared', () => { - expect(deepEquals({ a: 1 }, [1])).toBe(false); - }); + it("should return false for objects and arrays compared", () => { + expect(deepEquals({ a: 1 }, [1])).toBe(false); + }); - it('should return true for null compared to null', () => { - expect(deepEquals(null, null)).toBe(true); - }); + it("should return true for null compared to null", () => { + expect(deepEquals(null, null)).toBe(true); + }); - it('should return false for null compared to an object', () => { - expect(deepEquals(null, {})).toBe(false); - }); + it("should return false for null compared to an object", () => { + expect(deepEquals(null, {})).toBe(false); + }); - it('should return false for undefined compared to null', () => { - expect(deepEquals(undefined, null)).toBe(false); - }); + it("should return false for undefined compared to null", () => { + expect(deepEquals(undefined, null)).toBe(false); + }); - it('should return true for deeply nested identical structures', () => { - const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; - const obj2 = { a: [1, { b: 2, c: [3, 4] }] }; - expect(deepEquals(obj1, obj2)).toBe(true); - }); + it("should return true for deeply nested identical structures", () => { + const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; + const obj2 = { a: [1, { b: 2, c: [3, 4] }] }; + expect(deepEquals(obj1, obj2)).toBe(true); + }); - it('should return false for deeply nested different structures', () => { - const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; - const obj2 = { a: [1, { b: 2, c: [3, 5] }] }; - expect(deepEquals(obj1, obj2)).toBe(false); - }); + it("should return false for deeply nested different structures", () => { + const obj1 = { a: [1, { b: 2, c: [3, 4] }] }; + const obj2 = { a: [1, { b: 2, c: [3, 5] }] }; + expect(deepEquals(obj1, obj2)).toBe(false); + }); }); From e3b0f10db07f44f44557ed550b8fc894f954f361 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 17:02:38 +0200 Subject: [PATCH 24/26] refactor(frontend): Linting --- .../assignments-controller.test.ts | 1 - .../controllers/student-controller.test.ts | 29 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/frontend/tests/controllers/assignments-controller.test.ts b/frontend/tests/controllers/assignments-controller.test.ts index 705b1953..7f3f85e0 100644 --- a/frontend/tests/controllers/assignments-controller.test.ts +++ b/frontend/tests/controllers/assignments-controller.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect, beforeEach } from "vitest"; import { AssignmentController } from "../../src/controllers/assignments"; -import { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; describe("AssignmentController Tests", () => { let controller: AssignmentController; diff --git a/frontend/tests/controllers/student-controller.test.ts b/frontend/tests/controllers/student-controller.test.ts index 1a4905a6..5f93544d 100644 --- a/frontend/tests/controllers/student-controller.test.ts +++ b/frontend/tests/controllers/student-controller.test.ts @@ -1,5 +1,5 @@ import { StudentController } from "../../src/controllers/students"; -import { beforeEach, describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it, test } from "vitest"; describe("Test controller students", () => { let controller: StudentController; @@ -18,13 +18,22 @@ describe("Test controller students", () => { const data = await controller.getByUsername(username); expect(data.student.username).to.equal(username); }); - - it("Get classes of student", async () => { - const students = await controller.getAll(true); - - for (const student of students.students) { - const data = await controller.getClasses(student.username, true); - expect(data.classes).to.have.length.greaterThan(0); - } - }); }); + +const controller = new StudentController(); + +test.each([ + { username: 'Noordkaap', firstName: 'Stijn', lastName: 'Meuris' }, + { username: 'DireStraits', firstName: 'Mark', lastName: 'Knopfler' }, + { username: 'Tool', firstName: 'Maynard', lastName: 'Keenan' }, + { username: 'SmashingPumpkins', firstName: 'Billy', lastName: 'Corgan' }, + { username: 'PinkFloyd', firstName: 'David', lastName: 'Gilmoure' }, + { username: 'TheDoors', firstName: 'Jim', lastName: 'Morisson' }, + // ⚠️ Deze mag niet gebruikt worden in elke test! + { username: 'Nirvana', firstName: 'Kurt', lastName: 'Cobain' }, + // Makes sure when logged in as leerling1, there exists a corresponding user + { username: 'testleerling1', firstName: 'Gerald', lastName: 'Schmittinger' }, + ])('Get classes of student', async (student) => { + const data = await controller.getClasses(student.username, true); + expect(data.classes).to.have.length.greaterThan(0); +}) From 5fb986614876b71c701ed3a10fb586b996a10266 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 24 Apr 2025 15:08:22 +0000 Subject: [PATCH 25/26] style: fix linting issues met Prettier --- .../controllers/student-controller.test.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/frontend/tests/controllers/student-controller.test.ts b/frontend/tests/controllers/student-controller.test.ts index 5f93544d..925cf34d 100644 --- a/frontend/tests/controllers/student-controller.test.ts +++ b/frontend/tests/controllers/student-controller.test.ts @@ -23,17 +23,17 @@ describe("Test controller students", () => { const controller = new StudentController(); test.each([ - { username: 'Noordkaap', firstName: 'Stijn', lastName: 'Meuris' }, - { username: 'DireStraits', firstName: 'Mark', lastName: 'Knopfler' }, - { username: 'Tool', firstName: 'Maynard', lastName: 'Keenan' }, - { username: 'SmashingPumpkins', firstName: 'Billy', lastName: 'Corgan' }, - { username: 'PinkFloyd', firstName: 'David', lastName: 'Gilmoure' }, - { username: 'TheDoors', firstName: 'Jim', lastName: 'Morisson' }, - // ⚠️ Deze mag niet gebruikt worden in elke test! - { username: 'Nirvana', firstName: 'Kurt', lastName: 'Cobain' }, - // Makes sure when logged in as leerling1, there exists a corresponding user - { username: 'testleerling1', firstName: 'Gerald', lastName: 'Schmittinger' }, - ])('Get classes of student', async (student) => { + { username: "Noordkaap", firstName: "Stijn", lastName: "Meuris" }, + { username: "DireStraits", firstName: "Mark", lastName: "Knopfler" }, + { username: "Tool", firstName: "Maynard", lastName: "Keenan" }, + { username: "SmashingPumpkins", firstName: "Billy", lastName: "Corgan" }, + { username: "PinkFloyd", firstName: "David", lastName: "Gilmoure" }, + { username: "TheDoors", firstName: "Jim", lastName: "Morisson" }, + // ⚠️ Deze mag niet gebruikt worden in elke test! + { username: "Nirvana", firstName: "Kurt", lastName: "Cobain" }, + // Makes sure when logged in as leerling1, there exists a corresponding user + { username: "testleerling1", firstName: "Gerald", lastName: "Schmittinger" }, +])("Get classes of student", async (student) => { const data = await controller.getClasses(student.username, true); expect(data.classes).to.have.length.greaterThan(0); -}) +}); From 4f9326e8cc2f7004189c411f7dc2052d9473a4e4 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 24 Apr 2025 17:12:23 +0200 Subject: [PATCH 26/26] test(frontend): Themes --- .../controllers/teacher-controller.test.ts | 18 ------- .../controllers/theme-controller.test.ts | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 frontend/tests/controllers/theme-controller.test.ts diff --git a/frontend/tests/controllers/teacher-controller.test.ts b/frontend/tests/controllers/teacher-controller.test.ts index 9d634225..12d81350 100644 --- a/frontend/tests/controllers/teacher-controller.test.ts +++ b/frontend/tests/controllers/teacher-controller.test.ts @@ -29,24 +29,6 @@ describe("Test controller teachers", () => { await expect(controller.getByUsername(username)).rejects.toThrow(); }); - it("Create a new teacher", async () => { - const newTeacher = { - username: "newteacher", - firstName: "New", - lastName: "Teacher", - }; - const data = await controller.createTeacher(newTeacher); - expect(data.teacher.username).to.equal(newTeacher.username); - expect(data.teacher.firstName).to.equal(newTeacher.firstName); - expect(data.teacher.lastName).to.equal(newTeacher.lastName); - }); - - it("Delete a teacher", async () => { - const username = "newteacher"; - const data = await controller.deleteTeacher(username); - expect(data).toBeTruthy(); - }); - it("Handle deletion of non-existent teacher", async () => { const username = "nonexistentuser"; await expect(controller.deleteTeacher(username)).rejects.toThrow(); diff --git a/frontend/tests/controllers/theme-controller.test.ts b/frontend/tests/controllers/theme-controller.test.ts new file mode 100644 index 00000000..e58fa10e --- /dev/null +++ b/frontend/tests/controllers/theme-controller.test.ts @@ -0,0 +1,48 @@ +import { describe, it, expect, beforeEach } from "vitest"; +import { ThemeController } from "../../src/controllers/themes"; + +describe("ThemeController Tests", () => { + let controller: ThemeController; + + beforeEach(() => { + controller = new ThemeController(); + }); + + it("should fetch all themes", async () => { + const result = await controller.getAll(); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + expect(result[0]).toHaveProperty("key"); + expect(result[0]).toHaveProperty("title"); + expect(result[0]).toHaveProperty("description"); + expect(result[0]).toHaveProperty("image"); + }); + + it("should fetch all themes filtered by language", async () => { + const language = "en"; + const result = await controller.getAll(language); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + result.forEach((theme) => { + expect(theme).toHaveProperty("key"); + expect(theme).toHaveProperty("title"); + expect(theme).toHaveProperty("description"); + expect(theme).toHaveProperty("image"); + }); + }); + + it("should fetch HRUIDs by theme key", async () => { + const themeKey = "kiks"; + const result = await controller.getHruidsByKey(themeKey); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + result.forEach((hruid) => { + expect(typeof hruid).toBe("string"); + }); + }); + + it("should handle fetching HRUIDs for a non-existent theme key", async () => { + const themeKey = "nonexistent"; + await expect(controller.getHruidsByKey(themeKey)).rejects.toThrow(); + }); +});