Skip to content

Commit b43daec

Browse files
author
Mastiuhin Olexandr
committed
Merge remote-tracking branch 'origin/2.3-develop' into MC-28956
2 parents 6a6a224 + e3e85a1 commit b43daec

File tree

103 files changed

+4491
-134
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+4491
-134
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Captcha\Test\Unit\CustomerData;
10+
11+
use Magento\Captcha\Helper\Data as CaptchaHelper;
12+
use Magento\Customer\Model\Session as CustomerSession;
13+
use Magento\Captcha\CustomerData\Captcha;
14+
use Magento\Captcha\Model\DefaultModel;
15+
use Magento\Customer\Api\Data\CustomerInterface as CustomerData;
16+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class CaptchaTest extends TestCase
20+
{
21+
/**
22+
* @var CaptchaHelper|\PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $helperMock;
25+
26+
/**
27+
* @var CustomerSession|\PHPUnit_Framework_MockObject_MockObject
28+
*/
29+
private $customerSessionMock;
30+
31+
/**
32+
* @var Captcha
33+
*/
34+
private $model;
35+
36+
/**
37+
* @var array
38+
*/
39+
private $formIds;
40+
41+
/**
42+
* @var ObjectManagerHelper
43+
*/
44+
protected $objectManagerHelper;
45+
46+
/**
47+
* Create mocks and model
48+
*/
49+
protected function setUp()
50+
{
51+
$this->helperMock = $this->createMock(CaptchaHelper::class);
52+
$this->customerSessionMock = $this->createMock(CustomerSession::class);
53+
$this->formIds = [
54+
'user_login'
55+
];
56+
$this->objectManagerHelper = new ObjectManagerHelper($this);
57+
$this->model = $this->objectManagerHelper->getObject(
58+
Captcha::class,
59+
[
60+
'helper' => $this->helperMock,
61+
'formIds' => $this->formIds,
62+
'customerSession' => $this->customerSessionMock
63+
]
64+
);
65+
}
66+
67+
/**
68+
* Test getSectionData() when user is login and require captcha
69+
*/
70+
public function testGetSectionDataWhenLoginAndRequireCaptcha()
71+
{
72+
$emailLogin = 'test@localhost.com';
73+
74+
$userLoginModel = $this->createMock(DefaultModel::class);
75+
$userLoginModel->expects($this->any())->method('isRequired')->with($emailLogin)
76+
->willReturn(true);
77+
$this->helperMock->expects($this->any())->method('getCaptcha')->with('user_login')->willReturn($userLoginModel);
78+
79+
$this->customerSessionMock->expects($this->any())->method('isLoggedIn')
80+
->willReturn(true);
81+
82+
$customerDataMock = $this->createMock(CustomerData::class);
83+
$customerDataMock->expects($this->any())->method('getEmail')->willReturn($emailLogin);
84+
$this->customerSessionMock->expects($this->any())->method('getCustomerData')
85+
->willReturn($customerDataMock);
86+
87+
/* Assert to test */
88+
$this->assertEquals(
89+
[
90+
"user_login" => [
91+
"isRequired" => true,
92+
"timestamp" => time()
93+
]
94+
],
95+
$this->model->getSectionData()
96+
);
97+
}
98+
}

