test(ticket-selector): cover compact option responses

This commit is contained in:
2026-08-14 10:15:01 -03:00
parent f7983b109f
commit 46dcb84985
2 changed files with 69 additions and 33 deletions

View File

@@ -1,6 +1,7 @@
import { TestBed, getTestBed } from '@angular/core/testing'; import { TestBed, getTestBed } from '@angular/core/testing';
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
import { of } from 'rxjs';
import { ApiPaginatedResponse } from '../../../core/services/api-paginated-response.interface'; import { ApiPaginatedResponse } from '../../../core/services/api-paginated-response.interface';
import { CartService } from '../../../core/services/cart/cart.service'; import { CartService } from '../../../core/services/cart/cart.service';
@@ -53,10 +54,26 @@ describe('ProductListComponent', () => {
productItems: CatalogFeaturedItems = paginatedItems(), productItems: CatalogFeaturedItems = paginatedItems(),
groupLayout: CatalogGroupLayout = 'paginated', groupLayout: CatalogGroupLayout = 'paginated',
) { ) {
const getVariantOptions = vi.fn().mockReturnValue(
of({
selectors: ['tipo', 'sector', 'fila', 'asiento'].map((key, index) => ({
key,
label: key,
options: [{ value: String(index + 1), label: String(index + 1) }],
enabled: index === 0,
})),
selected_values: {},
resolved_variant: null,
valid: true,
available_variant_count: 2,
matching_variant_count: 2,
price_range: { minimum: '10000.00', maximum: '12000.00' },
}),
);
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ProductListComponent], imports: [ProductListComponent],
providers: [ providers: [
{ provide: CatalogService, useValue: {} }, { provide: CatalogService, useValue: { getVariantOptions } },
{ provide: CartService, useValue: {} }, { provide: CartService, useValue: {} },
], ],
}).compileComponents(); }).compileComponents();
@@ -307,23 +324,20 @@ describe('ProductListComponent', () => {
}); });
}); });
it('removes unavailable variants from the ticket selector', async () => { it('loads ticket selector availability without requiring catalog variants', async () => {
const ticket: ProductListItem = { const ticket: ProductListItem = {
...items[0], ...items[0],
variants: [ variants: undefined,
{ id: 401, stock_tecnico: 1, values: { asiento: { value: '1', label: '1' } } },
{ id: 402, stock_tecnico: 1, values: { asiento: { value: '2', label: '2' } } },
],
}; };
const fixture = await render('ticket_selector', [ticket], 'single'); const fixture = await render('ticket_selector', [ticket], 'single');
fixture.componentRef.setInput('unavailableVariantIds', new Set([401]));
await fixture.whenStable(); await fixture.whenStable();
fixture.detectChanges(); fixture.detectChanges();
const selector = fixture.debugElement.query(By.directive(ProductTicketSelectorComponent)) const selector = fixture.debugElement.query(By.directive(ProductTicketSelectorComponent))
.componentInstance as ProductTicketSelectorComponent; .componentInstance as ProductTicketSelectorComponent;
expect(selector['selectableVariants']().map((variant) => variant.id)).toEqual([402]); expect(selector['availableVariantCount']()).toBe(2);
expect(fixture.nativeElement.querySelectorAll('.variant-selector__select')).toHaveLength(4);
}); });
it('renders carousel groups with the reusable carousel', async () => { it('renders carousel groups with the reusable carousel', async () => {

View File

@@ -20,33 +20,59 @@ describe('ProductTicketSelectorComponent', () => {
afterEach(() => TestBed.resetTestingModule()); afterEach(() => TestBed.resetTestingModule());
it('checks partial selections and reserves the resolved variant in the cart', async () => { it('checks partial selections and reserves the resolved variant in the cart', async () => {
const variants = [ const resolvedVariant = {
{ id: 401,
id: 401, precio: '10000.00',
precio: '10000.00', stock_tecnico: 1,
stock_tecnico: 1, values: { sector: { value: 'a', label: 'Sector A' }, seat: '1' },
values: { sector: { value: 'a', label: 'Sector A' }, seat: '1' }, };
}, const summary = {
]; valid: true,
available_variant_count: 1,
matching_variant_count: 1,
price_range: { minimum: '10000.00', maximum: '10000.00' },
};
const catalogService = { const catalogService = {
getVariantOptions: vi getVariantOptions: vi
.fn() .fn()
.mockReturnValueOnce( .mockReturnValueOnce(
of({ of({
variants, ...summary,
options: { seat: ['1'] }, selectors: [
selected_values: { sector: 'a' }, {
resolved_variant_id: null, key: 'sector',
valid: true, label: 'Sector',
options: [{ value: 'a', label: 'Sector A' }],
enabled: true,
},
{ key: 'seat', label: 'Seat', options: ['1'], enabled: false },
],
selected_values: {},
resolved_variant: null,
}), }),
) )
.mockReturnValueOnce( .mockReturnValueOnce(
of({ of({
variants, ...summary,
options: { seat: ['1'] }, selectors: [
{
key: 'sector',
label: 'Sector',
options: [{ value: 'a', label: 'Sector A' }],
enabled: true,
},
{ key: 'seat', label: 'Seat', options: ['1'], enabled: true },
],
selected_values: { sector: 'a' },
resolved_variant: null,
}),
)
.mockReturnValueOnce(
of({
...summary,
selectors: [],
selected_values: { sector: 'a', seat: '1' }, selected_values: { sector: 'a', seat: '1' },
resolved_variant_id: 401, resolved_variant: resolvedVariant,
valid: true,
}), }),
), ),
}; };
@@ -82,12 +108,11 @@ describe('ProductTicketSelectorComponent', () => {
const fixture = TestBed.createComponent(ProductTicketSelectorComponent); const fixture = TestBed.createComponent(ProductTicketSelectorComponent);
fixture.componentRef.setInput('productId', 7); fixture.componentRef.setInput('productId', 7);
fixture.componentRef.setInput('title', 'Entrada'); fixture.componentRef.setInput('title', 'Entrada');
fixture.componentRef.setInput('variants', variants);
fixture.detectChanges(); fixture.detectChanges();
fixture.componentInstance['onSelectionChange'](1, { fixture.componentInstance['onSelectionChange'](1, 'sector', {
values: { sector: { value: 'a', label: 'Sector A' } }, value: 'a',
selectedVariant: null, label: 'Sector A',
}); });
expect(catalogService.getVariantOptions).toHaveBeenLastCalledWith(7, { expect(catalogService.getVariantOptions).toHaveBeenLastCalledWith(7, {
@@ -96,10 +121,7 @@ describe('ProductTicketSelectorComponent', () => {
}); });
expect(fixture.componentInstance['rows']()[0].status).toBe('selecting'); expect(fixture.componentInstance['rows']()[0].status).toBe('selecting');
fixture.componentInstance['onSelectionChange'](1, { fixture.componentInstance['onSelectionChange'](1, 'seat', '1');
values: { sector: { value: 'a', label: 'Sector A' }, seat: '1' },
selectedVariant: 401,
});
expect(cartService.addItem).toHaveBeenCalledWith(7, 401, 1); expect(cartService.addItem).toHaveBeenCalledWith(7, 401, 1);
expect(fixture.componentInstance['rows']()[0]).toMatchObject({ expect(fixture.componentInstance['rows']()[0]).toMatchObject({