fix(checkout): show backend start errors

This commit is contained in:
2026-08-25 16:46:12 -03:00
parent 1362d0c163
commit 8c2b738806
4 changed files with 48 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { signal } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
@@ -680,6 +681,34 @@ describe('StoreLayoutComponent', () => {
expect((fixture.componentInstance as any).isCartOpen()).toBe(false);
});
it('shows the backend message when starting checkout fails', async () => {
const message = 'Alcanzaste el límite de compra para este producto.';
checkoutServiceStub.startCheckout.mockRejectedValue(
new HttpErrorResponse({ status: 422, error: { message } }),
);
cartState.set({
id: 1,
tenant_codigo: tenant.codigo,
status: 'active',
subtotal: '100.00',
items: [],
});
authUserState.set({
id: 7,
nombre_apellido: 'Juan Perez',
email: 'juan@example.com',
dni: '12345678',
telefono: '3415555555',
});
const fixture = TestBed.createComponent(StoreLayoutComponent);
fixture.detectChanges();
await (fixture.componentInstance as any).onCheckoutClick();
expect(TestBed.inject(ToastService).danger).toHaveBeenCalledWith(message);
});
it('allows modifying quantities directly in the regular cart without a toggle', () => {
cartState.set({
id: 1,

View File

@@ -1,3 +1,4 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, computed, DestroyRef, inject, OnInit, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import {
@@ -278,7 +279,12 @@ export class StoreLayoutComponent implements OnInit {
});
} catch (error) {
console.error('Failed to create cart purchase:', error);
this.toastService.danger('No se pudo iniciar la compra.');
const message =
error instanceof HttpErrorResponse && typeof error.error?.message === 'string'
? error.error.message
: 'No se pudo iniciar la compra.';
this.toastService.danger(message);
} finally {
this.isCreatingPurchase.set(false);
}

View File

@@ -170,7 +170,12 @@ export class CategoryItemsPageComponent {
await this.router.navigate(['/checkout'], { queryParams: { purchase: purchase.id } });
} catch (error) {
console.error('Failed to create direct purchase:', error);
this.toastService.danger('No se pudo iniciar la compra directa.');
const message =
error instanceof HttpErrorResponse && typeof error.error?.message === 'string'
? error.error.message
: 'No se pudo iniciar la compra directa.';
this.toastService.danger(message);
} finally {
this.creatingDirectPurchase.set(false);
}

View File

@@ -202,7 +202,12 @@ export class SearchPageComponent {
await this.router.navigate(['/checkout'], { queryParams: { purchase: purchase.id } });
} catch (error) {
console.error('Failed to create direct purchase:', error);
this.toastService.danger('No se pudo iniciar la compra directa.');
const message =
error instanceof HttpErrorResponse && typeof error.error?.message === 'string'
? error.error.message
: 'No se pudo iniciar la compra directa.';
this.toastService.danger(message);
} finally {
this.creatingDirectPurchase.set(false);
}