From fe52519b72a6035997d349d4b8e9e0afabd30908 Mon Sep 17 00:00:00 2001 From: nahu Date: Sun, 12 Jul 2026 19:21:27 +0000 Subject: [PATCH] feat(checkout-page): refactor payment method components and enhance styling for improved modularity --- .../checkout-payment-step.component.html | 90 +------- .../checkout-payment-step.component.scss | 196 +----------------- .../checkout-payment-step.component.spec.ts | 65 ++++++ .../checkout-payment-step.component.ts | 12 +- .../payment-methods/_payment-panel.scss | 33 +++ .../qr-payment-content.component.html | 14 ++ .../qr-payment-content.component.scss | 79 +++++++ .../qr-payment-content.component.spec.ts | 30 +++ .../qr-payment-content.component.ts | 15 ++ .../telepagos-payment-content.component.html | 22 ++ .../telepagos-payment-content.component.scss | 45 ++++ ...elepagos-payment-content.component.spec.ts | 20 ++ .../telepagos-payment-content.component.ts | 10 + .../transfer-payment-content.component.html | 46 ++++ .../transfer-payment-content.component.scss | 52 +++++ ...transfer-payment-content.component.spec.ts | 54 +++++ .../transfer-payment-content.component.ts | 23 ++ 17 files changed, 527 insertions(+), 279 deletions(-) create mode 100644 src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/_payment-panel.scss create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.html create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.scss create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.spec.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.html create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.scss create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.spec.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.html create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.scss create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.spec.ts create mode 100644 src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.ts diff --git a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.html b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.html index b740468..6685883 100644 --- a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.html +++ b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.html @@ -40,90 +40,15 @@

