Skip to content

Commit a495ff4

Browse files
authored
LYNX-464: GraphQL error when removing other products with insufficient
1 parent c04a4b8 commit a495ff4

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed

app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
8787

8888
try {
8989
$this->updateCartItems->processCartItems($cart, $cartItems);
90-
$this->cartRepository->save($cart);
90+
$updatedCart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId);
91+
$this->cartRepository->save($updatedCart);
9192
} catch (NoSuchEntityException $e) {
9293
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
9394
} catch (LocalizedException $e) {
@@ -96,7 +97,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
9697

9798
return [
9899
'cart' => [
99-
'model' => $cart,
100+
'model' => $updatedCart,
100101
],
101102
];
102103
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,22 @@
99

1010
use Exception;
1111
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
13+
use Magento\Catalog\Test\Fixture\ProductStock as ProductStockFixture;
14+
use Magento\ConfigurableProduct\Test\Fixture\AddProductToCart as AddConfigurableProductToCartFixture;
15+
use Magento\ConfigurableProduct\Test\Fixture\Attribute as AttributeFixture;
16+
use Magento\ConfigurableProduct\Test\Fixture\Product as ConfigurableProductFixture;
17+
use Magento\Framework\Exception\NoSuchEntityException;
18+
use Magento\Quote\Model\Quote\Item;
1219
use Magento\Quote\Model\QuoteFactory;
1320
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
1421
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
22+
use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture;
23+
use Magento\Quote\Test\Fixture\GuestCart as GuestCartFixture;
24+
use Magento\Quote\Test\Fixture\QuoteIdMask as QuoteMaskFixture;
25+
use Magento\TestFramework\Fixture\DataFixture;
26+
use Magento\TestFramework\Fixture\DataFixtureStorage;
27+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
1528
use Magento\TestFramework\Helper\Bootstrap;
1629
use Magento\TestFramework\TestCase\GraphQlAbstract;
1730

@@ -40,13 +53,19 @@ class UpdateCartItemsTest extends GraphQlAbstract
4053
*/
4154
private $productRepository;
4255

56+
/**
57+
* @var DataFixtureStorage
58+
*/
59+
private $fixtures;
60+
4361
protected function setUp(): void
4462
{
4563
$objectManager = Bootstrap::getObjectManager();
4664
$this->quoteResource = $objectManager->get(QuoteResource::class);
4765
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
4866
$this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class);
4967
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
68+
$this->fixtures = DataFixtureStorageManager::getStorage();
5069
}
5170

5271
/**
@@ -320,6 +339,88 @@ public function testUpdateGiftMessageCartForItem()
320339
}
321340
}
322341

342+
#[
343+
DataFixture(ProductFixture::class, as: 'configProd1'),
344+
DataFixture(ProductFixture::class, as: 'configProd2'),
345+
DataFixture(AttributeFixture::class, as: 'attr'),
346+
DataFixture(
347+
ConfigurableProductFixture::class,
348+
['_options' => ['$attr$'], '_links' => ['$configProd1$', '$configProd2$']],
349+
'configurableProduct'
350+
),
351+
DataFixture(ProductFixture::class, as: 'simpleProduct'),
352+
DataFixture(GuestCartFixture::class, ['reserved_order_id' => 'test_quote'], 'cart'),
353+
DataFixture(
354+
AddConfigurableProductToCartFixture::class,
355+
[
356+
'cart_id' => '$cart.id$',
357+
'product_id' => '$configurableProduct.id$',
358+
'child_product_id' => '$configProd1.id$',
359+
'qty' => 10
360+
],
361+
),
362+
DataFixture(
363+
AddProductToCartFixture::class,
364+
[
365+
'cart_id' => '$cart.id$',
366+
'product_id' => '$simpleProduct.id$',
367+
'qty' => 10
368+
]
369+
),
370+
//We are reducing the stock of confProd1 to 6, which is less than the quantity (10) in cart
371+
DataFixture(ProductStockFixture::class, ['prod_id' => '$configProd1.id$', 'prod_qty' => 6]),
372+
DataFixture(QuoteMaskFixture::class, ['cart_id' => '$cart.id$'], 'quoteIdMask'),
373+
]
374+
/**
375+
* Test updateCartItems GQL error when removing other products with insufficient configurable product in cart
376+
*
377+
* configProd1 & simpleProduct is added to cart with quantity 10.
378+
* configProd1 stock is reduced to 6. So requested qty of configProd1 is not available now.
379+
* updateCartItems mutation is used to remove simpleProduct from cart
380+
*/
381+
public function testRemoveCartItemIfOtherProductStockIsReduced(): void
382+
{
383+
$maskedQuoteId = $this->fixtures->get('quoteIdMask')->getMaskedId();
384+
$simpleProdSku = $this->fixtures->get('simpleProduct')->getSku();
385+
$simpleProdId = $this->getQuoteItemIdBySku($simpleProdSku);
386+
$quantity = 0.0;
387+
388+
/*
389+
* Set simple product quantity to 0.
390+
* This will remove simple product from cart
391+
*/
392+
$query = $this->getQuery($maskedQuoteId, $simpleProdId, $quantity);
393+
$mutationResponse = $this->graphQlMutation($query);
394+
$this->assertArrayHasKey('updateCartItems', $mutationResponse);
395+
$this->assertArrayHasKey('cart', $mutationResponse['updateCartItems']);
396+
$this->assertArrayHasKey('items', $mutationResponse['updateCartItems']['cart']);
397+
$mutationResponseCartItems = $mutationResponse['updateCartItems']['cart']['items'];
398+
$this->assertCount(1, $mutationResponseCartItems);
399+
//Check that update is correctly reflected in cart
400+
$cartQuery = $this->getCartQuery($maskedQuoteId);
401+
$cartResponse = $this->graphQlQuery($cartQuery);
402+
$cartResponseItems = $cartResponse['cart']['items'];
403+
$this->assertCount(1, $cartResponseItems);
404+
}
405+
406+
/**
407+
* Returns quote item id by product's SKU
408+
*
409+
* @param string $sku
410+
* @return int
411+
* @throws NoSuchEntityException
412+
*/
413+
private function getQuoteItemIdBySku(string $sku): int
414+
{
415+
$quote = $this->quoteFactory->create();
416+
$product = $this->productRepository->get($sku);
417+
$this->quoteResource->load($quote, 'test_quote', 'reserved_order_id');
418+
/** @var Item $quoteItem */
419+
$quoteItem = $quote->getItemByProduct($product);
420+
421+
return (int)$quoteItem->getId();
422+
}
423+
323424
private function getUpdateGiftMessageQuery(string $messageTo, string $messageFrom, string $message)
324425
{
325426
$quote = $this->quoteFactory->create();

0 commit comments

Comments
 (0)