Commit 28b1c7daab for woocommerce
commit 28b1c7daab083e7a325d8c9763ce095c8ee4c567
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date: Thu Sep 18 14:49:58 2025 +0200
Add to Cart + Options: don't disable optimistic updates when adding grouped product children to cart if only one fails (#60992)
* Add changelog file
* Add to Cart + Options: don't disable optimistic updates when adding grouped product children to cart if only one fails
* CodeRabbit suggestions
* Further cleanup
* Add test
* Typo
diff --git a/plugins/woocommerce/changelog/fix-60979-grouped-products-optimistic-updates-on-failure b/plugins/woocommerce/changelog/fix-60979-grouped-products-optimistic-updates-on-failure
new file mode 100644
index 0000000000..3e63952678
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-60979-grouped-products-optimistic-updates-on-failure
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Add to Cart + Options: don't disable optimistic updates when adding grouped product children to cart if only one fails
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
index eebff41f79..f1ea3afad1 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
@@ -438,6 +438,8 @@ const { state, actions } = store< Store >(
existingItem.quantity = item.quantity;
if ( existingItem.key ) {
quantityChanges.cartItemsPendingQuantity = [
+ ...( quantityChanges.cartItemsPendingQuantity ??
+ [] ),
existingItem.key,
];
}
@@ -493,6 +495,10 @@ const { state, actions } = store< Store >(
const json: BatchResponse = yield res.json();
+ // Checks if the response contains an error.
+ if ( isApiErrorResponse( res, json ) )
+ throw generateError( json );
+
const errorResponses = Array.isArray( json.responses )
? json.responses.filter(
( response ) =>
@@ -501,12 +507,6 @@ const { state, actions } = store< Store >(
)
: [];
- if ( errorResponses.length > 0 ) {
- throw generateError(
- errorResponses[ 0 ].body as ApiErrorResponse
- );
- }
-
const successfulResponses = Array.isArray( json.responses )
? json.responses.filter(
( response ) =>
diff --git a/plugins/woocommerce/client/blocks/tests/e2e/tests/add-to-cart-with-options/add-to-cart-with-options.block_theme.spec.ts b/plugins/woocommerce/client/blocks/tests/e2e/tests/add-to-cart-with-options/add-to-cart-with-options.block_theme.spec.ts
index da758a47bd..3386e60320 100644
--- a/plugins/woocommerce/client/blocks/tests/e2e/tests/add-to-cart-with-options/add-to-cart-with-options.block_theme.spec.ts
+++ b/plugins/woocommerce/client/blocks/tests/e2e/tests/add-to-cart-with-options/add-to-cart-with-options.block_theme.spec.ts
@@ -370,6 +370,43 @@ test.describe( 'Add to Cart + Options Block', () => {
await expect( page.getByLabel( '3 items in cart' ) ).toBeVisible();
} );
+
+ await test.step( 'if one product succeeds and another fails, optimistic updates are applied and an error is displayed', async () => {
+ await page.reload();
+
+ // Try to add the individually sold product to cart again (it will fail).
+ const individuallySoldProductCheckbox = page.getByRole(
+ 'checkbox',
+ { name: 'Buy one of Hoodie with Logo' }
+ );
+ await individuallySoldProductCheckbox.click();
+
+ // Try to add another product to cart again (it will succeed).
+ const beanieIncreaseQuantityButton = page.getByLabel(
+ 'Increase quantity of Beanie'
+ );
+ await beanieIncreaseQuantityButton.click();
+
+ await expect( addToCartButton ).not.toHaveClass( /\bdisabled\b/ );
+ await addToCartButton.click();
+
+ // Verify button updated successfully.
+ await expect(
+ page.getByRole( 'button', {
+ name: 'Added to cart',
+ exact: true,
+ } )
+ ).toBeVisible();
+ // Verify error message is displayed.
+ await expect(
+ page.getByText(
+ 'The quantity of "Hoodie with Logo" cannot be changed'
+ )
+ ).toBeVisible();
+ // Verify optimistic updates were applied, so the product that was
+ // successfully added to cart is counted.
+ await expect( page.getByLabel( '4 items in cart' ) ).toBeVisible();
+ } );
} );
test( "doesn't allow selecting invalid variations in pills mode", async ( {