fix(product-attribute-selector): update variant values type and normalize value extraction

This commit is contained in:
ncoronel 2026-09-04 11:36:13 -03:00
parent 70d47ac310
commit d601cc1984
3 changed files with 43 additions and 5 deletions

View File

@ -72,7 +72,7 @@ export interface CatalogItemVariant {
maximum_use_date?: string | null;
effective_minimum_use_date?: string | null;
effective_maximum_use_date?: string | null;
values: Record<string, string | string[]>;
values: Record<string, CatalogVariantValue>;
}
export interface SelectedCatalogItemVariant extends CatalogItemVariant {

View File

@ -1,7 +1,10 @@
import { TestBed } from '@angular/core/testing';
import { beforeEach, describe, expect, it } from 'vitest';
import { ProductAttribute } from '../../../../core/services/catalog/catalog.interface';
import {
CatalogItemVariant,
ProductAttribute,
} from '../../../../core/services/catalog/catalog.interface';
import { ProductAttributeSelectorComponent } from './product-attribute-selector.component';
describe('ProductAttributeSelectorComponent', () => {
@ -24,6 +27,30 @@ describe('ProductAttributeSelectorComponent', () => {
}).compileComponents();
});
it.each([{ size: { value: 'S', label: 'Small' } }, { size: [{ value: 'S', label: 'Small' }] }])(
'initializes and matches structured variant values: %j',
(values) => {
const fixture = TestBed.createComponent(ProductAttributeSelectorComponent);
const variant: CatalogItemVariant = { id: 1, maximum_addable_quantity: null, values };
const emittedIds: Array<number | null> = [];
fixture.componentInstance.variantChange.subscribe((selected) =>
emittedIds.push(selected?.id ?? null),
);
fixture.componentRef.setInput('attributes', [sizeAttribute]);
fixture.componentRef.setInput('inventoryPolicy', 'unlimited');
fixture.componentRef.setInput('variants', [variant]);
fixture.componentRef.setInput('selectedVariant', variant);
fixture.detectChanges();
const button = fixture.nativeElement.querySelector(
'.attribute-selector__text-option',
) as HTMLButtonElement;
expect(button.getAttribute('aria-pressed')).toBe('true');
expect(button.disabled).toBe(false);
expect(emittedIds.at(-1)).toBe(1);
},
);
it('keeps an unlimited option available when maximum quantity is null', () => {
const fixture = TestBed.createComponent(ProductAttributeSelectorComponent);
fixture.componentRef.setInput('attributes', [sizeAttribute]);
@ -94,7 +121,16 @@ describe('ProductAttributeSelectorComponent', () => {
fixture.componentRef.setInput('variants', [
{ id: 1, maximum_addable_quantity: null, values: { event_date: '1' } },
{ id: 2, maximum_addable_quantity: null, values: { event_date: '2' } },
{ id: 3, maximum_addable_quantity: null, values: { event_date: ['1', '2'] } },
{
id: 3,
maximum_addable_quantity: null,
values: {
event_date: [
{ value: '1', label: '09/10/2026' },
{ value: '2', label: '10/10/2026' },
],
},
},
]);
fixture.detectChanges();

View File

@ -202,7 +202,7 @@ export class ProductAttributeSelectorComponent {
private getVariantAttributeValues(
attribute: ProductAttribute,
variantAttributes: Record<string, string | string[]>,
variantAttributes: CatalogItemVariant['values'],
): string[] {
const normalizedCodigo = this.normalizeText(attribute.codigo);
const normalizedNombre = this.normalizeText(attribute.nombre);
@ -211,7 +211,9 @@ export class ProductAttributeSelectorComponent {
const normalizedKey = this.normalizeText(key);
if (normalizedKey === normalizedCodigo || normalizedKey === normalizedNombre) {
return (Array.isArray(value) ? value : [value]).map((item) => this.normalizeText(item));
return (Array.isArray(value) ? value : [value]).map((item) =>
this.normalizeText(typeof item === 'string' ? item : item.value || item.label),
);
}
}