* Empty commit for release pull request

* Added readme.txt changelog entry

* Update HPOS compatibility snippet (https://github.com/woocommerce/woocommerce-blocks/pull/7395)

* 8.7.2 Testing notes

* Update testing notes

* Update testing notes

* Bumped version

* Refactor force billing: remove forcedBillingAddress from conditions for showBillingFields (https://github.com/woocommerce/woocommerce-blocks/pull/7393)

Co-authored-by: Niels Lange <info@nielslange.de>

* Updated testing instructions and changelog to include woocommerce/woocommerce-blocks#7393

* Updated testing zip

* Bumping version strings to new version.

* Empty commit for release pull request

* Fix wrong keys being sent in `canMakePayment` and customer data showing in the Checkout block in the editor (https://github.com/woocommerce/woocommerce-blocks/pull/7434)

* Construct args for canMakePayment with correct keys

* When the CheckoutEventsContext mounts, initialize payment store

* Destructure useSelect correctly

* Dispatch __internalInitializePaymentStore in selector tests

* Update selector name to __internalUpdateAvailablePaymentMethods

* Remove check for editor when registering checkout store

* Add check for when express payment methods have updated too

* Ensure billingAddress key exists in canMakePayment arg

* Use editor context to know if we're in editor

* Updated readme.txt

* Reverted stable tag change on readme.txt

* Testing instructions

* Cleaned out testing instructions

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Paulo Arromba <17236129+wavvves@users.noreply.github.com>
Co-authored-by: Alex Florisca <alex.florisca@automattic.com>
Co-authored-by: Tarun Vijwani <tarun.vijwani@automattic.com>
Co-authored-by: Niels Lange <info@nielslange.de>
Co-authored-by: Thomas Roberts <5656702+opr@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2022-10-21 10:59:32 +01:00 committed by GitHub
parent f6b025e894
commit d779ccaf31
13 changed files with 173 additions and 51 deletions

View File

@ -16,6 +16,7 @@ import deprecated from '@wordpress/deprecated';
import { useDispatch, useSelect } from '@wordpress/data'; import { useDispatch, useSelect } from '@wordpress/data';
import { import {
CHECKOUT_STORE_KEY, CHECKOUT_STORE_KEY,
PAYMENT_STORE_KEY,
VALIDATION_STORE_KEY, VALIDATION_STORE_KEY,
} from '@woocommerce/block-data'; } from '@woocommerce/block-data';
@ -28,6 +29,11 @@ import { STATUS } from '../../../../../data/checkout/constants';
import { useStoreEvents } from '../../../hooks/use-store-events'; import { useStoreEvents } from '../../../hooks/use-store-events';
import { useCheckoutNotices } from '../../../hooks/use-checkout-notices'; import { useCheckoutNotices } from '../../../hooks/use-checkout-notices';
import { CheckoutState } from '../../../../../data/checkout/default-state'; import { CheckoutState } from '../../../../../data/checkout/default-state';
import {
getExpressPaymentMethods,
getPaymentMethods,
} from '../../../../../blocks-registry/payment-methods/registry';
import { useEditorContext } from '../../editor-context';
type CheckoutEventsContextType = { type CheckoutEventsContextType = {
// Submits the checkout and begins processing. // Submits the checkout and begins processing.
@ -69,6 +75,32 @@ export const CheckoutEventsProvider = ( {
children: React.ReactChildren; children: React.ReactChildren;
redirectUrl: string; redirectUrl: string;
} ): JSX.Element => { } ): JSX.Element => {
const paymentMethods = getPaymentMethods();
const expressPaymentMethods = getExpressPaymentMethods();
const { isEditor } = useEditorContext();
const { __internalUpdateAvailablePaymentMethods } =
useDispatch( PAYMENT_STORE_KEY );
// Update the payment method store when paymentMethods or expressPaymentMethods changes.
// Ensure this happens in the editor even if paymentMethods is empty. This won't happen instantly when the objects
// are updated, but on the next re-render.
useEffect( () => {
if (
! isEditor &&
Object.keys( paymentMethods ).length === 0 &&
Object.keys( expressPaymentMethods ).length === 0
) {
return;
}
__internalUpdateAvailablePaymentMethods();
}, [
isEditor,
paymentMethods,
expressPaymentMethods,
__internalUpdateAvailablePaymentMethods,
] );
const checkoutActions = useDispatch( CHECKOUT_STORE_KEY ); const checkoutActions = useDispatch( CHECKOUT_STORE_KEY );
const checkoutState: CheckoutState = useSelect( ( select ) => const checkoutState: CheckoutState = useSelect( ( select ) =>
select( CHECKOUT_STORE_KEY ).getCheckoutState() select( CHECKOUT_STORE_KEY ).getCheckoutState()

View File

@ -81,7 +81,7 @@ const registerMockPaymentMethods = () => {
ariaLabel: name, ariaLabel: name,
} ); } );
} ); } );
dispatch( PAYMENT_STORE_KEY ).__internalInitializePaymentStore(); dispatch( PAYMENT_STORE_KEY ).__internalUpdateAvailablePaymentMethods();
}; };
const resetMockPaymentMethods = () => { const resetMockPaymentMethods = () => {

View File

@ -50,7 +50,7 @@ const unsubscribeInitializePaymentStore = registeredStore.subscribe(
if ( cartLoaded ) { if ( cartLoaded ) {
wpDataDispatch( wpDataDispatch(
'wc/store/payment' 'wc/store/payment'
).__internalInitializePaymentStore(); ).__internalUpdateAvailablePaymentMethods();
unsubscribeInitializePaymentStore(); unsubscribeInitializePaymentStore();
} }
} }

View File

@ -1,13 +1,7 @@
/** /**
* External dependencies * External dependencies
*/ */
import { import { createReduxStore, register } from '@wordpress/data';
createReduxStore,
register,
subscribe,
select as wpDataSelect,
dispatch as wpDataDispatch,
} from '@wordpress/data';
/** /**
* Internal dependencies * Internal dependencies
@ -17,7 +11,6 @@ import * as selectors from './selectors';
import * as actions from './actions'; import * as actions from './actions';
import reducer from './reducers'; import reducer from './reducers';
import { DispatchFromMap, SelectFromMap } from '../mapped-types'; import { DispatchFromMap, SelectFromMap } from '../mapped-types';
import { checkPaymentMethodsCanPay } from '../payment/check-payment-methods';
export const config = { export const config = {
reducer, reducer,
@ -32,22 +25,6 @@ export const config = {
const store = createReduxStore( STORE_KEY, config ); const store = createReduxStore( STORE_KEY, config );
register( store ); register( store );
const isEditor = !! wpDataSelect( 'core/editor' );
// This is needed to ensure that the payment methods are displayed in the editor
if ( isEditor ) {
const unsubscribeEditor = subscribe( async () => {
await checkPaymentMethodsCanPay();
await checkPaymentMethodsCanPay( true );
} );
const unsubscribeInitializePaymentStore = subscribe( async () => {
wpDataDispatch( 'wc/store/payment' ).__internalInitializePaymentStore();
unsubscribeEditor();
unsubscribeInitializePaymentStore();
} );
}
export const CHECKOUT_STORE_KEY = STORE_KEY; export const CHECKOUT_STORE_KEY = STORE_KEY;
declare module '@wordpress/data' { declare module '@wordpress/data' {
function dispatch( function dispatch(

View File

@ -158,13 +158,17 @@ export const __internalRemoveAvailableExpressPaymentMethod = (
/** /**
* The store is initialised once we have checked whether the payment methods registered can pay or not * The store is initialised once we have checked whether the payment methods registered can pay or not
*/ */
export function __internalInitializePaymentStore() { export function __internalUpdateAvailablePaymentMethods() {
return async ( { dispatch } ) => { return async ( { select, dispatch } ) => {
const expressRegistered = await checkPaymentMethodsCanPay( true ); const expressRegistered = await checkPaymentMethodsCanPay( true );
const registered = await checkPaymentMethodsCanPay( false ); const registered = await checkPaymentMethodsCanPay( false );
if ( registered && expressRegistered ) { const { paymentMethodsInitialized, expressPaymentMethodsInitialized } =
dispatch( __internalSetExpressPaymentMethodsInitialized( true ) ); select;
if ( registered && paymentMethodsInitialized ) {
dispatch( __internalSetPaymentMethodsInitialized( true ) ); dispatch( __internalSetPaymentMethodsInitialized( true ) );
} }
if ( expressRegistered && expressPaymentMethodsInitialized ) {
dispatch( __internalSetExpressPaymentMethodsInitialized( true ) );
}
}; };
} }

View File

@ -7,7 +7,10 @@ import {
} from '@woocommerce/type-defs/payments'; } from '@woocommerce/type-defs/payments';
import { CURRENT_USER_IS_ADMIN, getSetting } from '@woocommerce/settings'; import { CURRENT_USER_IS_ADMIN, getSetting } from '@woocommerce/settings';
import { dispatch, select } from '@wordpress/data'; import { dispatch, select } from '@wordpress/data';
import { deriveSelectedShippingRates } from '@woocommerce/base-utils'; import {
deriveSelectedShippingRates,
emptyHiddenAddressFields,
} from '@woocommerce/base-utils';
import { __, sprintf } from '@wordpress/i18n'; import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices'; import { store as noticesStore } from '@wordpress/notices';
@ -15,6 +18,7 @@ import {
getExpressPaymentMethods, getExpressPaymentMethods,
getPaymentMethods, getPaymentMethods,
} from '@woocommerce/blocks-registry'; } from '@woocommerce/blocks-registry';
import { previewCart } from '@woocommerce/resource-previews';
/** /**
* Internal dependencies * Internal dependencies
@ -22,6 +26,15 @@ import {
import { STORE_KEY as CART_STORE_KEY } from '../cart/constants'; import { STORE_KEY as CART_STORE_KEY } from '../cart/constants';
import { STORE_KEY as PAYMENT_STORE_KEY } from './constants'; import { STORE_KEY as PAYMENT_STORE_KEY } from './constants';
import { noticeContexts } from '../../base/context/event-emit'; import { noticeContexts } from '../../base/context/event-emit';
import {
EMPTY_CART_ERRORS,
EMPTY_CART_ITEM_ERRORS,
EMPTY_EXTENSIONS,
} from '../../data/constants';
import {
defaultBillingAddress,
defaultShippingAddress,
} from '../../base/context/providers/cart-checkout/customer/constants';
export const checkPaymentMethodsCanPay = async ( express = false ) => { export const checkPaymentMethodsCanPay = async ( express = false ) => {
const isEditor = !! select( 'core/editor' ); const isEditor = !! select( 'core/editor' );
@ -46,19 +59,95 @@ export const checkPaymentMethodsCanPay = async ( express = false ) => {
const noticeContext = express const noticeContext = express
? noticeContexts.EXPRESS_PAYMENTS ? noticeContexts.EXPRESS_PAYMENTS
: noticeContexts.PAYMENTS; : noticeContexts.PAYMENTS;
const cart = select( CART_STORE_KEY ).getCartData();
let cartForCanPayArgument: Record< string, unknown > = {};
let canPayArgument: Record< string, unknown > = {};
if ( ! isEditor ) {
const store = select( CART_STORE_KEY );
const cart = store.getCartData();
const cartErrors = store.getCartErrors();
const cartTotals = store.getCartTotals();
const cartIsLoading = ! store.hasFinishedResolution( 'getCartData' );
const isLoadingRates = store.isCustomerDataUpdating();
const selectedShippingMethods = deriveSelectedShippingRates( const selectedShippingMethods = deriveSelectedShippingRates(
cart.shippingRates cart.shippingRates
); );
const canPayArgument = {
cart, cartForCanPayArgument = {
cartCoupons: cart.coupons,
cartItems: cart.items,
crossSellsProducts: cart.crossSells,
cartFees: cart.fees,
cartItemsCount: cart.itemsCount,
cartItemsWeight: cart.itemsWeight,
cartNeedsPayment: cart.needsPayment,
cartNeedsShipping: cart.needsShipping,
cartItemErrors: cart.errors,
cartTotals,
cartIsLoading,
cartErrors,
billingData: emptyHiddenAddressFields( cart.billingAddress ),
billingAddress: emptyHiddenAddressFields( cart.billingAddress ),
shippingAddress: emptyHiddenAddressFields( cart.shippingAddress ),
extensions: cart.extensions,
shippingRates: cart.shippingRates,
isLoadingRates,
cartHasCalculatedShipping: cart.hasCalculatedShipping,
paymentRequirements: cart.paymentRequirements,
receiveCart: dispatch( CART_STORE_KEY ).receiveCart,
};
canPayArgument = {
cart: cartForCanPayArgument,
cartTotals: cart.totals, cartTotals: cart.totals,
cartNeedsShipping: cart.needsShipping, cartNeedsShipping: cart.needsShipping,
billingData: cart.billingAddress, billingData: cart.billingAddress,
billingAddress: cart.billingAddress,
shippingAddress: cart.shippingAddress, shippingAddress: cart.shippingAddress,
selectedShippingMethods, selectedShippingMethods,
paymentRequirements: cart.paymentRequirements, paymentRequirements: cart.paymentRequirements,
}; };
} else {
cartForCanPayArgument = {
cartCoupons: previewCart.coupons,
cartItems: previewCart.items,
crossSellsProducts: previewCart.cross_sells,
cartFees: previewCart.fees,
cartItemsCount: previewCart.items_count,
cartItemsWeight: previewCart.items_weight,
cartNeedsPayment: previewCart.needs_payment,
cartNeedsShipping: previewCart.needs_shipping,
cartItemErrors: EMPTY_CART_ITEM_ERRORS,
cartTotals: previewCart.totals,
cartIsLoading: false,
cartErrors: EMPTY_CART_ERRORS,
billingData: defaultBillingAddress,
billingAddress: defaultBillingAddress,
shippingAddress: defaultShippingAddress,
extensions: EMPTY_EXTENSIONS,
shippingRates: previewCart.shipping_rates,
isLoadingRates: false,
cartHasCalculatedShipping: previewCart.has_calculated_shipping,
paymentRequirements: previewCart.paymentRequirements,
receiveCart:
typeof previewCart?.receiveCart === 'function'
? previewCart.receiveCart
: () => undefined,
};
canPayArgument = {
cart: cartForCanPayArgument,
cartTotals: cartForCanPayArgument.totals,
cartNeedsShipping: cartForCanPayArgument.needsShipping,
billingData: cartForCanPayArgument.billingAddress,
billingAddress: cartForCanPayArgument.billingAddress,
shippingAddress: cartForCanPayArgument.shippingAddress,
selectedShippingMethods: deriveSelectedShippingRates(
cartForCanPayArgument.shippingRates
),
paymentRequirements: cartForCanPayArgument.paymentRequirements,
};
}
let paymentMethodsOrder; let paymentMethodsOrder;
if ( express ) { if ( express ) {

View File

@ -24,7 +24,6 @@ import {
CheckoutExpressPayment, CheckoutExpressPayment,
SavedPaymentMethodOptions, SavedPaymentMethodOptions,
} from '../../../blocks/cart-checkout-shared/payment-methods'; } from '../../../blocks/cart-checkout-shared/payment-methods';
import { checkPaymentMethodsCanPay } from '../check-payment-methods';
import { defaultCartState } from '../../cart/default-state'; import { defaultCartState } from '../../cart/default-state';
const originalSelect = jest.requireActual( '@wordpress/data' ).select; const originalSelect = jest.requireActual( '@wordpress/data' ).select;
@ -132,8 +131,9 @@ const registerMockPaymentMethods = ( savedCards = true ) => {
}, },
} ); } );
} ); } );
checkPaymentMethodsCanPay(); wpDataFunctions
checkPaymentMethodsCanPay( true ); .dispatch( PAYMENT_STORE_KEY )
.__internalUpdateAvailablePaymentMethods();
}; };
const resetMockPaymentMethods = () => { const resetMockPaymentMethods = () => {

View File

@ -0,0 +1,14 @@
# Testing notes and ZIP for release 8.7.3
Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/9831749/woocommerce-gutenberg-products-block.zip)
## Feature plugin and package inclusion in WooCommerce
### Fix wrong keys being sent in canMakePayment and customer data showing in the Checkout block in the editor ([7434](https://github.com/woocommerce/woocommerce-blocks/pull/7434))
#### User Facing Testing
1. Ensure you can check out using Stripe. Please also try various other payment gateways.
2. If you can, please check out with an express payment method.
3. Open the Checkout block in the editor. Ensure your customer details are not there.
4. Upload this extension [extension-for-testing.zip](https://github.com/woocommerce/woocommerce-blocks/files/9828874/extension-for-testing.zip) to your site and activate it. Ensure you see a payment method called `some-extension-name payment method` on your checkout.

View File

@ -94,6 +94,7 @@ Every release includes specific testing instructions for new features and bug fi
- [8.7.0](./870.md) - [8.7.0](./870.md)
- [8.7.1](./871.md) - [8.7.1](./871.md)
- [8.7.2](./872.md) - [8.7.2](./872.md)
- [8.7.3](./873.md)
<!-- FEEDBACK --> <!-- FEEDBACK -->

View File

@ -2,7 +2,7 @@
"name": "@woocommerce/block-library", "name": "@woocommerce/block-library",
"title": "WooCommerce Blocks", "title": "WooCommerce Blocks",
"author": "Automattic", "author": "Automattic",
"version": "8.7.2", "version": "8.7.3",
"description": "WooCommerce blocks for the Gutenberg editor.", "description": "WooCommerce blocks for the Gutenberg editor.",
"homepage": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/", "homepage": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/",
"keywords": [ "keywords": [

View File

@ -4,7 +4,7 @@ Tags: gutenberg, woocommerce, woo commerce, products, blocks, woocommerce blocks
Requires at least: 6.0 Requires at least: 6.0
Tested up to: 6.0 Tested up to: 6.0
Requires PHP: 7.0 Requires PHP: 7.0
Stable tag: 8.7.2 Stable tag: 8.7.3
License: GPLv3 License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html License URI: https://www.gnu.org/licenses/gpl-3.0.html
@ -80,6 +80,11 @@ Release and roadmap notes available on the [WooCommerce Developers Blog](https:/
== Changelog == == Changelog ==
= 8.7.3 - 2022-10-20 =
#### Bug fixes
- Fixed an issue where the argument passed to `canMakePayment` contained the incorrect keys. Also fixed the current user's customer data appearing in the editor when editing the Checkout block.
= 8.7.2 - 2022-10-13 = = 8.7.2 - 2022-10-13 =
#### Bug Fixes #### Bug Fixes

View File

@ -109,7 +109,7 @@ class Package {
NewPackage::class, NewPackage::class,
function ( $container ) { function ( $container ) {
// leave for automated version bumping. // leave for automated version bumping.
$version = '8.7.2'; $version = '8.7.3';
return new NewPackage( return new NewPackage(
$version, $version,
dirname( __DIR__ ), dirname( __DIR__ ),

View File

@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Blocks * Plugin Name: WooCommerce Blocks
* Plugin URI: https://github.com/woocommerce/woocommerce-gutenberg-products-block * Plugin URI: https://github.com/woocommerce/woocommerce-gutenberg-products-block
* Description: WooCommerce blocks for the Gutenberg editor. * Description: WooCommerce blocks for the Gutenberg editor.
* Version: 8.7.2 * Version: 8.7.3
* Author: Automattic * Author: Automattic
* Author URI: https://woocommerce.com * Author URI: https://woocommerce.com
* Text Domain: woo-gutenberg-products-block * Text Domain: woo-gutenberg-products-block