Skip to content

Commit 9e0b76e

Browse files
rtiohtdat
andauthored
Add feature flag for the dynamic Google/Apple pay button and setttings on the admin (#11009)
Co-authored-by: Dat Hoang <[email protected]>
1 parent 37fa6b0 commit 9e0b76e

14 files changed

+387
-40
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: add
3+
4+
Add new feature flag for the dynamic checkout place order button, and new option on payment settings.

client/data/settings/__tests__/actions.test.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import { apiFetch } from '@wordpress/data-controls';
77
/**
88
* Internal dependencies
99
*/
10-
import { saveSettings, updateIsSavingSettings } from '../actions';
10+
import {
11+
saveSettings,
12+
updateIsSavingSettings,
13+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled,
14+
} from '../actions';
1115

1216
jest.mock( '@wordpress/data' );
1317
jest.mock( '@wordpress/data-controls' );
@@ -160,4 +164,32 @@ describe( 'Settings actions tests', () => {
160164
);
161165
} );
162166
} );
167+
168+
describe( 'updateIsAppleGooglePayInPaymentMethodsOptionsEnabled()', () => {
169+
test( 'returns action with correct payload for enabled state', () => {
170+
const action = updateIsAppleGooglePayInPaymentMethodsOptionsEnabled(
171+
true
172+
);
173+
174+
expect( action ).toEqual( {
175+
type: 'SET_SETTINGS_VALUES',
176+
payload: {
177+
is_apple_google_pay_in_payment_methods_options_enabled: true,
178+
},
179+
} );
180+
} );
181+
182+
test( 'returns action with correct payload for disabled state', () => {
183+
const action = updateIsAppleGooglePayInPaymentMethodsOptionsEnabled(
184+
false
185+
);
186+
187+
expect( action ).toEqual( {
188+
type: 'SET_SETTINGS_VALUES',
189+
payload: {
190+
is_apple_google_pay_in_payment_methods_options_enabled: false,
191+
},
192+
} );
193+
} );
194+
} );
163195
} );

client/data/settings/__tests__/hooks.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
useTestMode,
1616
usePaymentRequestEnabledSettings,
1717
usePaymentRequestLocations,
18+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings,
1819
useWooPayEnabledSettings,
1920
useWooPayCustomMessage,
2021
useWooPayStoreLogo,
@@ -233,6 +234,34 @@ describe( 'Settings hooks tests', () => {
233234
} );
234235
} );
235236

