feat(cart): prevent automatic variant replacement and handle selection errors
This commit is contained in:
parent
4923010afb
commit
de10de2376
|
|
@ -31,8 +31,9 @@
|
||||||
class="cart-item-variant-selector"
|
class="cart-item-variant-selector"
|
||||||
[variants]="variants()"
|
[variants]="variants()"
|
||||||
[selectedVariant]="selectedVariant()"
|
[selectedVariant]="selectedVariant()"
|
||||||
|
[autoSelectFirst]="false"
|
||||||
[compact]="true"
|
[compact]="true"
|
||||||
(selectedVariantChange)="onVariantChange($event)"
|
(selectionValuesChange)="onVariantChange($event.selectedVariant)"
|
||||||
/>
|
/>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="d-grid cart-item-attributes">
|
<div class="d-grid cart-item-attributes">
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ import { signal } from '@angular/core';
|
||||||
import { TestBed, getTestBed } from '@angular/core/testing';
|
import { TestBed, getTestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
|
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, Subject, throwError } from 'rxjs';
|
||||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { CartService } from '../../../core/services/cart/cart.service';
|
import { CartService } from '../../../core/services/cart/cart.service';
|
||||||
import { ModalService } from '../../../core/services/modal.service';
|
import { ModalService } from '../../../core/services/modal.service';
|
||||||
import { ToastService } from '../../../core/services/toast.service';
|
import { ToastService } from '../../../core/services/toast.service';
|
||||||
import { CartComponent } from './cart.component';
|
import { CartComponent } from './cart.component';
|
||||||
|
import { VariantSelectorComponent } from '../variant-selector/variant-selector.component';
|
||||||
|
|
||||||
describe('CartComponent', () => {
|
describe('CartComponent', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
|
|
@ -22,6 +23,7 @@ describe('CartComponent', () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
TestBed.resetTestingModule();
|
TestBed.resetTestingModule();
|
||||||
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows an empty cart message when there are no items', async () => {
|
it('shows an empty cart message when there are no items', async () => {
|
||||||
|
|
@ -565,6 +567,57 @@ describe('CartComponent', () => {
|
||||||
expect(quantityChange).not.toHaveBeenCalled();
|
expect(quantityChange).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not automatically replace an unavailable variant or retry a rejected selection', async () => {
|
||||||
|
const response = new Subject<unknown>();
|
||||||
|
const updateItemVariant = vi.fn().mockReturnValue(response);
|
||||||
|
const danger = vi.fn();
|
||||||
|
vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [CartComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: CartService, useValue: { cart: signal(null), updateItemVariant } },
|
||||||
|
{ provide: ModalService, useValue: {} },
|
||||||
|
{ provide: ToastService, useValue: { success: vi.fn(), danger } },
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
const fixture = TestBed.createComponent(CartComponent);
|
||||||
|
const item = {
|
||||||
|
cartItemId: 10,
|
||||||
|
imageUrl: null,
|
||||||
|
product: 'Entrada',
|
||||||
|
originalPrice: null,
|
||||||
|
discountedPrice: 1000,
|
||||||
|
discountPercentage: null,
|
||||||
|
attributes: [],
|
||||||
|
quantity: 2,
|
||||||
|
variantId: 20,
|
||||||
|
variants: [{ id: 20, values: { fecha: '09/10' } }],
|
||||||
|
};
|
||||||
|
fixture.componentRef.setInput('items', [item]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const rescheduledItem = {
|
||||||
|
...item, variants: [{ id: 21, values: { fecha: '20/10' } }],
|
||||||
|
};
|
||||||
|
fixture.componentRef.setInput('items', [rescheduledItem]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(updateItemVariant).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
const selector = fixture.debugElement.query(By.directive(VariantSelectorComponent));
|
||||||
|
(selector.componentInstance as any).onValueChange('fecha', '20/10');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(updateItemVariant).toHaveBeenCalledExactlyOnceWith(10, 2, 21);
|
||||||
|
|
||||||
|
response.error({ status: 422, error: { message: 'Variante no disponible.' } });
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.componentRef.setInput('items', [{
|
||||||
|
...rescheduledItem, variants: [...rescheduledItem.variants],
|
||||||
|
}]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(updateItemVariant).toHaveBeenCalledTimes(1);
|
||||||
|
expect(danger).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
it('persists a variant selected from a cart row', async () => {
|
it('persists a variant selected from a cart row', async () => {
|
||||||
const updateItemVariant = vi.fn().mockReturnValue(
|
const updateItemVariant = vi.fn().mockReturnValue(
|
||||||
of({
|
of({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue