Skip to content

Commit

Permalink
Merge pull request #253 from magento-l3/ACP2E-1005-clean
Browse files Browse the repository at this point in the history
ACP2E-1005: Exception in storefront when trying to search product if Display Out of Stock Products = Yes
  • Loading branch information
dhorytskyi authored Jul 21, 2022
2 parents 3f3dcad + 3fa1276 commit cf5718a
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,20 @@
namespace Magento\InventoryCatalog\Plugin\Catalog\Block\ProductList;

use Magento\Catalog\Block\Product\ProductList\Toolbar;
use Magento\Catalog\Helper\Data;
use Magento\Catalog\Model\CategoryFactory;
use Magento\Catalog\Model\Layer\Resolver as LayerResolver;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\InventorySalesApi\Api\AreProductsSalableInterface;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;

/**
* Update toolbar count for the category list view
*/
class UpdateToolbarCount
{
/**
* @var ScopeConfigInterface
*/
private $config;

/**
* @var Data
*/
private $categoryHelper;

/**
* @var CategoryFactory
*/
Expand All @@ -58,30 +48,42 @@ class UpdateToolbarCount
private $storeManager;

/**
* @param ScopeConfigInterface $config
* @param Data $categoryHelper
* Catalog layer
*
* @var LayerResolver
*/
private $layerResolver;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param CategoryFactory $categoryFactory
* @param StockRegistryInterface $stockRegistry
* @param StockConfigurationInterface $stockConfiguration
* @param AreProductsSalableInterface $areProductsSalable
* @param StoreManagerInterface $storeManager
* @param LayerResolver $layerResolver
* @param LoggerInterface $logger
*/
public function __construct(
ScopeConfigInterface $config,
Data $categoryHelper,
CategoryFactory $categoryFactory,
StockRegistryInterface $stockRegistry,
StockConfigurationInterface $stockConfiguration,
AreProductsSalableInterface $areProductsSalable,
StoreManagerInterface $storeManager
StoreManagerInterface $storeManager,
LayerResolver $layerResolver,
LoggerInterface $logger
) {
$this->config = $config;
$this->categoryHelper = $categoryHelper;
$this->categoryFactory = $categoryFactory;
$this->stockRegistry = $stockRegistry;
$this->stockConfiguration = $stockConfiguration;
$this->areProductsSalable = $areProductsSalable;
$this->storeManager = $storeManager;
$this->layerResolver = $layerResolver;
$this->logger = $logger;
}

/**
Expand All @@ -96,21 +98,25 @@ public function __construct(
public function afterGetTotalNum(Toolbar $subject, int $result): int
{
if ($this->stockConfiguration->isShowOutOfStock()) {
$currentCategory = $this->categoryHelper->getCategory();
$category = $this->categoryFactory->create()->load($currentCategory->getEntityId());
$defaultScopeId = $this->storeManager->getWebsite()->getCode();
$stock_id = (int) $this->stockRegistry->getStock($defaultScopeId)->getStockId();
$skus = [];
$items = $category->getProductCollection()->getItems();
array_walk(
$items,
function ($item) use (&$skus) {
array_push($skus, $item->getSku());
try {
$currentCategory = $this->layerResolver->get()->getCurrentCategory();
$category = $this->categoryFactory->create()->load($currentCategory->getEntityId());
$defaultScopeId = $this->storeManager->getWebsite()->getCode();
$stock_id = (int) $this->stockRegistry->getStock($defaultScopeId)->getStockId();
$skus = [];
$items = $category->getProductCollection()->getItems();
array_walk(
$items,
function ($item) use (&$skus) {
array_push($skus, $item->getSku());
}
);
$salableProducts = $this->areProductsSalable->execute($skus, $stock_id);
if ($salableProducts) {
$result = count($salableProducts);
}
);
$salableProducts = $this->areProductsSalable->execute($skus, $stock_id);
if ($salableProducts) {
$result = count($salableProducts);
} catch (\Exception $e) {
$this->logger->critical($e->getMessage());
}
}
return $result;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StorefrontValidateNoExceptionOnProductSearchTest">
<annotations>
<stories value="Exception in storefront when trying to search product if Display Out of Stock Products = Yes"/>
<title value="Validate no exception error when trying to search product if display out of stock product = yes"/>
<description value="Validate no exception error when trying to search product if display out of stock product = yes"/>
<testCaseId value="AC-5960"/>
<useCaseId value="ACP2E-1005"/>
<severity value="CRITICAL"/>
<group value="msi"/>
</annotations>
<before>
<!-- Login to backend-->
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
<!-- Display out of stock product -->
<actionGroup ref="DisplayOutOfStockProductActionGroup" stepKey="displayOutOfStockProduct"/>
<!--Create category and product.-->
<createData entity="SimpleSubCategory" stepKey="category"/>
<createData entity="SimpleProduct" stepKey="firstProduct">
<field key="status">1</field>
<requiredEntity createDataKey="category"/>
</createData>
<createData entity="SimpleProduct" stepKey="secondProduct">
<field key="status">1</field>
<requiredEntity createDataKey="category"/>
</createData>
<createData entity="SimpleProduct" stepKey="thirdProduct">
<field key="status">0</field>
<requiredEntity createDataKey="category"/>
</createData>
</before>
<after>
<!-- Don't display out of stock product -->
<actionGroup ref="NoDisplayOutOfStockProductActionGroup" stepKey="revertDisplayOutOfStockProduct"/>
<deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/>
<deleteData createDataKey="secondProduct" stepKey="deleteSecondProduct"/>
<deleteData createDataKey="thirdProduct" stepKey="deleteThirdProduct"/>
<deleteData createDataKey="category" stepKey="deleteCategory"/>
<!--Logout from backend-->
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutOfAdmin"/>
</after>

<!-- Search for the product on Storefront -->
<actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/>
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="quickSearchByProductName">
<argument name="phrase" value="simple"/>
</actionGroup>
</test>
</tests>
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@
namespace Magento\InventoryCatalog\Test\Unit\Plugin\Catalog\Block\ProductList;

use Magento\Catalog\Block\Product\ProductList\Toolbar;
use Magento\Catalog\Helper\Data;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\CategoryFactory;
use Magento\CatalogInventory\Api\Data\StockInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DB\Adapter\Pdo\Mysql;
use Magento\Framework\DB\Select;
use Magento\Framework\Exception\LocalizedException;
Expand All @@ -27,6 +25,8 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Magento\Framework\DataObject;
use Magento\Catalog\Model\Layer;
use Magento\Catalog\Model\Layer\Resolver;

/**
* Test class for Update toolbar count plugin
Expand Down Expand Up @@ -54,21 +54,11 @@ class UpdateToolbarCountTest extends TestCase
*/
private $selectMock;

/**
* @var ScopeConfigInterface|MockObject
*/
private $configMock;

/**
* @var Toolbar|MockObject
*/
private $toolbarMock;

/**
* @var Data|MockObject
*/
private $categoryHelperMock;

/**
* @var CategoryFactory|MockObject
*/
Expand Down Expand Up @@ -104,13 +94,22 @@ class UpdateToolbarCountTest extends TestCase
*/
private $storeManagerMock;

/**
* @var Layer|MockObject
*/
private $layerMock;

/**
* @var Resolver|MockObject
*/
private $resolverMock;

/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function setUp(): void
{
$objectManager = new ObjectManager($this);
$this->configMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
$this->connectionMock = $this->getMockBuilder(Mysql::class)
->disableOriginalConstructor()
->getMock();
Expand All @@ -130,7 +129,6 @@ protected function setUp(): void
$this->areProductsSalableMock = $this->createMock(AreProductsSalableInterface::class);
$this->toolbarMock = $this->createMock(Toolbar::class);
$this->categoryMock = $this->createMock(Category::class);
$this->categoryHelperMock = $this->createMock(Data::class);
$this->categoryFactoryMock = $this->getMockBuilder(CategoryFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
Expand All @@ -142,10 +140,6 @@ protected function setUp(): void
->expects($this->any())
->method('getCollection')
->willReturn($this->collectionMock);
$this->categoryHelperMock
->expects($this->any())
->method('getCategory')
->willReturn($this->categoryMock);
$this->categoryFactoryMock
->expects($this->any())
->method('create')
Expand All @@ -167,16 +161,24 @@ protected function setUp(): void
->expects($this->any())
->method('getWebsite')
->willReturn($websiteMock);

$this->resolverMock = $this->getMockBuilder(Resolver::class)
->disableOriginalConstructor()
->getMock();

$this->layerMock = $this->getMockBuilder(Layer::class)
->disableOriginalConstructor()
->getMock();

$this->model = $objectManager->getObject(
UpdateToolbarCount::class,
[
'config' => $this->configMock,
'categoryHelper' => $this->categoryHelperMock,
'categoryFactory' => $this->categoryFactoryMock,
'stockRegistry' => $this->stockRegistryMock,
'stockConfiguration' => $this->stockConfigurationMock,
'areProductsSalable' => $this->areProductsSalableMock,
'storeManager' => $this->storeManagerMock
'storeManager' => $this->storeManagerMock,
'layerResolver' => $this->resolverMock
]
);
}
Expand All @@ -185,7 +187,6 @@ protected function setUp(): void
* Test case to check afterGetTotalNum returns valid result
*
* @param array $items
* @param bool $outOfStockFlagValue
* @param int $defaultStockId
* @param int $actualResult
* @param int $expectedResult
Expand All @@ -194,11 +195,14 @@ protected function setUp(): void
*/
public function testAfterGetTotalNumReturnValidResult(
array $items,
bool $outOfStockFlagValue,
int $defaultStockId,
int $actualResult,
int $expectedResult
): void {
$this->resolverMock
->expects($this->any())
->method('get')
->willReturn($this->layerMock);
$this->stockRegistryMock
->expects($this->any())
->method('getStock')
Expand All @@ -215,11 +219,6 @@ public function testAfterGetTotalNumReturnValidResult(
$this->collectionMock->expects($this->any())
->method('getItems')
->willReturn($items);
$this->configMock
->expects($this->any())
->method('getValue')
->with('cataloginventory/options/show_out_of_stock')
->willReturn($outOfStockFlagValue);

$updatedResult = $this->model->afterGetTotalNum($this->toolbarMock, $actualResult);
$this->assertEquals($expectedResult, $updatedResult);
Expand All @@ -237,9 +236,9 @@ public function dataProviderForAfterGetTotalNum(): array
$item3 = new DataObject(['id' => 3, 'sku' => 'item3']);
$item4 = new DataObject(['id' => 4, 'sku' => 'item4']);
return [
'verify total number of products when OUT OF STOCK status YES' => [[$item1, $item2], true, 1, 2, 2],
'verify total number of products when OUT OF STOCK status NO' => [[$item2,$item3,$item4], false, 1, 4, 4],
'verify total number of products when category is empty and OUT OF STOCK status YES' => [[], true, 1, 0, 0]
'verify total number of products when OUT OF STOCK status YES' => [[$item1, $item2], 1, 2, 2],
'verify total number of products when OUT OF STOCK status NO' => [[$item2,$item3,$item4], 1, 4, 4],
'verify total number of products when category is empty and OUT OF STOCK status YES' => [[], 1, 0, 0]
];
}
}

0 comments on commit cf5718a

Please sign in to comment.