![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/dev/tests/integration/testsuite/Magento/Checkout/Block/Cart/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Checkout\Block\Cart; use Magento\Catalog\Block\Product\ProductList\AbstractLinksTest; use Magento\Catalog\ViewModel\Product\Listing\PreparePostData; use Magento\Checkout\Model\Session; use Magento\TestFramework\Helper\Xpath; use Magento\TestFramework\Quote\Model\GetQuoteByReservedOrderId; use Magento\TestFramework\Store\ExecuteInStoreContext; /** * Check the correct behavior of cross-sell products in the shopping cart * * @see \Magento\Checkout\Block\Cart\Crosssell * @magentoDbIsolation disabled * @magentoAppIsolation enabled * @magentoAppArea frontend */ class CrosssellTest extends AbstractLinksTest { private const MAX_ITEM_COUNT = 4; /** @var Session */ private $checkoutSession; /** @var string */ private $addToCartButtonXpath = "//div[contains(@class, 'actions-primary')]/button[@type='button']"; /** @var string */ private $addToCartSubmitXpath = "//div[contains(@class, 'actions-primary')]" . "/form[@data-product-sku='%s']/button[@type='submit']"; /** @var string */ private $addToLinksXpath = "//div[contains(@class, 'actions-secondary')]"; /** @var ExecuteInStoreContext */ private $executeInStoreContext; /** * @inheritdoc */ protected function setUp(): void { parent::setUp(); $this->block = $this->layout->createBlock(Crosssell::class); $this->linkType = 'crosssell'; $this->titleName = (string)__('More Choices:'); $this->checkoutSession = $this->objectManager->get(Session::class); $this->executeInStoreContext = $this->objectManager->get(ExecuteInStoreContext::class); } /** * Checks for a simple cross-sell product when block code is generated * * @magentoDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php * @return void */ public function testSimpleCrosssellProduct(): void { $relatedProduct = $this->productRepository->get('simple-1'); $this->linkProducts('simple', ['simple-1' => ['position' => 2]]); $this->setCheckoutSessionQuote('test_order_with_simple_product_without_address'); $this->prepareBlock(); $html = $this->block->toHtml(); $this->assertNotEmpty($html); $this->assertEquals( 1, Xpath::getElementsCountForXpath(sprintf($this->titleXpath, $this->linkType, $this->titleName), $html), 'Expected title is incorrect or missing!' ); $this->assertEquals( 1, Xpath::getElementsCountForXpath(sprintf($this->addToCartSubmitXpath, $relatedProduct->getSku()), $html), 'Expected add to cart button is incorrect or missing!' ); $this->assertEquals( 1, Xpath::getElementsCountForXpath($this->addToLinksXpath, $html), 'Expected add to links is incorrect or missing!' ); } /** * Checks for a cross-sell product with required option when block code is generated * * @magentoDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoDataFixture Magento/Catalog/_files/product_virtual_with_options.php * @return void */ public function testCrosssellProductWithRequiredOption(): void { $this->linkProducts('simple', ['virtual' => ['position' => 1]]); $this->setCheckoutSessionQuote('test_order_with_simple_product_without_address'); $this->prepareBlock(); $html = $this->block->toHtml(); $this->assertEquals( 1, Xpath::getElementsCountForXpath($this->addToCartButtonXpath, $html), 'Expected add to cart button is incorrect or missing!' ); } /** * Test the display of cross-sell products in the block * * @dataProvider displayLinkedProductsProvider * @magentoDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoDataFixture Magento/Catalog/_files/products_list.php * @param array $data * @return void */ public function testDisplayCrosssellProducts(array $data): void { $this->updateProducts($data['updateProducts']); $this->linkProducts('simple', $this->existingProducts); $items = $this->getBlockItems('test_order_with_simple_product_without_address'); $this->assertEquals( $data['expectedProductLinks'], $this->getActualLinks($items), 'Expected cross-sell products do not match actual cross-sell products!' ); } /** * Test the position and max count of cross-sell products in the block * * @magentoDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php * @magentoDataFixture Magento/Catalog/_files/products_list.php * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php * @return void */ public function testPositionCrosssellProducts(): void { $positionData = array_merge_recursive( $this->getPositionData(), [ 'productLinks' => [ 'simple-1' => ['position' => 5], 'simple2' => ['position' => 4], ], 'expectedProductLinks' => [ 'simple2', ], ] ); $this->linkProducts('simple', $positionData['productLinks']); $items = $this->getBlockItems('test_order_with_simple_product_without_address'); $this->assertCount( self::MAX_ITEM_COUNT, $items, 'Expected quantity of cross-sell products do not match the actual quantity!' ); $this->assertEquals( $positionData['expectedProductLinks'], $this->getActualLinks($items), 'Expected cross-sell products do not match actual cross-sell products!' ); } /** * Test the position and max count of cross-sell products in the block * when set last added product in checkout session * * @dataProvider positionWithLastAddedProductProvider * @magentoDataFixture Magento/Sales/_files/quote_with_multiple_products.php * @magentoDataFixture Magento/Catalog/_files/products_list.php * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php * @param array $positionData * @param array $expectedProductLinks * @return void */ public function testPositionCrosssellProductsWithLastAddedProduct( array $positionData, array $expectedProductLinks ): void { foreach ($positionData as $sku => $productLinks) { $this->linkProducts($sku, $productLinks); } $this->checkoutSession->setLastAddedProductId($this->productRepository->get('simple-tableRate-1')->getId()); $items = $this->getBlockItems('tableRate'); $this->assertCount( self::MAX_ITEM_COUNT, $items, 'Expected quantity of cross-sell products do not match the actual quantity!' ); $this->assertEquals( $expectedProductLinks, $this->getActualLinks($items), 'Expected cross-sell products do not match actual cross-sell products!' ); } /** * Provide test data to verify the position of linked products of the last added product. * * @return array */ public function positionWithLastAddedProductProvider(): array { return [ 'less_four_linked_products_to_last_added_product' => [ 'positionData' => [ 'simple-tableRate-1' => [ 'simple-249' => ['position' => 2], 'simple-156' => ['position' => 1], ], 'simple-tableRate-2' => [ 'simple-1' => ['position' => 2], 'simple2' => ['position' => 1], 'wrong-simple' => ['position' => 3], ], ], 'expectedProductLinks' => [ 'simple-156', 'simple-249', 'simple2', 'simple-1', ], ], 'four_linked_products_to_last_added_product' => [ 'positionData' => [ 'simple-tableRate-1' => [ 'wrong-simple' => ['position' => 3], 'simple-249' => ['position' => 1], 'simple-156' => ['position' => 2], 'simple2' => ['position' => 4], ], 'simple-tableRate-2' => [ 'simple-1' => ['position' => 1], ], ], 'expectedProductLinks' => [ 'simple-249', 'simple-156', 'wrong-simple', 'simple2', ], ], ]; } /** * Test the display of cross-sell products in the block on different websites * * @dataProvider multipleWebsitesLinkedProductsProvider * @magentoDataFixture Magento/Catalog/_files/products_with_websites_and_stores.php * @magentoDataFixture Magento/Sales/_files/quote_with_multiple_products.php * @magentoDataFixture Magento/Catalog/_files/products_list.php * @param array $data * @return void */ public function testMultipleWebsitesCrosssellProducts(array $data): void { $this->updateProducts($this->prepareProductsWebsiteIds()); $productLinks = array_merge($this->existingProducts, $data['productLinks']); $this->linkProducts('simple-tableRate-1', $productLinks); $items = $this->executeInStoreContext->execute($data['storeCode'], [$this, 'getBlockItems'], 'tableRate'); $this->assertEquals( $data['expectedProductLinks'], $this->getActualLinks($items), 'Expected cross-sell products do not match actual cross-sell products!' ); } /** * Test the invisibility of cross-sell products in the block which added to cart * * @magentoDataFixture Magento/Sales/_files/quote_with_multiple_products.php * @magentoDataFixture Magento/Catalog/_files/product_simple_duplicated.php * @return void */ public function testInvisibilityCrosssellProductAddedToCart(): void { $productLinks = [ 'simple-1' => ['position' => 1], 'simple-tableRate-2' => ['position' => 2], ]; $this->linkProducts('simple-tableRate-1', $productLinks); $items = $this->getBlockItems('tableRate'); $this->assertEquals( ['simple-1'], $this->getActualLinks($items), 'Expected cross-sell products do not match actual cross-sell products!' ); } /** * Get products of block when quote in checkout session * * @param string $reservedOrderId * @return array */ public function getBlockItems(string $reservedOrderId): array { $this->setCheckoutSessionQuote($reservedOrderId); return $this->block->getItems(); } /** * @inheritdoc */ protected function prepareBlock(): void { parent::prepareBlock(); $this->block->setViewModel($this->objectManager->get(PreparePostData::class)); } /** * @inheritdoc */ protected function prepareProductsWebsiteIds(): array { $productsWebsiteIds = parent::prepareProductsWebsiteIds(); $simple = $productsWebsiteIds['simple-1']; unset($productsWebsiteIds['simple-1']); return array_merge($productsWebsiteIds, ['simple-tableRate-1' => $simple]); } /** * Set quoteId in checkoutSession object. * * @param string $reservedOrderId * @return void */ private function setCheckoutSessionQuote(string $reservedOrderId): void { $this->checkoutSession->clearQuote(); $quote = $this->objectManager->get(GetQuoteByReservedOrderId::class)->execute($reservedOrderId); if ($quote !== null) { $this->checkoutSession->setQuoteId($quote->getId()); } } }