Skip to content

Commit fd1fe53

Browse files
MC-29690: Layered Navigation with in stock/out of stock products on Category page
1 parent 420a8b6 commit fd1fe53

File tree

4 files changed

+240
-0
lines changed

4 files changed

+240
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\Product\Type;
11+
use Magento\Catalog\Model\Product\Visibility;
12+
use Magento\Catalog\Model\ProductFactory;
13+
use Magento\Store\Api\WebsiteRepositoryInterface;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
16+
require __DIR__ . '/category.php';
17+
18+
$objectManager = Bootstrap::getObjectManager();
19+
/** @var ProductFactory $productFactory */
20+
$productFactory = $objectManager->get(ProductFactory::class);
21+
/** @var WebsiteRepositoryInterface $websiteRepository */
22+
$websiteRepository = $objectManager->get(WebsiteRepositoryInterface::class);
23+
$defaultWebsiteId = $websiteRepository->get('base')->getId();
24+
$product = $productFactory->create();
25+
$product->isObjectNew(true);
26+
$product->setTypeId(Type::TYPE_SIMPLE)
27+
->setAttributeSetId($product->getDefaultAttributeSetId())
28+
->setWebsiteIds([$defaultWebsiteId])
29+
->setName('Simple Product In Stock')
30+
->setSku('in-stock-product')
31+
->setPrice(10)
32+
->setWeight(1)
33+
->setShortDescription("Short description")
34+
->setTaxClassId(0)
35+
->setDescription('Description with <b>html tag</b>')
36+
->setMetaTitle('meta title')
37+
->setMetaKeyword('meta keyword')
38+
->setMetaDescription('meta description')
39+
->setVisibility(Visibility::VISIBILITY_BOTH)
40+
->setStatus(Status::STATUS_ENABLED)
41+
->setCategoryIds([333])
42+
->setStockData(['use_config_manage_stock' => 0])
43+
->setCanSaveCustomOptions(true)
44+
->setHasOptions(true);
45+
/** @var ProductRepositoryInterface $productRepositoryFactory */
46+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
47+
$productRepository->save($product);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Framework\Exception\NoSuchEntityException;
10+
use Magento\Framework\Registry;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
13+
require __DIR__ . '/category_rollback.php';
14+
15+
$objectManager = Bootstrap::getObjectManager();
16+
/** @var Registry $registry */
17+
$registry = $objectManager->get(Registry::class);
18+
19+
$registry->unregister('isSecureArea');
20+
$registry->register('isSecureArea', true);
21+
/** @var ProductRepositoryInterface $productRepository */
22+
$productRepository = $objectManager->create(ProductRepositoryInterface::class);
23+
24+
try {
25+
$productRepository->deleteById('in-stock-product');
26+
} catch (NoSuchEntityException $e) {
27+
//already removed
28+
}
29+
$registry->unregister('isSecureArea');
30+
$registry->register('isSecureArea', false);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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\LayeredNavigation\Block\Navigation\Category;
9+
10+
use Magento\Catalog\Model\Layer\Resolver;
11+
use Magento\CatalogInventory\Model\Configuration;
12+
use Magento\Framework\App\Config\MutableScopeConfigInterface;
13+
use Magento\Framework\App\ScopeInterface;
14+
use Magento\LayeredNavigation\Block\Navigation\AbstractFiltersTest;
15+
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
16+
use Magento\Store\Model\ScopeInterface as StoreScope;
17+
18+
/**
19+
* Provides tests for select filter in navigation block on category page with out of stock products
20+
* and enabled out of stock products displaying.
21+
*
22+
* @magentoAppArea frontend
23+
* @magentoAppIsolation enabled
24+
* @magentoDbIsolation disabled
25+
*/
26+
class OutOfStockProductsFilterTest extends AbstractFiltersTest
27+
{
28+
/**
29+
* @var MutableScopeConfigInterface
30+
*/
31+
private $scopeConfig;
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
protected function setUp()
37+
{
38+
parent::setUp();
39+
$this->scopeConfig = $this->objectManager->get(MutableScopeConfigInterface::class);
40+
}
41+
42+
/**
43+
* @magentoDataFixture Magento/Catalog/_files/product_dropdown_attribute.php
44+
* @magentoDataFixture Magento/Catalog/_files/out_of_stock_product_with_category.php
45+
* @magentoDataFixture Magento/Catalog/_files/product_with_category.php
46+
* @dataProvider getFiltersWithOutOfStockProduct
47+
* @param int $showOutOfStock
48+
* @param array $expectation
49+
* @return void
50+
*/
51+
public function testGetFiltersWithOutOfStockProduct(int $showOutOfStock, array $expectation): void
52+
{
53+
$this->updateConfigShowOutOfStockFlag($showOutOfStock);
54+
$this->getCategoryFiltersAndAssert(
55+
['out-of-stock-product' => 'Option 1', 'in-stock-product' => 'Option 2'],
56+
['is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS],
57+
$expectation,
58+
'Category 1'
59+
);
60+
}
61+
62+
/**
63+
* @return array
64+
*/
65+
public function getFiltersWithOutOfStockProduct(): array
66+
{
67+
return [
68+
'show_out_of_stock' => [
69+
'show_out_of_stock' => 1,
70+
'expectation' => [['label' => 'Option 1', 'count' => 1], ['label' => 'Option 2', 'count' => 1]],
71+
],
72+
'not_show_out_of_stock' => [
73+
'show_out_of_stock' => 0,
74+
'expectation' => [['label' => 'Option 2', 'count' => 1]],
75+
],
76+
];
77+
}
78+
79+
/**
80+
* @inheritdoc
81+
*/
82+
protected function getLayerType(): string
83+
{
84+
return Resolver::CATALOG_LAYER_CATEGORY;
85+
}
86+
87+
/**
88+
* @inheritdoc
89+
*/
90+
protected function getAttributeCode(): string
91+
{
92+
return 'dropdown_attribute';
93+
}
94+
95+
/**
96+
* Updates store config 'cataloginventory/options/show_out_of_stock' flag.
97+
*
98+
* @param int $showOutOfStock
99+
* @return void
100+
*/
101+
protected function updateConfigShowOutOfStockFlag(int $showOutOfStock): void
102+
{
103+
$this->scopeConfig->setValue(
104+
Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
105+
$showOutOfStock,
106+
StoreScope::SCOPE_STORE,
107+
ScopeInterface::SCOPE_DEFAULT
108+
);
109+
}
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\LayeredNavigation\Block\Navigation\Search;
9+
10+
use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
11+
use Magento\Catalog\Model\Layer\Resolver;
12+
use Magento\LayeredNavigation\Block\Navigation\Category\OutOfStockProductsFilterTest as CategoryFilterTest;
13+
14+
/**
15+
* Provides tests for select filter in navigation block on search page with out of stock products
16+
* and enabled out of stock products displaying.
17+
*
18+
* @magentoAppArea frontend
19+
* @magentoAppIsolation enabled
20+
* @magentoDbIsolation disabled
21+
*/
22+
class OutOfStockProductsFilterTest extends CategoryFilterTest
23+
{
24+
/**
25+
* @magentoDataFixture Magento/Catalog/_files/product_dropdown_attribute.php
26+
* @magentoDataFixture Magento/Catalog/_files/out_of_stock_product_with_category.php
27+
* @magentoDataFixture Magento/Catalog/_files/product_with_category.php
28+
* @dataProvider getFiltersWithOutOfStockProduct
29+
* @param int $showOutOfStock
30+
* @param array $expectation
31+
* @return void
32+
*/
33+
public function testGetFiltersWithOutOfStockProduct(int $showOutOfStock, array $expectation): void
34+
{
35+
$this->updateConfigShowOutOfStockFlag($showOutOfStock);
36+
$this->getSearchFiltersAndAssert(
37+
['out-of-stock-product' => 'Option 1', 'in-stock-product' => 'Option 2'],
38+
[
39+
'is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS,
40+
'is_filterable_in_search' => 1,
41+
],
42+
$expectation
43+
);
44+
}
45+
46+
/**
47+
* @inheritdoc
48+
*/
49+
protected function getLayerType(): string
50+
{
51+
return Resolver::CATALOG_LAYER_SEARCH;
52+
}
53+
}

0 commit comments

Comments
 (0)