Cargando información de pago...

} @else if (selectedPaymentMethod() === 'qr') { -
-

Ingresa a tu billetera y escanea el siguiente QR

-
- -
- @if (qrData()) { - - } @else { - - - - } -
-
+ } @else if (selectedPaymentMethod() === 'transfer') { -
-

Transferi a la siguiente cuenta desde cualquier billetera

-
- - -
+ } @else { -
-

Descarga la app de TelePagos para finalizar la compra

-
- -
-
- - - Disponible en - Google Play - -
- -
- - - Descargalo en - App Store - -
-
-
+ } @@ -150,4 +75,3 @@ - diff --git a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.scss b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.scss index c745e9e..329cbee 100644 --- a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.scss +++ b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.scss @@ -1,3 +1,5 @@ +@use './components/payment-methods/payment-panel' as payment-panel; + .checkout-payment { display: grid; gap: 1rem; @@ -110,197 +112,5 @@ .payment-panel { min-width: 0; - &__card { - width: 100%; - max-width: 290px; - min-height: 269px; - padding: 1.5rem 1.75rem; - border-radius: 5px; - background: #ffffff; - color: #666666; - box-shadow: 0 0 0 1px #f1f1f1; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - } - - &__title { - max-width: 18rem; - margin: 0; - color: #8a8a8a; - font-size: 13px; - font-weight: 700; - line-height: 1.35; - } - - &__divider { - width: 100%; - max-width: 220px; - height: 1px; - margin: 1.2rem 0 1.45rem; - background: #dddddd; - } - - &__account { - width: 100%; - display: grid; - gap: 0.75rem; - color: #7a7a7a; - font-size: 12px; - } - - &__eyebrow { - margin: 0; - color: #838383; - font-size: 12px; - font-weight: 325; - letter-spacing: 0.06em; - } + @include payment-panel.card; } - -.payment-detail { - display: grid; - grid-template-columns: auto auto; - justify-content: center; - gap: 0.35rem; - align-items: center; - font-size: 12px; - - &--copy { - grid-template-columns: auto auto auto; - } - - &__label { - color: #8a8a8a; - font-weight: 325; - } - - &__value { - color: #5e5e5e; - font-weight: 500; - } - - &__feedback { - display: block; - margin-top: -0.25rem; - color: var(--tenant-primary, #6376f3); - font-size: 0.78rem; - font-weight: 700; - } -} - -.qr-code { - position: relative; - width: min(170px, 100%); - aspect-ratio: 1; - border: 8px solid #ffffff; - background-color: #ffffff; - background-image: - linear-gradient( - 90deg, - rgba(17, 17, 17, 0.95) 0 14%, - transparent 14% 28%, - rgba(17, 17, 17, 0.95) 28% 42%, - transparent 42% 56%, - rgba(17, 17, 17, 0.95) 56% 70%, - transparent 70% 84%, - rgba(17, 17, 17, 0.95) 84% 100% - ), - linear-gradient( - rgba(17, 17, 17, 0.95) 0 14%, - transparent 14% 28%, - rgba(17, 17, 17, 0.95) 28% 42%, - transparent 42% 56%, - rgba(17, 17, 17, 0.95) 56% 70%, - transparent 70% 84%, - rgba(17, 17, 17, 0.95) 84% 100% - ); - background-size: 18px 18px; - background-position: 0 0, 9px 9px; - display: flex; - justify-content: center; - align-items: center; - - qrcode { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - - ::ng-deep canvas, - ::ng-deep img { - display: block !important; - width: 100% !important; - height: 100% !important; - max-width: 100%; - max-height: 100%; - } - } -} - -.qr-code__finder { - position: absolute; - width: 38px; - height: 38px; - border: 5px solid #111111; - background: #ffffff; - box-shadow: inset 0 0 0 8px #ffffff, inset 0 0 0 14px #111111; - - &--tl { - top: 10px; - left: 10px; - } - - &--tr { - top: 10px; - right: 10px; - } - - &--bl { - bottom: 10px; - left: 10px; - } -} - -.store-badges { - width: 100%; - max-width: 210px; - display: grid; - gap: 0.8rem; -} - -.store-badge { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.75rem 0.95rem; - border-radius: 0.85rem; - background: #111111; - color: #ffffff; - box-shadow: 0 10px 24px rgba(17, 17, 17, 0.16); - - i { - font-size: 1.35rem; - } - - &__text { - display: grid; - text-align: left; - line-height: 1.1; - - small { - font-size: 0.62rem; - letter-spacing: 0.05em; - text-transform: uppercase; - opacity: 0.8; - } - - strong { - font-size: 1rem; - font-weight: 700; - } - } -} - 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 new file mode 100644 index 0000000..0cbae36 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.spec.ts @@ -0,0 +1,65 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CheckoutPaymentStepComponent } from './checkout-payment-step.component'; +import { PaymentMethod, PaymentMethodOption, TransferAccount } from './checkout-page.models'; + +describe('CheckoutPaymentStepComponent', () => { + const paymentMethods: ReadonlyArray = [ + { id: 'qr', label: 'QR' }, + { id: 'transfer', label: 'Transferencia' }, + { id: 'telepagos', label: 'TelePagos' } + ]; + const transferAccount: TransferAccount = { + titular: 'Titular Test', + entidad: 'Entidad Test', + cvu: '0000000000000000000000', + alias: 'alias.test' + }; + + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CheckoutPaymentStepComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(CheckoutPaymentStepComponent); + fixture.componentRef.setInput('paymentMethods', paymentMethods); + fixture.componentRef.setInput('transferAccount', transferAccount); + }); + + it.each([ + ['qr', 'app-qr-payment-content'], + ['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); + 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); + 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'); + fixture.detectChanges(); + + 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 }]); + }); +}); diff --git a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.ts b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.ts index 9c3f8c4..6f54c5f 100644 --- a/src/app/features/store/pages/checkout-page/checkout-payment-step.component.ts +++ b/src/app/features/store/pages/checkout-page/checkout-payment-step.component.ts @@ -1,14 +1,20 @@ import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; import { ButtonComponent } from '../../../../shared/components/button/button.component'; -import { IconButtonComponent } from '../../../../shared/components/icon-button/icon-button.component'; -import { QRCodeComponent } from '../../../../shared/components/qrcode/qrcode.component'; +import { QrPaymentContentComponent } from './components/payment-methods/qr-payment-content.component'; +import { TelepagosPaymentContentComponent } from './components/payment-methods/telepagos-payment-content.component'; +import { TransferPaymentContentComponent } from './components/payment-methods/transfer-payment-content.component'; import { PaymentMethod, PaymentMethodOption, TransferAccount, TransferField } from './checkout-page.models'; @Component({ selector: 'app-checkout-payment-step', standalone: true, - imports: [ButtonComponent, IconButtonComponent, QRCodeComponent], + imports: [ + ButtonComponent, + QrPaymentContentComponent, + TelepagosPaymentContentComponent, + TransferPaymentContentComponent + ], templateUrl: './checkout-payment-step.component.html', styleUrl: './checkout-payment-step.component.scss', changeDetection: ChangeDetectionStrategy.OnPush diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/_payment-panel.scss b/src/app/features/store/pages/checkout-page/components/payment-methods/_payment-panel.scss new file mode 100644 index 0000000..37c44e2 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/_payment-panel.scss @@ -0,0 +1,33 @@ +@mixin card { + &__card { + width: 100%; + max-width: 290px; + min-height: 269px; + padding: 1.5rem 1.75rem; + border-radius: 5px; + background: #ffffff; + color: #666666; + box-shadow: 0 0 0 1px #f1f1f1; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + } + + &__title { + max-width: 18rem; + margin: 0; + color: #8a8a8a; + font-size: 13px; + font-weight: 700; + line-height: 1.35; + } + + &__divider { + width: 100%; + max-width: 220px; + height: 1px; + margin: 1.2rem 0 1.45rem; + background: #dddddd; + } +} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.html b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.html new file mode 100644 index 0000000..06e008d --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.html @@ -0,0 +1,14 @@ +
+

Ingresa a tu billetera y escanea el siguiente QR

+
+ +
+ @if (qrData()) { + + } @else { + + + + } +
+
diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.scss b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.scss new file mode 100644 index 0000000..653b867 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.scss @@ -0,0 +1,79 @@ +@use 'payment-panel' as payment-panel; + +.payment-panel { + @include payment-panel.card; +} + +.qr-code { + position: relative; + width: min(170px, 100%); + aspect-ratio: 1; + border: 8px solid #ffffff; + background-color: #ffffff; + background-image: + linear-gradient( + 90deg, + rgba(17, 17, 17, 0.95) 0 14%, + transparent 14% 28%, + rgba(17, 17, 17, 0.95) 28% 42%, + transparent 42% 56%, + rgba(17, 17, 17, 0.95) 56% 70%, + transparent 70% 84%, + rgba(17, 17, 17, 0.95) 84% 100% + ), + linear-gradient( + rgba(17, 17, 17, 0.95) 0 14%, + transparent 14% 28%, + rgba(17, 17, 17, 0.95) 28% 42%, + transparent 42% 56%, + rgba(17, 17, 17, 0.95) 56% 70%, + transparent 70% 84%, + rgba(17, 17, 17, 0.95) 84% 100% + ); + background-size: 18px 18px; + background-position: 0 0, 9px 9px; + display: flex; + justify-content: center; + align-items: center; + + qrcode { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + + ::ng-deep canvas, + ::ng-deep img { + display: block !important; + width: 100% !important; + height: 100% !important; + max-width: 100%; + max-height: 100%; + } + } +} + +.qr-code__finder { + position: absolute; + width: 38px; + height: 38px; + border: 5px solid #111111; + background: #ffffff; + box-shadow: inset 0 0 0 8px #ffffff, inset 0 0 0 14px #111111; + + &--tl { + top: 10px; + left: 10px; + } + + &--tr { + top: 10px; + right: 10px; + } + + &--bl { + bottom: 10px; + left: 10px; + } +} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.spec.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.spec.ts new file mode 100644 index 0000000..5e6116e --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.spec.ts @@ -0,0 +1,30 @@ +import { TestBed } from '@angular/core/testing'; + +import { QrPaymentContentComponent } from './qr-payment-content.component'; + +describe('QrPaymentContentComponent', () => { + it('shows the QR placeholder when there is no QR data', async () => { + await TestBed.configureTestingModule({ + imports: [QrPaymentContentComponent] + }).compileComponents(); + + const fixture = TestBed.createComponent(QrPaymentContentComponent); + fixture.detectChanges(); + + expect(fixture.nativeElement.querySelectorAll('.qr-code__finder')).toHaveLength(3); + expect(fixture.nativeElement.querySelector('qrcode')).toBeNull(); + }); + + it('renders the QR component when data is provided', async () => { + await TestBed.configureTestingModule({ + imports: [QrPaymentContentComponent] + }).compileComponents(); + + const fixture = TestBed.createComponent(QrPaymentContentComponent); + fixture.componentRef.setInput('qrData', 'payment-data'); + fixture.detectChanges(); + + expect(fixture.nativeElement.querySelector('qrcode')).not.toBeNull(); + expect(fixture.nativeElement.querySelector('.qr-code__finder')).toBeNull(); + }); +}); diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.ts new file mode 100644 index 0000000..de32382 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/qr-payment-content.component.ts @@ -0,0 +1,15 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +import { QRCodeComponent } from '../../../../../../shared/components/qrcode/qrcode.component'; + +@Component({ + selector: 'app-qr-payment-content', + standalone: true, + imports: [QRCodeComponent], + templateUrl: './qr-payment-content.component.html', + styleUrl: './qr-payment-content.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class QrPaymentContentComponent { + readonly qrData = input(null); +} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.html b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.html new file mode 100644 index 0000000..3e21971 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.html @@ -0,0 +1,22 @@ +
+

Descarga la app de TelePagos para finalizar la compra

+
+ +
+
+ + + Disponible en + Google Play + +
+ +
+ + + Descargalo en + App Store + +
+
+
diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.scss b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.scss new file mode 100644 index 0000000..166d776 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.scss @@ -0,0 +1,45 @@ +@use 'payment-panel' as payment-panel; + +.payment-panel { + @include payment-panel.card; +} + +.store-badges { + width: 100%; + max-width: 210px; + display: grid; + gap: 0.8rem; +} + +.store-badge { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 0.95rem; + border-radius: 0.85rem; + background: #111111; + color: #ffffff; + box-shadow: 0 10px 24px rgba(17, 17, 17, 0.16); + + i { + font-size: 1.35rem; + } + + &__text { + display: grid; + text-align: left; + line-height: 1.1; + + small { + font-size: 0.62rem; + letter-spacing: 0.05em; + text-transform: uppercase; + opacity: 0.8; + } + + strong { + font-size: 1rem; + font-weight: 700; + } + } +} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.spec.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.spec.ts new file mode 100644 index 0000000..9d6c579 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.spec.ts @@ -0,0 +1,20 @@ +import { TestBed } from '@angular/core/testing'; + +import { TelepagosPaymentContentComponent } from './telepagos-payment-content.component'; + +describe('TelepagosPaymentContentComponent', () => { + it('shows the TelePagos download options', async () => { + await TestBed.configureTestingModule({ + imports: [TelepagosPaymentContentComponent] + }).compileComponents(); + + const fixture = TestBed.createComponent(TelepagosPaymentContentComponent); + fixture.detectChanges(); + + const text = fixture.nativeElement.textContent as string; + expect(text).toContain('Descarga la app de TelePagos'); + expect(text).toContain('Google Play'); + expect(text).toContain('App Store'); + expect(fixture.nativeElement.querySelectorAll('.store-badge')).toHaveLength(2); + }); +}); diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.ts new file mode 100644 index 0000000..78dcf30 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/telepagos-payment-content.component.ts @@ -0,0 +1,10 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-telepagos-payment-content', + standalone: true, + templateUrl: './telepagos-payment-content.component.html', + styleUrl: './telepagos-payment-content.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TelepagosPaymentContentComponent {} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.html b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.html new file mode 100644 index 0000000..ca7e67c --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.html @@ -0,0 +1,46 @@ +
+

Transferi a la siguiente cuenta desde cualquier billetera

+
+ + +
diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.scss b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.scss new file mode 100644 index 0000000..3cd0db2 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.scss @@ -0,0 +1,52 @@ +@use 'payment-panel' as payment-panel; + +.payment-panel { + @include payment-panel.card; + + &__account { + width: 100%; + display: grid; + gap: 0.75rem; + color: #7a7a7a; + font-size: 12px; + } + + &__eyebrow { + margin: 0; + color: #838383; + font-size: 12px; + font-weight: 325; + letter-spacing: 0.06em; + } +} + +.payment-detail { + display: grid; + grid-template-columns: auto auto; + justify-content: center; + gap: 0.35rem; + align-items: center; + font-size: 12px; + + &--copy { + grid-template-columns: auto auto auto; + } + + &__label { + color: #8a8a8a; + font-weight: 325; + } + + &__value { + color: #5e5e5e; + font-weight: 500; + } + + &__feedback { + display: block; + margin-top: -0.25rem; + color: var(--tenant-primary, #6376f3); + font-size: 0.78rem; + font-weight: 700; + } +} diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.spec.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.spec.ts new file mode 100644 index 0000000..d0dad19 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.spec.ts @@ -0,0 +1,54 @@ +import { TestBed } from '@angular/core/testing'; + +import { TransferAccount } from '../../checkout-page.models'; +import { TransferPaymentContentComponent } from './transfer-payment-content.component'; + +describe('TransferPaymentContentComponent', () => { + const transferAccount: TransferAccount = { + titular: 'Titular Test', + entidad: 'Entidad Test', + cvu: '0000000000000000000000', + alias: 'alias.test' + }; + + it('shows the account information and copied-field feedback', async () => { + await TestBed.configureTestingModule({ + imports: [TransferPaymentContentComponent] + }).compileComponents(); + + const fixture = TestBed.createComponent(TransferPaymentContentComponent); + fixture.componentRef.setInput('transferAccount', transferAccount); + fixture.componentRef.setInput('copiedTransferField', 'cvu'); + fixture.detectChanges(); + + const text = fixture.nativeElement.textContent as string; + expect(text).toContain(transferAccount.titular); + expect(text).toContain(transferAccount.entidad); + expect(text).toContain(transferAccount.cvu); + expect(text).toContain(transferAccount.alias); + expect(text).toContain('CVU copiado'); + expect(text).not.toContain('Alias copiado'); + }); + + it('emits the selected transfer value', async () => { + await TestBed.configureTestingModule({ + imports: [TransferPaymentContentComponent] + }).compileComponents(); + + const fixture = TestBed.createComponent(TransferPaymentContentComponent); + fixture.componentRef.setInput('transferAccount', transferAccount); + fixture.detectChanges(); + + const emitted: Array<{ field: string; value: string }> = []; + fixture.componentInstance.copyTransferValue.subscribe((value) => emitted.push(value)); + + const copyButtons = fixture.nativeElement.querySelectorAll('app-icon-button'); + copyButtons[0].click(); + copyButtons[1].click(); + + expect(emitted).toEqual([ + { field: 'cvu', value: transferAccount.cvu }, + { field: 'alias', value: transferAccount.alias } + ]); + }); +}); diff --git a/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.ts b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.ts new file mode 100644 index 0000000..030a566 --- /dev/null +++ b/src/app/features/store/pages/checkout-page/components/payment-methods/transfer-payment-content.component.ts @@ -0,0 +1,23 @@ +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; + +import { IconButtonComponent } from '../../../../../../shared/components/icon-button/icon-button.component'; +import { TransferAccount, TransferField } from '../../checkout-page.models'; + +@Component({ + selector: 'app-transfer-payment-content', + standalone: true, + imports: [IconButtonComponent], + templateUrl: './transfer-payment-content.component.html', + styleUrl: './transfer-payment-content.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TransferPaymentContentComponent { + readonly transferAccount = input.required(); + readonly copiedTransferField = input(null); + + readonly copyTransferValue = output<{ field: TransferField; value: string }>(); + + protected requestCopy(field: TransferField, value: string): void { + this.copyTransferValue.emit({ field, value }); + } +}