From 40180ae9d6a3a60c25971e495529501c1e045e43 Mon Sep 17 00:00:00 2001 From: Raluca Stan Date: Tue, 12 Apr 2022 13:20:22 +0200 Subject: [PATCH] Register missing C&C inner blocks and update fallback template for older C& C versions (#6195) * Register missing C & C inner blocks and update fallback template for older C & C versions This will fix the issues with missing order summary inner blocks: Coupons (both in C & C blocks) and the Cart header. The issue was happening because, for example, for Cart the coupons were registred on the on frontend, but it just wasn't forced in the attributes. Because it also wasn't added to the PHP fallback layout, the render function didn't include it. For the Checkout block the coupons inner block wasn't registered at all. * Revert changes to Checkout.php, we don't need to test for inner blocks * Revert "Revert changes to Checkout.php, we don't need to test for inner blocks" This reverts commit fc39535f8476d02e35353374d9434a8723458cfa. * Fix the returned template for older Checkout block iterations * Fix Cart and Checkout templates to accommodate the Summary order inner blocks * Hide coupon form div from inner blocks if coubons are not enabled * Fix checkout coupon tests in checkout They have been written for logged in user * Fix Order Summary Heading inner block's default text * Update comments with better wording * Revert "Hide coupon form div from inner blocks if coubons are not enabled" This reverts commit ab09021b923fad4218b3016e47760ad07f6bc960. --- .../cart-order-summary-heading/attributes.ts | 2 +- .../cart-order-summary-heading/block.json | 2 +- .../cart/inner-blocks/register-components.ts | 22 +++++++--- .../inner-blocks/register-components.ts | 32 +++++++-------- src/BlockTypes/Cart.php | 41 ++++++++++++++++--- src/BlockTypes/Checkout.php | 35 ++++++++++++++-- .../shopper/cart-checkout/checkout.test.js | 7 ++-- 7 files changed, 105 insertions(+), 36 deletions(-) diff --git a/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/attributes.ts b/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/attributes.ts index fedd2b0abac..cd08b4fdff7 100644 --- a/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/attributes.ts +++ b/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/attributes.ts @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n'; export default { content: { type: 'string', - default: __( 'Heading', 'woo-gutenberg-products-block' ), + default: __( 'Cart totals', 'woo-gutenberg-products-block' ), }, lock: { type: 'object', diff --git a/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/block.json b/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/block.json index 6026baba422..86d494d7ab0 100644 --- a/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/block.json +++ b/assets/js/blocks/cart/inner-blocks/cart-order-summary-heading/block.json @@ -17,7 +17,7 @@ }, "content": { "type": "string", - "default": "Heading" + "default": "Cart totals" }, "lock": { "type": "object", diff --git a/assets/js/blocks/cart/inner-blocks/register-components.ts b/assets/js/blocks/cart/inner-blocks/register-components.ts index fb645f51d60..6db34a47bba 100644 --- a/assets/js/blocks/cart/inner-blocks/register-components.ts +++ b/assets/js/blocks/cart/inner-blocks/register-components.ts @@ -104,6 +104,16 @@ registerCheckoutBlock( { ), } ); +registerCheckoutBlock( { + metadata: metadata.CART_ORDER_SUMMARY_HEADING, + component: lazy( () => + import( + /* webpackChunkName: "cart-blocks/order-summary-heading" */ + './cart-order-summary-heading/frontend' + ) + ), +} ); + registerCheckoutBlock( { metadata: metadata.CART_ORDER_SUMMARY_SUBTOTAL, component: lazy( () => @@ -135,21 +145,21 @@ registerCheckoutBlock( { } ); registerCheckoutBlock( { - metadata: metadata.CART_ORDER_SUMMARY_SHIPPING, + metadata: metadata.CART_ORDER_SUMMARY_COUPON_FORM, component: lazy( () => import( - /* webpackChunkName: "cart-blocks/order-summary-shipping" */ - './cart-order-summary-shipping/frontend' + /* webpackChunkName: "cart-blocks/order-summary-coupon-form" */ + './cart-order-summary-coupon-form/frontend' ) ), } ); registerCheckoutBlock( { - metadata: metadata.CART_ORDER_SUMMARY_COUPON_FORM, + metadata: metadata.CART_ORDER_SUMMARY_SHIPPING, component: lazy( () => import( - /* webpackChunkName: "cart-blocks/order-summary-coupon-form" */ - './cart-order-summary-coupon-form/frontend' + /* webpackChunkName: "cart-blocks/order-summary-shipping" */ + './cart-order-summary-shipping/frontend' ) ), } ); diff --git a/assets/js/blocks/checkout/inner-blocks/register-components.ts b/assets/js/blocks/checkout/inner-blocks/register-components.ts index c605b2e2b55..a6837e41ee0 100644 --- a/assets/js/blocks/checkout/inner-blocks/register-components.ts +++ b/assets/js/blocks/checkout/inner-blocks/register-components.ts @@ -123,6 +123,16 @@ registerCheckoutBlock( { ), } ); +registerCheckoutBlock( { + metadata: metadata.CHECKOUT_ORDER_SUMMARY_CART_ITEMS, + component: lazy( () => + import( + /* webpackChunkName: "checkout-blocks/order-summary-cart-items" */ + './checkout-order-summary-cart-items/frontend' + ) + ), +} ); + registerCheckoutBlock( { metadata: metadata.CHECKOUT_ORDER_SUMMARY_SUBTOTAL, component: lazy( () => @@ -153,16 +163,6 @@ registerCheckoutBlock( { ), } ); -registerCheckoutBlock( { - metadata: metadata.CHECKOUT_ORDER_SUMMARY_SHIPPING, - component: lazy( () => - import( - /* webpackChunkName: "checkout-blocks/order-summary-shipping" */ - './checkout-order-summary-shipping/frontend' - ) - ), -} ); - registerCheckoutBlock( { metadata: metadata.CHECKOUT_ORDER_SUMMARY_COUPON_FORM, component: lazy( () => @@ -174,21 +174,21 @@ registerCheckoutBlock( { } ); registerCheckoutBlock( { - metadata: metadata.CHECKOUT_ORDER_SUMMARY_TAXES, + metadata: metadata.CHECKOUT_ORDER_SUMMARY_SHIPPING, component: lazy( () => import( - /* webpackChunkName: "checkout-blocks/order-summary-taxes" */ - './checkout-order-summary-taxes/frontend' + /* webpackChunkName: "checkout-blocks/order-summary-shipping" */ + './checkout-order-summary-shipping/frontend' ) ), } ); registerCheckoutBlock( { - metadata: metadata.CHECKOUT_ORDER_SUMMARY_CART_ITEMS, + metadata: metadata.CHECKOUT_ORDER_SUMMARY_TAXES, component: lazy( () => import( - /* webpackChunkName: "checkout-blocks/order-summary-cart-items" */ - './checkout-order-summary-cart-items/frontend' + /* webpackChunkName: "checkout-blocks/order-summary-taxes" */ + './checkout-order-summary-taxes/frontend' ) ), } ); diff --git a/src/BlockTypes/Cart.php b/src/BlockTypes/Cart.php index 58892c7741a..395699250e0 100644 --- a/src/BlockTypes/Cart.php +++ b/src/BlockTypes/Cart.php @@ -80,13 +80,21 @@ protected function render( $attributes, $content ) { wp_dequeue_script( 'selectWoo' ); wp_dequeue_style( 'select2' ); - // If the content contains new inner blocks, it means we're in the newer version of Cart. - $regex_for_new_block = '//mi'; + /** + * We need to check if $content has any templates from prior iterations of the block, in order to update to the latest iteration. + * We test the iteration version by searching for new blocks brought in by it. + * The blocks used for testing should be always available in the block (not removable by the user). + */ - $is_new = preg_match( $regex_for_new_block, $content ); + $regex_for_filled_cart_block = '//mi'; + // Filled Cart block was added in i2, so we search for it to see if we have a Cart i1 template. + $has_i1_template = ! preg_match( $regex_for_filled_cart_block, $content ); - if ( ! $is_new ) { - // This fallback needs to match the default templates defined in our Blocks. + if ( $has_i1_template ) { + /** + * This fallback structure needs to match the defaultTemplate variables defined in the block's edit.tsx files, + * starting from the parent block and going down each inner block, in the order the blocks were registered. + */ $inner_blocks_html = '$0
@@ -105,6 +113,29 @@ protected function render( $attributes, $content ) { $content = preg_replace( '/
/mi', $inner_blocks_html, $content ); $content = $content . '
'; } + + /** + * Cart i3 added inner blocks for Order summary. We need to add them to Cart i2 templates. + * The order needs to match the order in which these blocks were registered. + */ + $order_summary_with_inner_blocks = '$0 +
+
+
+
+
+
+
+ '; + // Order summary subtotal block was added in i3, so we search for it to see if we have a Cart i2 template. + $regex_for_order_summary_subtotal = '//mi'; + $regex_for_order_summary = '//mi'; + $has_i2_template = ! preg_match( $regex_for_order_summary_subtotal, $content ); + + if ( $has_i2_template ) { + $content = preg_replace( $regex_for_order_summary, $order_summary_with_inner_blocks, $content ); + } + return $content; } diff --git a/src/BlockTypes/Checkout.php b/src/BlockTypes/Checkout.php index b5cc56d8f18..6eb828b0791 100644 --- a/src/BlockTypes/Checkout.php +++ b/src/BlockTypes/Checkout.php @@ -82,12 +82,16 @@ protected function render( $attributes, $content ) { wp_dequeue_script( 'selectWoo' ); wp_dequeue_style( 'select2' ); - // If the content is empty, we may still be in the older checkout block. Insert the default list of blocks. + /** + * We need to check if $content has any templates from prior iterations of the block, in order to update to the latest iteration. + * We test the iteration version by searching for new blocks brought in by it. + * The blocks used for testing should be always available in the block (not removable by the user). + * Checkout i1's content was returning an empty div, with no data-block-name attribute + */ $regex_for_empty_block = '/
<\/div>/mi'; + $has_i1_template = preg_match( $regex_for_empty_block, $content ); - $is_empty = preg_match( $regex_for_empty_block, $content ); - - if ( $is_empty ) { + if ( $has_i1_template ) { // This fallback needs to match the default templates defined in our Blocks. $inner_blocks_html = '
@@ -109,6 +113,29 @@ protected function render( $attributes, $content ) { $content = str_replace( '
', $inner_blocks_html . '
', $content ); } + /** + * Checkout i3 added inner blocks for Order summary. + * We need to add them to Checkout i2 templates. + * The order needs to match the order in which these blocks were registered. + */ + $order_summary_with_inner_blocks = '$0 +
+
+
+
+
+
+
+ '; + // Order summary subtotal block was added in i3, so we search for it to see if we have a Checkout i2 template. + $regex_for_order_summary_subtotal = '//mi'; + $regex_for_order_summary = '//mi'; + $has_i2_template = ! preg_match( $regex_for_order_summary_subtotal, $content ); + + if ( $has_i2_template ) { + $content = preg_replace( $regex_for_order_summary, $order_summary_with_inner_blocks, $content ); + } + return $content; } diff --git a/tests/e2e/specs/shopper/cart-checkout/checkout.test.js b/tests/e2e/specs/shopper/cart-checkout/checkout.test.js index 5840b50cd99..10663f72be6 100644 --- a/tests/e2e/specs/shopper/cart-checkout/checkout.test.js +++ b/tests/e2e/specs/shopper/cart-checkout/checkout.test.js @@ -242,13 +242,15 @@ describe( 'Shopper → Checkout', () => { describe( 'Coupons', () => { beforeAll( async () => { coupon = await createCoupon( { usageLimit: 1 } ); + await merchant.login(); } ); afterAll( async () => { await withRestApi.deleteCoupon( coupon.id ); + await merchant.logout(); } ); - it( 'User can apply single-use coupon once', async () => { + it( 'Logged in user can apply single-use coupon and place order', async () => { await shopper.goToShop(); await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME ); await shopper.block.goToCheckout(); @@ -272,7 +274,6 @@ describe( 'Shopper → Checkout', () => { text: coupon.code, } ); - await shopper.block.placeOrder(); await expect( page ).toMatch( 'Your order has been received.' ); @@ -286,7 +287,7 @@ describe( 'Shopper → Checkout', () => { ); } ); - it( 'User cannot apply single-use coupon twice', async () => { + it( 'Logged in user cannot apply single-use coupon twice', async () => { await shopper.goToShop(); await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME ); await shopper.block.goToCheckout();