diff --git a/src/app/core/services/checkout.service.spec.ts b/src/app/core/services/checkout.service.spec.ts new file mode 100644 index 0000000..65407f3 --- /dev/null +++ b/src/app/core/services/checkout.service.spec.ts @@ -0,0 +1,41 @@ +import { provideHttpClient } from '@angular/common/http'; +import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { TestBed } from '@angular/core/testing'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; + +import { environment } from '../../../environments/environment'; +import { CheckoutService } from './checkout.service'; + +describe('CheckoutService', () => { + let service: CheckoutService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [CheckoutService, provideHttpClient(), provideHttpClientTesting()], + }); + + service = TestBed.inject(CheckoutService); + httpMock = TestBed.inject(HttpTestingController); + }); + + afterEach(() => httpMock.verify()); + + it('starts one direct checkout with all selected variants', async () => { + const payload = { + direct_items: [ + { catalog_item_id: 10, variant_id: 101, cantidad: 1 }, + { catalog_item_id: 10, variant_id: 102, cantidad: 1 }, + ], + }; + const purchasePromise = service.startCheckout('desfile', payload); + const request = httpMock.expectOne(`${environment.url}tenants/desfile/compras/start-checkout`); + + expect(request.request.method).toBe('POST'); + expect(request.request.body).toEqual(payload); + + request.flush({ data: { id: 55 } }); + + await expect(purchasePromise).resolves.toMatchObject({ id: 55 }); + }); +}); diff --git a/src/app/core/services/checkout.service.ts b/src/app/core/services/checkout.service.ts index 3d54c7d..7899eda 100644 --- a/src/app/core/services/checkout.service.ts +++ b/src/app/core/services/checkout.service.ts @@ -21,9 +21,6 @@ export type StartCheckoutPayload = | { cart_id: number; } - | { - direct_item: DirectCheckoutItem; - } | { direct_items: DirectCheckoutItem[]; }; @@ -186,10 +183,7 @@ export class CheckoutService extends BaseApiService { return purchase; } - async completePurchase( - tenantCode: string, - purchaseId: number, - ): Promise { + async completePurchase(tenantCode: string, purchaseId: number): Promise { const response = await firstValueFrom( this.http.post<{ data?: PurchaseStatusResponse } | PurchaseStatusResponse>( `${environment.url}tenants/${tenantCode}/compras/${purchaseId}/complete`, @@ -227,10 +221,7 @@ export class CheckoutService extends BaseApiService { return { status: purchase.status ?? null }; } - async cancelPurchase( - tenantCode: string, - purchaseId: number, - ): Promise { + async cancelPurchase(tenantCode: string, purchaseId: number): Promise { const response = await firstValueFrom( this.http.post<{ data?: PurchaseStatusResponse } | PurchaseStatusResponse>( `${environment.url}tenants/${tenantCode}/compras/${purchaseId}/cancel`, @@ -254,9 +245,7 @@ export class CheckoutService extends BaseApiService { if (status) { url += `?status=${status}`; } - const response = await firstValueFrom( - this.http.get<{ data: PurchaseSummaryResponse[] }>(url), - ); + const response = await firstValueFrom(this.http.get<{ data: PurchaseSummaryResponse[] }>(url)); if (!response) { throw new Error('Error al obtener las compras.'); } diff --git a/src/app/features/store/pages/category-items-page/category-items-page.component.ts b/src/app/features/store/pages/category-items-page/category-items-page.component.ts index ae683f6..de914c1 100644 --- a/src/app/features/store/pages/category-items-page/category-items-page.component.ts +++ b/src/app/features/store/pages/category-items-page/category-items-page.component.ts @@ -127,11 +127,13 @@ export class CategoryItemsPageComponent { this.creatingDirectPurchase.set(true); try { const purchase = await this.injector.get(CheckoutService).startCheckout(tenant.codigo, { - direct_item: { - catalog_item_id: event.product.id, - variant_id: event.variant ?? null, - cantidad: event.quantity, - }, + direct_items: [ + { + catalog_item_id: event.product.id, + variant_id: event.variant ?? null, + cantidad: event.quantity, + }, + ], }); await this.router.navigate(['/checkout'], { queryParams: { purchase: purchase.id } }); } catch (error) { diff --git a/src/app/features/store/pages/product-detail-page/product-detail-page.component.spec.ts b/src/app/features/store/pages/product-detail-page/product-detail-page.component.spec.ts index da11222..9c25820 100644 --- a/src/app/features/store/pages/product-detail-page/product-detail-page.component.spec.ts +++ b/src/app/features/store/pages/product-detail-page/product-detail-page.component.spec.ts @@ -480,11 +480,13 @@ describe('ProductDetailPageComponent', () => { await Promise.resolve(); expect(checkoutServiceStub.startCheckout).toHaveBeenCalledWith('tenant-test', { - direct_item: { - catalog_item_id: 1, - variant_id: null, - cantidad: 1, - }, + direct_items: [ + { + catalog_item_id: 1, + variant_id: null, + cantidad: 1, + }, + ], }); expect(routerStub.navigate).toHaveBeenCalledWith(['/checkout'], { queryParams: { purchase: 44 }, diff --git a/src/app/features/store/pages/product-detail-page/product-detail-page.component.ts b/src/app/features/store/pages/product-detail-page/product-detail-page.component.ts index 8a5e96b..254c760 100644 --- a/src/app/features/store/pages/product-detail-page/product-detail-page.component.ts +++ b/src/app/features/store/pages/product-detail-page/product-detail-page.component.ts @@ -319,11 +319,13 @@ export class ProductDetailPageComponent implements OnInit, OnDestroy { this.creatingDirectPurchase.set(true); try { const purchase = await this.checkoutService.startCheckout(tenant.codigo, { - direct_item: { - catalog_item_id: currentProduct.id, - variant_id: variant?.id ?? null, - cantidad: this.quantity(), - }, + direct_items: [ + { + catalog_item_id: currentProduct.id, + variant_id: variant?.id ?? null, + cantidad: this.quantity(), + }, + ], }); await this.router.navigate(['/checkout'], { diff --git a/src/app/features/store/pages/search-page/search-page.component.ts b/src/app/features/store/pages/search-page/search-page.component.ts index 9aab8b0..03d872c 100644 --- a/src/app/features/store/pages/search-page/search-page.component.ts +++ b/src/app/features/store/pages/search-page/search-page.component.ts @@ -159,11 +159,13 @@ export class SearchPageComponent { this.creatingDirectPurchase.set(true); try { const purchase = await this.injector.get(CheckoutService).startCheckout(tenant.codigo, { - direct_item: { - catalog_item_id: event.product.id, - variant_id: event.variant ?? null, - cantidad: event.quantity, - }, + direct_items: [ + { + catalog_item_id: event.product.id, + variant_id: event.variant ?? null, + cantidad: event.quantity, + }, + ], }); await this.router.navigate(['/checkout'], { queryParams: { purchase: purchase.id } }); } catch (error) { diff --git a/src/app/features/store/pages/store-home-page/store-home-page.component.ts b/src/app/features/store/pages/store-home-page/store-home-page.component.ts index d9eea52..52bd9ca 100644 --- a/src/app/features/store/pages/store-home-page/store-home-page.component.ts +++ b/src/app/features/store/pages/store-home-page/store-home-page.component.ts @@ -180,21 +180,23 @@ export class StoreHomePageComponent implements OnInit, OnDestroy { try { const checkoutService = this.injector.get(CheckoutService); const variantIds = event.variantIds ?? []; - const purchase = - variantIds.length > 1 - ? await this.startTicketCheckout( - checkoutService, - tenant.codigo, - event.product.id, - variantIds, - ) - : await checkoutService.startCheckout(tenant.codigo, { - direct_item: { + const directItems = + variantIds.length > 0 + ? variantIds.map((variantId) => ({ + catalog_item_id: event.product.id, + variant_id: variantId, + cantidad: 1, + })) + : [ + { catalog_item_id: event.product.id, variant_id: event.variant ?? null, cantidad: event.quantity, }, - }); + ]; + const purchase = await checkoutService.startCheckout(tenant.codigo, { + direct_items: directItems, + }); await this.router.navigate(['/checkout'], { queryParams: { purchase: purchase.id } }); } catch (error) { console.error('Failed to create direct purchase:', error); @@ -204,21 +206,6 @@ export class StoreHomePageComponent implements OnInit, OnDestroy { } } - private async startTicketCheckout( - checkoutService: CheckoutService, - tenantCode: string, - catalogItemId: number, - variantIds: number[], - ) { - return checkoutService.startCheckout(tenantCode, { - direct_items: variantIds.map((variantId) => ({ - catalog_item_id: catalogItemId, - variant_id: variantId, - cantidad: 1, - })), - }); - } - protected onAddToCart(event: ProductListCartEvent): void { this.cartService.addItem(event.product.id, event.variant ?? null, event.quantity).subscribe({ next: (response) => {