Skip to content

Commit

Permalink
fix: show the instant payments when they are the only supported PMs (#…
Browse files Browse the repository at this point in the history
…2629)

* fix: show the instant payment when it is the only supported pm

* test: added tests
  • Loading branch information
longyulongyu authored Apr 8, 2024
1 parent f48a7b0 commit 17f15e9
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/smart-tables-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@adyen/adyen-web": patch
---

Fix the bug that the drop-in is not rendered when there are only instant payments.
70 changes: 69 additions & 1 deletion packages/lib/src/components/Dropin/Dropin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ import { screen, render } from '@testing-library/preact';
const submitMock = jest.fn();
(global as any).HTMLFormElement.prototype.submit = () => submitMock;

const mockCreateGooglePayButton = jest.fn();
jest.mock('../GooglePay/GooglePayService', () => {
return jest.fn().mockImplementation(() => {
const mockClient = {
createButton: mockCreateGooglePayButton
};
return {
isReadyToPay: () => Promise.resolve({ result: 'dummy', paymentMethodPresent: true }),
paymentsClient: Promise.resolve(mockClient)
};
});
});

describe('Dropin', () => {
let dropin: DropinElement;
let checkout;
Expand All @@ -17,6 +30,10 @@ describe('Dropin', () => {
dropin = checkout.create('dropin');
});

afterEach(() => {
jest.clearAllMocks();
});

describe('isValid', () => {
test('should fail if no activePaymentMethod', () => {
expect(dropin.isValid).toEqual(false);
Expand Down Expand Up @@ -66,7 +83,11 @@ describe('Dropin', () => {
});

test('should handle new challenge action', async () => {
const checkout = await AdyenCheckout({ environment: 'test', clientKey: 'test_123456', analytics: { enabled: false } });
const checkout = await AdyenCheckout({
environment: 'test',
clientKey: 'test_123456',
analytics: { enabled: false }
});

const dropin = checkout.create('dropin');

Expand Down Expand Up @@ -161,6 +182,53 @@ describe('Dropin', () => {
expect(dropin.props.paymentMethods).toStrictEqual(paymentMethods);
expect(dropin.props.instantPaymentMethods).toHaveLength(0);
});

describe('Render instant payments', () => {
let checkout;

beforeEach(async () => {
mockCreateGooglePayButton.mockImplementation(() => {
const mockGooglePayElement = document.createElement('div');
mockGooglePayElement.setAttribute('data-testid', 'mock-google-pay-element');
return Promise.resolve(mockGooglePayElement);
});
checkout = await AdyenCheckout({
environment: 'test',
clientKey: 'test_123456',
analytics: { enabled: false },
paymentMethodsResponse: {
paymentMethods: [
{
configuration: {
merchantId: '12345678',
gatewayMerchantId: 'testMerchant'
},
name: 'Google Pay',
type: 'paywithgoogle'
}
]
}
});
});

test('should show the instant payment if the payment response includes the specified instantPaymentTypes', async () => {
const dropin = checkout.create('dropin', { instantPaymentTypes: ['paywithgoogle'] });
render(dropin.render());
expect(await screen.findByTestId('mock-google-pay-element')).toBeTruthy();
});

test('should not show the instant payment if instantPaymentTypes are not specified', async () => {
const dropin = checkout.create('dropin');
render(dropin.render());
expect(screen.queryByTestId('mock-google-pay-element')).not.toBeInTheDocument();
});

test('should not show the instant payment if the payment response does not include any instantPaymentTypes', async () => {
const dropin = checkout.create('dropin', { instantPaymentTypes: ['applepay'] });
render(dropin.render());
expect(screen.queryByTestId('mock-google-pay-element')).not.toBeInTheDocument();
});
});
});

describe('Payment status', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo
render(props, { elements, instantPaymentElements, status, activePaymentMethod, cachedPaymentMethods }) {
const isLoading = status.type === 'loading';
const isRedirecting = status.type === 'redirect';
const hasPayments = elements?.length > 0 || instantPaymentElements?.length > 0;

switch (status.type) {
case 'success':
Expand All @@ -130,7 +131,7 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo
<div className={`adyen-checkout__dropin adyen-checkout__dropin--${status.type}`}>
{isRedirecting && status.props.component && status.props.component.render()}
{isLoading && status.props && status.props.component && status.props.component.render()}
{elements && !!elements.length && (
{hasPayments && (
<PaymentMethodList
isLoading={isLoading || isRedirecting}
isDisablingPaymentMethod={this.state.isDisabling}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import UIElement from '../../../UIElement';

interface InstantPaymentMethodsProps {
paymentMethods: UIElement[];
showContentSeparator: boolean;
}

function InstantPaymentMethods({ paymentMethods }: InstantPaymentMethodsProps) {
function InstantPaymentMethods({ paymentMethods, showContentSeparator }: InstantPaymentMethodsProps) {
const { i18n } = useCoreContext();

return (
Expand All @@ -17,7 +18,7 @@ function InstantPaymentMethods({ paymentMethods }: InstantPaymentMethodsProps) {
<li key={pm.type}>{pm.render()}</li>
))}
</ul>
<ContentSeparator label={i18n.get('orPayWith')} />
{showContentSeparator && <ContentSeparator label={i18n.get('orPayWith')} />}
</Fragment>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class PaymentMethodList extends Component<PaymentMethodListProps> {
});

const brandLogoConfiguration = useBrandLogoConfiguration(paymentMethods);
const showContentSeparator = paymentMethods?.length > 0;

return (
<Fragment>
Expand All @@ -80,7 +81,9 @@ class PaymentMethodList extends Component<PaymentMethodListProps> {
/>
)}

{!!instantPaymentMethods.length && <InstantPaymentMethods paymentMethods={instantPaymentMethods} />}
{!!instantPaymentMethods.length && (
<InstantPaymentMethods showContentSeparator={showContentSeparator} paymentMethods={instantPaymentMethods} />
)}

<ul className={paymentMethodListClassnames} role="radiogroup" aria-label={i18n.get('paymentMethodsList.aria.label')} required>
{paymentMethods.map((paymentMethod, index, paymentMethodsCollection) => {
Expand Down

0 comments on commit 17f15e9

Please sign in to comment.