237+
describe( 'useAppleGooglePayInPaymentMethodsOptionsEnabledSettings()', () => {
238+
test( 'returns Apple Google Pay in payment methods options settings from selector', () => {
239+
actions = {
240+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled: jest.fn(),
241+
};
242+
243+
selectors = {
244+
getIsAppleGooglePayInPaymentMethodsOptionsEnabled: jest.fn(
245+
() => true
246+
),
247+
};
248+
249+
const [
250+
isAppleGooglePayInPaymentMethodsOptionsEnabled,
251+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled,
252+
] = useAppleGooglePayInPaymentMethodsOptionsEnabledSettings();
253+
254+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled( false );
255+
256+
expect( isAppleGooglePayInPaymentMethodsOptionsEnabled ).toEqual(
257+
true
258+
);
259+
expect(
260+
actions.updateIsAppleGooglePayInPaymentMethodsOptionsEnabled
261+
).toHaveBeenCalledWith( false );
262+
} );
263+
} );
264+
236265
describe( 'usePaymentRequestLocations()', () => {
237266
test( 'returns and updates payment request locations', () => {
238267
const locationsBeforeUpdate = [];

client/data/settings/__tests__/selectors.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
isSavingSettings,
1111
getPaymentRequestLocations,
1212
getIsPaymentRequestEnabled,
13+
getIsAppleGooglePayInPaymentMethodsOptionsEnabled,
1314
getAccountBusinessSupportEmail,
1415
getAccountBusinessSupportPhone,
1516
getIsWooPayEnabled,
@@ -179,6 +180,33 @@ describe( 'Settings selectors tests', () => {
179180
} );
180181
} );
181182

183+
describe( 'getIsAppleGooglePayInPaymentMethodsOptionsEnabled()', () => {
184+
test( 'returns the value of state.settings.data.is_apple_google_pay_in_payment_methods_options_enabled', () => {
185+
const state = {
186+
settings: {
187+
data: {
188+
is_apple_google_pay_in_payment_methods_options_enabled: true,
189+
},
190+
},
191+
};
192+
193+
expect(
194+
getIsAppleGooglePayInPaymentMethodsOptionsEnabled( state )
195+
).toBeTruthy();
196+
} );
197+
198+
test.each( [
199+
[ undefined ],
200+
[ {} ],
201+
[ { settings: {} } ],
202+
[ { settings: { data: {} } } ],
203+
] )( 'returns false if missing (tested state: %j)', ( state ) => {
204+
expect(
205+
getIsAppleGooglePayInPaymentMethodsOptionsEnabled( state )
206+
).toBeFalsy();
207+
} );
208+
} );
209+
182210
describe( 'getPaymentRequestLocations()', () => {
183211
test( 'returns the value of state.settings.data.payment_request_enabled_locations', () => {
184212
const state = {

client/data/settings/actions.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ export function updateIsPaymentRequestEnabled( isEnabled ) {
6262
return updateSettingsValues( { is_payment_request_enabled: isEnabled } );
6363
}
6464

65+
export function updateIsAppleGooglePayInPaymentMethodsOptionsEnabled(
66+
isEnabled
67+
) {
68+
return updateSettingsValues( {
69+
is_apple_google_pay_in_payment_methods_options_enabled: isEnabled,
70+
} );
71+
}
72+
6573
export function updateEnabledPaymentMethodIds( methodIds ) {
6674
return updateSettingsValues( {
6775
enabled_payment_method_ids: [ ...methodIds ],

client/data/settings/hooks.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,27 @@ export const usePaymentRequestEnabledSettings = () => {
368368
return [ isPaymentRequestEnabled, updateIsPaymentRequestEnabled ];
369369
};
370370

371+
/**
372+
* @return {import('wcpay/types/wcpay-data-settings-hooks').GenericSettingsHook<boolean>}
373+
*/
374+
export const useAppleGooglePayInPaymentMethodsOptionsEnabledSettings = () => {
375+
const {
376+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled,
377+
} = useDispatch( STORE_NAME );
378+
379+
const isAppleGooglePayInPaymentMethodsOptionsEnabled = useSelect(
380+
( select ) =>
381+
select(
382+
STORE_NAME
383+
).getIsAppleGooglePayInPaymentMethodsOptionsEnabled()
384+
);
385+
386+
return [
387+
isAppleGooglePayInPaymentMethodsOptionsEnabled,
388+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabled,
389+
];
390+
};
391+
371392
/**
372393
* @return {import('wcpay/types/wcpay-data-settings-hooks').GenericSettingsHook<string[]>}
373394
*/

client/data/settings/selectors.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ export const getIsPaymentRequestEnabled = ( state ) => {
121121
return getSettings( state ).is_payment_request_enabled || false;
122122
};
123123

124+
export const getIsAppleGooglePayInPaymentMethodsOptionsEnabled = ( state ) => {
125+
return (
126+
getSettings( state )
127+
.is_apple_google_pay_in_payment_methods_options_enabled || false
128+
);
129+
};
130+
124131
export const getIsDebugLogEnabled = ( state ) => {
125132
return getSettings( state ).is_debug_log_enabled || false;
126133
};

client/globals.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ declare global {
3232
isDisputeIssuerEvidenceEnabled: boolean;
3333
multiCurrency?: boolean;
3434
isFRTReviewFeatureActive: boolean;
35+
isDynamicCheckoutPlaceOrderButtonEnabled: boolean;
3536
};
3637
accountFees: Record< string, any >;
3738
fraudServices: unknown[];

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ jest.mock( '../../../data', () => ( {
2222
usePaymentRequestLocations: jest
2323
.fn()
2424
.mockReturnValue( [ [ true, true, true ], jest.fn() ] ),
25+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings: jest
26+
.fn()
27+
.mockReturnValue( [ false, jest.fn() ] ),
2528
useWooPayEnabledSettings: jest.fn().mockReturnValue( [ true, jest.fn() ] ),
2629
useWooPayCustomMessage: jest.fn().mockReturnValue( [ 'test', jest.fn() ] ),
2730
useWooPayStoreLogo: jest.fn().mockReturnValue( [ 'test', jest.fn() ] ),
@@ -108,6 +111,7 @@ describe( 'ExpressCheckoutSettings', () => {
108111
restUrl: 'http://example.com/wp-json/',
109112
featureFlags: {
110113
woopayExpressCheckout: true,
114+
isDynamicCheckoutPlaceOrderButtonEnabled: true,
111115
},
112116
};
113117
} );

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

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
usePaymentRequestButtonSize,
1919
usePaymentRequestButtonTheme,
2020
useWooPayEnabledSettings,
21+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings,
2122
} from '../../../data';
2223
import WCPaySettingsContext from 'wcpay/settings/wcpay-settings-context';
2324

@@ -31,6 +32,7 @@ jest.mock( '../../../data', () => ( {
3132
usePaymentRequestButtonTheme: jest.fn().mockReturnValue( [ 'dark' ] ),
3233
useWooPayEnabledSettings: jest.fn(),
3334
useWooPayShowIncompatibilityNotice: jest.fn().mockReturnValue( false ),
35+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings: jest.fn(),
3436
} ) );
3537

3638
jest.mock( '../payment-request-button-preview' );
@@ -51,6 +53,11 @@ const getMockPaymentRequestEnabledSettings = (
5153

5254
const getMockWooPayEnabledSettings = ( isEnabled ) => [ isEnabled ];
5355

56+
const getMockAppleGooglePayInPaymentMethodsOptionsEnabledSettings = (
57+
isEnabled,
58+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler
59+
) => [ isEnabled, updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler ];
60+
5461
const getMockPaymentRequestLocations = (
5562
isCheckoutEnabled,
5663
isProductPageEnabled,
@@ -102,6 +109,15 @@ const renderWithSettingsProvider = ( ui ) =>
102109

103110
describe( 'PaymentRequestSettings', () => {
104111
beforeEach( () => {
112+
// Mock the global wcpaySettings
113+
global.wcpaySettings = {
114+
accountStatus: {},
115+
restUrl: 'http://example.com/wp-json/',
116+
featureFlags: {
117+
isDynamicCheckoutPlaceOrderButtonEnabled: true,
118+
},
119+
};
120+
105121
usePaymentRequestEnabledSettings.mockReturnValue(
106122
getMockPaymentRequestEnabledSettings( true, jest.fn() )
107123
);
@@ -113,6 +129,13 @@ describe( 'PaymentRequestSettings', () => {
113129
useWooPayEnabledSettings.mockReturnValue(
114130
getMockWooPayEnabledSettings( true )
115131
);
132+
133+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings.mockReturnValue(
134+
getMockAppleGooglePayInPaymentMethodsOptionsEnabledSettings(
135+
false,
136+
jest.fn()
137+
)
138+
);
116139
} );
117140

118141
it( 'renders enable settings with defaults', () => {
@@ -121,9 +144,36 @@ describe( 'PaymentRequestSettings', () => {
121144
);
122145

123146
// confirm checkbox groups displayed
124-
const [ enableCheckbox ] = screen.queryAllByRole( 'checkbox' );
147+
const checkboxes = screen.queryAllByRole( 'checkbox' );
125148

126-
expect( enableCheckbox ).toBeInTheDocument();
149+
expect( checkboxes ).toHaveLength( 5 ); // Apple/Google Pay in payment methods, express buttons, and 3 location checkboxes
150+
} );
151+
152+
it( 'renders Apple Pay / Google Pay in payment methods checkbox when feature flag is enabled', () => {
153+
renderWithSettingsProvider(
154+
<PaymentRequestSettings section="enable" />
155+
);
156+
157+
expect(
158+
screen.getByLabelText(
159+
'Enable Apple Pay / Google Pay as options in the payment methods list'
160+
)
161+
).toBeInTheDocument();
162+
} );
163+
164+
it( 'does not render Apple Pay / Google Pay in payment methods checkbox when feature flag is disabled', () => {
165+
// Mock the feature flag as disabled
166+
global.wcpaySettings.featureFlags.isDynamicCheckoutPlaceOrderButtonEnabled = false;
167+
168+
renderWithSettingsProvider(
169+
<PaymentRequestSettings section="enable" />
170+
);
171+
172+
expect(
173+
screen.queryByLabelText(
174+
'Enable Apple Pay / Google Pay as options in the payment methods list'
175+
)
176+
).not.toBeInTheDocument();
127177
} );
128178

129179
it( 'triggers the hooks when the enable setting is being interacted with', async () => {
@@ -148,12 +198,61 @@ describe( 'PaymentRequestSettings', () => {
148198
expect( screen.getByLabelText( 'Show on product page' ) ).toBeChecked();
149199
expect( screen.getByLabelText( 'Show on cart page' ) ).toBeChecked();
150200

151-
await userEvent.click( screen.getByLabelText( /Enable Apple Pay/ ) );
201+
await userEvent.click(
202+
screen.getByLabelText( /Enable Apple Pay.*express payment buttons/ )
203+
);
152204
expect( updateIsPaymentRequestEnabledHandler ).toHaveBeenCalledWith(
153205
false
154206
);
155207
} );
156208

209+
it( 'triggers the Apple Pay / Google Pay in payment methods hook when the checkbox is interacted with', async () => {
210+
const updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler = jest.fn();
211+
212+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings.mockReturnValue(
213+
getMockAppleGooglePayInPaymentMethodsOptionsEnabledSettings(
214+
true,
215+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler
216+
)
217+
);
218+
219+
renderWithSettingsProvider(
220+
<PaymentRequestSettings section="enable" />
221+
);
222+
223+
expect(
224+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler
225+
).not.toHaveBeenCalled();
226+
227+
await userEvent.click(
228+
screen.getByLabelText(
229+
'Enable Apple Pay / Google Pay as options in the payment methods list'
230+
)
231+
);
232+
expect(
233+
updateIsAppleGooglePayInPaymentMethodsOptionsEnabledHandler
234+
).toHaveBeenCalledWith( false );
235+
} );
236+
237+
it( 'displays the correct checked state for Apple Pay / Google Pay in payment methods checkbox', () => {
238+
useAppleGooglePayInPaymentMethodsOptionsEnabledSettings.mockReturnValue(
239+
getMockAppleGooglePayInPaymentMethodsOptionsEnabledSettings(
240+
true,
241+
jest.fn()
242+
)
243+
);
244+
245+
renderWithSettingsProvider(
246+
<PaymentRequestSettings section="enable" />
247+
);
248+
249+
expect(
250+
screen.getByLabelText(
251+
'Enable Apple Pay / Google Pay as options in the payment methods list'
252+
)
253+
).toBeChecked();
254+
} );
255+
157256
it( 'renders general settings with defaults', () => {
158257
renderWithSettingsProvider(
159258
<PaymentRequestSettings section="general" />

0 commit comments

Comments
 (0)