Skip to content

Commit 9fd1d67

Browse files
committed
ACP2E-316: Some product are missed from layered navigation with manually configured price ranges
1 parent 44f6a52 commit 9fd1d67

File tree

5 files changed

+156
-29
lines changed

5 files changed

+156
-29
lines changed

app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
class Price extends AbstractFilter
1919
{
2020
/** Price delta for filter */
21-
const PRICE_DELTA = 0.001;
21+
public const PRICE_DELTA = 0.001;
2222

2323
/**
2424
* @var \Magento\Catalog\Model\Layer\Filter\DataProvider\Price
@@ -274,6 +274,9 @@ protected function getFrom($from)
274274
private function prepareData($key, $count, $isLast = false)
275275
{
276276
[$from, $to] = explode('_', $key);
277+
if ($isLast) {
278+
$to = '';
279+
}
277280
$label = $this->_renderRangeLabel($from, $to, $isLast);
278281
$value = $from . '-' . $to . $this->dataProvider->getAdditionalRequestData();
279282

dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
namespace Magento\CatalogSearch\Model\Layer\Filter;
99

10+
use Magento\Catalog\Api\CategoryRepositoryInterface;
11+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
12+
use Magento\Catalog\Model\Layer\Category as CategoryLayer;
13+
use Magento\CatalogSearch\Model\Layer\Filter\Price as PriceFilter;
1014
use Magento\TestFramework\Helper\Bootstrap;
1115

1216
/**
@@ -19,9 +23,9 @@
1923
class PriceTest extends \PHPUnit\Framework\TestCase
2024
{
2125
/**
22-
* @var \Magento\CatalogSearch\Model\Layer\Filter\Price
26+
* @var PriceFilter
2327
*/
24-
protected $_model;
28+
private $model;
2529

2630
/**
2731
* @var \Magento\Framework\ObjectManagerInterface
@@ -31,37 +35,28 @@ class PriceTest extends \PHPUnit\Framework\TestCase
3135
protected function setUp(): void
3236
{
3337
$this->objectManager = Bootstrap::getObjectManager();
34-
$category = $this->objectManager->create(
35-
\Magento\Catalog\Model\Category::class
36-
);
37-
$category->load(4);
38-
$layer = $this->objectManager->get(\Magento\Catalog\Model\Layer\Category::class);
39-
$layer->setCurrentCategory($category);
40-
$this->_model = $this->objectManager->create(
41-
\Magento\CatalogSearch\Model\Layer\Filter\Price::class,
42-
['layer' => $layer]
43-
);
38+
$this->initializePriceFilter();
4439
}
4540

4641
public function testApplyNothing()
4742
{
48-
$this->assertEmpty($this->_model->getData('price_range'));
43+
$this->assertEmpty($this->model->getData('price_range'));
4944
/** @var $request \Magento\TestFramework\Request */
5045
$request = $this->objectManager->get(\Magento\TestFramework\Request::class);
51-
$this->_model->apply($request);
46+
$this->model->apply($request);
5247

53-
$this->assertEmpty($this->_model->getData('price_range'));
48+
$this->assertEmpty($this->model->getData('price_range'));
5449
}
5550

5651
public function testApplyInvalid()
5752
{
58-
$this->assertEmpty($this->_model->getData('price_range'));
53+
$this->assertEmpty($this->model->getData('price_range'));
5954
/** @var $request \Magento\TestFramework\Request */
6055
$request = $this->objectManager->get(\Magento\TestFramework\Request::class);
6156
$request->setParam('price', 'non-numeric');
62-
$this->_model->apply($request);
57+
$this->model->apply($request);
6358

64-
$this->assertEmpty($this->_model->getData('price_range'));
59+
$this->assertEmpty($this->model->getData('price_range'));
6560
}
6661

6762
/**
@@ -72,7 +67,7 @@ public function testApplyManual()
7267
/** @var $request \Magento\TestFramework\Request */
7368
$request = $this->objectManager->get(\Magento\TestFramework\Request::class);
7469
$request->setParam('price', '10-20');
75-
$this->_model->apply($request);
70+
$this->model->apply($request);
7671
}
7772

