Prevent resetting default payment method if available payment method is still available (https://github.com/woocommerce/woocommerce-blocks/pull/7276)

* Refresh the default payment method only if the active one is unavailable

* Add new type for serializable data store payment method

* Update uses of PaymentMethods/ExpressPaymentMethods to the plain version

* Add tests for setAvailablePaymentMethods action

* Update data store key  in tests
This commit is contained in:
Thomas Roberts 2022-10-07 10:32:17 -07:00 committed by GitHub
parent 02f42ded18
commit c798378edf
7 changed files with 94 additions and 18 deletions

View File

@ -2,8 +2,8 @@
* External dependencies
*/
import {
PaymentMethods,
ExpressPaymentMethods,
PlainPaymentMethods,
PlainExpressPaymentMethods,
} from '@woocommerce/type-defs/payments';
/**
@ -109,13 +109,14 @@ export const __internalSetPaymentMethodData = (
* An available payment method is one that has been validated and can make a payment.
*/
export const __internalSetAvailablePaymentMethods = (
paymentMethods: PaymentMethods
paymentMethods: PlainPaymentMethods
) => {
return async ( { dispatch } ) => {
return async ( { dispatch, select } ) => {
// If the currently selected method is not in this new list, then we need to select a new one, or select a default.
// TODO See if we can stop this being dispatched if the currently selected method is still available.
await setDefaultPaymentMethod( paymentMethods );
const activePaymentMethod = select.getActivePaymentMethod();
if ( ! ( activePaymentMethod in paymentMethods ) ) {
await setDefaultPaymentMethod( paymentMethods );
}
dispatch( {
type: ACTION_TYPES.SET_AVAILABLE_PAYMENT_METHODS,
paymentMethods,
@ -128,7 +129,7 @@ export const __internalSetAvailablePaymentMethods = (
* An available payment method is one that has been validated and can make a payment.
*/
export const __internalSetAvailableExpressPaymentMethods = (
paymentMethods: ExpressPaymentMethods
paymentMethods: PlainExpressPaymentMethods
) => ( {
type: ACTION_TYPES.SET_AVAILABLE_EXPRESS_PAYMENT_METHODS,
paymentMethods,

View File

@ -4,8 +4,8 @@
import type { EmptyObjectType } from '@woocommerce/types';
import { getSetting } from '@woocommerce/settings';
import {
PaymentMethods,
ExpressPaymentMethods,
PlainPaymentMethods,
PlainExpressPaymentMethods,
} from '@woocommerce/type-defs/payments';
/**
@ -29,8 +29,8 @@ export interface PaymentMethodDataState {
activePaymentMethod: string;
activeSavedToken: string;
// Avilable payment methods are payment methods which have been validated and can make payment
availablePaymentMethods: PaymentMethods;
availableExpressPaymentMethods: ExpressPaymentMethods;
availablePaymentMethods: PlainPaymentMethods;
availableExpressPaymentMethods: PlainExpressPaymentMethods;
savedPaymentMethods:
| Record< string, SavedPaymentMethod[] >
| EmptyObjectType;

View File

@ -2,7 +2,7 @@
* External dependencies
*/
import { select, dispatch } from '@wordpress/data';
import { PaymentMethods } from '@woocommerce/type-defs/payments';
import { PlainPaymentMethods } from '@woocommerce/type-defs/payments';
/**
* Internal dependencies
@ -10,7 +10,7 @@ import { PaymentMethods } from '@woocommerce/type-defs/payments';
import { STORE_KEY as PAYMENT_STORE_KEY } from './constants';
export const setDefaultPaymentMethod = async (
paymentMethods: PaymentMethods
paymentMethods: PlainPaymentMethods
) => {
const paymentMethodKeys = Object.keys( paymentMethods );

View File

@ -0,0 +1,49 @@
/**
* Internal dependencies
*/
import * as setDefaultPaymentMethodFunctions from '../set-default-payment-method';
import { PAYMENT_STORE_KEY } from '..';
import { PlainPaymentMethods } from '../../../types';
const originalDispatch = jest.requireActual( '@wordpress/data' ).dispatch;
jest.mock( '../set-default-payment-method', () => ( {
setDefaultPaymentMethod: jest.fn(),
} ) );
describe( 'payment data store actions', () => {
const paymentMethods: PlainPaymentMethods = {
'wc-payment-gateway-1': {
name: 'wc-payment-gateway-1',
},
'wc-payment-gateway-2': {
name: 'wc-payment-gateway-2',
},
};
describe( 'setAvailablePaymentMethods', () => {
it( 'Does not call setDefaultPaymentGateway if the current method is still available', () => {
const actions = originalDispatch( PAYMENT_STORE_KEY );
actions.__internalSetActivePaymentMethod(
Object.keys( paymentMethods )[ 0 ]
);
actions.__internalSetAvailablePaymentMethods( paymentMethods );
expect(
setDefaultPaymentMethodFunctions.setDefaultPaymentMethod
).not.toBeCalled();
} );
it( 'Resets the default gateway if the current method is no longer available', () => {
const actions = originalDispatch( PAYMENT_STORE_KEY );
actions.__internalSetActivePaymentMethod(
Object.keys( paymentMethods )[ 0 ]
);
actions.__internalSetAvailablePaymentMethods( [
paymentMethods[ Object.keys( paymentMethods )[ 0 ] ],
] );
expect(
setDefaultPaymentMethodFunctions.setDefaultPaymentMethod
).toBeCalled();
} );
} );
} );

View File

@ -8,7 +8,7 @@ import * as wpDataFunctions from '@wordpress/data';
* Internal dependencies
*/
import { setDefaultPaymentMethod } from '../set-default-payment-method';
import { PaymentMethods } from '../../../types';
import { PlainPaymentMethods } from '../../../types';
import { PAYMENT_STORE_KEY } from '..';
const originalSelect = jest.requireActual( '@wordpress/data' ).select;
@ -19,7 +19,7 @@ describe( 'setDefaultPaymentMethod', () => {
jest.resetModules();
} );
const paymentMethods: PaymentMethods = {
const paymentMethods: PlainPaymentMethods = {
'wc-payment-gateway-1': {
name: 'wc-payment-gateway-1',
},

View File

@ -1,7 +1,10 @@
/**
* External dependencies
*/
import { PaymentMethods } from '@woocommerce/type-defs/payments';
import {
PlainPaymentMethods,
PlainExpressPaymentMethods,
} from '@woocommerce/type-defs/payments';
import type {
EmptyObjectType,
ObjectType,
@ -32,6 +35,19 @@ export type SavedPaymentMethods =
| Record< string, SavedPaymentMethod[] >
| EmptyObjectType;
export interface PaymentMethodDispatchers {
setRegisteredPaymentMethods: (
paymentMethods: PlainPaymentMethods
) => void;
setRegisteredExpressPaymentMethods: (
paymentMethods: PlainExpressPaymentMethods
) => void;
setActivePaymentMethod: (
paymentMethod: string,
paymentMethodData?: ObjectType | EmptyObjectType
) => void;
}
export interface PaymentStatusDispatchers {
pristine: () => void;
started: () => void;
@ -69,7 +85,7 @@ export type PaymentMethodCurrentStatusType = {
};
export type PaymentMethodsDispatcherType = (
paymentMethods: PaymentMethods
paymentMethods: PlainPaymentMethods
) => undefined | void;
/**

View File

@ -91,6 +91,16 @@ export type PaymentMethods =
| Record< string, PaymentMethodConfigInstance >
| EmptyObjectType;
/**
* Used to represent payment methods in a context where storing objects is not allowed, i.e. in data stores.
*/
export type PlainPaymentMethods = Record< string, { name: string } >;
/**
* Used to represent payment methods in a context where storing objects is not allowed, i.e. in data stores.
*/
export type PlainExpressPaymentMethods = PlainPaymentMethods;
export type ExpressPaymentMethods =
| Record< string, ExpressPaymentMethodConfigInstance >
| EmptyObjectType;