-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect multiple enabled payment methods of the same type (#8513)
Co-authored-by: Timur Karimov <timurkarimov@timurs-macbook-pro.home>
- Loading branch information
Showing
22 changed files
with
896 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: add | ||
|
||
Detect payment methods enabled by multiple payment gateways. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React, { useCallback } from 'react'; | ||
import InlineNotice from '../inline-notice'; | ||
import interpolateComponents from '@automattic/interpolate-components'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { getAdminUrl } from 'wcpay/utils'; | ||
import { useDispatch } from '@wordpress/data'; | ||
|
||
interface DuplicateNoticeProps { | ||
paymentMethod: string; | ||
dismissedDuplicateNotices: string[]; | ||
setDismissedDuplicateNotices: ( notices: string[] ) => void; | ||
} | ||
|
||
function DuplicateNotice( { | ||
paymentMethod, | ||
dismissedDuplicateNotices, | ||
setDismissedDuplicateNotices, | ||
}: DuplicateNoticeProps ): JSX.Element | null { | ||
const { updateOptions } = useDispatch( 'wc/admin/options' ); | ||
|
||
const handleDismiss = useCallback( () => { | ||
const updatedNotices = [ ...dismissedDuplicateNotices, paymentMethod ]; | ||
setDismissedDuplicateNotices( updatedNotices ); | ||
updateOptions( { | ||
wcpay_duplicate_payment_method_notices_dismissed: updatedNotices, | ||
} ); | ||
wcpaySettings.dismissedDuplicateNotices = updatedNotices; | ||
}, [ | ||
paymentMethod, | ||
dismissedDuplicateNotices, | ||
setDismissedDuplicateNotices, | ||
updateOptions, | ||
] ); | ||
|
||
if ( dismissedDuplicateNotices.includes( paymentMethod ) ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<InlineNotice | ||
status="warning" | ||
icon={ true } | ||
isDismissible={ true } | ||
onRemove={ handleDismiss } | ||
> | ||
{ interpolateComponents( { | ||
mixedString: __( | ||
'This payment method is enabled by other extensions. {{reviewExtensions}}Review extensions{{/reviewExtensions}} to improve the shopper experience.', | ||
'woocommerce-payments' | ||
), | ||
components: { | ||
reviewExtensions: ( | ||
<a | ||
href={ getAdminUrl( { | ||
page: 'wc-settings', | ||
tab: 'checkout', | ||
} ) } | ||
> | ||
Review extensions | ||
</a> | ||
), | ||
}, | ||
} ) } | ||
</InlineNotice> | ||
); | ||
} | ||
|
||
export default DuplicateNotice; |
100 changes: 100 additions & 0 deletions
100
client/components/duplicate-notice/tests/index.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React from 'react'; | ||
import { render, fireEvent, screen, cleanup } from '@testing-library/react'; | ||
import { useDispatch } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import DuplicateNotice from '..'; | ||
|
||
jest.mock( '@wordpress/data', () => ( { | ||
useDispatch: jest.fn(), | ||
} ) ); | ||
|
||
const mockUseDispatch = useDispatch as jest.MockedFunction< any >; | ||
|
||
describe( 'DuplicateNotice', () => { | ||
const mockDispatch = jest.fn(); | ||
mockUseDispatch.mockReturnValue( { | ||
updateOptions: mockDispatch, | ||
} ); | ||
|
||
afterEach( () => { | ||
cleanup(); | ||
} ); | ||
|
||
test( 'does not render when the payment method is dismissed', () => { | ||
render( | ||
<DuplicateNotice | ||
paymentMethod="bancontact" | ||
dismissedDuplicateNotices={ [ 'bancontact' ] } | ||
setDismissedDuplicateNotices={ jest.fn() } | ||
/> | ||
); | ||
expect( | ||
screen.queryByText( | ||
'This payment method is enabled by other extensions. Review extensions to improve the shopper experience.' | ||
) | ||
).not.toBeInTheDocument(); | ||
} ); | ||
|
||
test( 'renders correctly when the payment method is not dismissed', () => { | ||
render( | ||
<DuplicateNotice | ||
paymentMethod="card" | ||
dismissedDuplicateNotices={ [] } | ||
setDismissedDuplicateNotices={ jest.fn() } | ||
/> | ||
); | ||
expect( | ||
screen.getByText( | ||
'This payment method is enabled by other extensions. Review extensions to improve the shopper experience.' | ||
) | ||
).toBeInTheDocument(); | ||
cleanup(); | ||
} ); | ||
|
||
test( 'dismissal process triggers appropriate actions', () => { | ||
const paymentMethod = 'ideal'; | ||
const props = { | ||
paymentMethod: paymentMethod, | ||
dismissedDuplicateNotices: [], | ||
setDismissedDuplicateNotices: jest.fn(), | ||
}; | ||
const { container } = render( <DuplicateNotice { ...props } /> ); | ||
const dismissButton = container.querySelector( | ||
'.components-button.components-notice__dismiss.has-icon' | ||
); | ||
if ( dismissButton ) { | ||
fireEvent.click( dismissButton ); | ||
} else { | ||
throw new Error( 'Dismiss button not found' ); | ||
} | ||
|
||
// Check if local state update function and Redux action dispatcher are called correctly | ||
expect( props.setDismissedDuplicateNotices ).toHaveBeenCalledWith( [ | ||
paymentMethod, | ||
] ); | ||
expect( mockDispatch ).toHaveBeenCalledWith( { | ||
wcpay_duplicate_payment_method_notices_dismissed: [ paymentMethod ], | ||
} ); | ||
} ); | ||
|
||
test( 'clicking on the Review extensions link navigates correctly', () => { | ||
const { getByText } = render( | ||
<DuplicateNotice | ||
{ ...{ | ||
paymentMethod: 'ideal', | ||
dismissedDuplicateNotices: [], | ||
setDismissedDuplicateNotices: jest.fn(), | ||
} } | ||
/> | ||
); | ||
expect( | ||
getByText( 'Review extensions' ).closest( 'a' ) | ||
).toHaveAttribute( 'href', 'admin.php?page=wc-settings&tab=checkout' ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.