app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ protected function _getNodeJson($node, $level = 0)
407407
public function buildNodeName($node)
408408
{
409409
$result = $this->escapeHtml($node->getName());
410+
$result .= ' (ID: ' . $node->getId() . ')';
410411
if ($this->_withProductCount) {
411412
$result .= ' (' . $node->getProductCount() . ')';
412413
}

app/code/Magento/Catalog/Model/Indexer/Category/Product.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,11 @@ protected function executeAction($ids)
137137

138138
/** @var Product\Action\Rows $action */
139139
$action = $this->rowsActionFactory->create();
140-
if ($indexer->isWorking()) {
140+
if ($indexer->isScheduled()) {
141141
$action->execute($ids, true);
142+
} else {
143+
$action->execute($ids);
142144
}
143-
$action->execute($ids);
144145

145146
return $this;
146147
}

app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Rows.php

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,24 @@
55
*/
66
namespace Magento\Catalog\Model\Indexer\Category\Product\Action;
77

8+
use Magento\Framework\DB\Adapter\AdapterInterface;
9+
use Magento\Framework\Indexer\CacheContext;
10+
use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
11+
use Magento\Framework\App\ObjectManager;
12+
use Magento\Framework\App\ResourceConnection;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
use Magento\Framework\DB\Query\Generator as QueryGenerator;
15+
use Magento\Framework\EntityManager\MetadataPool;
16+
use Magento\Catalog\Model\Config;
17+
use Magento\Catalog\Model\Category;
18+
use Magento\Framework\Indexer\IndexerRegistry;
19+
use Magento\Catalog\Model\Indexer\Product\Category as ProductCategoryIndexer;
20+
821
/**
922
* Reindex multiple rows action.
1023
*
1124
* @package Magento\Catalog\Model\Indexer\Category\Product\Action
25+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1226
*/
1327
class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractAction
1428
{
@@ -19,12 +33,54 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
1933
*/
2034
protected $limitationByCategories;
2135

36+
/**
37+
* @var CacheContext
38+
*/
39+
private $cacheContext;
40+
41+
/**
42+
* @var EventManagerInterface|null
43+
*/
44+
private $eventManager;
45+
46+
/**
47+
* @var IndexerRegistry
48+
*/
49+
private $indexerRegistry;
50+
51+
/**
52+
* @param ResourceConnection $resource
53+
* @param StoreManagerInterface $storeManager
54+
* @param Config $config
55+
* @param QueryGenerator|null $queryGenerator
56+
* @param MetadataPool|null $metadataPool
57+
* @param CacheContext|null $cacheContext
58+
* @param EventManagerInterface|null $eventManager
59+
* @param IndexerRegistry|null $indexerRegistry
60+
*/
61+
public function __construct(
62+
ResourceConnection $resource,
63+
StoreManagerInterface $storeManager,
64+
Config $config,
65+
QueryGenerator $queryGenerator = null,
66+
MetadataPool $metadataPool = null,
67+
CacheContext $cacheContext = null,
68+
EventManagerInterface $eventManager = null,
69+
IndexerRegistry $indexerRegistry = null
70+
) {
71+
parent::__construct($resource, $storeManager, $config, $queryGenerator, $metadataPool);
72+
$this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class);
73+
$this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManagerInterface::class);
74+
$this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()->get(IndexerRegistry::class);
75+
}
76+
2277
/**
2378
* Refresh entities index
2479
*
2580
* @param int[] $entityIds
2681
* @param bool $useTempTable
2782
* @return $this
83+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
2884
*/
2985
public function execute(array $entityIds = [], $useTempTable = false)
3086
{
@@ -40,12 +96,58 @@ public function execute(array $entityIds = [], $useTempTable = false)
4096
}
4197
$this->limitationByCategories = array_unique($this->limitationByCategories);
4298
$this->useTempTable = $useTempTable;
43-
$this->removeEntries();
99+
$indexer = $this->indexerRegistry->get(ProductCategoryIndexer::INDEXER_ID);
100+
$workingState = $indexer->isWorking();
101+
102+
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
103+
foreach ($this->storeManager->getStores() as $store) {
104+
$this->connection->truncateTable($this->getIndexTable($store->getId()));
105+
}
106+
} else {
107+
$this->removeEntries();
108+
}
109+
44110
$this->reindex();
45111

112+
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
113+
foreach ($this->storeManager->getStores() as $store) {
114+
$removalCategoryIds = array_diff($this->limitationByCategories, [$this->getRootCategoryId($store)]);
115+
$this->connection->delete(
116+
$this->tableMaintainer->getMainTable($store->getId()),
117+
['category_id IN (?)' => $removalCategoryIds]
118+
);
119+
$select = $this->connection->select()
120+
->from($this->tableMaintainer->getMainReplicaTable($store->getId()));
121+
$this->connection->query(
122+
$this->connection->insertFromSelect(
123+
$select,
124+
$this->tableMaintainer->getMainTable($store->getId()),
125+
[],
126+
AdapterInterface::INSERT_ON_DUPLICATE
127+
)
128+
);
129+
}
130+
}
131+
132+
$this->registerCategories($entityIds);
133+
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
134+
46135
return $this;
47136
}
48137

138+
/**
139+
* Register categories assigned to products
140+
*
141+
* @param array $categoryIds
142+
* @return void
143+
*/
144+
private function registerCategories(array $categoryIds)
145+
{
146+
if ($categoryIds) {
147+
$this->cacheContext->registerEntities(Category::CACHE_TAG, $categoryIds);
148+
}
149+
}
150+
49151
/**
50152
* Return array of all category root IDs + tree root ID
51153
*

app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
1616
use Magento\Framework\Indexer\CacheContext;
1717
use Magento\Store\Model\StoreManagerInterface;
18+
use Magento\Framework\DB\Adapter\AdapterInterface;
19+
use Magento\Framework\Indexer\IndexerRegistry;
20+
use Magento\Catalog\Model\Indexer\Category\Product as CategoryProductIndexer;
1821

1922
/**
2023
* Category rows indexer.
@@ -40,6 +43,11 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
4043
*/
4144
private $eventManager;
4245

46+
/**
47+
* @var IndexerRegistry
48+
*/
49+
private $indexerRegistry;
50+
4351
/**
4452
* @param ResourceConnection $resource
4553
* @param StoreManagerInterface $storeManager
@@ -48,6 +56,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractActio
4856
* @param MetadataPool|null $metadataPool
4957
* @param CacheContext|null $cacheContext
5058
* @param EventManagerInterface|null $eventManager
59+
* @param IndexerRegistry|null $indexerRegistry
5160
*/
5261
public function __construct(
5362
ResourceConnection $resource,
@@ -56,11 +65,13 @@ public function __construct(
5665
QueryGenerator $queryGenerator = null,
5766
MetadataPool $metadataPool = null,
5867
CacheContext $cacheContext = null,
59-
EventManagerInterface $eventManager = null
68+
EventManagerInterface $eventManager = null,
69+
IndexerRegistry $indexerRegistry = null
6070
) {
6171
parent::__construct($resource, $storeManager, $config, $queryGenerator, $metadataPool);
6272
$this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class);
6373
$this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManagerInterface::class);
74+
$this->indexerRegistry = $indexerRegistry ?: ObjectManager::getInstance()->get(IndexerRegistry::class);
6475
}
6576

