blob: bd503f386df6755ec317673887f55e749b326a5d [file] [edit]
import '@angular/compiler';
import { Injector, runInInjectionContext, signal, WritableSignal } from '@angular/core';
import { HeaderComponent, DOCUMENTATION_URL, BUG_REPORT_URL } from './header.component';
import { GatewayService } from '../gateway/gateway.service';
import { ThemeService } from '../theme/theme.service';
import { assert } from 'chai';
import * as sinon from 'sinon';
describe('HeaderComponent', () => {
let stubConsoleError: sinon.SinonStub;
let openStub: sinon.SinonStub;
let mockIsDarkMode: WritableSignal<boolean>;
let toggleThemeSpy: sinon.SinonSpy;
beforeEach(() => {
stubConsoleError = sinon.stub(console, 'error');
openStub = sinon.stub(window, 'open');
mockIsDarkMode = signal<boolean>(false);
toggleThemeSpy = sinon.spy();
});
afterEach(() => {
stubConsoleError.restore();
openStub.restore();
});
function createHeaderComponent(mockGateway?: Partial<GatewayService>): HeaderComponent {
const gateway = mockGateway || {
GetUserInfo: async () => ({ email: 'somebody@google.com' }),
};
const mockThemeService: Partial<ThemeService> = {
isDarkMode: mockIsDarkMode,
toggleTheme: toggleThemeSpy,
};
const injector = Injector.create({
providers: [
{ provide: GatewayService, useValue: gateway },
{ provide: ThemeService, useValue: mockThemeService },
],
});
let component!: HeaderComponent;
runInInjectionContext(injector, () => {
component = new HeaderComponent();
});
return component;
}
it('should set userEmail when GetUserInfo succeeds', async () => {
const component = createHeaderComponent();
await component.ngOnInit();
assert.equal(component.userEmail(), 'somebody@google.com');
});
it('should set userEmail to "Unknown user" when GetUserInfo returns no email', async () => {
const component = createHeaderComponent({
GetUserInfo: async () => ({ email: '' }),
});
await component.ngOnInit();
assert.equal(component.userEmail(), 'Unknown user');
});
it('should log an error and set userEmail to an error when GetUserInfo fails', async () => {
const testError = new Error('Network Error');
const component = createHeaderComponent({
GetUserInfo: async () => {
throw testError;
},
});
await component.ngOnInit();
assert.equal(component.userEmail(), 'Error loading user');
assert.isTrue(stubConsoleError.calledOnceWithExactly('Failed to load user info:', testError));
});
it('should redirect to the proxy logout URL on sign out click', () => {
const component = createHeaderComponent();
let redirectedUrl = '';
component.redirect = (url: string) => {
redirectedUrl = url;
};
component.onSignOutClick();
assert.equal(redirectedUrl, `/logout/?redirect=${encodeURIComponent(window.location.origin)}`);
});
it('should open documentation on help click', () => {
const component = createHeaderComponent();
component.onHelpClick();
assert.isTrue(openStub.calledOnceWithExactly(DOCUMENTATION_URL, '_blank'));
});
it('should open buganizer on bug click', () => {
const component = createHeaderComponent();
component.onBugClick();
assert.isTrue(openStub.calledOnceWithExactly(BUG_REPORT_URL, '_blank'));
});
describe('theme toggle', () => {
it('should toggle theme when toggleTheme is called', () => {
const component = createHeaderComponent();
component.toggleTheme();
assert.isTrue(toggleThemeSpy.calledOnce);
});
it('should expose isDarkMode signal from ThemeService', () => {
const component = createHeaderComponent();
assert.isFalse(component.isDarkMode());
mockIsDarkMode.set(true);
assert.isTrue(component.isDarkMode());
});
});
});