Deploy payments banner in settings page (#34326)

* Deploy payments banner in settings page, updated tests

* Add track on banner CTA click

* Add test for track

* Changelog

* Fix unit tests
This commit is contained in:
Ilyas Foo 2022-08-17 11:33:24 +08:00 committed by GitHub
parent 68985e3222
commit cd5ffed61b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 134 deletions

View File

@ -9,13 +9,18 @@ import {
WCPayBannerBody,
WCPayBannerFooter,
} from '@woocommerce/onboarding';
import { recordEvent } from '@woocommerce/tracks';
/**
* Internal dependencies
*/
import './payment-recommendations.scss';
import { getAdminSetting } from '~/utils/admin-settings';
import { usePaymentExperiment } from './use-payments-experiment';
import { usePaymentsBanner } from './use-payments-banner';
const recordTrack = () => {
recordEvent( 'settings_payments_banner_connect_click' );
};
const WCPaySettingBanner = () => {
const WC_PAY_SETUP_URL = getAdminLink(
@ -28,7 +33,11 @@ const WCPaySettingBanner = () => {
<WCPayBannerBody
textPosition="right"
actionButton={
<Button href={ WC_PAY_SETUP_URL } isPrimary>
<Button
href={ WC_PAY_SETUP_URL }
isPrimary
onClick={ recordTrack }
>
{ __( 'Get started', 'woocommerce' ) }
</Button>
}
@ -53,13 +62,9 @@ const DefaultPaymentMethodsHeaderText = () => (
);
export const PaymentsBannerWrapper = () => {
const { isLoadingExperiment, experimentAssignment } =
usePaymentExperiment();
const { hasFinishedResolution, shouldShowBanner } = usePaymentsBanner();
if (
! isLoadingExperiment &&
experimentAssignment?.variationName === 'treatment'
) {
if ( hasFinishedResolution && shouldShowBanner ) {
return <WCPaySettingBanner />;
}
return <DefaultPaymentMethodsHeaderText />;

View File

@ -1,9 +1,9 @@
/**
* External dependencies
*/
import { waitFor, render } from '@testing-library/react';
import { waitFor, render, fireEvent } from '@testing-library/react';
import { useSelect } from '@wordpress/data';
import { loadExperimentAssignment } from '@woocommerce/explat';
import { recordEvent } from '@woocommerce/tracks';
/**
* Internal dependencies
@ -15,13 +15,7 @@ jest.mock( '@wordpress/data', () => ( {
useSelect: jest.fn(),
} ) );
jest.mock( '@woocommerce/explat' );
const whenExperimentAssigned = (
experimentVariation: 'treatment' | 'control'
) =>
( loadExperimentAssignment as jest.Mock ).mockImplementation( () => {
return Promise.resolve( { variationName: experimentVariation } );
} );
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
const paymentsBannerShouldBe = async ( status: 'hidden' | 'visible' ) => {
const { container } = render( <PaymentsBannerWrapper /> );
@ -65,28 +59,14 @@ describe( 'Payment Settings Banner', () => {
whenWcPay( { supported: true, activated: false, installed: true } );
whenExperimentAssigned( 'treatment' );
await paymentsBannerShouldBe( 'visible' );
} );
it( 'should not render the banner if treatment is control', async () => {
expect.assertions( 1 );
whenWcPay( { supported: true, activated: false, installed: true } );
whenExperimentAssigned( 'control' );
await paymentsBannerShouldBe( 'hidden' );
} );
it( 'should not render anything if woocommerce payments is not supported', async () => {
expect.assertions( 1 );
whenWcPay( { supported: false, activated: false, installed: false } );
whenExperimentAssigned( 'treatment' );
await paymentsBannerShouldBe( 'hidden' );
} );
@ -95,8 +75,17 @@ describe( 'Payment Settings Banner', () => {
whenWcPay( { supported: true, activated: true, installed: true } );
whenExperimentAssigned( 'treatment' );
await paymentsBannerShouldBe( 'hidden' );
} );
it( 'should record track when clicking the action button', async () => {
whenWcPay( { supported: true, activated: false, installed: true } );
const { getByText } = render( <PaymentsBannerWrapper /> );
fireEvent.click( getByText( 'Get started' ) );
expect( recordEvent ).toHaveBeenCalledWith(
'settings_payments_banner_connect_click'
);
} );
} );

View File

@ -0,0 +1,64 @@
/**
* External dependencies
*/
import { useSelect } from '@wordpress/data';
import {
ONBOARDING_STORE_NAME,
PAYMENT_GATEWAYS_STORE_NAME,
PaymentGateway,
WCDataSelector,
} from '@woocommerce/data';
/**
* Internal dependencies
*/
import { isWcPaySupported } from './utils';
export const usePaymentsBanner = () => {
const {
installedPaymentGateways,
paymentGatewaySuggestions,
hasFinishedResolution,
} = useSelect( ( select: WCDataSelector ) => {
return {
installedPaymentGateways: select(
PAYMENT_GATEWAYS_STORE_NAME
).getPaymentGateways(),
paymentGatewaySuggestions: select(
ONBOARDING_STORE_NAME
).getPaymentGatewaySuggestions(),
hasFinishedResolution:
select( ONBOARDING_STORE_NAME ).hasFinishedResolution(
'getPaymentGatewaySuggestions'
) &&
select( PAYMENT_GATEWAYS_STORE_NAME ).hasFinishedResolution(
'getPaymentGateways'
),
};
} );
const isWcPayInstalled = installedPaymentGateways.some(
( gateway: PaymentGateway ) => {
return gateway.id === 'woocommerce_payments';
}
);
const isWcPayDisabled = installedPaymentGateways.find(
( gateway: PaymentGateway ) => {
return (
gateway.id === 'woocommerce_payments' &&
gateway.enabled === false
);
}
);
const shouldShowBanner =
isWcPaySupported( paymentGatewaySuggestions ) &&
isWcPayInstalled &&
isWcPayDisabled;
return {
hasFinishedResolution,
shouldShowBanner,
};
};

View File

@ -1,101 +0,0 @@
/**
* External dependencies
*/
import { useState, useEffect } from '@wordpress/element';
import { loadExperimentAssignment } from '@woocommerce/explat';
import { ExperimentAssignment } from '@automattic/explat-client';
import { useSelect } from '@wordpress/data';
import {
ONBOARDING_STORE_NAME,
PAYMENT_GATEWAYS_STORE_NAME,
PaymentGateway,
WCDataSelector,
} from '@woocommerce/data';
import moment from 'moment';
/**
* Internal dependencies
*/
import { isWcPaySupported } from './utils';
export const usePaymentExperiment = () => {
const [ isLoadingExperiment, setIsLoadingExperiment ] =
useState< boolean >( true );
const [ experimentAssignment, setExperimentAssignment ] =
useState< null | ExperimentAssignment >( null );
const {
installedPaymentGateways,
paymentGatewaySuggestions,
hasFinishedResolution,
} = useSelect( ( select: WCDataSelector ) => {
return {
installedPaymentGateways: select(
PAYMENT_GATEWAYS_STORE_NAME
).getPaymentGateways(),
paymentGatewaySuggestions: select(
ONBOARDING_STORE_NAME
).getPaymentGatewaySuggestions(),
hasFinishedResolution:
select( ONBOARDING_STORE_NAME ).hasFinishedResolution(
'getPaymentGatewaySuggestions'
) &&
select( PAYMENT_GATEWAYS_STORE_NAME ).hasFinishedResolution(
'getPaymentGateways'
),
};
} );
const isWcPayInstalled = installedPaymentGateways.some(
( gateway: PaymentGateway ) => {
return gateway.id === 'woocommerce_payments';
}
);
const isWcPayDisabled = installedPaymentGateways.find(
( gateway: PaymentGateway ) => {
return (
gateway.id === 'woocommerce_payments' &&
gateway.enabled === false
);
}
);
useEffect( () => {
if (
experimentAssignment === null &&
hasFinishedResolution &&
isWcPaySupported( paymentGatewaySuggestions ) &&
isWcPayInstalled &&
isWcPayDisabled
) {
const momentDate = moment().utc();
const year = momentDate.format( 'YYYY' );
const month = momentDate.format( 'MM' );
setIsLoadingExperiment( true );
loadExperimentAssignment(
`woocommerce_payments_settings_banner_${ year }_${ month }`
)
.then( ( assignment ) => {
setExperimentAssignment( assignment );
setIsLoadingExperiment( false );
} )
.catch( () => {
setIsLoadingExperiment( false );
} );
} else if ( hasFinishedResolution ) {
setIsLoadingExperiment( false );
}
}, [
experimentAssignment,
hasFinishedResolution,
isWcPayDisabled,
isWcPayInstalled,
paymentGatewaySuggestions,
] );
return {
isLoadingExperiment,
experimentAssignment,
};
};

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Deploy payments settings banner and add tracks