7873
/**
@@ -84,11 +79,11 @@ public function testApplyWithCustomCurrencyRate()
8479
$request = $this->objectManager->get(\Magento\TestFramework\Request::class);
8580

8681
$request->setParam('price', '10-20');
87-
$this->_model->setCurrencyRate(10);
82+
$this->model->setCurrencyRate(10);
8883

89-
$this->_model->apply($request);
84+
$this->model->apply($request);
9085

91-
$filters = $this->_model->getLayer()->getState()->getFilters();
86+
$filters = $this->model->getLayer()->getState()->getFilters();
9287
$this->assertArrayHasKey(0, $filters);
9388
$this->assertEquals(
9489
'<span class="price">$100.00</span> - <span class="price">$199.99</span>',
@@ -100,22 +95,64 @@ public function testGetSetCustomerGroupId()
10095
{
10196
$this->assertEquals(
10297
\Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID,
103-
$this->_model->getCustomerGroupId()
98+
$this->model->getCustomerGroupId()
10499
);
105100

106101
$customerGroupId = 123;
107-
$this->_model->setCustomerGroupId($customerGroupId);
102+
$this->model->setCustomerGroupId($customerGroupId);
108103

109-
$this->assertEquals($customerGroupId, $this->_model->getCustomerGroupId());
104+
$this->assertEquals($customerGroupId, $this->model->getCustomerGroupId());
110105
}
111106

112107
public function testGetSetCurrencyRate()
113108
{
114-
$this->assertEquals(1, $this->_model->getCurrencyRate());
109+
$this->assertEquals(1, $this->model->getCurrencyRate());
115110

116111
$currencyRate = 42;
117-
$this->_model->setCurrencyRate($currencyRate);
112+
$this->model->setCurrencyRate($currencyRate);
113+
114+
$this->assertEquals($currencyRate, $this->model->getCurrencyRate());
115+
}
116+
117+
/**
118+
* @magentoDbIsolation disabled
119+
* @magentoConfigFixture current_store catalog/layered_navigation/price_range_calculation manual
120+
* @magentoConfigFixture current_store catalog/layered_navigation/price_range_step 10
121+
* @magentoConfigFixture current_store catalog/layered_navigation/price_range_max_intervals 2
122+
* @magentoDataFixture Magento/CatalogSearch/_files/products_with_different_price.php
123+
*/
124+
public function testGetItemsWithManualAlgorithm(): void
125+
{
126+
$attributeRepository = $this->objectManager->get(ProductAttributeRepositoryInterface::class);
127+
$priceAttribute = $attributeRepository->get('price');
128+
$this->model->setAttributeModel($priceAttribute);
118129

119-
$this->assertEquals($currencyRate, $this->_model->getCurrencyRate());
130+
/** @var \Magento\Catalog\Model\Layer\Filter\Item[] $ranges */
131+
$ranges = $this->model->getItems();
132+
self::assertCount(2, $ranges);
133+
134+
$request = $this->objectManager->get(\Magento\TestFramework\Request::class);
135+
foreach ($ranges as $range) {
136+
$request->setParam('price', $range->getValueString());
137+
$this->initializePriceFilter();
138+
$this->model->apply($request);
139+
$products = $this->model->getLayer()->getProductCollection()->getItems();
140+
self::assertCount($range->getCount(), $products);
141+
}
142+
}
143+
144+
/**
145+
* @return void
146+
*/
147+
private function initializePriceFilter(): void
148+
{
149+
$categoryRepository = $this->objectManager->get(CategoryRepositoryInterface::class);
150+
$category = $categoryRepository->get(4);
151+
$layer = $this->objectManager->create(CategoryLayer::class);
152+
$layer->setCurrentCategory($category);
153+
$this->model = $this->objectManager->create(
154+
PriceFilter::class,
155+
['layer' => $layer]
156+
);
120157
}
121158
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\CategoryLinkManagementInterface;
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Catalog\Model\Category;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
13+
use Magento\Catalog\Model\Product\Type as ProductType;
14+
use Magento\Catalog\Model\Product\Visibility;
15+
use Magento\TestFramework\Helper\Bootstrap;
16+
17+
$category = Bootstrap::getObjectManager()->create(Category::class);
18+
$category->isObjectNew(true);
19+
$category->setId(4)
20+
->setName('Category 1')
21+
->setParentId(2)
22+
->setPath('1/2/4')
23+
->setLevel(2)
24+
->setAvailableSortBy('name')
25+
->setDefaultSortBy('name')
26+
->setIsActive(true)
27+
->setPosition(1)
28+
->save();
29+
30+
$prices = [11, 12, 23, 29, 100];
31+
32+
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
33+
$categoryLinkManagement = Bootstrap::getObjectManager()->get(CategoryLinkManagementInterface::class);
34+
foreach ($prices as $price) {
35+
$product = Bootstrap::getObjectManager()->create(Product::class);
36+
$product->setTypeId(ProductType::TYPE_SIMPLE)
37+
->setAttributeSetId($product->getDefaultAttributeSetId())
38+
->setWebsiteIds([1])
39+
->setName('Simple with price ' . $price)
40+
->setSku('simple_' . $price)
41+
->setPrice($price)
42+
->setWeight(1)
43+
->setVisibility(Visibility::VISIBILITY_BOTH)
44+
->setStatus(Status::STATUS_ENABLED)
45+
->setStockData(
46+
[
47+
'use_config_manage_stock' => 1,
48+
'qty' => 100,
49+
'is_qty_decimal' => 0,
50+
'is_in_stock' => 1,
51+
]
52+
);
53+
$product = $productRepository->save($product);
54+
$categoryLinkManagement->assignProductToCategories($product->getSku(), [$category->getId()]);
55+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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\CategoryRepositoryInterface;
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
13+
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
14+
foreach (['simple_11', 'simple_12', 'simple_23', 'simple_23', 'simple_100'] as $sku) {
15+
try {
16+
$product = $productRepository->get($sku, false, null, true);
17+
$productRepository->delete($product);
18+
} catch (NoSuchEntityException $e) {
19+
//Product already removed
20+
}
21+
}
22+
23+
$categoryRepository = Bootstrap::getObjectManager()->get(CategoryRepositoryInterface::class);
24+
try {
25+
$category = $categoryRepository->get(4);
26+
$categoryRepository->delete($category);
27+
} catch (NoSuchEntityException $e) {
28+
//Category already removed
29+
}

lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public function create()
6161
->create();
6262
}
6363
$this->data[SearchCriteria::SORT_ORDERS] = [$this->sortOrderBuilder->create()];
64+
$this->filters = [];
6465
return parent::create();
6566
}
6667

@@ -77,6 +78,8 @@ public function addFilter(\Magento\Framework\Api\Filter $filter)
7778
}
7879

7980
/**
81+
* Set sort order
82+
*
8083
* @param string $field
8184
* @param string $direction
8285
* @return $this

0 commit comments

Comments
 (0)