Skip to content

Commit 2a32fed

Browse files
author
Oleksii Korshenko
committed
MAGETWO-87151: [EngCom Team] Batch 7. Forwardports to 2.3-develop #1289
- Merge Pull Request magento-engcom/magento2ce#1289 from magento-engcom-team/magento2:batch-7-forwardport-2.3-develop - Merged commits: 1. b415941 2. 7369261 3. dce1c66 4. 95ed67e 5. 05fcdd1 6. 8b1a297 7. 90addb7 8. d5c9eef 9. 6ec6271 10. f0af87e 11. 2497062 12. 1f7347f 13. 0d151c4 14. 07982fd 15. 617da6c 16. 39ed21f 17. 9aa036d 18. fda37ef 19. 47b1091 20. ef6bada 21. 809ec05
2 parents c7207f6 + 809ec05 commit 2a32fed

File tree

26 files changed

+758
-47
lines changed

26 files changed

+758
-47
lines changed

app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ private function mergeCategoryLinks($newCategoryPositions, $oldCategoryPositions
119119

120120
if ($key === false) {
121121
$result[] = $newCategoryPosition;
122-
} elseif ($oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']) {
122+
} elseif (isset($oldCategoryPositions[$key])
123+
&& $oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']
124+
) {
123125
$result[] = $newCategoryPositions[$key];
124126
unset($oldCategoryPositions[$key]);
125127
}

app/code/Magento/Catalog/Model/ResourceModel/Config.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ public function getAttributesUsedForSortBy()
149149
['main_table' => $this->getTable('eav_attribute')]
150150
)->join(
151151
['additional_table' => $this->getTable('catalog_eav_attribute')],
152-
'main_table.attribute_id = additional_table.attribute_id',
153-
[]
152+
'main_table.attribute_id = additional_table.attribute_id'
154153
)->joinLeft(
155154
['al' => $this->getTable('eav_attribute_label')],
156155
'al.attribute_id = main_table.attribute_id AND al.store_id = ' . $this->getStoreId(),

app/code/Magento/Catalog/Test/Unit/Model/Category/Link/SaveHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,21 @@ public function getCategoryDataProvider()
197197
],
198198
[], //affected category_ids
199199
],
200+
[
201+
[3], //model category_ids
202+
[
203+
['category_id' => 3, 'position' => 20],
204+
['category_id' => 4, 'position' => 30],
205+
], // dto category links
206+
[
207+
['category_id' => 3, 'position' => 10],
208+
],
209+
[
210+
['category_id' => 3, 'position' => 20],
211+
['category_id' => 4, 'position' => 30],
212+
],
213+
[3, 4], //affected category_ids
214+
],
200215
];
201216
}
202217

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;
8+
9+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
10+
11+
/**
12+
* Test for Magento\Catalog\Model\ResourceModel\Config
13+
*/
14+
class ConfigTest extends \PHPUnit\Framework\TestCase
15+
{
16+
/**
17+
* @var \Magento\Catalog\Model\ResourceModel\Config
18+
*/
19+
private $model;
20+
21+
/**
22+
* @var \PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $resource;
25+
26+
/**
27+
* @var \PHPUnit_Framework_MockObject_MockObject
28+
*/
29+
private $storeManager;
30+
31+
/**
32+
* @var \PHPUnit_Framework_MockObject_MockObject
33+
*/
34+
private $eavConfig;
35+
36+
protected function setUp()
37+
{
38+
$objectManager = new ObjectManager($this);
39+
40+
$this->resource = $this->createMock(\Magento\Framework\App\ResourceConnection::class);
41+
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
42+
$this->eavConfig = $this->createMock(\Magento\Eav\Model\Config::class);
43+
44+
$this->model = $objectManager->getObject(
45+
\Magento\Catalog\Model\ResourceModel\Config::class,
46+
[
47+
'resource' => $this->resource,
48+
'storeManager' => $this->storeManager,
49+
'eavConfig' => $this->eavConfig,
50+
]
51+
);
52+
53+
parent::setUp();
54+
}
55+
56+
public function testGetAttributesUsedForSortBy()
57+
{
58+
$expression = 'someExpression';
59+
$storeId = 1;
60+
$entityTypeId = 4;
61+
62+
$connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
63+
$selectMock = $this->createMock(\Magento\Framework\DB\Select::class);
64+
$storeMock = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class);
65+
$entityTypeMock = $this->createMock(\Magento\Eav\Model\Entity\Type::class);
66+
67+
$this->resource->expects($this->atLeastOnce())->method('getConnection')->willReturn($connectionMock);
68+
69+
$connectionMock->expects($this->once())->method('getCheckSql')
70+
->with('al.value IS NULL', 'main_table.frontend_label', 'al.value')
71+
->willReturn($expression);
72+
$connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($selectMock);
73+
74+
$this->resource->expects($this->exactly(3))->method('getTableName')->withConsecutive(
75+
['eav_attribute'],
76+
['catalog_eav_attribute'],
77+
['eav_attribute_label']
78+
)->willReturnOnConsecutiveCalls('eav_attribute', 'catalog_eav_attribute', 'eav_attribute_label');
79+
80+
$this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
81+
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
82+
83+
$this->eavConfig->expects($this->once())->method('getEntityType')->willReturn($entityTypeMock);
84+
$entityTypeMock->expects($this->once())->method('getId')->willReturn($entityTypeId);
85+
86+
$selectMock->expects($this->once())->method('from')
87+
->with(['main_table' => 'eav_attribute'])->willReturn($selectMock);
88+
$selectMock->expects($this->once())->method('join')->with(
89+
['additional_table' => 'catalog_eav_attribute'],
90+
'main_table.attribute_id = additional_table.attribute_id'
91+
)->willReturn($selectMock);
92+
$selectMock->expects($this->once())->method('joinLeft')
93+
->with(
94+
['al' => 'eav_attribute_label'],
95+
'al.attribute_id = main_table.attribute_id AND al.store_id = ' . $storeId,
96+
['store_label' => $expression]
97+
)->willReturn($selectMock);
98+
$selectMock->expects($this->exactly(2))->method('where')->withConsecutive(
99+
['main_table.entity_type_id = ?', $entityTypeId],
100+
['additional_table.used_for_sort_by = ?', 1]
101+
)->willReturn($selectMock);
102+
103+
$connectionMock->expects($this->once())->method('fetchAll')->with($selectMock);
104+
105+
$this->model->getAttributesUsedForSortBy();
106+
}
107+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CatalogInventory\Observer;
8+
9+
use Magento\Catalog\Model\Product;
10+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
11+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
12+
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
13+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
14+
use Magento\Framework\Event\Observer;
15+
use Magento\Framework\Event\ObserverInterface;
16+
17+
/**
18+
* Add Stock items to product collection.
19+
*/
20+
class AddStockItemsObserver implements ObserverInterface
21+
{
22+
/**
23+
* @var StockItemCriteriaInterfaceFactory
24+
*/
25+
private $criteriaInterfaceFactory;
26+
27+
/**
28+
* @var StockItemRepositoryInterface
29+
*/
30+
private $stockItemRepository;
31+
32+
/**
33+
* @var StockConfigurationInterface
34+
*/
35+
private $stockConfiguration;
36+
37+
/**
38+
* AddStockItemsObserver constructor.
39+
*
40+
* @param StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory
41+
* @param StockItemRepositoryInterface $stockItemRepository
42+
* @param StockConfigurationInterface $stockConfiguration
43+
*/
44+
public function __construct(
45+
StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory,
46+
StockItemRepositoryInterface $stockItemRepository,
47+
StockConfigurationInterface $stockConfiguration
48+
) {
49+
$this->criteriaInterfaceFactory = $criteriaInterfaceFactory;
50+
$this->stockItemRepository = $stockItemRepository;
51+
$this->stockConfiguration = $stockConfiguration;
52+
}
53+
54+
/**
55+
* Add stock items to products in collection.
56+
*
57+
* @param Observer $observer
58+
* @return void
59+
*/
60+
public function execute(Observer $observer)
61+
{
62+
/** @var Collection $productCollection */
63+
$productCollection = $observer->getData('collection');
64+
$productIds = array_keys($productCollection->getItems());
65+
$criteria = $this->criteriaInterfaceFactory->create();
66+
$criteria->setProductsFilter($productIds);
67+
$criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
68+
$stockItemCollection = $this->stockItemRepository->getList($criteria);
69+
foreach ($stockItemCollection->getItems() as $item) {
70+
/** @var Product $product */
71+
$product = $productCollection->getItemById($item->getProductId());
72+
$productExtension = $product->getExtensionAttributes();
73+
$productExtension->setStockItem($item);
74+
$product->setExtensionAttributes($productExtension);
75+
}
76+
}
77+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CatalogInventory\Test\Unit\Observer;
8+
9+
use Magento\Catalog\Api\Data\ProductExtensionInterface;
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
12+
use Magento\CatalogInventory\Api\Data\StockItemCollectionInterface;
13+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
14+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
15+
use Magento\CatalogInventory\Api\StockItemCriteriaInterface;
16+
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
17+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
18+
use Magento\CatalogInventory\Observer\AddStockItemsObserver;
19+
use Magento\Framework\Event\Observer;
20+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
21+
use PHPUnit\Framework\TestCase;
22+
23+
class AddStockItemsObserverTest extends TestCase
24+
{
25+
/**
26+
* Test subject.
27+
*
28+
* @var AddStockItemsObserver
29+
*/
30+
private $subject;
31+
/**
32+
* @var StockItemCriteriaInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
33+
*/
34+
private $criteriaInterfaceFactoryMock;
35+
36+
/**
37+
* @var StockItemRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
38+
*/
39+
private $stockItemRepositoryMock;
40+
41+
/**
42+
* @var StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject
43+
*/
44+
private $stockConfigurationMock;
45+
46+
/**
47+
* @inheritdoc
48+
*/
49+
protected function setUp()
50+
{
51+
$objectManager = new ObjectManager($this);
52+
$this->criteriaInterfaceFactoryMock = $this->getMockBuilder(StockItemCriteriaInterfaceFactory::class)
53+
->setMethods(['create'])
54+
->disableOriginalConstructor()
55+
->getMockForAbstractClass();
56+
$this->stockItemRepositoryMock = $this->getMockBuilder(StockItemRepositoryInterface::class)
57+
->setMethods(['getList'])
58+
->disableOriginalConstructor()
59+
->getMockForAbstractClass();
60+
$this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class)
61+
->setMethods(['getDefaultScopeId'])
62+
->disableOriginalConstructor()
63+
->getMockForAbstractClass();
64+
$this->subject = $objectManager->getObject(
65+
AddStockItemsObserver::class,
66+
[
67+
'criteriaInterfaceFactory' => $this->criteriaInterfaceFactoryMock,
68+
'stockItemRepository' => $this->stockItemRepositoryMock,
69+
'stockConfiguration' => $this->stockConfigurationMock
70+
]
71+
);
72+
}
73+
74+
/**
75+
* Test AddStockItemsObserver::execute() add stock item to product as extension attribute.
76+
*/
77+
public function testExecute()
78+
{
79+
$productId = 1;
80+
$defaultScopeId = 0;
81+
82+
$criteria = $this->getMockBuilder(StockItemCriteriaInterface::class)
83+
->setMethods(['setProductsFilter', 'setScopeFilter'])
84+
->disableOriginalConstructor()
85+
->getMockForAbstractClass();
86+
$criteria->expects(self::once())
87+
->method('setProductsFilter')
88+
->with(self::identicalTo([$productId]))
89+
->willReturn(true);
90+
$criteria->expects(self::once())
91+
->method('setScopeFilter')
92+
->with(self::identicalTo($defaultScopeId))
93+
->willReturn(true);
94+
95+
$this->criteriaInterfaceFactoryMock->expects(self::once())
96+
->method('create')
97+
->willReturn($criteria);
98+
$stockItemCollection = $this->getMockBuilder(StockItemCollectionInterface::class)
99+
->setMethods(['getItems'])
100+
->disableOriginalConstructor()
101+
->getMockForAbstractClass();
102+
$stockItem = $this->getMockBuilder(StockItemInterface::class)
103+
->setMethods(['getProductId'])
104+
->disableOriginalConstructor()
105+
->getMockForAbstractClass();
106+
$stockItem->expects(self::once())
107+
->method('getProductId')
108+
->willReturn($productId);
109+
110+
$stockItemCollection->expects(self::once())
111+
->method('getItems')
112+
->willReturn([$stockItem]);
113+
114+
$this->stockItemRepositoryMock->expects(self::once())
115+
->method('getList')
116+
->with(self::identicalTo($criteria))
117+
->willReturn($stockItemCollection);
118+
119+
$this->stockConfigurationMock->expects(self::once())
120+
->method('getDefaultScopeId')
121+
->willReturn($defaultScopeId);
122+
123+
$productExtension = $this->getMockBuilder(ProductExtensionInterface::class)
124+
->setMethods(['setStockItem'])
125+
->disableOriginalConstructor()
126+
->getMockForAbstractClass();
127+
$productExtension->expects(self::once())
128+
->method('setStockItem')
129+
->with(self::identicalTo($stockItem));
130+
131+
$product = $this->getMockBuilder(Product::class)
132+
->disableOriginalConstructor()
133+
->getMock();
134+
$product->expects(self::once())
135+
->method('getExtensionAttributes')
136+
->willReturn($productExtension);
137+
$product->expects(self::once())
138+
->method('setExtensionAttributes')
139+
->with(self::identicalTo($productExtension))
140+
->willReturnSelf();
141+
142+
/** @var ProductCollection|\PHPUnit_Framework_MockObject_MockObject $productCollection */
143+
$productCollection = $this->getMockBuilder(ProductCollection::class)
144+
->disableOriginalConstructor()
145+
->getMock();
146+
$productCollection->expects(self::once())
147+
->method('getItems')
148+
->willReturn([$productId => $product]);
149+
$productCollection->expects(self::once())
150+
->method('getItemById')
151+
->with(self::identicalTo($productId))
152+
->willReturn($product);
153+
154+
/** @var Observer|\PHPUnit_Framework_MockObject_MockObject $observer */
155+
$observer = $this->getMockBuilder(Observer::class)
156+
->disableOriginalConstructor()
157+
->getMock();
158+
$observer->expects(self::once())
159+
->method('getData')
160+
->with('collection')
161+
->willReturn($productCollection);
162+
163+
$this->subject->execute($observer);
164+
}
165+
}

0 commit comments

Comments
 (0)