Scaffold backend/frontend services, OIDC auth, and compose.yml
This commit is contained in:
1 parent
71a2b3081f
commit
bdc2e1bc57
41 files changed
+3223
No files matched your search
@@ -0,0 +1,153 @@
|
||||
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: () => {},
|
||||
logOut: () => {}
|
||||
};
|
||||
|
||||
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, 'logOut');
|
||||
|
||||
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);
|
||||
const app = fixture.componentInstance;
|
||||
|
||||
// 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!');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user