feat: refactor routing and enhance tenant service integration

- Updated app routing to redirect to the store feature and load children routes correctly.
- Enhanced app styles with tenant-specific branding and loading states.
- Improved app component to dynamically set CSS variables based on tenant colors.
- Refactored store layout components to simplify logo handling and improve accessibility.
- Updated tenant service to manage state more effectively and handle SSR scenarios.
- Added tests for tenant service and layout components to ensure proper functionality.
- Introduced a new SSR cache store for tenant state management.
- Enhanced button styles to utilize tenant colors for better branding consistency.
This commit is contained in:
2026-06-26 15:55:45 -03:00
parent 7ee103b77b
commit 86680fc976
22 changed files with 726 additions and 188 deletions

View File

@@ -1,23 +1,72 @@
import { signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { provideRouter } from '@angular/router';
import { App } from './app';
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', currentTenant: Tenant | null) {
const tenantState = signal(currentTenant);
const statusState = signal(status);
return {
tenant: tenantState.asReadonly(),
status: statusState.asReadonly(),
getTenant: () => tenantState(),
bootstrap: vi.fn().mockResolvedValue(undefined)
};
}
describe('App', () => {
beforeEach(async () => {
it('creates the app when the tenant is ready', async () => {
await TestBed.configureTestingModule({
imports: [App],
providers: [
provideRouter([]),
{
provide: TenantService,
useValue: createTenantServiceStub('ready', tenant)
}
]
}).compileComponents();
const fixture = TestBed.createComponent(App);
expect(fixture.componentInstance).toBeTruthy();
expect(fixture.nativeElement.style.getPropertyValue('--tenant-primary')).toBe(
tenant.primary_color
);
});
it('should create the app', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it('renders the tenant not found screen when the tenant is missing', async () => {
await TestBed.configureTestingModule({
imports: [App],
providers: [
provideRouter([]),
{
provide: TenantService,
useValue: createTenantServiceStub('not-found', null)
}
]
}).compileComponents();
it('should render title', async () => {
const fixture = TestBed.createComponent(App);
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('router-outlet')).not.toBeNull();
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('No encontramos una tienda para este dominio');
});
});