feat(checkout): add error handling for expired purchases in checkout process

This commit is contained in:
2026-08-21 10:10:20 -03:00
parent b14f34d3e8
commit 9b69a1d387
7 changed files with 155 additions and 329 deletions

View File

@@ -9,17 +9,17 @@
@if (
allowModify() &&
(!readonly() || showModifyWhenReadonly()) &&
requireEditingMode() &&
(requireEditingMode() || modifyAsAction()) &&
items().length > 0
) {
<button
class="btn btn-link p-0 border-0 cart-edit-btn"
type="button"
[attr.aria-pressed]="editing()"
[attr.aria-pressed]="modifyAsAction() ? null : editing()"
[disabled]="editingDisabled()"
(click)="toggleEditing()"
>
{{ editing() ? 'Listo' : 'Modificar' }}
{{ !modifyAsAction() && editing() ? 'Listo' : 'Modificar' }}
</button>
}

View File

@@ -367,6 +367,57 @@ describe('CartComponent', () => {
expect(editingChange).toHaveBeenLastCalledWith(false);
});
it('emits Modificar as an action without toggling to Listo', async () => {
await TestBed.configureTestingModule({
imports: [CartComponent],
providers: [
{
provide: CartService,
useValue: {
cart: signal(null).asReadonly(),
updateItemQuantity: vi.fn(),
removeItem: vi.fn(),
},
},
{ provide: ModalService, useValue: {} },
{
provide: ToastService,
useValue: { success: vi.fn(), info: vi.fn(), danger: vi.fn() },
},
],
}).compileComponents();
const fixture = TestBed.createComponent(CartComponent);
fixture.componentRef.setInput('items', [
{
cartItemId: 10,
imageUrl: null,
product: 'Producto de prueba',
originalPrice: null,
discountedPrice: 1000,
discountPercentage: null,
attributes: [],
quantity: 1,
},
]);
fixture.componentRef.setInput('readonly', true);
fixture.componentRef.setInput('showModifyWhenReadonly', true);
fixture.componentRef.setInput('modifyAsAction', true);
const modify = vi.fn();
fixture.componentInstance.modify.subscribe(modify);
fixture.detectChanges();
const modifyButton = fixture.debugElement.query(By.css('.cart-edit-btn'));
expect(modifyButton.nativeElement.textContent.trim()).toBe('Modificar');
modifyButton.nativeElement.click();
fixture.detectChanges();
expect(modify).toHaveBeenCalledOnce();
expect(modifyButton.nativeElement.textContent.trim()).toBe('Modificar');
expect(fixture.componentInstance.editing()).toBe(false);
});
it('allows editing directly when the optional Modificar toggle is disabled', async () => {
await TestBed.configureTestingModule({
imports: [CartComponent],

View File

@@ -56,6 +56,7 @@ export class CartComponent {
readonly allowUpdateQuantity = input<boolean>(true);
readonly allowModify = input<boolean>(true);
readonly showModifyWhenReadonly = input<boolean>(false);
readonly modifyAsAction = input<boolean>(false);
readonly requireEditingMode = input<boolean>(false);
readonly allowUpdateVariant = input<boolean>(true);
readonly allowDelete = input<boolean>(true);
@@ -66,6 +67,7 @@ export class CartComponent {
readonly editing = model<boolean>(false);
readonly closed = output<void>();
readonly modify = output<void>();
readonly itemQuantityChange = output<{
item: CartItemMock;
index: number;
@@ -257,6 +259,11 @@ export class CartComponent {
return;
}
if (this.modifyAsAction()) {
this.modify.emit();
return;
}
const editing = !this.editing();
this.editing.set(editing);
}