1010namespace Magento \Checkout \Controller ;
1111
1212use Magento \Catalog \Api \ProductRepositoryInterface ;
13- use Magento \Checkout \Model \Session ;
13+ use Magento \Catalog \Model \Product ;
14+ use Magento \Catalog \Test \Fixture \Product as ProductFixture ;
15+ use Magento \CatalogInventory \Api \StockItemRepositoryInterface ;
1416use Magento \Checkout \Model \Session as CheckoutSession ;
1517use Magento \Customer \Model \ResourceModel \CustomerRepository ;
1618use Magento \Framework \Data \Form \FormKey ;
1719use Magento \Framework \Api \SearchCriteriaBuilder ;
1820use Magento \Quote \Model \Quote ;
1921use Magento \Quote \Api \CartRepositoryInterface ;
22+ use Magento \Quote \Model \QuoteRepository ;
23+ use Magento \Quote \Test \Fixture \AddProductToCart ;
24+ use Magento \Quote \Test \Fixture \GuestCart ;
25+ use Magento \TestFramework \Fixture \DataFixture ;
26+ use Magento \TestFramework \Fixture \DataFixtureStorage ;
27+ use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
2028use Magento \TestFramework \Helper \Bootstrap ;
2129use Magento \TestFramework \Request ;
2230use Magento \Customer \Model \Session as CustomerSession ;
@@ -33,6 +41,16 @@ class CartTest extends \Magento\TestFramework\TestCase\AbstractController
3341 /** @var CheckoutSession */
3442 private $ checkoutSession ;
3543
44+ /**
45+ * @var ProductRepositoryInterface
46+ */
47+ private $ productRepository ;
48+
49+ /**
50+ * @var DataFixtureStorage
51+ */
52+ private $ fixtures ;
53+
3654 /**
3755 * @inheritdoc
3856 */
@@ -41,6 +59,8 @@ protected function setUp(): void
4159 parent ::setUp ();
4260 $ this ->checkoutSession = $ this ->_objectManager ->get (CheckoutSession::class);
4361 $ this ->_objectManager ->addSharedInstance ($ this ->checkoutSession , CheckoutSession::class);
62+ $ this ->productRepository = $ this ->_objectManager ->create (ProductRepositoryInterface::class);
63+ $ this ->fixtures = DataFixtureStorageManager::getStorage ();
4464 }
4565
4666 /**
@@ -447,4 +467,98 @@ private function prepareRequest(string $method)
447467 break ;
448468 }
449469 }
470+
471+ #[
472+ DataFixture(ProductFixture::class, ['sku ' => 's1 ' , 'stock_item ' => ['is_in_stock ' => true ]], 'p1 ' ),
473+ DataFixture(ProductFixture::class, ['sku ' => 's2 ' ,'stock_item ' => ['is_in_stock ' => true ]], 'p2 ' ),
474+ DataFixture(GuestCart::class, as: 'cart ' ),
475+ DataFixture(
476+ AddProductToCart::class,
477+ ['cart_id ' => '$cart.id$ ' , 'product_id ' => '$p1.id$ ' , 'qty ' => 1 ],
478+ 'item1 '
479+ ),
480+ DataFixture(
481+ AddProductToCart::class,
482+ ['cart_id ' => '$cart.id$ ' , 'product_id ' => '$p2.id$ ' , 'qty ' => 1 ],
483+ 'item2 '
484+ )
485+ ]
486+ public function testUpdatePostActionWithMultipleProducts () {
487+ $ cartId = (int )$ this ->fixtures ->get ('cart ' )->getId ();
488+ if (!$ cartId ) {
489+ $ this ->fail ('quote fixture failed ' );
490+ }
491+ /** @var QuoteRepository $quoteRepository */
492+ $ quoteRepository = Bootstrap::getObjectManager ()->get (QuoteRepository::class);
493+ $ quote = $ quoteRepository ->get ($ cartId );
494+
495+ $ checkoutSession = Bootstrap::getObjectManager ()->get (CheckoutSession::class);
496+ $ checkoutSession ->setQuoteId ($ quote ->getId ());
497+
498+ /** @var \Magento\Quote\Model\Quote\Item $item1 */
499+ $ item1 = $ this ->fixtures ->get ('item1 ' );
500+ /** @var \Magento\Quote\Model\Quote\Item $item2 */
501+ $ item2 = $ this ->fixtures ->get ('item2 ' );
502+
503+ $ p1 = $ this ->fixtures ->get ('p1 ' );
504+ /** @var $p1 Product */
505+ $ product1 = $ this ->productRepository ->get ($ p1 ->getSku (), true );
506+ $ stockItem = $ product1 ->getExtensionAttributes ()->getStockItem ();
507+ $ stockItem ->setQty (0 );
508+ $ stockItem ->setIsInStock (false );
509+ $ stockItemRepository = Bootstrap::getObjectManager ()->get (StockItemRepositoryInterface::class);
510+ $ stockItemRepository ->save ($ stockItem );
511+
512+ $ originalQuantity = 1 ;
513+ $ updatedQuantity = 2 ;
514+
515+ $ this ->assertEquals (
516+ $ quote ->getItemsQty (),
517+ $ originalQuantity + $ originalQuantity ,
518+ "Precondition failed: invalid quote item quantity "
519+ );
520+
521+ /** @var FormKey $formKey */
522+ $ formKey = Bootstrap::getObjectManager ()->get (FormKey::class);
523+
524+ $ request = [
525+ 'form_key ' => $ formKey ->getFormKey (),
526+ 'cart ' => [
527+ $ item1 ->getId () => ['qty ' => $ updatedQuantity ],
528+ $ item2 ->getId () => ['qty ' => $ updatedQuantity ]
529+ ]
530+ ];
531+
532+ $ this ->getRequest ()->setMethod (HttpRequest::METHOD_POST );
533+ $ this ->getRequest ()->setPostValue ($ request );
534+ $ this ->dispatch ('checkout/cart/updateItemQty ' );
535+ $ response = $ this ->getResponse ()->getBody ();
536+ $ response = json_decode ($ response , true );
537+
538+ $ this ->assertContains ('[{"error":"There are no source items with the in stock status","itemId": ' .$ item1 ->getId ().'}] ' , $ response );
539+
540+ $ request = [
541+ 'cart ' => [
542+ $ item1 ->getId () => ['qty ' => $ originalQuantity ],
543+ $ item2 ->getId () => ['qty ' => $ updatedQuantity ]
544+ ],
545+ 'update_cart_action ' => 'update_qty ' ,
546+ 'form_key ' => $ formKey ->getFormKey (),
547+ ];
548+ $ this ->getRequest ()->setMethod (HttpRequest::METHOD_POST );
549+ $ this ->getRequest ()->setPostValue ($ request );
550+ $ this ->dispatch ('checkout/cart/updatePost ' );
551+ $ response = $ this ->getResponse ()->getBody ();
552+ $ response = json_decode ($ response , true );
553+
554+ $ this ->assertContains ('[{"error":"There are no source items with the in stock status","itemId": ' .$ item1 ->getId ().'}] ' , $ response );
555+
556+ $ quote ->collectTotals ();
557+
558+ $ this ->assertEquals (
559+ $ quote ->getItemsQty (),
560+ $ originalQuantity + $ updatedQuantity ,
561+ "Precondition failed: invalid quote item quantity "
562+ );
563+ }
450564}
0 commit comments