Skip to content

Commit 1be2cd7

Browse files
authored
Merge branch '2.4-develop' into fix-28388
2 parents aea9276 + c35093a commit 1be2cd7

File tree

39 files changed

+1460
-345
lines changed

39 files changed

+1460
-345
lines changed

app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml

Lines changed: 0 additions & 26 deletions
This file was deleted.

app/code/Magento/Catalog/Model/ResourceModel/Category/AggregateCount.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88
use Magento\Catalog\Model\Category;
99

1010
/**
11+
* Aggregate count for parent category after deleting child category
12+
*
1113
* Class AggregateCount
1214
*/
1315
class AggregateCount
1416
{
1517
/**
18+
* Reduces children count for parent categories
19+
*
1620
* @param Category $category
1721
* @return void
1822
*/
@@ -25,9 +29,7 @@ public function processDelete(Category $category)
2529
*/
2630
$parentIds = $category->getParentIds();
2731
if ($parentIds) {
28-
$childDecrease = $category->getChildrenCount() + 1;
29-
// +1 is itself
30-
$data = ['children_count' => new \Zend_Db_Expr('children_count - ' . $childDecrease)];
32+
$data = ['children_count' => new \Zend_Db_Expr('children_count - 1')];
3133
$where = ['entity_id IN(?)' => $parentIds];
3234
$resourceModel->getConnection()->update($resourceModel->getEntityTable(), $data, $where);
3335
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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\Catalog\Test\Unit\Model\ResourceModel\Category;
9+
10+
use Magento\Catalog\Model\Category;
11+
use Magento\Catalog\Model\ResourceModel\Category\AggregateCount;
12+
use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory;
13+
use Magento\Framework\DB\Adapter\AdapterInterface;
14+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
15+
use PHPUnit\Framework\MockObject\MockObject;
16+
use PHPUnit\Framework\TestCase;
17+
18+
/**
19+
* Aggregate count model test
20+
*/
21+
class AggregateCountTest extends TestCase
22+
{
23+
24+
/**
25+
* @var AggregateCount
26+
*/
27+
protected $aggregateCount;
28+
29+
/**
30+
* @var ObjectManagerHelper
31+
*/
32+
protected $objectManagerHelper;
33+
34+
/**
35+
* @var Category|MockObject
36+
*/
37+
protected $categoryMock;
38+
39+
/**
40+
* @var ResourceCategory|MockObject
41+
*/
42+
protected $resourceCategoryMock;
43+
44+
/**
45+
* @var AdapterInterface|MockObject
46+
*/
47+
protected $connectionMock;
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
public function setUp(): void
53+
{
54+
$this->categoryMock = $this->createMock(Category::class);
55+
$this->resourceCategoryMock = $this->createMock(ResourceCategory::class);
56+
$this->connectionMock = $this->getMockBuilder(AdapterInterface::class)
57+
->getMockForAbstractClass();
58+
$this->objectManagerHelper = new ObjectManagerHelper($this);
59+
$this->aggregateCount = $this->objectManagerHelper->getObject(AggregateCount::class);
60+
}
61+
62+
/**
63+
* @return void
64+
*/
65+
public function testProcessDelete(): void
66+
{
67+
$parentIds = 3;
68+
$table = 'catalog_category_entity';
69+
70+
$this->categoryMock->expects($this->once())
71+
->method('getResource')
72+
->willReturn($this->resourceCategoryMock);
73+
$this->categoryMock->expects($this->once())
74+
->method('getParentIds')
75+
->willReturn($parentIds);
76+
$this->resourceCategoryMock->expects($this->any())
77+
->method('getEntityTable')
78+
->willReturn($table);
79+
$this->resourceCategoryMock->expects($this->once())
80+
->method('getConnection')
81+
->willReturn($this->connectionMock);
82+
$this->connectionMock->expects($this->once())
83+
->method('update')
84+
->with(
85+
$table,
86+
['children_count' => new \Zend_Db_Expr('children_count - 1')],
87+
['entity_id IN(?)' => $parentIds]
88+
);
89+
$this->aggregateCount->processDelete($this->categoryMock);
90+
}
91+
}

app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77

88
namespace Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier;
99

10-
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
11-
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
1210
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories;
11+
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
12+
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1313
use Magento\Framework\AuthorizationInterface;
1414
use Magento\Framework\DB\Helper as DbHelper;
1515
use Magento\Framework\UrlInterface;
1616
use Magento\Store\Model\Store;
17+
use Magento\Backend\Model\Auth\Session;
18+
use Magento\Authorization\Model\Role;
19+
use Magento\User\Model\User;
1720
use PHPUnit\Framework\MockObject\MockObject;
1821

1922
/**
@@ -51,6 +54,11 @@ class CategoriesTest extends AbstractModifierTest
5154
*/
5255
private $authorizationMock;
5356

57+
/**
58+
* @var Session|MockObject
59+
*/
60+
private $sessionMock;
61+
5462
protected function setUp(): void
5563
{
5664
parent::setUp();
@@ -72,7 +80,10 @@ protected function setUp(): void
7280
$this->authorizationMock = $this->getMockBuilder(AuthorizationInterface::class)
7381
->disableOriginalConstructor()
7482
->getMockForAbstractClass();
75-
83+
$this->sessionMock = $this->getMockBuilder(Session::class)
84+
->setMethods(['getUser'])
85+
->disableOriginalConstructor()
86+
->getMock();
7687
$this->categoryCollectionFactoryMock->expects($this->any())
7788
->method('create')
7889
->willReturn($this->categoryCollectionMock);
@@ -88,6 +99,26 @@ protected function setUp(): void
8899
$this->categoryCollectionMock->expects($this->any())
89100
->method('getIterator')
90101
->willReturn(new \ArrayIterator([]));
102+
103+
$roleAdmin = $this->getMockBuilder(Role::class)
104+
->setMethods(['getId'])
105+
->disableOriginalConstructor()
106+
->getMock();
107+
$roleAdmin->expects($this->any())
108+
->method('getId')
109+
->willReturn(0);
110+
111+
$userAdmin = $this->getMockBuilder(User::class)
112+
->setMethods(['getRole'])
113+
->disableOriginalConstructor()
114+
->getMock();
115+
$userAdmin->expects($this->any())
116+
->method('getRole')
117+
->willReturn($roleAdmin);
118+
119+
$this->sessionMock->expects($this->any())
120+
->method('getUser')
121+
->willReturn($userAdmin);
91122
}
92123

93124
/**
@@ -101,11 +132,28 @@ protected function createModel()
101132
'locator' => $this->locatorMock,
102133
'categoryCollectionFactory' => $this->categoryCollectionFactoryMock,
103134
'arrayManager' => $this->arrayManagerMock,
104-
'authorization' => $this->authorizationMock
135+
'authorization' => $this->authorizationMock,
136+
'session' => $this->sessionMock
105137
]
106138
);
107139
}
108140

141+
/**
142+
* @param object $object
143+
* @param string $method
144+
* @param array $args
145+
* @return mixed
146+
* @throws \ReflectionException
147+
*/
148+
private function invokeMethod($object, $method, $args = [])
149+
{
150+
$class = new \ReflectionClass(Categories::class);
151+
$method = $class->getMethod($method);
152+
$method->setAccessible(true);
153+
154+
return $method->invokeArgs($object, $args);
155+
}
156+
109157
public function testModifyData()
110158
{
111159
$this->assertSame([], $this->getModel()->modifyData([]));
@@ -176,4 +224,44 @@ public function modifyMetaLockedDataProvider()
176224
{
177225
return [[true], [false]];
178226
}
227+
228+
/**
229+
* Asserts that a user with an ACL role ID of 0 and a user with an ACL role ID of 1 do not have the same cache IDs
230+
* Assumes a store ID of 0
231+
*
232+
* @throws \ReflectionException
233+
*/
234+
public function testAclCacheIds()
235+
{
236+
$categoriesAdmin = $this->createModel();
237+
$cacheIdAdmin = $this->invokeMethod($categoriesAdmin, 'getCategoriesTreeCacheId', [0]);
238+
239+
$roleAclUser = $this->getMockBuilder(Role::class)
240+
->disableOriginalConstructor()
241+
->getMock();
242+
$roleAclUser->expects($this->any())
243+
->method('getId')
244+
->willReturn(1);
245+
246+
$userAclUser = $this->getMockBuilder(User::class)
247+
->disableOriginalConstructor()
248+
->getMock();
249+
$userAclUser->expects($this->any())
250+
->method('getRole')
251+
->will($this->returnValue($roleAclUser));
252+
253+
$this->sessionMock = $this->getMockBuilder(Session::class)
254+
->setMethods(['getUser'])
255+
->disableOriginalConstructor()
256+
->getMock();
257+
258+
$this->sessionMock->expects($this->any())
259+
->method('getUser')
260+
->will($this->returnValue($userAclUser));
261+
262+
$categoriesAclUser = $this->createModel();
263+
$cacheIdAclUser = $this->invokeMethod($categoriesAclUser, 'getCategoriesTreeCacheId', [0]);
264+
265+
$this->assertNotEquals($cacheIdAdmin, $cacheIdAclUser);
266+
}
179267
}

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
use Magento\Framework\UrlInterface;
1919
use Magento\Framework\Stdlib\ArrayManager;
2020
use Magento\Framework\AuthorizationInterface;
21+
use Magento\Backend\Model\Auth\Session;
2122

2223
/**
2324
* Data provider for categories field of product page
2425
*
2526
* @api
2627
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2729
* @since 101.0.0
2830
*/
2931
class Categories extends AbstractModifier
@@ -86,6 +88,11 @@ class Categories extends AbstractModifier
8688
*/
8789
private $authorization;
8890

91+
/**
92+
* @var Session
93+
*/
94+
private $session;
95+
8996
/**
9097
* @param LocatorInterface $locator
9198
* @param CategoryCollectionFactory $categoryCollectionFactory
@@ -94,6 +101,7 @@ class Categories extends AbstractModifier
94101
* @param ArrayManager $arrayManager
95102
* @param SerializerInterface $serializer
96103
* @param AuthorizationInterface $authorization
104+
* @param Session $session
97105
*/
98106
public function __construct(
99107
LocatorInterface $locator,
@@ -102,7 +110,8 @@ public function __construct(
102110
UrlInterface $urlBuilder,
103111
ArrayManager $arrayManager,
104112
SerializerInterface $serializer = null,
105-
AuthorizationInterface $authorization = null
113+
AuthorizationInterface $authorization = null,
114+
Session $session = null
106115
) {
107116
$this->locator = $locator;
108117
$this->categoryCollectionFactory = $categoryCollectionFactory;
@@ -111,6 +120,7 @@ public function __construct(
111120
$this->arrayManager = $arrayManager;
112121
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
113122
$this->authorization = $authorization ?: ObjectManager::getInstance()->get(AuthorizationInterface::class);
123+
$this->session = $session ?: ObjectManager::getInstance()->get(Session::class);
114124
}
115125

116126
/**
@@ -370,10 +380,16 @@ protected function getCategoriesTree($filter = null)
370380
* @param string $filter
371381
* @return string
372382
*/
373-
private function getCategoriesTreeCacheId(int $storeId, string $filter = '') : string
383+
private function getCategoriesTreeCacheId(int $storeId, string $filter = ''): string
374384
{
385+
if ($this->session->getUser() !== null) {
386+
return self::CATEGORY_TREE_ID
387+
. '_' . (string)$storeId
388+
. '_' . $this->session->getUser()->getAclRole()
389+
. '_' . $filter;
390+
}
375391
return self::CATEGORY_TREE_ID
376-
. '_' . (string) $storeId
392+
. '_' . (string)$storeId
377393
. '_' . $filter;
378394
}
379395

0 commit comments

Comments
 (0)