diff --git a/changelog/add-7846-test-mode-confirm-modal b/changelog/add-7846-test-mode-confirm-modal new file mode 100644 index 00000000000..0725c55b1aa --- /dev/null +++ b/changelog/add-7846-test-mode-confirm-modal @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Display a Confirmaton Modal on enabling Test Mode diff --git a/client/settings/general-settings/index.js b/client/settings/general-settings/index.js index 23512d7a66c..b85e9e07632 100644 --- a/client/settings/general-settings/index.js +++ b/client/settings/general-settings/index.js @@ -13,12 +13,14 @@ import { useDevMode, useIsWCPayEnabled, useTestMode } from 'wcpay/data'; import CardBody from '../card-body'; import InlineNotice from 'wcpay/components/inline-notice'; import SetupLivePaymentsModal from 'wcpay/overview/modal/setup-live-payments'; +import TestModeConfirmationModal from './test-mode-confirm-modal'; const GeneralSettings = () => { const [ isWCPayEnabled, setIsWCPayEnabled ] = useIsWCPayEnabled(); const [ isEnabled, updateIsTestModeEnabled ] = useTestMode(); const [ modalVisible, setModalVisible ] = useState( false ); const isDevModeEnabled = useDevMode(); + const [ testModeModalVisible, setTestModeModalVisible ] = useState( false ); return ( <> @@ -48,7 +50,15 @@ const GeneralSettings = () => { </h4> <CheckboxControl checked={ isEnabled } - onChange={ updateIsTestModeEnabled } + onChange={ ( enableTestMode ) => { + if ( enableTestMode ) { + setTestModeModalVisible( true ); + } else { + updateIsTestModeEnabled( + enableTestMode + ); + } + } } label={ __( 'Enable test mode', 'woocommerce-payments' @@ -133,6 +143,17 @@ const GeneralSettings = () => { closeModal={ () => setModalVisible( false ) } /> ) } + { testModeModalVisible && ( + <TestModeConfirmationModal + onClose={ () => { + setTestModeModalVisible( false ); + } } + onConfirm={ () => { + updateIsTestModeEnabled( true ); + setTestModeModalVisible( false ); + } } + /> + ) } </> ); }; diff --git a/client/settings/general-settings/test-mode-confirm-modal.tsx b/client/settings/general-settings/test-mode-confirm-modal.tsx new file mode 100644 index 00000000000..21e62af1ac8 --- /dev/null +++ b/client/settings/general-settings/test-mode-confirm-modal.tsx @@ -0,0 +1,63 @@ +/** @format **/ + +/** + * External dependencies + */ +import React from 'react'; +import { Button, ExternalLink } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import ConfirmationModal from '../../components/confirmation-modal'; + +interface TestModeConfirmationModalProps { + onClose: () => void; + onConfirm: () => void; +} + +const TestModeConfirmationModal: React.FC< TestModeConfirmationModalProps > = ( { + onClose, + onConfirm, +} ) => { + return ( + <ConfirmationModal + title={ __( 'Enable test mode', 'woocommerce-payments' ) } + onRequestClose={ onClose } + actions={ + <> + <Button onClick={ onClose } variant="secondary"> + { __( 'Cancel', 'woocommerce-payments' ) } + </Button> + <Button onClick={ onConfirm } variant="primary"> + { __( 'Enable', 'woocommerce-payments' ) } + </Button> + </> + } + > + <h3> + { __( + 'Are you sure you want to enable test mode?', + 'woocommerce-payments' + ) } + </h3> + <p> + { __( + "Test mode lets you try out payments, refunds, disputes and other such processes as you're working on your store " + + 'without handling live payment information. ' + + 'All incoming orders will be simulated, and test mode will have to be disabled before you can accept real orders.', + 'woocommerce-payments' + ) } + </p> + <ExternalLink + // eslint-disable-next-line max-len + href="https://woo.com/document/woopayments/testing-and-troubleshooting/testing/" + > + { __( 'Learn more about test mode', 'woocommerce-payments' ) } + </ExternalLink> + </ConfirmationModal> + ); +}; + +export default TestModeConfirmationModal; diff --git a/client/settings/general-settings/test/general-settings.test.js b/client/settings/general-settings/test/general-settings.test.js index 93f27d56b2a..2e9ae53fcf6 100644 --- a/client/settings/general-settings/test/general-settings.test.js +++ b/client/settings/general-settings/test/general-settings.test.js @@ -71,4 +71,43 @@ describe( 'GeneralSettings', () => { ); } ); + + it.each( [ [ true ], [ false ] ] )( + 'display of CheckBox when initial Test Mode = %s', + ( isEnabled ) => { + useTestMode.mockReturnValue( [ isEnabled, jest.fn() ] ); + render( <GeneralSettings /> ); + const enableTestModeCheckbox = screen.getByLabelText( + 'Enable test mode' + ); + + let expectation = expect( enableTestModeCheckbox ); + if ( ! isEnabled ) { + expectation = expectation.not; + } + expectation.toBeChecked(); + } + ); + + it.each( [ [ true ], [ false ] ] )( + 'Checks Confirmation Modal display when initial Test Mode = %s', + ( isEnabled ) => { + useTestMode.mockReturnValue( [ isEnabled, jest.fn() ] ); + render( <GeneralSettings /> ); + const enableTestModeCheckbox = screen.getByLabelText( + 'Enable test mode' + ); + fireEvent.click( enableTestModeCheckbox ); + + let expectation = expect( + screen.queryByText( + 'Are you sure you want to enable test mode?' + ) + ); + if ( isEnabled ) { + expectation = expectation.not; + } + expectation.toBeInTheDocument(); + } + ); } ); diff --git a/client/settings/general-settings/test/test-mode-confirm-modal.test.js b/client/settings/general-settings/test/test-mode-confirm-modal.test.js new file mode 100644 index 00000000000..df247142d81 --- /dev/null +++ b/client/settings/general-settings/test/test-mode-confirm-modal.test.js @@ -0,0 +1,50 @@ +/** @format */ + +/** + * External dependencies + */ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import user from '@testing-library/user-event'; + +/** + * Internal dependencies + */ +import TestModeConfirmationModal from '../test-mode-confirm-modal'; + +const mockOnClose = jest.fn(); +const mockOnConfirm = jest.fn(); + +describe( 'Dev Mode Confirmation Modal', () => { + const renderTestModeConfirmationModal = () => { + return render( + <TestModeConfirmationModal + onClose={ mockOnClose } + onConfirm={ mockOnConfirm } + /> + ); + }; + + it( 'Dev mode confirmation modal asks confirmation', () => { + renderTestModeConfirmationModal(); + expect( + screen.queryByText( 'Are you sure you want to enable test mode?' ) + ).toBeInTheDocument(); + } ); + + it( 'triggers the onClose function on close button click', () => { + renderTestModeConfirmationModal(); + const closeButton = screen.queryByRole( 'button', { name: 'Cancel' } ); + expect( mockOnClose ).not.toBeCalled(); + user.click( closeButton ); + expect( mockOnClose ).toBeCalled(); + } ); + + it( 'triggers the onConfirm function on Enable button click', () => { + renderTestModeConfirmationModal(); + const enableButton = screen.queryByRole( 'button', { name: 'Enable' } ); + expect( mockOnConfirm ).not.toBeCalled(); + user.click( enableButton ); + expect( mockOnConfirm ).toBeCalled(); + } ); +} );