Skip to content

Commit 8cc9290

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-98521' into 2.2-develop-pr105
2 parents f027a46 + 6ca8e5a commit 8cc9290

File tree

10 files changed

+264
-6
lines changed

10 files changed

+264
-6
lines changed

app/code/Magento/Catalog/Controller/Product/Compare/Add.php

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,71 @@
66
*/
77
namespace Magento\Catalog\Controller\Product\Compare;
88

9+
use Magento\Catalog\ViewModel\Product\Checker\AddToCompareAvailability;
910
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Framework\Data\Form\FormKey\Validator;
13+
use Magento\Framework\View\Result\PageFactory;
1014

1115
/**
1216
* Add item to compare list action.
17+
*
18+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1319
*/
1420
class Add extends \Magento\Catalog\Controller\Product\Compare
1521
{
22+
/**
23+
* @var AddToCompareAvailability
24+
*/
25+
private $compareAvailability;
26+
27+
/**
28+
* @param \Magento\Framework\App\Action\Context $context
29+
* @param \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory
30+
* @param \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory
31+
* @param \Magento\Customer\Model\Session $customerSession
32+
* @param \Magento\Customer\Model\Visitor $customerVisitor
33+
* @param \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList
34+
* @param \Magento\Catalog\Model\Session $catalogSession
35+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
36+
* @param Validator $formKeyValidator
37+
* @param PageFactory $resultPageFactory
38+
* @param ProductRepositoryInterface $productRepository
39+
* @param AddToCompareAvailability|null $compareAvailability
40+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
41+
*/
42+
public function __construct(
43+
\Magento\Framework\App\Action\Context $context,
44+
\Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory,
45+
\Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory,
46+
\Magento\Customer\Model\Session $customerSession,
47+
\Magento\Customer\Model\Visitor $customerVisitor,
48+
\Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList,
49+
\Magento\Catalog\Model\Session $catalogSession,
50+
\Magento\Store\Model\StoreManagerInterface $storeManager,
51+
Validator $formKeyValidator,
52+
PageFactory $resultPageFactory,
53+
ProductRepositoryInterface $productRepository,
54+
AddToCompareAvailability $compareAvailability = null
55+
) {
56+
parent::__construct(
57+
$context,
58+
$compareItemFactory,
59+
$itemCollectionFactory,
60+
$customerSession,
61+
$customerVisitor,
62+
$catalogProductCompareList,
63+
$catalogSession,
64+
$storeManager,
65+
$formKeyValidator,
66+
$resultPageFactory,
67+
$productRepository
68+
);
69+
70+
$this->compareAvailability = $compareAvailability
71+
?: $this->_objectManager->get(AddToCompareAvailability::class);
72+
}
73+
1674
/**
1775
* Add item to compare list.
1876
*
@@ -35,7 +93,7 @@ public function execute()
3593
$product = null;
3694
}
3795

38-
if ($product && $product->isSalable()) {
96+
if ($product && $this->compareAvailability->isAvailableForCompare($product)) {
3997
$this->_catalogProductCompareList->addProduct($product);
4098
$productName = $this->_objectManager->get(
4199
\Magento\Framework\Escaper::class

app/code/Magento/Catalog/Controller/Product/Compare/Remove.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
namespace Magento\Catalog\Controller\Product\Compare;
88

9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
910
use Magento\Framework\Exception\NoSuchEntityException;
1011

1112
/**
@@ -31,7 +32,7 @@ public function execute()
3132
$product = null;
3233
}
3334

34-
if ($product && $product->isSalable()) {
35+
if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) {
3536
/** @var $item \Magento\Catalog\Model\Product\Compare\Item */
3637
$item = $this->_compareItemFactory->create();
3738
if ($this->_customerSession->isLoggedIn()) {

app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCompareActionGroup.xml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,19 @@
6767
<see selector="{{StorefrontMessagesSection.successMessage}}" userInput="You cleared the comparison list." stepKey="assertMessageCleared"/>
6868
<waitForElementVisible selector="{{StorefrontComparisonSidebarSection.noItemsMessage}}" stepKey="assertNoItems"/>
6969
</actionGroup>
70-
</actionGroups>
70+
71+
<actionGroup name="RemoveProductFromComparisonList">
72+
<arguments>
73+
<argument name="product"/>
74+
</arguments>
75+
<click selector="{{StorefrontProductCompareMainSection.removeProduct(product.name)}}" stepKey="clickRemoveProductButton"/>
76+
<waitForElementVisible selector="{{StorefrontModalConfirmationSection.okButton}}" stepKey="waitForConfirmationPopup"/>
77+
<click selector="{{StorefrontModalConfirmationSection.okButton}}" stepKey="confirmProductRemove"/>
78+
<waitForElementVisible selector="{{StorefrontMessagesSection.successMessage}}" stepKey="waitForProductRemoveSuccessMessage"/>
79+
<see selector="{{StorefrontMessagesSection.successMessage}}" userInput="You removed product {{product.name}} from the comparison list." stepKey="assertProductRemoveSuccessMessage"/>
80+
</actionGroup>
81+
82+
<actionGroup name="StorefrontCheckCompareOutOfStockProductActionGroup" extends="StorefrontCheckCompareSimpleProductActionGroup">
83+
<remove keyForRemoval="assertProductAddToCart"/>
84+
</actionGroup>
85+
</actionGroups>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
11+
<entity name="CatalogInventoryOptionsShowOutOfStockEnable">
12+
<data key="path">cataloginventory/options/show_out_of_stock</data>
13+
<data key="label">Yes</data>
14+
<data key="value">1</data>
15+
</entity>
16+
<entity name="CatalogInventoryOptionsShowOutOfStockDisable">
17+
<!-- Magento default value -->
18+
<data key="path">cataloginventory/options/show_out_of_stock</data>
19+
<data key="label">No</data>
20+
<data key="value">0</data>
21+
</entity>
22+
</entities>

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,16 @@
333333
<data key="filename">magento3</data>
334334
<data key="file_extension">jpg</data>
335335
</entity>
336+
<entity name="OutOfStockProduct" type="product">
337+
<data key="sku" unique="suffix">testSku</data>
338+
<data key="type_id">simple</data>
339+
<data key="attribute_set_id">4</data>
340+
<data key="visibility">4</data>
341+
<data key="name" unique="suffix">OutOfStockProduct</data>
342+
<data key="price">123.00</data>
343+
<data key="urlKey" unique="suffix">testurlkey</data>
344+
<data key="status">1</data>
345+
<data key="quantity">0</data>
346+
<requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity>
347+
</entity>
336348
</entities>

app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductCompareMainSection.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
-->
88

99
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10-
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd">
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="StorefrontProductCompareMainSection">
1212
<element name="pageName" type="text" selector="#maincontent h1 span"/>
1313
<element name="productLinkByName" type="button" selector="//*[@id='product-comparison']//tr//strong[@class='product-item-name']/a[contains(text(), '{{var1}}')]" parameterized="true"/>
1414
<element name="productPriceByName" type="text" selector="//*[@id='product-comparison']//td[.//strong[@class='product-item-name']/a[contains(text(), '{{var1}}')]]//span[@class='price']" parameterized="true"/>
1515
<element name="productImageByName" type="text" selector="//*[@id='product-comparison']//td[.//strong[@class='product-item-name']/a[contains(text(), '{{var1}}')]]//img[@class='product-image-photo']" parameterized="true"/>
1616
<element name="productAttributeByCodeAndProductName" type="text" selector="//*[@id='product-comparison']//tr[.//th[./span[contains(text(), '{{var1}}')]]]//td[count(//*[@id='product-comparison']//tr//td[.//strong[@class='product-item-name']/a[contains(text(), '{{var2}}')]]/preceding-sibling::td)+1]/div" parameterized="true"/>
1717
<element name="productAttributeByName" type="text" selector="//table[@id='product-comparison']/tbody/tr/th/*[contains(text(),'{{name}}')]" parameterized="true"/>
18+
<element name="removeProduct" type="button" selector="//table[@id='product-comparison']//thead//td[count(//table[@id='product-comparison']//strong[contains(@class, 'product-item-name') and contains(.,'{{productName}}')]/ancestor::td/preceding-sibling::td) + 1]//a[contains(@class, 'delete')]" parameterized="true" timeout="30"/>
1819
</section>
1920
</sections>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="AddOutOfStockProductToCompareListTest">
12+
<annotations>
13+
<features value="Catalog"/>
14+
<title value="Add out of stock product to compare list"/>
15+
<description value="Add out of stock product to compare list"/>
16+
<stories value="Add product to compare list"/>
17+
<severity value="MAJOR"/>
18+
<testCaseId value="MC-18542"/>
19+
<useCaseId value="MAGETWO-98521"/>
20+
<group value="catalog"/>
21+
</annotations>
22+
<before>
23+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockTrue"/>
24+
<createData entity="SimpleSubCategory" stepKey="createCategory"/>
25+
<createData entity="OutOfStockProduct" stepKey="createProduct">
26+
<requiredEntity createDataKey="createCategory"/>
27+
</createData>
28+
</before>
29+
<after>
30+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/>
31+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
32+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
33+
</after>
34+
35+
<!--Open product page-->
36+
<amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage"/>
37+
<!--'Add to compare' link is not available-->
38+
<dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="doNotSeeAddToCompareLink"/>
39+
40+
<!--Turn on 'out on stock' config-->
41+
<magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/>
42+
<magentoCLI command="indexer:reindex" stepKey="reindex"/>
43+
44+
<!-- Add product to comparison list -->
45+
<amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPageAgain"/>
46+
<actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="addProductToCompare">
47+
<argument name="productVar" value="$$createProduct$$"/>
48+
</actionGroup>
49+
50+
<!--See product in the comparison list-->
51+
<amOnPage url="{{StorefrontProductComparePage.url}}" stepKey="navigateToComparePage"/>
52+
<actionGroup ref="StorefrontCheckCompareOutOfStockProductActionGroup" stepKey="checkSimpleProductOnCompareListPage">
53+
<argument name="productVar" value="$$createProduct$$"/>
54+
</actionGroup>
55+
56+
<!--Go to Category page and delete product from comparison list-->
57+
<amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="onCategoryPage"/>
58+
<actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clearCompareList"/>
59+
60+
<!--Add product to compare list from Category page-->
61+
<actionGroup ref="StorefrontAddCategoryProductToCompareActionGroup" stepKey="addProductToCompareFromCategory">
62+
<argument name="productVar" value="$$createProduct$$"/>
63+
</actionGroup>
64+
65+
<!--Check that product displays on add to compare widget-->
66+
<actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="seeProductNameOnCompareWidget">
67+
<argument name="productVar" value="$$createProduct$$"/>
68+
</actionGroup>
69+
70+
<!--See product on the compare page-->
71+
<amOnPage url="{{StorefrontProductComparePage.url}}" stepKey="navigateToComparePageAgain"/>
72+
<actionGroup ref="StorefrontCheckCompareOutOfStockProductActionGroup" stepKey="checkSimpleProductOnCompareListPageAgain">
73+
<argument name="productVar" value="$$createProduct$$"/>
74+
</actionGroup>
75+
76+
<actionGroup ref="RemoveProductFromComparisonList" stepKey="removeProductFromComparisonList">
77+
<argument name="product" value="$$createProduct$$"/>
78+
</actionGroup>
79+
</test>
80+
</tests>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\ViewModel\Product\Checker;
9+
10+
use Magento\Framework\View\Element\Block\ArgumentInterface;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
13+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
14+
15+
/**
16+
* Check is available add to compare.
17+
*/
18+
class AddToCompareAvailability implements ArgumentInterface
19+
{
20+
/**
21+
* @var StockConfigurationInterface
22+
*/
23+
private $stockConfiguration;
24+
25+
/**
26+
* @param StockConfigurationInterface $stockConfiguration
27+
*/
28+
public function __construct(StockConfigurationInterface $stockConfiguration)
29+
{
30+
$this->stockConfiguration = $stockConfiguration;
31+
}
32+
33+
/**
34+
* Is product available for comparison.
35+
*
36+
* @param ProductInterface $product
37+
* @return bool
38+
*/
39+
public function isAvailableForCompare(ProductInterface $product): bool
40+
{
41+
if ((int)$product->getStatus() !== Status::STATUS_DISABLED) {
42+
return $this->isInStock($product) || $this->stockConfiguration->isShowOutOfStock();
43+
}
44+
45+
return false;
46+
}
47+
48+
/**
49+
* Get is in stock status.
50+
*
51+
* @param ProductInterface $product
52+
* @return bool
53+
*/
54+
private function isInStock(ProductInterface $product): bool
55+
{
56+
$quantityAndStockStatus = $product->getQuantityAndStockStatus();
57+
if (!$quantityAndStockStatus) {
58+
return $product->isSalable();
59+
}
60+
61+
return $quantityAndStockStatus['is_in_stock'] ?? false;
62+
}
63+
}

app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@
9191
<container name="product.info.social" label="Product social links container" htmlTag="div" htmlClass="product-social-links">
9292
<block class="Magento\Catalog\Block\Product\View" name="product.info.addto" as="addto" template="Magento_Catalog::product/view/addto.phtml">
9393
<block class="Magento\Catalog\Block\Product\View\AddTo\Compare" name="view.addto.compare" after="view.addto.wishlist"
94-
template="Magento_Catalog::product/view/addto/compare.phtml" />
94+
template="Magento_Catalog::product/view/addto/compare.phtml" >
95+
<arguments>
96+
<argument name="addToCompareViewModel" xsi:type="object">Magento\Catalog\ViewModel\Product\Checker\AddToCompareAvailability</argument>
97+
</arguments>
98+
</block>
9599
</block>
96100
<block class="Magento\Catalog\Block\Product\View" name="product.info.mailto" template="Magento_Catalog::product/view/mailto.phtml"/>
97101
</container>

app/code/Magento/Catalog/view/frontend/templates/product/view/addto/compare.phtml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
/** @var $block \Magento\Catalog\Block\Product\View\Addto\Compare */
88
?>
9-
9+
<?php $viewModel = $block->getData('addToCompareViewModel'); ?>
10+
<?php if ($viewModel->isAvailableForCompare($block->getProduct())) : ?>
1011
<a href="#" data-post='<?= /* @noEscape */ $block->getPostDataParams() ?>'
1112
data-role="add-to-links"
1213
class="action tocompare"><span><?= $block->escapeHtml(__('Add to Compare')) ?></span></a>
14+
<?php endif; ?>

0 commit comments

Comments
 (0)