345 lines
11 KiB
TypeScript
345 lines
11 KiB
TypeScript
import { signal } from '@angular/core';
|
|
import { TestBed, getTestBed } from '@angular/core/testing';
|
|
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
|
|
import { of } from 'rxjs';
|
|
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { ModalService } from '../../../../core/services/modal.service';
|
|
import { Tenant } from '../../../../core/services/tenant.interface';
|
|
import { TenantService } from '../../../../core/services/tenant.service';
|
|
import { ToastService } from '../../../../core/services/toast.service';
|
|
import { ReutilizablesTestPageComponent } from './reutilizables-test-page.component';
|
|
|
|
const tenant: Tenant = {
|
|
id: 1,
|
|
codigo: 'test',
|
|
nombre: 'Test Tenant',
|
|
dominio: 'localhost',
|
|
primary_color: '#6376F3',
|
|
secondary_color: '#A0A0A0',
|
|
danger_color: '#FF8888',
|
|
success_color: '#198754',
|
|
header_bg_color: '#313131',
|
|
footer_bg_color: '#313131',
|
|
header_logo: 'https://example.com/header.png',
|
|
footer_logo: 'https://example.com/footer.png',
|
|
};
|
|
|
|
function createTenantServiceStub(currentTenant: Tenant | null) {
|
|
const tenantState = signal(currentTenant);
|
|
const statusState = signal<'ready' | 'not-found'>('ready');
|
|
|
|
return {
|
|
tenant: tenantState.asReadonly(),
|
|
status: statusState.asReadonly(),
|
|
getTenant: () => tenantState(),
|
|
bootstrap: vi.fn().mockResolvedValue(undefined),
|
|
};
|
|
}
|
|
|
|
function createToastServiceStub() {
|
|
return {
|
|
success: vi.fn(),
|
|
danger: vi.fn(),
|
|
info: vi.fn(),
|
|
};
|
|
}
|
|
|
|
function createModalServiceStub() {
|
|
return {
|
|
open: vi.fn(),
|
|
openConfirm: vi.fn().mockReturnValue(of(true)),
|
|
openConfirmDelete: vi.fn().mockReturnValue(of(false)),
|
|
};
|
|
}
|
|
|
|
describe('ReutilizablesTestPageComponent', () => {
|
|
beforeAll(() => {
|
|
try {
|
|
getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting());
|
|
} catch {
|
|
// Test environment may already be initialized by another setup entrypoint.
|
|
}
|
|
});
|
|
|
|
afterEach(() => {
|
|
TestBed.resetTestingModule();
|
|
});
|
|
|
|
it('renders the tenant configuration section with logo sources and swatch colors', async () => {
|
|
const modalServiceStub = createModalServiceStub();
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: modalServiceStub,
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
const sectionTitle = element.querySelector('.configuracion-tennant h2');
|
|
|
|
expect(sectionTitle?.textContent).toContain('Configuracion Tenant');
|
|
|
|
const headerImg = element.querySelector(
|
|
'.tenant-logo-card img[alt="Header Logo"]',
|
|
) as HTMLImageElement;
|
|
expect(headerImg?.src).toBe(tenant.header_logo);
|
|
|
|
const footerImg = element.querySelector(
|
|
'.tenant-logo-card img[alt="Footer Logo"]',
|
|
) as HTMLImageElement;
|
|
expect(footerImg?.src).toBe(tenant.footer_logo);
|
|
|
|
expect(element.textContent).toContain(tenant.primary_color);
|
|
expect(element.textContent).toContain(tenant.secondary_color);
|
|
expect(element.textContent).toContain(tenant.danger_color);
|
|
expect(element.textContent).toContain(tenant.success_color);
|
|
});
|
|
|
|
it('renders the paginator demo with the initial page status', async () => {
|
|
const modalServiceStub = createModalServiceStub();
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: modalServiceStub,
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
|
|
expect(element.querySelector('app-paginator')).not.toBeNull();
|
|
expect(element.querySelector('[data-testid="paginator-status"]')?.textContent?.trim()).toBe(
|
|
'1/8',
|
|
);
|
|
});
|
|
|
|
it('renders the reusable map demo with all configured locations', async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: createModalServiceStub(),
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const mapDemo = fixture.nativeElement.querySelector(
|
|
'[data-testid="location-map-demo"]',
|
|
) as HTMLElement;
|
|
const accessibleLocations = mapDemo.querySelectorAll('app-location-map .visually-hidden li');
|
|
|
|
expect(mapDemo.querySelector('app-location-map')).not.toBeNull();
|
|
expect(accessibleLocations).toHaveLength(3);
|
|
expect(mapDemo.textContent).toContain('Gigante de Arroyito');
|
|
|
|
fixture.destroy();
|
|
});
|
|
|
|
it('renders the carousel demo with mocked product images', async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: createModalServiceStub(),
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
const carouselDemo = element.querySelector('[data-testid="products-carousel"]');
|
|
const carouselItems = carouselDemo?.querySelectorAll('[data-carousel-index]');
|
|
const productImages = carouselDemo?.querySelectorAll('app-product-column-with-image img');
|
|
|
|
expect(carouselDemo?.querySelector('app-carousel')).not.toBeNull();
|
|
expect(carouselItems).toHaveLength(6);
|
|
expect(productImages).toHaveLength(6);
|
|
expect(productImages?.[0].getAttribute('src')).toContain('/images/carousel-mochila-roja.webp');
|
|
expect(productImages?.[1].getAttribute('src')).toContain(
|
|
'/images/carousel-auriculares-amarillos.webp',
|
|
);
|
|
expect(
|
|
new Set(Array.from(productImages ?? [], (image) => image.getAttribute('src'))).size,
|
|
).toBe(6);
|
|
});
|
|
|
|
it('renders the main carousel demo with remote images', async () => {
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: createModalServiceStub(),
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
const carouselDemo = element.querySelector('[data-testid="main-carousel"]');
|
|
const images = carouselDemo?.querySelectorAll('.main-carousel__image');
|
|
const indicators = carouselDemo?.querySelectorAll('.main-carousel__indicator');
|
|
|
|
expect(carouselDemo?.querySelector('app-main-carousel')).not.toBeNull();
|
|
expect(images).toHaveLength(3);
|
|
expect(indicators).toHaveLength(3);
|
|
expect(images?.[0].getAttribute('src')).toContain('images.unsplash.com');
|
|
|
|
fixture.destroy();
|
|
});
|
|
|
|
it('renders the modal showcase and opens the confirm demos from the buttons', async () => {
|
|
const modalServiceStub = createModalServiceStub();
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: modalServiceStub,
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
const buttons = Array.from(element.querySelectorAll('.button-group app-button button'));
|
|
const confirmButton = buttons.find((button) =>
|
|
button.textContent?.includes('Abrir confirm modal'),
|
|
) as HTMLButtonElement;
|
|
const deleteButton = buttons.find((button) =>
|
|
button.textContent?.includes('Abrir confirm delete'),
|
|
) as HTMLButtonElement;
|
|
|
|
expect(element.querySelector('[data-testid="modal-last-result"]')?.textContent).toContain(
|
|
'Todavia no se abrio ningun modal.',
|
|
);
|
|
|
|
confirmButton.click();
|
|
fixture.detectChanges();
|
|
deleteButton.click();
|
|
fixture.detectChanges();
|
|
|
|
expect(modalServiceStub.openConfirm).toHaveBeenCalledWith({
|
|
title: 'Confirmar accion',
|
|
content: 'Caso base para verificar apertura, cierre y devolucion de resultado.',
|
|
confirmLabel: 'Confirmar',
|
|
});
|
|
expect(modalServiceStub.openConfirmDelete).toHaveBeenCalledWith({
|
|
title: 'Eliminar producto',
|
|
content:
|
|
'Esta accion eliminara el producto del catalogo. Podras volver a crearlo manualmente.',
|
|
confirmLabel: 'Eliminar',
|
|
});
|
|
expect(element.querySelector('[data-testid="modal-last-result"]')?.textContent).toContain(
|
|
'Resultado: false',
|
|
);
|
|
});
|
|
|
|
it('updates the visible result when the confirm modal resolves to true', async () => {
|
|
const modalServiceStub = createModalServiceStub();
|
|
await TestBed.configureTestingModule({
|
|
imports: [ReutilizablesTestPageComponent],
|
|
providers: [
|
|
{
|
|
provide: TenantService,
|
|
useValue: createTenantServiceStub(tenant),
|
|
},
|
|
{
|
|
provide: ToastService,
|
|
useValue: createToastServiceStub(),
|
|
},
|
|
{
|
|
provide: ModalService,
|
|
useValue: modalServiceStub,
|
|
},
|
|
],
|
|
}).compileComponents();
|
|
|
|
const fixture = TestBed.createComponent(ReutilizablesTestPageComponent);
|
|
fixture.detectChanges();
|
|
|
|
const element = fixture.nativeElement as HTMLElement;
|
|
const confirmButton = Array.from(
|
|
element.querySelectorAll('.button-group app-button button'),
|
|
).find((button) => button.textContent?.includes('Abrir confirm modal')) as HTMLButtonElement;
|
|
|
|
confirmButton.click();
|
|
fixture.detectChanges();
|
|
|
|
expect(element.querySelector('[data-testid="modal-last-result"]')?.textContent).toContain(
|
|
'Resultado: true',
|
|
);
|
|
});
|
|
});
|