fix(gift-card): inconsistency custom logo display (#2215)

This commit is contained in:
Yu Long
2023-06-12 10:59:42 +02:00
committed by GitHub
parent 33fb6e1e21
commit 85d98530d9
6 changed files with 95 additions and 5 deletions

View File

@@ -0,0 +1,5 @@
---
'@adyen/adyen-web': patch
---
Fix inconsistency displaying custom brand logo for the gift card payment

View File

@@ -1,11 +1,10 @@
import { h } from 'preact';
import PaymentMethodIcon from './PaymentMethodIcon';
import useCoreContext from '../../../../core/Context/useCoreContext';
import './OrderPaymentMethods.scss';
import useImage from '../../../../core/Context/useImage';
export const OrderPaymentMethods = ({ order, orderStatus, onOrderCancel }) => {
export const OrderPaymentMethods = ({ order, orderStatus, onOrderCancel, brandLogoConfiguration }) => {
const { i18n } = useCoreContext();
const getImage = useImage();
@@ -19,7 +18,7 @@ export const OrderPaymentMethods = ({ order, orderStatus, onOrderCancel }) => {
<PaymentMethodIcon
altDescription={orderPaymentMethod.name}
type={orderPaymentMethod.type}
src={getImage({})(orderPaymentMethod.type)}
src={brandLogoConfiguration[orderPaymentMethod.type] || getImage({})(orderPaymentMethod.type)}
/>
{orderPaymentMethod.lastFour}
</div>

View File

@@ -1,10 +1,12 @@
import { h } from 'preact';
import PaymentMethodList from './PaymentMethodList';
import { render, screen } from '@testing-library/preact';
import { render, screen, within } from '@testing-library/preact';
import { mock } from 'jest-mock-extended';
import UIElement from '../../../UIElement';
import EventEmitter from '../../../EventEmitter';
import userEvent from '@testing-library/user-event';
import Giftcard from '../../../Giftcard';
import { Order, OrderStatus } from '../../../../types';
function createInstantPaymentMethods() {
return [
@@ -157,3 +159,54 @@ test('should display instant payment methods', () => {
expect(screen.getByTestId('instant-googlepay')).toBeVisible();
expect(screen.getByTestId('instant-applepay')).toBeVisible();
});
describe('Gift card', () => {
let giftCardPayment;
beforeEach(() => {
const props = {
id: '3',
type: 'giftcard',
brand: 'givex',
oneClick: true,
brandsConfiguration: {
givex: { icon: 'https://example.com' }
}
};
giftCardPayment = new Giftcard(props);
});
test('should display the gift card custom icon in the payment method list', async () => {
render(
<PaymentMethodList paymentMethods={[giftCardPayment]} cachedPaymentMethods={{}} isLoading={false} openFirstStoredPaymentMethod={true} />
);
const img = await screen.findByRole('img');
// @ts-ignore img element contains src
expect(img.src).toContain('https://example.com');
});
test('should display the gift card custom icon in the order payment section', async () => {
const order: Order = { orderData: 'dummy', pspReference: 'dummyPsp' };
const orderStatus: OrderStatus = {
expiresAt: '2023-06-08T13:08:29.00Z',
pspReference: 'dummyPsp',
reference: 'dummyRef',
paymentMethods: [{ lastFour: '0000', type: 'givex', amount: { currency: 'USD', value: 5000 } }],
remainingAmount: { currency: 'USD', value: 20940 }
};
render(
<PaymentMethodList
order={order}
orderStatus={orderStatus}
paymentMethods={[giftCardPayment]}
cachedPaymentMethods={{}}
isLoading={false}
openFirstStoredPaymentMethod={true}
/>
);
const orderHeader = await screen.findByText(/0000/);
const img = await within(orderHeader).findByRole('img');
// @ts-ignore img element contains src
expect(img.src).toContain('https://example.com');
});
});

View File

@@ -8,6 +8,7 @@ import { Order, OrderStatus } from '../../../../types';
import OrderPaymentMethods from './OrderPaymentMethods';
import InstantPaymentMethods from './InstantPaymentMethods';
import useCoreContext from '../../../../core/Context/useCoreContext';
import { useBrandLogoConfiguration } from './useBrandLogoConfiguration';
interface PaymentMethodListProps {
paymentMethods: UIElement[];
@@ -66,10 +67,17 @@ class PaymentMethodList extends Component<PaymentMethodListProps> {
'adyen-checkout__payment-methods-list--loading': isLoading
});
const brandLogoConfiguration = useBrandLogoConfiguration(paymentMethods);
return (
<Fragment>
{this.props.orderStatus && (
<OrderPaymentMethods order={this.props.order} orderStatus={this.props.orderStatus} onOrderCancel={this.props.onOrderCancel} />
<OrderPaymentMethods
order={this.props.order}
orderStatus={this.props.orderStatus}
onOrderCancel={this.props.onOrderCancel}
brandLogoConfiguration={brandLogoConfiguration}
/>
)}
{!!instantPaymentMethods.length && <InstantPaymentMethods paymentMethods={instantPaymentMethods} />}

View File

@@ -0,0 +1,24 @@
import { useEffect, useState } from 'preact/hooks';
import UIElement from '../../../UIElement';
type BrandLogoConfiguration = {
[key: string]: string;
};
export function useBrandLogoConfiguration(paymentMethods: UIElement[]): BrandLogoConfiguration {
const [brandLogoConfiguration, setBrandLogoConfiguration] = useState<BrandLogoConfiguration>({});
useEffect(() => {
setBrandLogoConfiguration(
paymentMethods.reduce(
(accumulator, paymentMethod) => ({
...accumulator,
...(paymentMethod.props.brand && paymentMethod.icon && { [paymentMethod.props.brand]: paymentMethod.icon })
}),
{}
)
);
}, [paymentMethods]);
return brandLogoConfiguration;
}

View File

@@ -246,6 +246,7 @@ export interface Order {
export interface OrderStatus {
expiresAt: string;
paymentMethods: {
amount?: PaymentAmount;
lastFour: string;
type: string;
}[];