6677
/**
@@ -78,12 +89,37 @@ public function execute(array $entityIds = [], $useTempTable = false)
7889

7990
$this->limitationByProducts = $idsToBeReIndexed;
8091
$this->useTempTable = $useTempTable;
92+
$indexer = $this->indexerRegistry->get(CategoryProductIndexer::INDEXER_ID);
93+
$workingState = $indexer->isWorking();
8194

8295
$affectedCategories = $this->getCategoryIdsFromIndex($idsToBeReIndexed);
8396

84-
$this->removeEntries();
85-
97+
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
98+
foreach ($this->storeManager->getStores() as $store) {
99+
$this->connection->truncateTable($this->getIndexTable($store->getId()));
100+
}
101+
} else {
102+
$this->removeEntries();
103+
}
86104
$this->reindex();
105+
if ($useTempTable && !$workingState && $indexer->isScheduled()) {
106+
foreach ($this->storeManager->getStores() as $store) {
107+
$this->connection->delete(
108+
$this->tableMaintainer->getMainTable($store->getId()),
109+
['product_id IN (?)' => $this->limitationByProducts]
110+
);
111+
$select = $this->connection->select()
112+
->from($this->tableMaintainer->getMainReplicaTable($store->getId()));
113+
$this->connection->query(
114+
$this->connection->insertFromSelect(
115+
$select,
116+
$this->tableMaintainer->getMainTable($store->getId()),
117+
[],
118+
AdapterInterface::INSERT_ON_DUPLICATE
119+
)
120+
);
121+
}
122+
}
87123

88124
$affectedCategories = array_merge($affectedCategories, $this->getCategoryIdsFromIndex($idsToBeReIndexed));
89125

app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
userInput="$$createProduct1.name$$" stepKey="seeProductName4"/>
132132
<see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}"
133133
userInput="$$createProduct12.name$$" stepKey="seeProductName5"/>
134-
<waitForText userInput="$$createCategory.name$$ (2)" stepKey="seeCorrectProductCount"/>
134+
<waitForText userInput="$$createCategory.name$$ (ID: 6) (2)" stepKey="seeCorrectProductCount"/>
135135
<dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}"
136136
userInput="$$createProduct0.name$$" stepKey="dontSeeProductName"/>
137137
<dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}"
@@ -151,7 +151,7 @@
151151
userInput="$$createProduct2.name$$" stepKey="seeProductName6"/>
152152
<see selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct12.name$$)}}"
153153
userInput="$$createProduct12.name$$" stepKey="seeProductName7"/>
154-
<waitForText userInput="$$createCategory.name$$ (2)" stepKey="seeCorrectProductCount2"/>
154+
<waitForText userInput="$$createCategory.name$$ (ID: 6) (2)" stepKey="seeCorrectProductCount2"/>
155155
<dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct0.name$$)}}"
156156
userInput="$$createProduct0.name$$" stepKey="dontSeeProductName2"/>
157157
<dontSee selector="{{AdminCategoryProductsGridSection.productGridNameProduct($$createProduct2.name$$)}}"

app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,13 @@ public function testExecuteWithIndexerWorking()
8484
{
8585
$ids = [1, 2, 3];
8686

87-
$this->indexerMock->expects($this->once())->method('isWorking')->will($this->returnValue(true));
8887
$this->prepareIndexer();
8988

9089
$rowMock = $this->createPartialMock(
9190
\Magento\Catalog\Model\Indexer\Category\Product\Action\Rows::class,
9291
['execute']
9392
);
94-
$rowMock->expects($this->at(0))->method('execute')->with($ids, true)->will($this->returnSelf());
95-
$rowMock->expects($this->at(1))->method('execute')->with($ids, false)->will($this->returnSelf());
93+
$rowMock->expects($this->at(0))->method('execute')->with($ids)->will($this->returnSelf());
9694

9795
$this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
9896

@@ -103,14 +101,13 @@ public function testExecuteWithIndexerNotWorking()
103101
{
104102
$ids = [1, 2, 3];
105103

106-
$this->indexerMock->expects($this->once())->method('isWorking')->will($this->returnValue(false));
107104
$this->prepareIndexer();
108105

109106
$rowMock = $this->createPartialMock(
110107
\Magento\Catalog\Model\Indexer\Category\Product\Action\Rows::class,
111108
['execute']
112109
);
113-
$rowMock->expects($this->once())->method('execute')->with($ids, false)->will($this->returnSelf());
110+
$rowMock->expects($this->once())->method('execute')->with($ids)->will($this->returnSelf());
114111

115112
$this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock));
116113

0 commit comments

Comments
 (0)