From 08f1bd8f3bd9329003c15943a23ff58fc3f9418f Mon Sep 17 00:00:00 2001 From: nahu Date: Sun, 12 Jul 2026 19:49:22 +0000 Subject: [PATCH] feat(checkout-page): refactor payment component tests to use signals and improve method delegation --- .../checkout-payment-step.component.spec.ts | 73 ++++++++++++++----- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts index 0cbae36..a586cd1 100644 --- a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts +++ b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts @@ -1,5 +1,8 @@ +import { signal } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { vi } from 'vitest'; +import { CheckoutPaymentFacade } from './checkout-payment.facade'; import { CheckoutPaymentStepComponent } from './checkout-payment-step.component'; import { PaymentMethod, PaymentMethodOption, TransferAccount } from './checkout-page.models'; @@ -17,15 +20,48 @@ describe('CheckoutPaymentStepComponent', () => { }; let fixture: ComponentFixture; + let payment: { + paymentMethods: ReadonlyArray; + selectedMethod: ReturnType>; + copiedTransferField: ReturnType>; + transferAccount: ReturnType>; + payerDni: ReturnType>; + transferRequestError: ReturnType>; + qrData: ReturnType>; + isLoading: ReturnType>; + canComplete: ReturnType>; + setPurchaseId: ReturnType; + selectMethod: ReturnType; + copyTransferValue: ReturnType; + requestTransferData: ReturnType; + }; beforeEach(async () => { + payment = { + paymentMethods, + selectedMethod: signal('qr'), + copiedTransferField: signal<'cvu' | 'alias' | null>(null), + transferAccount: signal(transferAccount), + payerDni: signal('12345678'), + transferRequestError: signal(null), + qrData: signal('qr-test'), + isLoading: signal(false), + canComplete: signal(true), + setPurchaseId: vi.fn(), + selectMethod: vi.fn(), + copyTransferValue: vi.fn(), + requestTransferData: vi.fn() + }; + await TestBed.configureTestingModule({ imports: [CheckoutPaymentStepComponent] - }).compileComponents(); + }) + .overrideComponent(CheckoutPaymentStepComponent, { + set: { providers: [{ provide: CheckoutPaymentFacade, useValue: payment }] } + }) + .compileComponents(); fixture = TestBed.createComponent(CheckoutPaymentStepComponent); - fixture.componentRef.setInput('paymentMethods', paymentMethods); - fixture.componentRef.setInput('transferAccount', transferAccount); }); it.each([ @@ -33,33 +69,34 @@ describe('CheckoutPaymentStepComponent', () => { ['transfer', 'app-transfer-payment-content'], ['telepagos', 'app-telepagos-payment-content'] ] as const)('renders the %s payment content', (method: PaymentMethod, selector: string) => { - fixture.componentRef.setInput('selectedPaymentMethod', method); + payment.selectedMethod.set(method); fixture.detectChanges(); expect(fixture.nativeElement.querySelector(selector)).not.toBeNull(); }); - it('shows only the loading state while generating the payment intent', () => { - fixture.componentRef.setInput('selectedPaymentMethod', 'qr'); - fixture.componentRef.setInput('isGeneratingIntent', true); + it('delegates method selection to the payment facade', () => { + fixture.detectChanges(); + const transferRadio = fixture.nativeElement.querySelector('input[value="transfer"]') as HTMLInputElement; + transferRadio.dispatchEvent(new Event('change')); + + expect(payment.selectMethod).toHaveBeenCalledWith('transfer'); + }); + + it('shows only the loading state while generating a QR intent', () => { + payment.selectedMethod.set('qr'); + payment.isLoading.set(true); fixture.detectChanges(); expect(fixture.nativeElement.textContent).toContain('Cargando información de pago...'); expect(fixture.nativeElement.querySelector('app-qr-payment-content')).toBeNull(); - expect(fixture.nativeElement.querySelector('app-transfer-payment-content')).toBeNull(); - expect(fixture.nativeElement.querySelector('app-telepagos-payment-content')).toBeNull(); }); - it('re-emits transfer copy requests', () => { - fixture.componentRef.setInput('selectedPaymentMethod', 'transfer'); + it('delegates transfer copy requests to the payment facade', () => { + payment.selectedMethod.set('transfer'); fixture.detectChanges(); + fixture.nativeElement.querySelector('app-icon-button').click(); - const emitted: Array<{ field: string; value: string }> = []; - fixture.componentInstance.copyTransferValue.subscribe((value) => emitted.push(value)); - - const copyButton = fixture.nativeElement.querySelector('app-icon-button'); - copyButton.click(); - - expect(emitted).toEqual([{ field: 'cvu', value: transferAccount.cvu }]); + expect(payment.copyTransferValue).toHaveBeenCalledWith('cvu', transferAccount.cvu); }); });