Skip to content

Commit 1eebf18

Browse files
Merge pull request #9406 from magento-cia/cia-2.4.8-beta2-develop-bugfix-12092024
AC-12885: Review Report Fix
2 parents 6de22d4 + 952a925 commit 1eebf18

File tree

4 files changed

+247
-21
lines changed

4 files changed

+247
-21
lines changed

app/code/Magento/Reports/Controller/Adminhtml/Report/Review.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,20 @@ public function _initAction()
6060
*/
6161
protected function _isAllowed()
6262
{
63-
return match ($this->getRequest()->getActionName()) {
64-
'exportCustomerCsv',
65-
'exportCustomerExcel',
63+
return match (strtolower($this->getRequest()->getActionName())) {
64+
'exportcustomercsv',
65+
'exportcustomerexcel',
6666
'customer' =>
67-
$this->_authorization->isAllowed('Magento_Reports::review_customer'),
68-
'exportProductCsv',
69-
'exportProductExcel',
70-
'exportProductDetailCsv',
71-
'exportProductDetailExcel',
72-
'productDetail',
67+
$this->_authorization->isAllowed('Magento_Reports::review_customer'),
68+
'exportproductcsv',
69+
'exportproductexcel',
70+
'exportproductdetailcsv',
71+
'exportproductdetailexcel',
72+
'productdetail',
7373
'product' =>
74-
$this->_authorization->isAllowed('Magento_Reports::review_product'),
74+
$this->_authorization->isAllowed('Magento_Reports::review_product'),
7575
default =>
76-
$this->_authorization->isAllowed('Magento_Reports::review'),
76+
$this->_authorization->isAllowed('Magento_Reports::review'),
7777
};
7878
}
7979
}

app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ public function resolve()
120120
$this->inputArraySizeLimitValue->set($route->getInputArraySizeLimit());
121121

