10
10
namespace Magento \Checkout \Controller ;
11
11
12
12
use 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 ;
14
16
use Magento \Checkout \Model \Session as CheckoutSession ;
15
17
use Magento \Customer \Model \ResourceModel \CustomerRepository ;
16
18
use Magento \Framework \Data \Form \FormKey ;
17
19
use Magento \Framework \Api \SearchCriteriaBuilder ;
20
+ use Magento \Framework \Exception \LocalizedException ;
21
+ use Magento \Framework \Exception \NoSuchEntityException ;
22
+ use Magento \Quote \Api \Data \CartInterface ;
23
+ use Magento \Quote \Api \Data \CartItemInterface ;
18
24
use Magento \Quote \Model \Quote ;
19
25
use Magento \Quote \Api \CartRepositoryInterface ;
26
+ use Magento \Quote \Model \QuoteRepository ;
27
+ use Magento \Quote \Test \Fixture \AddProductToCart ;
28
+ use Magento \Quote \Test \Fixture \GuestCart ;
29
+ use Magento \TestFramework \Fixture \DataFixture ;
30
+ use Magento \TestFramework \Fixture \DataFixtureStorage ;
31
+ use Magento \TestFramework \Fixture \DataFixtureStorageManager ;
20
32
use Magento \TestFramework \Helper \Bootstrap ;
21
33
use Magento \TestFramework \Request ;
22
34
use Magento \Customer \Model \Session as CustomerSession ;
@@ -33,6 +45,16 @@ class CartTest extends \Magento\TestFramework\TestCase\AbstractController
33
45
/** @var CheckoutSession */
34
46
private $ checkoutSession ;
35
47
48
+ /**
49
+ * @var ProductRepositoryInterface
50
+ */
51
+ private $ productRepository ;
52
+
53
+ /**
54
+ * @var DataFixtureStorage
55
+ */
56
+ private $ fixtures ;
57
+
36
58
/**
37
59
* @inheritdoc
38
60
*/
@@ -41,6 +63,8 @@ protected function setUp(): void
41
63
parent ::setUp ();
42
64
$ this ->checkoutSession = $ this ->_objectManager ->get (CheckoutSession::class);
43
65
$ this ->_objectManager ->addSharedInstance ($ this ->checkoutSession , CheckoutSession::class);
66
+ $ this ->productRepository = $ this ->_objectManager ->create (ProductRepositoryInterface::class);
67
+ $ this ->fixtures = DataFixtureStorageManager::getStorage ();
44
68
}
45
69
46
70
/**
@@ -370,7 +394,7 @@ public function testReorderItems(bool $loggedIn, string $request)
370
394
$ customerSession = $ this ->_objectManager ->get (CustomerSession::class);
371
395
$ customerSession ->logout ();
372
396
373
- $ checkoutSession = Bootstrap::getObjectManager ()->get (Session ::class);
397
+ $ checkoutSession = Bootstrap::getObjectManager ()->get (CheckoutSession ::class);
374
398
$ expected = [];
375
399
if ($ loggedIn && $ request == Request::METHOD_POST ) {
376
400
$ customer = $ this ->_objectManager ->create (CustomerRepository::class)->get ('customer2@example.com ' );
@@ -447,4 +471,133 @@ private function prepareRequest(string $method)
447
471
break ;
448
472
}
449
473
}
474
+
475
+ /**
476
+ * @throws NoSuchEntityException
477
+ * @throws LocalizedException
478
+ */
479
+ #[
480
+ DataFixture(ProductFixture::class, ['sku ' => 's1 ' , 'stock_item ' => ['is_in_stock ' => true ]], 'p1 ' ),
481
+ DataFixture(ProductFixture::class, ['sku ' => 's2 ' ,'stock_item ' => ['is_in_stock ' => true ]], 'p2 ' ),
482
+ DataFixture(GuestCart::class, as: 'cart ' ),
483
+ DataFixture(
484
+ AddProductToCart::class,
485
+ ['cart_id ' => '$cart.id$ ' , 'product_id ' => '$p1.id$ ' , 'qty ' => 1 ],
486
+ 'item1 '
487
+ ),
488
+ DataFixture(
489
+ AddProductToCart::class,
490
+ ['cart_id ' => '$cart.id$ ' , 'product_id ' => '$p2.id$ ' , 'qty ' => 1 ],
491
+ 'item2 '
492
+ )
493
+ ]
494
+ public function testUpdatePostActionWithMultipleProducts ()
495
+ {
496
+ $ cartId = (int )$ this ->fixtures ->get ('cart ' )->getId ();
497
+ if (!$ cartId ) {
498
+ $ this ->fail ('quote fixture failed ' );
499
+ }
500
+ /** @var QuoteRepository $quoteRepository */
501
+ $ quoteRepository = Bootstrap::getObjectManager ()->get (QuoteRepository::class);
502
+ $ quote = $ quoteRepository ->get ($ cartId );
503
+
504
+ $ checkoutSession = Bootstrap::getObjectManager ()->get (CheckoutSession::class);
505
+ $ checkoutSession ->setQuoteId ($ quote ->getId ());
506
+
507
+ /** @var \Magento\Quote\Model\Quote\Item $item1 */
508
+ $ item1 = $ this ->fixtures ->get ('item1 ' );
509
+ /** @var \Magento\Quote\Model\Quote\Item $item2 */
510
+ $ item2 = $ this ->fixtures ->get ('item2 ' );
511
+
512
+ $ p1 = $ this ->fixtures ->get ('p1 ' );
513
+ /** @var $p1 Product */
514
+ $ product1 = $ this ->productRepository ->get ($ p1 ->getSku (), true );
515
+ $ stockItem = $ product1 ->getExtensionAttributes ()->getStockItem ();
516
+ $ stockItem ->setQty (0 );
517
+ $ stockItem ->setIsInStock (false );
518
+ $ stockItemRepository = Bootstrap::getObjectManager ()->get (StockItemRepositoryInterface::class);
519
+ $ stockItemRepository ->save ($ stockItem );
520
+
521
+ $ originalQuantity = 1 ;
522
+ $ updatedQuantity = 2 ;
523
+
524
+ $ this ->assertEquals (
525
+ $ originalQuantity + $ originalQuantity ,
526
+ $ quote ->getItemsQty (),
527
+ "Precondition failed: quote totals does not match. "
528
+ );
529
+
530
+ $ response = $ this ->updatePostRequest ($ quote , $ item1 , $ item2 , $ updatedQuantity , $ updatedQuantity , true );
531
+
532
+ $ this ->assertStringContainsString (
533
+ '"itemId": ' .$ item1 ->getId ().'}] ' ,
534
+ $ response ['error_message ' ]
535
+ );
536
+
537
+ $ response = $ this ->updatePostRequest ($ quote , $ item1 , $ item2 , $ originalQuantity , $ updatedQuantity , false );
538
+
539
+ $ this ->assertStringContainsString (
540
+ '"itemId": ' .$ item1 ->getId ().'}] ' ,
541
+ $ response ['error_message ' ]
542
+ );
543
+ $ this ->assertEquals (
544
+ $ originalQuantity + $ updatedQuantity ,
545
+ $ quote ->getItemsQty (),
546
+ "Precondition failed: quote totals does not match. "
547
+ );
548
+
549
+ $ response = $ this ->updatePostRequest ($ quote , $ item1 , $ item2 , $ updatedQuantity , $ updatedQuantity , false );
550
+
551
+ $ this ->assertStringContainsString (
552
+ '"itemId": ' .$ item1 ->getId ().'}] ' ,
553
+ $ response ['error_message ' ]
554
+ );
555
+ $ this ->assertEquals (
556
+ $ originalQuantity + $ updatedQuantity ,
557
+ $ quote ->getItemsQty (),
558
+ "Precondition failed: quote totals does not match. "
559
+ );
560
+ }
561
+
562
+ /**
563
+ * @param CartInterface $quote
564
+ * @param CartItemInterface $item1
565
+ * @param CartItemInterface $item2
566
+ * @param float $qty1
567
+ * @param float $qty2
568
+ * @param bool $updateQty
569
+ * @return mixed
570
+ * @throws LocalizedException
571
+ */
572
+ private function updatePostRequest (
573
+ CartInterface $ quote ,
574
+ CartItemInterface $ item1 ,
575
+ CartItemInterface $ item2 ,
576
+ float $ qty1 ,
577
+ float $ qty2 ,
578
+ bool $ updateQty = true
579
+ ): array {
580
+ /** @var FormKey $formKey */
581
+ $ formKey = Bootstrap::getObjectManager ()->get (FormKey::class);
582
+
583
+ $ request = [
584
+ 'cart ' => [
585
+ $ item1 ->getId () => ['qty ' => $ qty1 ],
586
+ $ item2 ->getId () => ['qty ' => $ qty2 ]
587
+ ],
588
+ 'update_cart_action ' => 'update_qty ' ,
589
+ 'form_key ' => $ formKey ->getFormKey (),
590
+ ];
591
+ $ this ->getRequest ()->setMethod (HttpRequest::METHOD_POST );
592
+ $ this ->getRequest ()->setPostValue ($ request );
593
+ if ($ updateQty ) {
594
+ $ this ->dispatch ('checkout/cart/updateItemQty ' );
595
+ } else {
596
+ $ this ->dispatch ('checkout/cart/updatePost ' );
597
+ $ quote ->collectTotals ();
598
+ }
599
+ $ response = $ this ->getResponse ()->getBody ();
600
+ $ response = json_decode ($ response , true );
601
+ return $ response ;
602
+ }
450
603
}
0 commit comments