153 lines
4.7 KiB
TypeScript
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!');
|
|
});
|
|
});
|