feat(checkout): refresh catalog availability on checkout failure
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import { provideHttpClient } from '@angular/common/http';
|
import { provideHttpClient } from '@angular/common/http';
|
||||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
|
import { CatalogAvailabilityService } from './catalog/catalog-availability.service';
|
||||||
import { CheckoutService } from './checkout.service';
|
import { CheckoutService } from './checkout.service';
|
||||||
|
|
||||||
describe('CheckoutService', () => {
|
describe('CheckoutService', () => {
|
||||||
@@ -39,6 +40,24 @@ describe('CheckoutService', () => {
|
|||||||
await expect(purchasePromise).resolves.toMatchObject({ id: 55 });
|
await expect(purchasePromise).resolves.toMatchObject({ id: 55 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('refreshes catalog availability when starting checkout fails', async () => {
|
||||||
|
const catalogAvailabilityService = TestBed.inject(CatalogAvailabilityService);
|
||||||
|
const notifyAvailabilityChanged = vi.spyOn(
|
||||||
|
catalogAvailabilityService,
|
||||||
|
'notifyAvailabilityChanged',
|
||||||
|
);
|
||||||
|
const purchasePromise = service.startCheckout('desfile', { cart_id: 12 });
|
||||||
|
const request = httpMock.expectOne(`${environment.url}tenants/desfile/compras/start-checkout`);
|
||||||
|
|
||||||
|
request.flush(
|
||||||
|
{ message: 'No hay stock disponible.' },
|
||||||
|
{ status: 422, statusText: 'Unprocessable Entity' },
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(purchasePromise).rejects.toBeTruthy();
|
||||||
|
expect(notifyAvailabilityChanged).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
it('preserves checkout timing fields when completing a purchase', async () => {
|
it('preserves checkout timing fields when completing a purchase', async () => {
|
||||||
const purchasePromise = service.completePurchase('desfile', 55);
|
const purchasePromise = service.completePurchase('desfile', 55);
|
||||||
const request = httpMock.expectOne(`${environment.url}tenants/desfile/compras/55/complete`);
|
const request = httpMock.expectOne(`${environment.url}tenants/desfile/compras/55/complete`);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
import { ApiPaginatedResponse } from './api-paginated-response.interface';
|
import { ApiPaginatedResponse } from './api-paginated-response.interface';
|
||||||
import { ApiPaginationQueryParams } from './api-pagination-query-params.interface';
|
import { ApiPaginationQueryParams } from './api-pagination-query-params.interface';
|
||||||
import { BaseApiService } from './base-api.service';
|
import { BaseApiService } from './base-api.service';
|
||||||
|
import { CatalogAvailabilityService } from './catalog/catalog-availability.service';
|
||||||
|
|
||||||
export interface UpdatePurchaseCustomerPayload {
|
export interface UpdatePurchaseCustomerPayload {
|
||||||
dni: string;
|
dni: string;
|
||||||
@@ -126,24 +127,31 @@ export interface PurchaseDetailResponse extends PurchaseStatusResponse {
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class CheckoutService extends BaseApiService {
|
export class CheckoutService extends BaseApiService {
|
||||||
|
private readonly catalogAvailabilityService = inject(CatalogAvailabilityService);
|
||||||
|
|
||||||
async startCheckout(
|
async startCheckout(
|
||||||
tenantCode: string,
|
tenantCode: string,
|
||||||
payload: StartCheckoutPayload,
|
payload: StartCheckoutPayload,
|
||||||
): Promise<PurchaseDetailResponse> {
|
): Promise<PurchaseDetailResponse> {
|
||||||
const response = await firstValueFrom(
|
try {
|
||||||
this.http.post<{ data?: PurchaseDetailResponse } | PurchaseDetailResponse>(
|
const response = await firstValueFrom(
|
||||||
`${environment.url}tenants/${tenantCode}/compras/start-checkout`,
|
this.http.post<{ data?: PurchaseDetailResponse } | PurchaseDetailResponse>(
|
||||||
payload,
|
`${environment.url}tenants/${tenantCode}/compras/start-checkout`,
|
||||||
),
|
payload,
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const purchase = this.extractResponseData<PurchaseDetailResponse>(response);
|
const purchase = this.extractResponseData<PurchaseDetailResponse>(response);
|
||||||
|
|
||||||
if (!purchase?.id) {
|
if (!purchase?.id) {
|
||||||
throw new Error('Error al crear la compra.');
|
throw new Error('Error al crear la compra.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return purchase;
|
||||||
|
} catch (error) {
|
||||||
|
this.catalogAvailabilityService.notifyAvailabilityChanged();
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return purchase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async generatePaymentIntent(
|
async generatePaymentIntent(
|
||||||
|
|||||||
Reference in New Issue
Block a user