Skip to content

Commit 6e53acd

Browse files
committed
ACP2E-1388:Bundle Products Not Combining Simple Product Prices When Set to Dynamic Pricing
address CR feedback
1 parent d26e362 commit 6e53acd

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

app/code/Magento/Bundle/Model/Plugin/ProductPriceIndexModifier.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ public function __construct(
7878
* @param callable $proceed
7979
* @param IndexTableStructure $priceTable
8080
* @param array $entityIds
81+
* @return void
82+
* @throws NoSuchEntityException
8183
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
82-
* @throws \Exception
8384
*/
8485
public function aroundModifyPrice(
8586
ProductPriceIndexFilter $subject,
@@ -88,7 +89,7 @@ public function aroundModifyPrice(
8889
array $entityIds = []
8990
) {
9091
if (empty($entityIds) || $this->stockConfiguration->isShowOutOfStock()) {
91-
$proceed($priceTable, $entityIds);
92+
return $proceed($priceTable, $entityIds);
9293
}
9394
$filteredEntities = $this->filterProductsFromDynamicPriceBundle($priceTable->getTableName(), $entityIds);
9495

app/code/Magento/Bundle/Test/Unit/Model/Plugin/ProductPriceIndexModifierTest.php

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,38 @@
88
namespace Magento\Bundle\Test\Unit\Model\Plugin;
99

1010
use Magento\Bundle\Model\Plugin\ProductPriceIndexModifier;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
1113
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
14+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1215
use Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter;
1316
use Magento\Framework\App\ResourceConnection;
1417
use Magento\Framework\DB\Adapter\AdapterInterface;
1518
use Magento\Framework\DB\Select;
19+
use Magento\Framework\EntityManager\EntityMetadataInterface;
20+
use Magento\Framework\EntityManager\MetadataPool;
1621
use PHPUnit\Framework\MockObject\MockObject;
1722
use PHPUnit\Framework\TestCase;
1823

1924
class ProductPriceIndexModifierTest extends TestCase
2025
{
2126
private const CONNECTION_NAME = 'indexer';
2227

28+
/**
29+
* @var StockConfigurationInterface|StockConfigurationInterface&MockObject|MockObject
30+
*/
31+
private StockConfigurationInterface $stockConfiguration;
32+
2333
/**
2434
* @var ResourceConnection|MockObject
2535
*/
2636
private ResourceConnection $resourceConnection;
2737

38+
/**
39+
* @var MetadataPool|MetadataPool&MockObject|MockObject
40+
*/
41+
private MetadataPool $metadataPool;
42+
2843
/**
2944
* @var ProductPriceIndexModifier
3045
*/
@@ -35,17 +50,31 @@ class ProductPriceIndexModifierTest extends TestCase
3550
*/
3651
private IndexTableStructure $table;
3752

53+
/**
54+
* @var ProductRepositoryInterface|ProductRepositoryInterface&MockObject|MockObject
55+
*/
56+
private ProductRepositoryInterface $productRepository;
57+
3858
/**
3959
* @var ProductPriceIndexFilter|MockObject
4060
*/
4161
private ProductPriceIndexFilter $subject;
4262

4363
protected function setUp(): void
4464
{
65+
$this->stockConfiguration = $this->createMock(StockConfigurationInterface::class);
4566
$this->table = $this->createMock(IndexTableStructure::class);
4667
$this->subject = $this->createMock(ProductPriceIndexFilter::class);
4768
$this->resourceConnection = $this->createMock(ResourceConnection::class);
48-
$this->plugin = new ProductPriceIndexModifier($this->resourceConnection, self::CONNECTION_NAME);
69+
$this->metadataPool = $this->createMock(MetadataPool::class);
70+
$this->productRepository = $this->createMock(ProductRepositoryInterface::class);
71+
$this->plugin = new ProductPriceIndexModifier(
72+
$this->stockConfiguration,
73+
$this->resourceConnection,
74+
$this->metadataPool,
75+
$this->productRepository,
76+
self::CONNECTION_NAME
77+
);
4978
}
5079

5180
public function testAroundModifyPriceNoEntities(): void
@@ -63,41 +92,58 @@ public function testAroundModifyPriceFilteredEntities()
6392
{
6493
$priceTableName = 'catalog_product_index_price_temp';
6594
$entities = [1, 2];
66-
$this->table->expects($this->exactly(2))
67-
->method('getTableName')
68-
->willReturn($priceTableName);
95+
$link = $this->createMock(EntityMetadataInterface::class);
96+
$link->expects($this->once())->method('getLinkField')->willReturn('id');
97+
$this->metadataPool->expects($this->once())
98+
->method('getMetadata')
99+
->with(ProductInterface::class)
100+
->willReturn($link);
69101
$select = $this->createMock(Select::class);
102+
$select->expects($this->once())
103+
->method('from');
70104
$select->expects($this->exactly(2))
71-
->method('from')
72-
->with(['selection' => 'catalog_product_bundle_selection'], 'selection_id');
105+
->method('joinInner');
73106
$select->expects($this->exactly(2))
74-
->method('joinInner')
75-
->with(
76-
['price' => $priceTableName],
77-
implode(' AND ', ['price.entity_id = selection.product_id']),
78-
null
79-
);
80-
$select->expects($this->exactly(4))
81-
->method('where')
82-
->withConsecutive(
83-
['selection.product_id = ?', $entities[0]],
84-
['price.tax_class_id = ?', \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC],
85-
['selection.product_id = ?', $entities[1]],
86-
['price.tax_class_id = ?', \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC]
87-
);
107+
->method('where');
88108
$connection = $this->createMock(AdapterInterface::class);
89-
$connection->expects($this->exactly(2))
109+
$connection->expects($this->once())
90110
->method('select')
91111
->willReturn($select);
92-
$connection->expects($this->exactly(2))
93-
->method('fetchOne')
112+
$connection->expects($this->exactly(1))
113+
->method('fetchAll')
94114
->with($select)
95-
->willReturn(null);
96-
$this->resourceConnection->expects($this->exactly(2))
115+
->willReturn([
116+
[
117+
'bundle_id' => 1,
118+
'child_product_id' => 1
119+
],
120+
[
121+
'bundle_id' => 1,
122+
'child_product_id' => 2
123+
]
124+
]);
125+
$this->resourceConnection->expects($this->once())
97126
->method('getConnection')
98127
->with(self::CONNECTION_NAME)
99128
->willReturn($connection);
100129

130+
$bundleProduct1 = $this->getMockBuilder(ProductInterface::class)
131+
->disableOriginalConstructor()
132+
->addMethods(['getPriceType'])
133+
->getMockForAbstractClass();
134+
$bundleProduct1->expects($this->once())->method('getPriceType')
135+
->willReturn(1);
136+
$bundleProduct2 = $this->getMockBuilder(ProductInterface::class)
137+
->disableOriginalConstructor()
138+
->addMethods(['getPriceType'])
139+
->getMockForAbstractClass();
140+
$bundleProduct2->expects($this->once())->method('getPriceType')
141+
->willReturn(1);
142+
143+
$this->productRepository->expects($this->exactly(2))
144+
->method('getById')
145+
->willReturnOnConsecutiveCalls($bundleProduct1, $bundleProduct2);
146+
101147
$calledPriceTable = '';
102148
$calledEntities = [];
103149
$callable = function () use (&$calledPriceTable, &$calledEntities, $priceTableName, $entities) {

0 commit comments

Comments
 (0)