Skip to content

Commit 63e8030

Browse files
committed
feat: add amazon pay settings storage
1 parent 325a46d commit 63e8030

File tree

16 files changed

+505
-75
lines changed

16 files changed

+505
-75
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: add
3+
4+
feat: add Amazon Pay settings storage

client/data/settings/actions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ export function updateIsWooPayEnabled( isEnabled ) {
223223
return updateSettingsValues( { is_woopay_enabled: isEnabled } );
224224
}
225225

226+
export function updateIsAmazonPayEnabled( isEnabled ) {
227+
return updateSettingsValues( { is_amazon_pay_enabled: isEnabled } );
228+
}
229+
226230
export function updateIsWooPayGlobalThemeSupportEnabled( isEnabled ) {
227231
return updateSettingsValues( {
228232
is_woopay_global_theme_support_enabled: isEnabled,

client/data/settings/hooks.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,26 @@ export const useWooPayStoreLogo = () => {
569569
*/
570570
export const useWooPayLocations = makeExpressCheckoutLocationHook( 'woopay' );
571571

572+
/**
573+
* @return {import('wcpay/types/wcpay-data-settings-hooks').GenericSettingsHook<boolean>}
574+
*/
575+
export const useAmazonPayEnabledSettings = () => {
576+
const { updateIsAmazonPayEnabled } = useDispatch( STORE_NAME );
577+
578+
const isAmazonPayEnabled = useSelect( ( select ) =>
579+
select( STORE_NAME ).getIsAmazonPayEnabled()
580+
);
581+
582+
return [ isAmazonPayEnabled, updateIsAmazonPayEnabled ];
583+
};
584+
585+
/**
586+
* @return {import('wcpay/types/wcpay-data-settings-hooks').GenericSettingsHook<string[]>}
587+
*/
588+
export const useAmazonPayLocations = makeExpressCheckoutLocationHook(
589+
'amazon_pay'
590+
);
591+
572592
/**
573593
* @return {import('wcpay/types/wcpay-data-settings-hooks').GenericSettingsHook<string>}
574594
*/

client/data/settings/selectors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ export const getIsWooPayEnabled = ( state ) => {
186186
return getSettings( state ).is_woopay_enabled || false;
187187
};
188188

189+
export const getIsAmazonPayEnabled = ( state ) => {
190+
return getSettings( state ).is_amazon_pay_enabled || false;
191+
};
192+
189193
export const getIsWooPayGlobalThemeSupportEnabled = ( state ) => {
190194
return getSettings( state ).is_woopay_global_theme_support_enabled || false;
191195
};

client/disable-confirmation-modal/index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* External dependencies
33
*/
4-
import React from 'react';
4+
import React, { useContext } from 'react';
55
import { Button } from '@wordpress/components';
66
import { __, sprintf } from '@wordpress/i18n';
77
import interpolateComponents from '@automattic/interpolate-components';
@@ -11,6 +11,7 @@ import interpolateComponents from '@automattic/interpolate-components';
1111
*/
1212
import './styles.scss';
1313
import {
14+
useAmazonPayEnabledSettings,
1415
useEnabledPaymentMethodIds,
1516
usePaymentRequestEnabledSettings,
1617
useWooPayEnabledSettings,
@@ -21,14 +22,19 @@ import WooCardIcon from 'assets/images/cards/woo-card.svg?asset';
2122
import ConfirmationModal from '../components/confirmation-modal';
2223
import paymentMethodsMap from 'wcpay/payment-methods-map';
2324
import { WooIconShort } from 'wcpay/payment-methods-icons';
25+
import WCPaySettingsContext from 'wcpay/settings/wcpay-settings-context';
2426

2527
const DisableConfirmationModal = ( { onClose, onConfirm } ) => {
2628
const [ enabledMethodIds ] = useEnabledPaymentMethodIds();
2729
const [ isWooPayEnabled ] = useWooPayEnabledSettings();
2830
const [ isPaymentRequestEnabled ] = usePaymentRequestEnabledSettings();
31+
const [ isAmazonPayEnabled ] = useAmazonPayEnabledSettings();
2932
const isStripeLinkEnabled = Boolean(
3033
enabledMethodIds.find( ( id ) => id === 'link' )
3134
);
35+
const {
36+
featureFlags: { amazonPay: isAmazonPayFeatureFlagEnabled },
37+
} = useContext( WCPaySettingsContext );
3238

3339
return (
3440
<ConfirmationModal
@@ -116,6 +122,14 @@ const DisableConfirmationModal = ( { onClose, onConfirm } ) => {
116122
</li>
117123
</>
118124
) }
125+
{ isAmazonPayEnabled && isAmazonPayFeatureFlagEnabled && (
126+
<li>
127+
<PaymentMethodIcon
128+
Icon={ paymentMethodsMap.amazon_pay.icon }
129+
label={ paymentMethodsMap.amazon_pay.label }
130+
/>
131+
</li>
132+
) }
119133
{ isStripeLinkEnabled && (
120134
<li>
121135
<PaymentMethodIcon
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import React from 'react';
5+
import { render, screen } from '@testing-library/react';
6+
import userEvent from '@testing-library/user-event';
7+
8+
/**
9+
* Internal dependencies
10+
*/
11+
import AmazonPaySettings from '../amazon-pay-settings';
12+
import { useAmazonPayEnabledSettings, useAmazonPayLocations } from 'wcpay/data';
13+
import WCPaySettingsContext from 'wcpay/settings/wcpay-settings-context';
14+
15+
jest.mock( 'wcpay/data', () => ( {
16+
useAmazonPayEnabledSettings: jest.fn(),
17+
useAmazonPayLocations: jest.fn(),
18+
usePaymentRequestButtonSize: jest.fn().mockReturnValue( [ 'medium' ] ),
19+
useWooPayEnabledSettings: jest.fn().mockReturnValue( [ false ] ),
20+
usePaymentRequestEnabledSettings: jest.fn().mockReturnValue( [ false ] ),
21+
} ) );
22+
23+
const renderWithSettingsProvider = ( ui ) =>
24+
render(
25+
<WCPaySettingsContext.Provider
26+
value={ { featureFlags: { woopay: false, amazonPay: false } } }
27+
>
28+
{ ui }
29+
</WCPaySettingsContext.Provider>
30+
);
31+
32+
describe( 'AmazonPaySettings', () => {
33+
beforeEach( () => {
34+
useAmazonPayEnabledSettings.mockReturnValue( [ true, jest.fn() ] );
35+
useAmazonPayLocations.mockReturnValue( [
36+
[ 'product', 'cart', 'checkout' ],
37+
jest.fn(),
38+
] );
39+
} );
40+
41+
it( 'triggers the update handler when the enable checkbox is clicked', async () => {
42+
const updateIsAmazonPayEnabledHandler = jest.fn();
43+
useAmazonPayEnabledSettings.mockReturnValue( [
44+
true,
45+
updateIsAmazonPayEnabledHandler,
46+
] );
47+
48+
renderWithSettingsProvider( <AmazonPaySettings section="enable" /> );
49+
50+
expect( updateIsAmazonPayEnabledHandler ).not.toHaveBeenCalled();
51+
52+
expect(
53+
screen.getByLabelText(
54+
'Enable Amazon Pay as an express payment button'
55+
)
56+
).toBeChecked();
57+
58+
userEvent.click(
59+
screen.getByLabelText(
60+
'Enable Amazon Pay as an express payment button'
61+
)
62+
);
63+
64+
expect( updateIsAmazonPayEnabledHandler ).toHaveBeenCalledWith( false );
65+
} );
66+
67+
it( 'renders location checkboxes as checked when locations are enabled', () => {
68+
useAmazonPayLocations.mockReturnValue( [
69+
[ 'product', 'cart', 'checkout' ],
70+
jest.fn(),
71+
] );
72+
73+
renderWithSettingsProvider( <AmazonPaySettings section="enable" /> );
74+
75+
expect(
76+
screen.getByLabelText( 'Show on checkout page' )
77+
).toBeChecked();
78+
expect( screen.getByLabelText( 'Show on product page' ) ).toBeChecked();
79+
expect( screen.getByLabelText( 'Show on cart page' ) ).toBeChecked();
80+
} );
81+
82+
it( 'renders location checkboxes as unchecked when locations are disabled', () => {
83+
useAmazonPayLocations.mockReturnValue( [ [], jest.fn() ] );
84+
85+
renderWithSettingsProvider( <AmazonPaySettings section="enable" /> );
86+
87+
expect(
88+
screen.getByLabelText( 'Show on checkout page' )
89+
).not.toBeChecked();
90+
expect(
91+
screen.getByLabelText( 'Show on product page' )
92+
).not.toBeChecked();
93+
expect(
94+
screen.getByLabelText( 'Show on cart page' )
95+
).not.toBeChecked();
96+
} );
97+
98+
it( 'disables location checkboxes when Amazon Pay is disabled', () => {
99+
useAmazonPayEnabledSettings.mockReturnValue( [ false, jest.fn() ] );
100+
101+
renderWithSettingsProvider( <AmazonPaySettings section="enable" /> );
102+
103+
expect(
104+
screen.getByLabelText(
105+
'Enable Amazon Pay as an express payment button'
106+
)
107+
).not.toBeChecked();
108+
expect(
109+
screen.getByLabelText( 'Show on checkout page' )
110+
).toBeDisabled();
111+
expect(
112+
screen.getByLabelText( 'Show on product page' )
113+
).toBeDisabled();
114+
expect( screen.getByLabelText( 'Show on cart page' ) ).toBeDisabled();
115+
} );
116+
117+
it( 'triggers the location update handler when location checkboxes are clicked', async () => {
118+
const updateAmazonPayLocationsHandler = jest.fn();
119+
useAmazonPayLocations.mockReturnValue( [
120+
[ 'product' ],
121+
updateAmazonPayLocationsHandler,
122+
] );
123+
124+
renderWithSettingsProvider( <AmazonPaySettings section="enable" /> );
125+
126+
expect( updateAmazonPayLocationsHandler ).not.toHaveBeenCalled();
127+
128+
userEvent.click( screen.getByLabelText( 'Show on checkout page' ) );
129+
expect( updateAmazonPayLocationsHandler ).toHaveBeenLastCalledWith(
130+
'checkout',
131+
true
132+
);
133+
134+
userEvent.click( screen.getByLabelText( 'Show on product page' ) );
135+
expect( updateAmazonPayLocationsHandler ).toHaveBeenLastCalledWith(
136+
'product',
137+
false
138+
);
139+
140+
userEvent.click( screen.getByLabelText( 'Show on cart page' ) );
141+
expect( updateAmazonPayLocationsHandler ).toHaveBeenLastCalledWith(
142+
'cart',
143+
true
144+
);
145+
} );
146+
147+
it( 'renders general settings section with button size options', () => {
148+
renderWithSettingsProvider( <AmazonPaySettings section="general" /> );
149+
150+
expect( screen.queryByText( 'Button size' ) ).toBeInTheDocument();
151+
152+
const radioButtons = screen.queryAllByRole( 'radio' );
153+
expect( radioButtons ).toHaveLength( 3 );
154+
} );
155+
} );

client/settings/express-checkout-settings/__tests__/index.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ jest.mock( '../../../data', () => ( {
3939
.fn()
4040
.mockReturnValue( [ [ true, true, true ], jest.fn() ] ),
4141
useWooPayShowIncompatibilityNotice: jest.fn().mockReturnValue( false ),
42+
useAmazonPayEnabledSettings: jest
43+
.fn()
44+
.mockReturnValue( [ false, jest.fn() ] ),
45+
useAmazonPayLocations: jest.fn().mockReturnValue( [ [], jest.fn() ] ),
4246
} ) );
4347

4448
jest.mock( '@wordpress/data', () => ( {

client/settings/express-checkout-settings/__tests__/payment-request-settings.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jest.mock( '../../../data', () => ( {
3333
useWooPayEnabledSettings: jest.fn(),
3434
useWooPayShowIncompatibilityNotice: jest.fn().mockReturnValue( false ),
3535
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings: jest.fn(),
36+
useAmazonPayEnabledSettings: jest
37+
.fn()
38+
.mockReturnValue( [ false, jest.fn() ] ),
3639
} ) );
3740

3841
jest.mock( '../payment-request-button-preview' );

client/settings/express-checkout-settings/amazon-pay-settings.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* External dependencies
33
*/
4-
import React, { useState } from 'react';
4+
import React from 'react';
55
import { __ } from '@wordpress/i18n';
66

77
/**
@@ -14,8 +14,13 @@ import {
1414
BaseControl,
1515
RadioControl,
1616
} from '@wordpress/components';
17-
import { usePaymentRequestButtonSize } from 'wcpay/data';
17+
import {
18+
usePaymentRequestButtonSize,
19+
useAmazonPayEnabledSettings,
20+
useAmazonPayLocations,
21+
} from 'wcpay/data';
1822
import interpolateComponents from '@automattic/interpolate-components';
23+
import ExpressCheckoutSettingsNotices from './express-checkout-settings-notices';
1924

2025
const makeButtonSizeText = ( string ) =>
2126
interpolateComponents( {
@@ -62,6 +67,7 @@ const GeneralSettings = () => {
6267

6368
return (
6469
<CardBody className="wcpay-card-body">
70+
<ExpressCheckoutSettingsNotices currentMethod="amazon_pay" />
6571
<RadioControl
6672
label={ __( 'Button size', 'woocommerce-payments' ) }
6773
selected={ size }
@@ -73,21 +79,17 @@ const GeneralSettings = () => {
7379
};
7480

7581
const AmazonPaySettings = ( { section } ) => {
76-
const [ isAmazonPayEnabled, setIsAmazonPayEnabled ] = useState( false );
77-
const [ amazonPayLocations, setAmazonPayLocations ] = useState( [
78-
'product',
79-
'cart',
80-
'checkout',
81-
] );
82+
const [
83+
isAmazonPayEnabled,
84+
updateIsAmazonPayEnabled,
85+
] = useAmazonPayEnabledSettings();
86+
const [
87+
amazonPayLocations,
88+
updateAmazonPayLocations,
89+
] = useAmazonPayLocations();
8290

8391
const makeLocationChangeHandler = ( location ) => ( isChecked ) => {
84-
if ( isChecked ) {
85-
setAmazonPayLocations( [ ...amazonPayLocations, location ] );
86-
} else {
87-
setAmazonPayLocations(
88-
amazonPayLocations.filter( ( name ) => name !== location )
89-
);
90-
}
92+
updateAmazonPayLocations( location, isChecked );
9193
};
9294

9395
return (
@@ -98,7 +100,7 @@ const AmazonPaySettings = ( { section } ) => {
98100
<CheckboxControl
99101
className="wcpay-payment-request-settings__enable__checkbox"
100102
checked={ isAmazonPayEnabled }
101-
onChange={ setIsAmazonPayEnabled }
103+
onChange={ updateIsAmazonPayEnabled }
102104
label={ __(
103105
'Enable Amazon Pay as an express payment button',
104106
'woocommerce-payments'

0 commit comments

Comments
 (0)