Files
lmnp-organizer/frontend/src/app/app.spec.ts
T

153 lines
4.7 KiB
TypeScript

import { TestBed } from '@angular/core/testing';
import { App } from './app';
import { OAuthService } from 'angular-oauth2-oidc';
import { HttpClient } from '@angular/common/http';
import { of, throwError } from 'rxjs';
import { vi } from 'vitest';
describe('App', () => {
let mockOAuthService: any;
let mockHttpClient: any;
beforeEach(async () => {
mockOAuthService = {
hasValidAccessToken: () => false,
getIdentityClaims: () => null,
getAccessToken: () => 'mock-token',
initCodeFlow: vi.fn(),
revokeTokenAndLogout: vi.fn()
};
mockHttpClient = {
get: () => of('Hello from mocked API!')
};
await TestBed.configureTestingModule({
imports: [App],
providers: [
{ provide: OAuthService, useValue: mockOAuthService },
{ provide: HttpClient, useValue: mockHttpClient }
]
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it('should render title', async () => {
const fixture = TestBed.createComponent(App);
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('LMNP Organizer');
});
it('should return login status based on OAuthService', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
mockOAuthService.hasValidAccessToken = () => true;
expect(app.isLoggedIn).toBe(true);
mockOAuthService.hasValidAccessToken = () => false;
expect(app.isLoggedIn).toBe(false);
});
it('should return username and email from identity claims', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
// Default username when no claims
expect(app.username).toBe('');
// Custom claims
mockOAuthService.getIdentityClaims = () => ({
preferred_username: 'Alice',
email: 'alice@example.com'
});
expect(app.username).toBe('Alice');
expect(app.email).toBe('alice@example.com');
});
it('should invoke OIDC login and logout flows', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
const loginSpy = vi.spyOn(mockOAuthService, 'initCodeFlow');
const logoutSpy = vi.spyOn(mockOAuthService, 'revokeTokenAndLogout');
app.login();
expect(loginSpy).toHaveBeenCalled();
app.logout();
expect(logoutSpy).toHaveBeenCalled();
});
it('should call hello API and set message on success', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
app.callHelloApi();
expect(app.helloMessage()).toBe('Hello from mocked API!');
});
it('should call hello API and handle error', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
mockHttpClient.get = () => throwError(() => ({ statusText: 'Unauthorized' }));
app.callHelloApi();
expect(app.helloMessage()).toBe('Failed to connect to backend: Unauthorized');
});
it('should render logged in state when user is authenticated', async () => {
const fixture = TestBed.createComponent(App);
// Log in
mockOAuthService.hasValidAccessToken = () => true;
mockOAuthService.getIdentityClaims = () => ({
preferred_username: 'Alice',
email: 'alice@example.com'
});
fixture.detectChanges();
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.user-details h3')?.textContent).toContain('Alice');
expect(compiled.querySelector('.user-email')?.textContent).toContain('alice@example.com');
});
it('should render hello API response when API button is clicked', async () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
// Log in
mockOAuthService.hasValidAccessToken = () => true;
mockOAuthService.getIdentityClaims = () => ({
preferred_username: 'Alice',
email: 'alice@example.com'
});
fixture.detectChanges();
await fixture.whenStable();
// Click button
const compiled = fixture.nativeElement as HTMLElement;
const button = compiled.querySelector('.api-actions button') as HTMLButtonElement;
button.click();
fixture.detectChanges();
await fixture.whenStable();
// Verify response message is shown
expect(app.helloMessage()).toBe('Hello from mocked API!');
fixture.detectChanges();
expect(compiled.querySelector('.api-response-code')?.textContent).toContain('Hello from mocked API!');
});
});