import { TestBed } from '@angular/core/testing'; import { provideRouter } from '@angular/router'; import { provideHttpClient } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { of } from 'rxjs'; import { BootstrapConfig } from '../../shared/models/config'; import { CONFIG_PROVIDER } from '../../core/config/config-provider.token'; import { ConfigService } from '../../core/config/config.service'; import { AuthService, AUTH_API_URL } from '@marketplaces/auth'; import { HeaderComponent } from './header.component'; function makeBootstrap(): BootstrapConfig { return { schemaVersion: '1', generatedAt: new Date().toISOString(), tenant: { id: 't1', slug: 't1', code: 't1', host: 'dexar.market', name: 'Dexar', websiteBaseUrl: 'https://dexar.market', builderBaseUrl: 'https://dexar.market', backofficeBaseUrl: 'https://dexar.market', defaultLocale: 'en', supportedLocales: ['en'], defaultCurrency: 'USD', supportedCurrencies: ['USD'], timezone: 'UTC' }, branding: { brandName: 'Dexar', legalName: 'Dexar LLC', logoUrl: 'logo.png', faviconUrl: 'favicon.png' }, theme: { themeId: 'default', mode: 'light', palette: {} as any, typography: {} as any, spacing: {} as any, borderRadiusScale: {}, shadows: {}, iconSet: 'default' }, company: { companyName: 'Dexar LLC', address: { country: 'US', city: 'NY' }, contacts: { email: 'sales@dexar.market' } }, featureFlags: {} as any, apiEndpoints: {} as any, localization: { defaultLocale: 'en', supportedLocales: ['en'], currencyByLocale: {}, dictionaries: [] }, seo: { default: { title: 'Dexar', description: 'Dexar' }, byPageKey: {} }, permissions: { definitions: [], roles: [] }, header: { showLogo: true, showSearch: true, showCategories: true, showLanguages: true, showCart: true, showProfile: true, showWishlist: true, showCompare: true, showRegion: true, sticky: true, layout: 'default' }, navigation: { header: [], footer: [] }, pages: [], } as unknown as BootstrapConfig; } describe('HeaderComponent profile control (login/logout gating regression)', () => { function configure(isAuthenticated: boolean): void { // Full fake - TelegramLoginComponent (rendered inside the profile control) reads // several signals/methods off AuthService directly, not just isAuthenticated. const fakeAuth = { session: () => null, status: () => (isAuthenticated ? 'authenticated' : 'unauthenticated'), isAuthenticated: () => isAuthenticated, showLoginDialog: () => false, displayName: () => null, requestLogin: jasmine.createSpy('requestLogin'), logout: jasmine.createSpy('logout'), hideLogin: jasmine.createSpy('hideLogin'), createWebSession: () => of({ webSessionID: 'x', botLoginUrl: '' }), checkSessionOnce: () => of(null), getTelegramAppLoginUrl: () => '', onTelegramLoginComplete: jasmine.createSpy('onTelegramLoginComplete'), }; TestBed.configureTestingModule({ providers: [ provideRouter([]), provideHttpClient(), provideHttpClientTesting(), { provide: CONFIG_PROVIDER, useValue: { loadBootstrap: () => of(makeBootstrap()) } }, { provide: AUTH_API_URL, useValue: 'https://test.local' }, { provide: AuthService, useValue: fakeAuth }, ], }); // Deterministically prime the bootstrap snapshot before component creation - // resolveHeaderConfig() reads getBootstrapSnapshot() synchronously and falls // back to DEFAULT_HEADER_CONFIG (showProfile: false) if it isn't populated yet. TestBed.inject(ConfigService).loadBootstrap().subscribe(); } it('shows a login button (not logout) when logged out', () => { configure(false); const fixture = TestBed.createComponent(HeaderComponent); fixture.detectChanges(); // Aria-labels render translated text (Russian by default), so assert on the // icon name attribute instead - stable regardless of active language. const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('app-icon[name="user"]')).toBeTruthy(); expect(compiled.querySelector('app-icon[name="logOut"]')).toBeFalsy(); }); it('shows a logout button (not login) when logged in - never both', () => { configure(true); const fixture = TestBed.createComponent(HeaderComponent); fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('app-icon[name="logOut"]')).toBeTruthy(); expect(compiled.querySelector('app-icon[name="user"]')).toBeFalsy(); }); });