122122
foreach ($inputData as $key => $singleEntityParams) {
123+
if (!is_array($singleEntityParams)) {
124+
continue;
125+
}
126+
123127
$webapiResolvedParams[$key] = $this->resolveBulkItemParams(
124128
$singleEntityParams,
125129
$routeServiceClass,

app/code/Magento/WebapiAsync/Controller/Rest/AsynchronousRequestProcessor.php

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Magento\Framework\Reflection\DataObjectProcessor;
1818
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory;
1919
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterface;
20+
use Magento\Framework\Webapi\Rest\Request;
21+
use Magento\Framework\Webapi\Exception;
2022

2123
/**
2224
* Responsible for dispatching single and bulk requests.
@@ -25,8 +27,8 @@
2527
*/
2628
class AsynchronousRequestProcessor implements RequestProcessorInterface
2729
{
28-
const PROCESSOR_PATH = "/^\\/async(\\/V.+)/";
29-
const BULK_PROCESSOR_PATH = "/^\\/async\/bulk(\\/V.+)/";
30+
public const PROCESSOR_PATH = "/^\\/async(\\/V.+)/";
31+
public const BULK_PROCESSOR_PATH = "/^\\/async\/bulk(\\/V.+)/";
3032

3133
/**
3234
* @var \Magento\Framework\Webapi\Rest\Response
@@ -87,9 +89,9 @@ public function __construct(
8789
}
8890

8991
/**
90-
* {@inheritdoc}
92+
* @inheritdoc
9193
*/
92-
public function process(\Magento\Framework\Webapi\Rest\Request $request)
94+
public function process(Request $request)
9395
{
9496
$path = $request->getPathInfo();
9597
$path = preg_replace($this->processorPath, "$1", $path);
@@ -119,7 +121,10 @@ public function process(\Magento\Framework\Webapi\Rest\Request $request)
119121
}
120122

121123
/**
124+
* Get topic name from webapi_async_config services config array by route url and http method
125+
*
122126
* @param \Magento\Framework\Webapi\Rest\Request $request
127+
*
123128
* @return string
124129
*/
125130
private function getTopicName($request)
@@ -133,29 +138,58 @@ private function getTopicName($request)
133138
}
134139

135140
/**
136-
* {@inheritdoc}
141+
* @inheritdoc
137142
*/
138-
public function canProcess(\Magento\Framework\Webapi\Rest\Request $request)
143+
public function canProcess(Request $request)
139144
{
140-
if ($request->getHttpMethod() === \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET) {
145+
if ($request->getHttpMethod() === Request::HTTP_METHOD_GET) {
141146
return false;
142147
}
143148

144149
if (preg_match($this->processorPath, $request->getPathInfo()) === 1) {
145-
return true;
150+
return $this->checkSelfResourceRequest($request);
146151
}
152+
147153
return false;
148154
}
149155

150156
/**
151-
* @param \Magento\Framework\Webapi\Rest\Request $request
157+
* Check if current request is bulk request
158+
*
159+
* @param Request $request
152160
* @return bool
153161
*/
154-
public function isBulk(\Magento\Framework\Webapi\Rest\Request $request)
162+
public function isBulk(Request $request)
155163
{
156164
if (preg_match(self::BULK_PROCESSOR_PATH, $request->getPathInfo()) === 1) {
157165
return true;
158166
}
159167
return false;
160168
}
169+
170+
/**
171+
* Check if current request is self resource request
172+
*
173+
* @param Request $request
174+
* @return bool
175+
*
176+
* @throws Exception
177+
*/
178+
private function checkSelfResourceRequest(Request $request): bool
179+
{
180+
$path = preg_replace($this->processorPath, "$1", $request->getPathInfo());
181+
$request->setPathInfo(
182+
$path
183+
);
184+
185+
$route = $this->inputParamsResolver->getRoute();
186+
$aclResources = $route->getAclResources();
187+
188+
// We do not process self resource requests asynchronously
189+
if (in_array('self', $aclResources, true)) {
190+
return false;
191+
}
192+
193+
return true;
194+
}
161195
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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\WebapiAsync\Test\Unit\Controller;
10+
11+
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory;
12+
use Magento\AsynchronousOperations\Model\ConfigInterface as WebApiAsyncConfig;
13+
use Magento\AsynchronousOperations\Model\MassSchedule;
14+
use Magento\Framework\Webapi\Rest\Request;
15+
use Magento\Webapi\Controller\Rest\Router;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
use Magento\Framework\Webapi\Rest\Response;
19+
use Magento\WebapiAsync\Controller\Rest\Asynchronous\InputParamsResolver;
20+
use Magento\WebapiAsync\Controller\Rest\AsynchronousRequestProcessor;
21+
use Magento\Framework\Reflection\DataObjectProcessor;
22+
23+
/**
24+
* Test for Magento\WebapiAsync\Controller\AsynchronousRequestProcessor class.
25+
*/
26+
class AsynchronousRequestProcessorTest extends TestCase
27+
{
28+
/**
29+
* @var Response|MockObject
30+
*/
31+
private $responseMock;
32+
33+
/**
34+
* @var InputParamsResolver|MockObject
35+
*/
36+
private $inputParamsResolverMock;
37+
38+
/**
39+
* @var MassSchedule|MockObject
40+
*/
41+
private $asyncBulkPublisher;
42+
43+
/**
44+
* @var WebApiAsyncConfig|MockObject
45+
*/
46+
private $webapiAsyncConfig;
47+
48+
/**
49+
* @var DataObjectProcessor|MockObject
50+
*/
51+
private $dataObjectProcessor;
52+
53+
/**
54+
* @var AsyncResponseInterfaceFactory|MockObject
55+
*/
56+
private $asyncResponseFactory;
57+
58+
/**
59+
* @var string Regex pattern
60+
*/
61+
private $processorPath;
62+
63+
/**
64+
* @var Request|MockObject
65+
*/
66+
private $requestMock;
67+
68+
/**
69+
* @var AsynchronousRequestProcessor
70+
*/
71+
private $subject;
72+
73+
/**
74+
* @inheritdoc
75+
*/
76+
protected function setUp(): void
77+
{
78+
$this->requestMock = $this->getRequestMock();
79+
80+
$this->responseMock = $this->getMockBuilder(Response::class)
81+
->disableOriginalConstructor()
82+
->getMock();
83+
84+
$this->inputParamsResolverMock = $this->getMockBuilder(InputParamsResolver::class)
85+
->disableOriginalConstructor()
86+
->getMock();
87+
88+
$this->asyncBulkPublisher = $this->getMockBuilder(MassSchedule::class)
89+
->disableOriginalConstructor()
90+
->getMock();
91+
92+
$this->webapiAsyncConfig = $this->getMockBuilder(WebApiAsyncConfig::class)
93+
->disableOriginalConstructor()
94+
->getMock();
95+
96+
$this->dataObjectProcessor = $this->getMockBuilder(DataObjectProcessor::class)
97+
->disableOriginalConstructor()
98+
->getMock();
99+
100+
$this->asyncResponseFactory = $this->getMockBuilder(AsyncResponseInterfaceFactory::class)
101+
->disableOriginalConstructor()
102+
->getMock();
103+
104+
$this->processorPath = AsynchronousRequestProcessor::PROCESSOR_PATH;
105+
106+
$this->subject = new AsynchronousRequestProcessor(
107+
$this->responseMock,
108+
$this->inputParamsResolverMock,
109+
$this->asyncBulkPublisher,
110+
$this->webapiAsyncConfig,
111+
$this->dataObjectProcessor,
112+
$this->asyncResponseFactory,
113+
$this->processorPath
114+
);
115+
}
116+
117+
public function testCanNotProcess(): void
118+
{
119+
$this->requestMock->expects($this->any())
120+
->method('getPathInfo')
121+
->willReturn("/async/bulk/V1/configurable-products/bySku/options");
122+
123+
$this->assertFalse($this->subject->canProcess($this->requestMock));
124+
}
125+
126+
public function testCanProcess(): void
127+
{
128+
$this->requestMock->expects($this->any())
129+
->method('getPathInfo')
130+
->willReturn("/async/V1/configurable-products/bySku/options");
131+
132+
$route = $this->getMockBuilder(Router\Route::class)
133+
->disableOriginalConstructor()
134+
->getMock();
135+
136+
$route->expects($this->once())
137+
->method('getAclResources')
138+
->willReturn(['Magento_Catalog::products']);
139+
140+
$this->inputParamsResolverMock->expects($this->once())
141+
->method('getRoute')
142+
->willReturn($route);
143+
144+
$this->assertTrue($this->subject->canProcess($this->requestMock));
145+
}
146+
147+
public function testCanProcessSelfResourceRequest(): void
148+
{
149+
$this->requestMock->expects($this->any())
150+
->method('getPathInfo')
151+
->willReturn("/async/V1/configurable-products/bySku/options");
152+
153+
$route = $this->getMockBuilder(Router\Route::class)
154+
->disableOriginalConstructor()
155+
->getMock();
156+
157+
$route->expects($this->once())
158+
->method('getAclResources')
159+
->willReturn(['self']);
160+
161+
$this->inputParamsResolverMock->expects($this->once())
162+
->method('getRoute')
163+
->willReturn($route);
164+
165+
$this->assertFalse($this->subject->canProcess($this->requestMock));
166+
}
167+
168+
/**
169+
* @return Request|MockObject
170+
*/
171+
private function getRequestMock()
172+
{
173+
return $this->getMockBuilder(Request::class)
174+
->onlyMethods(
175+
[
176+
'isSecure',
177+
'getRequestData',
178+
'getParams',
179+
'getParam',
180+
'getRequestedServices',
181+
'getPathInfo',
182+
'getHttpHost',
183+
'getMethod',
184+
]
185+
)->disableOriginalConstructor()
186+
->getMock();
187+
}
188+
}

0 commit comments

Comments
 (0)