fix(product-attribute-selector): improve variant availability logic and add tests for maximum quantity handling
This commit is contained in:
parent
d601cc1984
commit
985316d3b4
|
|
@ -51,6 +51,39 @@ describe('ProductAttributeSelectorComponent', () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it.each([0, 2, null])(
|
||||||
|
'uses maximum quantity %s for alternatives to a preselected option',
|
||||||
|
(maximum) => {
|
||||||
|
const fixture = TestBed.createComponent(ProductAttributeSelectorComponent);
|
||||||
|
const variants: CatalogItemVariant[] = [
|
||||||
|
{ id: 1, maximum_addable_quantity: 3, values: { size: { value: 'S', label: 'Small' } } },
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
maximum_addable_quantity: maximum,
|
||||||
|
values: { size: { value: 'M', label: 'Medium' } },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const emittedIds: Array<number | null> = [];
|
||||||
|
fixture.componentInstance.variantChange.subscribe((variant) =>
|
||||||
|
emittedIds.push(variant?.id ?? null),
|
||||||
|
);
|
||||||
|
fixture.componentRef.setInput('attributes', [sizeAttribute]);
|
||||||
|
fixture.componentRef.setInput('inventoryPolicy', maximum === null ? 'unlimited' : 'tracked');
|
||||||
|
fixture.componentRef.setInput('variants', variants);
|
||||||
|
fixture.componentRef.setInput('selectedVariant', variants[0]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const buttons = fixture.nativeElement.querySelectorAll(
|
||||||
|
'.attribute-selector__text-option',
|
||||||
|
) as NodeListOf<HTMLButtonElement>;
|
||||||
|
expect(buttons[1].disabled).toBe(maximum === 0);
|
||||||
|
buttons[1].click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(emittedIds.at(-1)).toBe(maximum === 0 ? 1 : 2);
|
||||||
|
expect(buttons[0].disabled).toBe(false);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it('keeps an unlimited option available when maximum quantity is null', () => {
|
it('keeps an unlimited option available when maximum quantity is null', () => {
|
||||||
const fixture = TestBed.createComponent(ProductAttributeSelectorComponent);
|
const fixture = TestBed.createComponent(ProductAttributeSelectorComponent);
|
||||||
fixture.componentRef.setInput('attributes', [sizeAttribute]);
|
fixture.componentRef.setInput('attributes', [sizeAttribute]);
|
||||||
|
|
|
||||||
|
|
@ -51,22 +51,15 @@ export class ProductAttributeSelectorComponent {
|
||||||
const optionNormalized = this.normalizeText(option.value || option.label);
|
const optionNormalized = this.normalizeText(option.value || option.label);
|
||||||
const selectedForAttribute = selections[attribute.codigo] ?? [];
|
const selectedForAttribute = selections[attribute.codigo] ?? [];
|
||||||
|
|
||||||
if (
|
|
||||||
!attribute.allow_multi_select &&
|
|
||||||
selectedForAttribute.length >= 1 &&
|
|
||||||
!selectedForAttribute.includes(option.id)
|
|
||||||
) {
|
|
||||||
availability[attribute.codigo][option.id] = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isAvailable = variants.some((variant) => {
|
const isAvailable = variants.some((variant) => {
|
||||||
if (!this.isVariantAvailable(variant)) return false;
|
if (!this.isVariantAvailable(variant)) return false;
|
||||||
|
|
||||||
const variantAttrValues = this.getVariantAttributeValues(attribute, variant.values);
|
const variantAttrValues = this.getVariantAttributeValues(attribute, variant.values);
|
||||||
const desiredOptionIds = selectedForAttribute.includes(option.id)
|
const desiredOptionIds = !attribute.allow_multi_select
|
||||||
? selectedForAttribute
|
? [option.id]
|
||||||
: [...selectedForAttribute, option.id];
|
: selectedForAttribute.includes(option.id)
|
||||||
|
? selectedForAttribute
|
||||||
|
: [...selectedForAttribute, option.id];
|
||||||
const desiredValues = desiredOptionIds
|
const desiredValues = desiredOptionIds
|
||||||
.map((id) => attribute.options.find((candidate) => candidate.id === id))
|
.map((id) => attribute.options.find((candidate) => candidate.id === id))
|
||||||
.filter((candidate): candidate is ProductAttributeOption => candidate !== undefined)
|
.filter((candidate): candidate is ProductAttributeOption => candidate !== undefined)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue