From b7cc56dd81a44eaa2b7764b038dbc453b8cf7e55 Mon Sep 17 00:00:00 2001 From: Seghir Nadir Date: Fri, 10 Dec 2021 16:26:57 +0100 Subject: [PATCH] Update item quantity if server result is different from client (#5352) * respect when quantity changes from up * add test --- .../cart/use-store-cart-item-quantity.ts | 3 +++ .../blocks/cart-checkout/cart/test/block.js | 27 +++++++++++++++++++ assets/js/data/cart/actions.ts | 3 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/assets/js/base/context/hooks/cart/use-store-cart-item-quantity.ts b/assets/js/base/context/hooks/cart/use-store-cart-item-quantity.ts index cf95a22f6bd..9575ff65ef7 100644 --- a/assets/js/base/context/hooks/cart/use-store-cart-item-quantity.ts +++ b/assets/js/base/context/hooks/cart/use-store-cart-item-quantity.ts @@ -66,6 +66,9 @@ export const useStoreCartItemQuantity = ( storeKey ); + // Update local state when server updates. + useEffect( () => setQuantity( cartItemQuantity ), [ cartItemQuantity ] ); + // Track when things are already pending updates. const isPending = useSelect( ( select ) => { diff --git a/assets/js/blocks/cart-checkout/cart/test/block.js b/assets/js/blocks/cart-checkout/cart/test/block.js index 0b62614defd..617ed41d306 100644 --- a/assets/js/blocks/cart-checkout/cart/test/block.js +++ b/assets/js/blocks/cart-checkout/cart/test/block.js @@ -178,4 +178,31 @@ describe( 'Testing cart', () => { await waitFor( () => expect( fetchMock ).toHaveBeenCalled() ); expect( screen.getAllByRole( 'cell' )[ 1 ] ).toHaveTextContent( '16€' ); } ); + + it( 'updates quantity when changed in server', async () => { + const cart = { + ...previewCart, + // Make it so there is only one item to simplify things. + items: [ + { + ...previewCart.items[ 0 ], + quantity: 5, + }, + ], + }; + const itemName = cart.items[ 0 ].name; + render( ); + + await waitFor( () => expect( fetchMock ).toHaveBeenCalled() ); + const quantityInput = screen.getByLabelText( + `Quantity of ${ itemName } in your cart.` + ); + expect( quantityInput.value ).toBe( '2' ); + + act( () => { + dispatch( storeKey ).receiveCart( cart ); + } ); + + expect( quantityInput.value ).toBe( '5' ); + } ); } ); diff --git a/assets/js/data/cart/actions.ts b/assets/js/data/cart/actions.ts index 197f05a14e7..892247b11b8 100644 --- a/assets/js/data/cart/actions.ts +++ b/assets/js/data/cart/actions.ts @@ -393,11 +393,10 @@ export function* changeCartItemQuantity( // eslint-disable-next-line @typescript-eslint/no-explicit-any -- unclear how to represent multiple different yields as type ): Generator< unknown, void, any > { const cartItem = yield select( CART_STORE_KEY, 'getCartItem', cartItemKey ); - yield itemIsPendingQuantity( cartItemKey ); - if ( cartItem?.quantity === quantity ) { return; } + yield itemIsPendingQuantity( cartItemKey ); try { const { response } = yield apiFetchWithHeaders( { path: '/wc/store/cart/update-item',