From e1ac06afa7686179afa557a84837d1c4d174c555 Mon Sep 17 00:00:00 2001 From: Chi-Hsuan Huang Date: Wed, 9 Feb 2022 14:12:20 +0800 Subject: [PATCH] Fix payments extensions displayed below the offline payments options (https://github.com/woocommerce/woocommerce-admin/pull/8232) * Fix payments extensions displayed below the offline payments options Add spaces back * Add changelog * Remove the snapshot test and update payment gateway render test * Make sorting compare function as a helper function --- ...8230-display-offline-payment-options-below | 4 + .../fills/PaymentGatewaySuggestions/index.js | 60 +++--- .../PaymentGatewaySuggestions/test/index.js | 178 ++++++++++++++++++ 3 files changed, 219 insertions(+), 23 deletions(-) create mode 100644 plugins/woocommerce-admin/changelogs/fix-8230-display-offline-payment-options-below create mode 100644 plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/test/index.js diff --git a/plugins/woocommerce-admin/changelogs/fix-8230-display-offline-payment-options-below b/plugins/woocommerce-admin/changelogs/fix-8230-display-offline-payment-options-below new file mode 100644 index 00000000000..f75121f3530 --- /dev/null +++ b/plugins/woocommerce-admin/changelogs/fix-8230-display-offline-payment-options-below @@ -0,0 +1,4 @@ +Significance: patch +Type: Fix + +Fix payments extensions displayed below the offline payments options. #8232 diff --git a/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/index.js b/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/index.js index eba3b200982..55ba77a1d74 100644 --- a/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/index.js +++ b/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/index.js @@ -23,6 +23,9 @@ import { getPluginSlug } from '~/utils'; import './plugins/Bacs'; import './payment-gateway-suggestions.scss'; +const comparePaymentGatewaysByPriority = ( a, b ) => + a.recommendation_priority - b.recommendation_priority; + export const PaymentGatewaySuggestions = ( { onComplete, query } ) => { const { updatePaymentGateway } = useDispatch( PAYMENT_GATEWAYS_STORE_NAME ); const { @@ -66,6 +69,7 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => { const enrichedSuggestion = { installed: !! mappedPaymentGateways[ id ], postInstallScripts: installedGateway.post_install_scripts, + hasPlugins: suggestion.plugins && suggestion.plugins.length, enabled: installedGateway.enabled || false, needsSetup: installedGateway.needs_setup, settingsUrl: installedGateway.settings_url, @@ -140,10 +144,7 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => { () => Array.from( paymentGateways.values() ) .filter( ( gateway ) => gateway.recommendation_priority ) - .sort( - ( a, b ) => - a.recommendation_priority - b.recommendation_priority - ) + .sort( comparePaymentGatewaysByPriority ) .map( ( gateway ) => gateway.id ) .shift(), [ paymentGateways ] @@ -165,27 +166,40 @@ export const PaymentGatewaySuggestions = ( { onComplete, query } ) => { const [ wcPayGateway, enabledGateways, additionalGateways ] = useMemo( () => - Array.from( paymentGateways.values() ).reduce( - ( all, gateway ) => { - const [ wcPay, enabled, additional ] = all; - - // WCPay is handled separately when not installed and configured - if ( - gateway.plugins?.length === 1 && - gateway.plugins[ 0 ] === 'woocommerce-payments' && - ! ( gateway.installed && ! gateway.needsSetup ) - ) { - wcPay.push( gateway ); - } else if ( gateway.enabled ) { - enabled.push( gateway ); - } else { - additional.push( gateway ); + Array.from( paymentGateways.values() ) + .sort( ( a, b ) => { + if ( a.hasPlugins === b.hasPlugins ) { + return comparePaymentGatewaysByPriority( a, b ); } - return all; - }, - [ [], [], [] ] - ), + // hasPlugins payment first + if ( a.hasPlugins ) { + return -1; + } + + return 1; + } ) + .reduce( + ( all, gateway ) => { + const [ wcPay, enabled, additional ] = all; + + // WCPay is handled separately when not installed and configured + if ( + gateway.plugins?.length === 1 && + gateway.plugins[ 0 ] === 'woocommerce-payments' && + ! ( gateway.installed && ! gateway.needsSetup ) + ) { + wcPay.push( gateway ); + } else if ( gateway.enabled ) { + enabled.push( gateway ); + } else { + additional.push( gateway ); + } + + return all; + }, + [ [], [], [] ] + ), [ paymentGateways ] ); diff --git a/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/test/index.js b/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/test/index.js new file mode 100644 index 00000000000..c605411ddc8 --- /dev/null +++ b/plugins/woocommerce-admin/client/tasks/fills/PaymentGatewaySuggestions/test/index.js @@ -0,0 +1,178 @@ +/** + * External dependencies + */ +import { useSelect } from '@wordpress/data'; +import { render } from '@testing-library/react'; +/** + * Internal dependencies + */ + +import { PaymentGatewaySuggestions } from '../index'; + +jest.mock( '@wordpress/data', () => ( { + ...jest.requireActual( '@wordpress/data' ), + useSelect: jest.fn(), + useDispatch: jest.fn().mockImplementation( () => ( { + updatePaymentGateway: jest.fn(), + } ) ), +} ) ); + +const paymentGatewaySuggestions = [ + { + id: 'stripe', + title: 'Stripe', + content: + 'Accept debit and credit cards in 135+ currencies, methods such as Alipay, and one-touch checkout with Apple Pay.', + image: + 'http://localhost:8888/wp-content/plugins/woocommerce/assets/images/stripe.png', + plugins: [ 'woocommerce-gateway-stripe' ], + is_visible: true, + recommendation_priority: 3, + }, + { + id: 'ppcp-gateway', + title: 'PayPal Payments', + content: + "Safe and secure payments using credit cards or your customer's PayPal account.", + image: + 'http://localhost:8888/wp-content/plugins/woocommerce/assets/images/paypal.png', + plugins: [ 'woocommerce-paypal-payments' ], + is_visible: true, + }, + { + id: 'cod', + title: 'Cash on delivery', + content: 'Take payments in cash upon delivery.', + image: + 'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/cod.svg', + is_visible: true, + }, + { + id: 'bacs', + title: 'Direct bank transfer', + content: 'Take payments via bank transfer.', + image: + 'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/bacs.svg', + is_visible: true, + }, + { + id: 'woocommerce_payments:non-us', + title: 'WooCommerce Payments', + content: + 'Manage transactions without leaving your WordPress Dashboard. Only with WooCommerce Payments.', + image: + 'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/wcpay.svg', + plugins: [ 'woocommerce-payments' ], + description: + 'With WooCommerce Payments, you can securely accept major cards, Apple Pay, and payments in over 100 currencies. Track cash flow and manage recurring revenue directly from your store’s dashboard - with no setup costs or monthly fees.', + is_visible: true, + recommendation_priority: 1, + }, + { + id: 'eway', + title: 'Eway', + content: + 'The Eway extension for WooCommerce allows you to take credit card payments directly on your store without redirecting your customers to a third party site to make payment.', + image: + 'http://localhost:8888/wp-content/plugins/woocommerce-admin/images/onboarding/eway.png', + plugins: [ 'woocommerce-gateway-eway' ], + is_visible: true, + }, +]; + +describe( 'PaymentGatewaySuggestions', () => { + test( 'should render payment gateway lists', () => { + const onComplete = jest.fn(); + const query = {}; + useSelect.mockImplementation( () => ( { + isResolving: false, + getPaymentGateway: jest.fn(), + paymentGatewaySuggestions, + installedPaymentGateways: [], + } ) ); + + const { container } = render( + + ); + + const paymentTitleElements = container.querySelectorAll( + '.woocommerce-task-payment__title' + ); + + const paymentTitles = Array.from( paymentTitleElements ).map( + ( e ) => e.textContent + ); + + expect( paymentTitles ).toEqual( [ + 'Stripe', + 'PayPal Payments', + 'Eway', + 'Cash on delivery', + 'Direct bank transfer', + ] ); + + expect( + container.getElementsByTagName( 'title' )[ 0 ].textContent + ).toBe( 'WooCommerce Payments' ); + } ); + + test( 'should the payment gateway offline options at the bottom', () => { + const onComplete = jest.fn(); + const query = {}; + useSelect.mockImplementation( () => ( { + isResolving: false, + getPaymentGateway: jest.fn(), + paymentGatewaySuggestions, + installedPaymentGateways: [], + } ) ); + + const { container } = render( + + ); + + const paymentTitles = container.querySelectorAll( + '.woocommerce-task-payment__title' + ); + + expect( paymentTitles[ paymentTitles.length - 1 ].textContent ).toBe( + 'Direct bank transfer' + ); + } ); + + test( 'should have finish setup button for installed payment gateways', () => { + const onComplete = jest.fn(); + const query = {}; + useSelect.mockImplementation( () => ( { + isResolving: false, + getPaymentGateway: jest.fn(), + paymentGatewaySuggestions, + installedPaymentGateways: [ + { + id: 'ppcp-gateway', + title: 'PayPal Payments', + content: + "Safe and secure payments using credit cards or your customer's PayPal account.", + image: + 'http://localhost:8888/wp-content/plugins/woocommerce/assets/images/paypal.png', + plugins: [ 'woocommerce-paypal-payments' ], + is_visible: true, + }, + ], + } ) ); + + const { getByText } = render( + + ); + + expect( getByText( 'Finish setup' ) ).toBeInTheDocument(); + } ); +} );