import { signal } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { provideRouter, Router } from '@angular/router'; import { App } from './app'; import { routes } from './app.routes'; import { Tenant } from './core/services/tenant.interface'; import { TenantService } from './core/services/tenant.service'; const tenant: Tenant = { id: 1, codigo: 'test', nombre: 'Test Tenant', dominio: 'localhost', primary_color: '#6376F3', secondary_color: '#A0A0A0', danger_color: '#FF8888', header_footer_bg_color: '#313131', header_logo: 'https://example.com/header.png', footer_logo: 'https://example.com/footer.png' }; function createTenantServiceStub( status: 'ready' | 'not-found' = 'ready', currentTenant: Tenant | null = tenant ) { const tenantState = signal(currentTenant); const statusState = signal(status); return { tenant: tenantState.asReadonly(), status: statusState.asReadonly(), getTenant: () => tenantState(), getTenantApiUrl: () => { const tenantVal = tenantState(); if (!tenantVal) { throw new Error('No se pudo resolver el tenant activo.'); } return `http://localhost:8000/api/tenants/${tenantVal.codigo}`; }, bootstrap: vi.fn().mockResolvedValue(undefined) }; } async function renderAppAt( url: string, tenantService: ReturnType = createTenantServiceStub() ) { TestBed.resetTestingModule(); await TestBed.configureTestingModule({ imports: [App], providers: [ provideRouter(routes), { provide: TenantService, useValue: tenantService } ] }).compileComponents(); const router = TestBed.inject(Router); const fixture = TestBed.createComponent(App); fixture.detectChanges(); await router.navigateByUrl(url); await fixture.whenStable(); fixture.detectChanges(); return { fixture, router }; } describe('app routes', () => { it('loads the store layout at /', async () => { const { fixture, router } = await renderAppAt('/'); const compiled = fixture.nativeElement as HTMLElement; expect(router.url).toBe('/'); expect(compiled.querySelector('.store-layout')).not.toBeNull(); expect(compiled.querySelector('app-store-home-page')).not.toBeNull(); expect(compiled.textContent).toContain('Productos'); expect(compiled.style.getPropertyValue('--tenant-primary')).toBe(tenant.primary_color); }); it('loads componentes-test under a valid tenant', async () => { const { fixture, router } = await renderAppAt('/'); await router.navigateByUrl('/componentes-test/reutilizables'); await fixture.whenStable(); fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; expect(router.url).toBe('/componentes-test/reutilizables'); expect(compiled.textContent).toContain('Componentes reutilizables'); }); it('renders the tenant not found screen for any route when the tenant is missing', async () => { const { fixture } = await renderAppAt( '/componentes-test/reutilizables', createTenantServiceStub('not-found', null) ); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('.tenant-status')).not.toBeNull(); expect(compiled.textContent).toContain('No encontramos una tienda para este dominio'); }); });