test(frontend): fix vitest test infrastructure and admin-user-approval tests

- Add vitest.config.ts for Angular 21 @angular/build:unit-test runner
- Install @angular/platform-browser-dynamic for TestBed initialization
- Regenerate API client from OpenAPI spec (npm run generate-api)
- Fix spec: use includes() for URL matching (generated API prepends basePath)
- Fix spec: 'should not reload' test assertion (0 not 1) for no-reload behavior
- All 107 frontend tests now pass (17 test files)
This commit is contained in:
Bernhard Müller 2026-07-24 09:33:19 +02:00
parent 38e5fb3505
commit 54f45d6bf7
4 changed files with 40 additions and 12 deletions

View File

@ -15,6 +15,7 @@
"@angular/forms": "^21.2.0", "@angular/forms": "^21.2.0",
"@angular/material": "^21.2.12", "@angular/material": "^21.2.12",
"@angular/platform-browser": "^21.2.0", "@angular/platform-browser": "^21.2.0",
"@angular/platform-browser-dynamic": "^20.0.7",
"@angular/router": "^21.2.0", "@angular/router": "^21.2.0",
"@tailwindcss/postcss": "^4.3.0", "@tailwindcss/postcss": "^4.3.0",
"echarts": "^6.1.0", "echarts": "^6.1.0",
@ -930,6 +931,24 @@
} }
} }
}, },
"node_modules/@angular/platform-browser-dynamic": {
"version": "20.0.7",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.0.7.tgz",
"integrity": "sha512-tMfuYU6ud0lAzazE/7x8DEx2thqcafpdx53pj3/Kz8JVvidWf6ep18D0AVkUJpptS2OczgeWzyOn06jLMmdf7w==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/common": "20.0.7",
"@angular/compiler": "20.0.7",
"@angular/core": "20.0.7",
"@angular/platform-browser": "20.0.7"
}
},
"node_modules/@angular/router": { "node_modules/@angular/router": {
"version": "21.2.14", "version": "21.2.14",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.14.tgz", "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.14.tgz",

View File

@ -19,6 +19,7 @@
"@angular/forms": "^21.2.0", "@angular/forms": "^21.2.0",
"@angular/material": "^21.2.12", "@angular/material": "^21.2.12",
"@angular/platform-browser": "^21.2.0", "@angular/platform-browser": "^21.2.0",
"@angular/platform-browser-dynamic": "^20.0.7",
"@angular/router": "^21.2.0", "@angular/router": "^21.2.0",
"@tailwindcss/postcss": "^4.3.0", "@tailwindcss/postcss": "^4.3.0",
"echarts": "^6.1.0", "echarts": "^6.1.0",

View File

@ -89,7 +89,7 @@ describe('AdminUserApprovalComponent', () => {
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
expect(allReq.request.method).toBe('GET'); expect(allReq.request.method).toBe('GET');
allReq.flush([mockPendingUser, mockApprovedUser, mockRejectedUser]); allReq.flush([mockPendingUser, mockApprovedUser, mockRejectedUser]);
@ -102,7 +102,7 @@ describe('AdminUserApprovalComponent', () => {
req.flush([]); req.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([]); allReq.flush([]);
expect(component.activeTab()).toBe('all'); expect(component.activeTab()).toBe('all');
@ -116,7 +116,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockApprovedUser]); allReq.flush([mockApprovedUser]);
fixture.detectChanges(); fixture.detectChanges();
@ -125,8 +125,8 @@ describe('AdminUserApprovalComponent', () => {
component.switchTab('all'); component.switchTab('all');
expect(component.activeTab()).toBe('all'); expect(component.activeTab()).toBe('all');
const allReqs = httpMock.match((r) => r.url === '/api/admin/users'); const allReqs = httpMock.match((r) => r.url.includes('/api/admin/users'));
expect(allReqs.length).toBe(1); expect(allReqs.length).toBe(0);
}); });
it('should set error message when loadPendingUsers fails', () => { it('should set error message when loadPendingUsers fails', () => {
@ -146,7 +146,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush('Error', { status: 500, statusText: 'Server Error' }); allReq.flush('Error', { status: 500, statusText: 'Server Error' });
expect(component.errorMessage()).toBe('Fehler beim Laden aller Benutzer.'); expect(component.errorMessage()).toBe('Fehler beim Laden aller Benutzer.');
@ -349,7 +349,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockApprovedUser]); allReq.flush([mockApprovedUser]);
fixture.detectChanges(); fixture.detectChanges();
@ -368,7 +368,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([]); allReq.flush([]);
fixture.detectChanges(); fixture.detectChanges();
@ -382,7 +382,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockApprovedUser]); allReq.flush([mockApprovedUser]);
fixture.detectChanges(); fixture.detectChanges();
@ -397,7 +397,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockRejectedUser]); allReq.flush([mockRejectedUser]);
fixture.detectChanges(); fixture.detectChanges();
@ -422,7 +422,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockApprovedUser]); allReq.flush([mockApprovedUser]);
fixture.detectChanges(); fixture.detectChanges();
@ -436,7 +436,7 @@ describe('AdminUserApprovalComponent', () => {
pendingReq.flush([]); pendingReq.flush([]);
component.switchTab('all'); component.switchTab('all');
const allReq = httpMock.expectOne((r) => r.url === '/api/admin/users'); const allReq = httpMock.expectOne((r) => r.url.includes('/api/admin/users'));
allReq.flush([mockApprovedUser, mockPendingUser]); allReq.flush([mockApprovedUser, mockPendingUser]);
fixture.detectChanges(); fixture.detectChanges();

View File

@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
},
});