From 689180a757a555f70e0c29d05b48df975213644a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Tue, 26 Jan 2021 15:50:19 +0100 Subject: [PATCH] Honor hidden property of cart item data and add support for experimenal property (#3732) * Honor hidden property of cart item data and add support for experimental property * Add docs to experimental property * Typo * Add protection in ProductDetails for the case where 'details' is not an array * Update ProductDetails so it works properly in cases where 'name' is not provided * Add snapshot testing to ProductDetails --- .../cart-checkout/product-details/index.js | 13 +++- .../test/__snapshots__/index.js.snap | 76 +++++++++++++++++++ .../product-details/test/index.js | 57 ++++++++++++++ ...ature-flags-and-experimental-interfaces.md | 3 +- src/StoreApi/Schemas/CartItemSchema.php | 10 ++- 5 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 assets/js/base/components/cart-checkout/product-details/test/__snapshots__/index.js.snap create mode 100644 assets/js/base/components/cart-checkout/product-details/test/index.js diff --git a/assets/js/base/components/cart-checkout/product-details/index.js b/assets/js/base/components/cart-checkout/product-details/index.js index 4c0ccde3710..1fd5a465bfc 100644 --- a/assets/js/base/components/cart-checkout/product-details/index.js +++ b/assets/js/base/components/cart-checkout/product-details/index.js @@ -12,6 +12,12 @@ import './style.scss'; // Component to display cart item data and variations. const ProductDetails = ( { details = [] } ) => { + if ( ! Array.isArray( details ) ) { + return null; + } + + details = details.filter( ( detail ) => ! detail.hidden ); + if ( details.length === 0 ) { return null; } @@ -25,7 +31,10 @@ const ProductDetails = ( { details = [] } ) => { ) }` : ''; return ( -
  • +
  • { detail.name && ( <> @@ -47,7 +56,7 @@ ProductDetails.propTypes = { details: PropTypes.arrayOf( PropTypes.shape( { display: PropTypes.string, - name: PropTypes.string.isRequired, + name: PropTypes.string, value: PropTypes.string.isRequired, } ) ), diff --git a/assets/js/base/components/cart-checkout/product-details/test/__snapshots__/index.js.snap b/assets/js/base/components/cart-checkout/product-details/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000..6a2b9f193c1 --- /dev/null +++ b/assets/js/base/components/cart-checkout/product-details/test/__snapshots__/index.js.snap @@ -0,0 +1,76 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ProductDetails should not render hidden details 1`] = ` +
      +
    • + + LOREM + : + + + + IPSUM + +
    • +
    +`; + +exports[`ProductDetails should not rendering anything if all details are hidden 1`] = `null`; + +exports[`ProductDetails should not rendering anything if details is an empty array 1`] = `null`; + +exports[`ProductDetails should render details 1`] = ` +
      +
    • + + Lorem + : + + + + Ipsum + +
    • +
    • + + LOREM + : + + + + IPSUM + +
    • +
    • + + Ipsum + +
    • +
    +`; diff --git a/assets/js/base/components/cart-checkout/product-details/test/index.js b/assets/js/base/components/cart-checkout/product-details/test/index.js new file mode 100644 index 00000000000..1dcd44aa803 --- /dev/null +++ b/assets/js/base/components/cart-checkout/product-details/test/index.js @@ -0,0 +1,57 @@ +/** + * External dependencies + */ +import TestRenderer from 'react-test-renderer'; + +/** + * Internal dependencies + */ +import ProductDetails from '..'; + +describe( 'ProductDetails', () => { + test( 'should render details', () => { + const details = [ + { name: 'Lorem', value: 'Ipsum' }, + { name: 'LOREM', value: 'Ipsum', display: 'IPSUM' }, + { value: 'Ipsum' }, + ]; + const component = TestRenderer.create( + + ); + + expect( component.toJSON() ).toMatchSnapshot(); + } ); + + test( 'should not render hidden details', () => { + const details = [ + { name: 'Lorem', value: 'Ipsum', hidden: true }, + { name: 'LOREM', value: 'Ipsum', display: 'IPSUM' }, + ]; + const component = TestRenderer.create( + + ); + + expect( component.toJSON() ).toMatchSnapshot(); + } ); + + test( 'should not rendering anything if all details are hidden', () => { + const details = [ + { name: 'Lorem', value: 'Ipsum', hidden: true }, + { name: 'LOREM', value: 'Ipsum', display: 'IPSUM', hidden: true }, + ]; + const component = TestRenderer.create( + + ); + + expect( component.toJSON() ).toMatchSnapshot(); + } ); + + test( 'should not rendering anything if details is an empty array', () => { + const details = []; + const component = TestRenderer.create( + + ); + + expect( component.toJSON() ).toMatchSnapshot(); + } ); +} ); diff --git a/docs/blocks/feature-flags-and-experimental-interfaces.md b/docs/blocks/feature-flags-and-experimental-interfaces.md index 86269fea74d..1d42038133d 100644 --- a/docs/blocks/feature-flags-and-experimental-interfaces.md +++ b/docs/blocks/feature-flags-and-experimental-interfaces.md @@ -56,4 +56,5 @@ We also have individual features or code blocks behind a feature flag, this is a - `__experimental_woocommerce_blocks_checkout_order_processed` hook when order has completed processing and is ready for payment ([experimental hook](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/accd1bbf402e043b9fc322f118ab614ba7437c92/src/StoreApi/Routes/Checkout.php#L237)). - `__experimentalDeRegisterPaymentMethod` function used to deregister a payment method, only used in tests ([experimental function](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/b07883b8b76feeb439d655b255507b24fc59e091/assets/js/blocks-registry/payment-methods/registry.js#L70)). - `__experimentalDeRegisterExpressPaymentMethod` function used to deregister an express payment method, only used in tests ([experimental function](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/b07883b8b76feeb439d655b255507b24fc59e091/assets/js/blocks-registry/payment-methods/registry.js#L74)). -- `__EXPERIMENTAL_TOTAL_LABEL_FILTER` constant which maps to the `wcBlocks.__experimental_total_label_filter` hook name. Used to filter the _Total_ label in the Cart and Checkout blocks. +- `__EXPERIMENTAL_TOTAL_LABEL_FILTER` constant which maps to the `wcBlocks.__experimental_total_label_filter` hook name. Used to filter the _Total_ label in the Cart and Checkout blocks ([experimental constant](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/9c4288b0ee46960bdc2bf8ef351d05ac23073b0c/packages/checkout/index.js#L8-L9)). +- `__experimental_woocommerce_blocks_hidden` property in a Cart item data array that allows overwriting the `hidden` property. This is useful to make some cart item data visible/hidden depending if it needs to be displayed in Blocks or shortcode ([experimental property](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/9c4288b0ee46960bdc2bf8ef351d05ac23073b0c/src/StoreApi/Schemas/CartItemSchema.php#L439-L441)). diff --git a/src/StoreApi/Schemas/CartItemSchema.php b/src/StoreApi/Schemas/CartItemSchema.php index 4173aa25bf3..6856f7eab4c 100644 --- a/src/StoreApi/Schemas/CartItemSchema.php +++ b/src/StoreApi/Schemas/CartItemSchema.php @@ -425,16 +425,20 @@ protected function format_variation_data( $variation_data, $product ) { */ protected function get_item_data( $cart_item ) { $item_data = apply_filters( 'woocommerce_get_item_data', array(), $cart_item ); - return array_map( [ $this, 'remove_tags_from_item_data' ], $item_data ); + return array_map( [ $this, 'format_item_data_element' ], $item_data ); } /** - * Remove HTML tags from cart item data. + * Remove HTML tags from cart item data and set the `hidden` property to + * `__experimental_woocommerce_blocks_hidden`. * * @param array $item_data_element Individual element of a cart item data. * @return array */ - protected function remove_tags_from_item_data( $item_data_element ) { + protected function format_item_data_element( $item_data_element ) { + if ( array_key_exists( '__experimental_woocommerce_blocks_hidden', $item_data_element ) ) { + $item_data_element['hidden'] = $item_data_element['__experimental_woocommerce_blocks_hidden']; + } return array_map( 'wp_strip_all_tags', $item_data_element ); } }