Skip to content

Commit f824b9e

Browse files
committed
Merge remote-tracking branch 'mainline/2.4-develop' into 2.4.1-develop
2 parents 7f2272d + c8794cb commit f824b9e

File tree

24 files changed

+321
-36
lines changed

24 files changed

+321
-36
lines changed

app/code/Magento/Captcha/Controller/Refresh/Index.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
namespace Magento\Captcha\Controller\Refresh;
99

1010
use Magento\Captcha\Helper\Data as CaptchaHelper;
11+
use Magento\Framework\App\Action\Action;
12+
use Magento\Framework\App\Action\Context;
1113
use Magento\Framework\App\Action\HttpPostActionInterface;
1214
use Magento\Framework\App\RequestInterface;
1315
use Magento\Framework\Controller\Result\JsonFactory as JsonResultFactory;
@@ -18,7 +20,7 @@
1820
* Refreshes captcha and returns JSON encoded URL to image (AJAX action)
1921
* Example: {'imgSrc': 'http://example.com/media/captcha/67842gh187612ngf8s.png'}
2022
*/
21-
class Index implements HttpPostActionInterface
23+
class Index extends Action implements HttpPostActionInterface
2224
{
2325
/**
2426
* @var CaptchaHelper
@@ -46,19 +48,22 @@ class Index implements HttpPostActionInterface
4648
private $jsonResultFactory;
4749

4850
/**
51+
* @param Context $context
4952
* @param RequestInterface $request
5053
* @param JsonResultFactory $jsonFactory
5154
* @param CaptchaHelper $captchaHelper
5255
* @param LayoutInterface $layout
5356
* @param JsonSerializer $serializer
5457
*/
5558
public function __construct(
59+
Context $context,
5660
RequestInterface $request,
5761
JsonResultFactory $jsonFactory,
5862
CaptchaHelper $captchaHelper,
5963
LayoutInterface $layout,
6064
JsonSerializer $serializer
6165
) {
66+
parent::__construct($context);
6267
$this->request = $request;
6368
$this->jsonResultFactory = $jsonFactory;
6469
$this->captchaHelper = $captchaHelper;

app/code/Magento/Captcha/Test/Unit/Controller/Refresh/IndexTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Captcha\Controller\Refresh\Index;
1111
use Magento\Captcha\Helper\Data as CaptchaHelper;
1212
use Magento\Captcha\Model\CaptchaInterface;
13+
use Magento\Framework\App\Action\Context;
1314
use Magento\Framework\App\RequestInterface;
1415
use Magento\Framework\Controller\Result\Json as ResultJson;
1516
use Magento\Framework\Controller\Result\JsonFactory as ResultJsonFactory;
@@ -45,6 +46,9 @@ class IndexTest extends TestCase
4546
/** @var MockObject|JsonSerializer */
4647
private $jsonSerializerMock;
4748

49+
/** @var MockObject|Context */
50+
private $contextMock;
51+
4852
/** @var Index */
4953
private $refreshAction;
5054

@@ -66,13 +70,16 @@ protected function setUp(): void
6670
$this->jsonSerializerMock = $this->createMock(JsonSerializer::class);
6771
$this->captchaHelperMock = $this->createMock(CaptchaHelper::class);
6872

73+
$this->contextMock = $this->createMock(Context::class);
74+
6975
$this->blockMock->method('setIsAjax')
7076
->willReturnSelf();
7177

7278
$this->layoutMock->method('createBlock')
7379
->willReturn($this->blockMock);
7480

7581
$this->refreshAction = new Index(
82+
$this->contextMock,
7683
$this->requestMock,
7784
$this->jsonResultFactoryMock,
7885
$this->captchaHelperMock,
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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\Model\Product\Webapi\Rest;
9+
10+
use Magento\Framework\Webapi\Rest\Request\DeserializerInterface;
11+
use Magento\Framework\Webapi\Rest\Request\DeserializerFactory;
12+
use Magento\Framework\Webapi\Rest\Request;
13+
14+
/**
15+
* Class RequestTypeBasedDeserializer
16+
*
17+
* Used for deserialization rest request body.
18+
* Runs appropriate deserialization class object based on request body content type.
19+
*/
20+
class RequestTypeBasedDeserializer implements DeserializerInterface
21+
{
22+
/**
23+
* @var Request
24+
*/
25+
private $request;
26+
27+
/**
28+
* @var DeserializerFactory
29+
*/
30+
private $deserializeFactory;
31+
32+
/**
33+
* RequestTypeBasedDeserializer constructor.
34+
*
35+
* @param DeserializerFactory $deserializeFactory
36+
* @param Request $request
37+
*/
38+
public function __construct(
39+
DeserializerFactory $deserializeFactory,
40+
Request $request
41+
) {
42+
$this->deserializeFactory = $deserializeFactory;
43+
$this->request = $request;
44+
}
45+
46+
/**
47+
* @inheritdoc
48+
*
49+
* Parse request body into array of params with identifying request body content type
50+
* to use appropriate instance of deserializer class
51+
*
52+
* @param string $body Posted content from request
53+
* @return array|null Return NULL if content is invalid
54+
* @throws \Magento\Framework\Exception\InputException
55+
* @throws \Magento\Framework\Webapi\Exception
56+
*/
57+
public function deserialize($body)
58+
{
59+
$deserializer = $this->deserializeFactory->get($this->request->getContentType());
60+
return $deserializer->deserialize($body);
61+
}
62+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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\Product\Webapi\Rest;
8+
9+
use Magento\Catalog\Model\Product\Webapi\Rest\RequestTypeBasedDeserializer;
10+
use Magento\Framework\Webapi\Rest\Request\DeserializerFactory;
11+
use Magento\Framework\Webapi\Rest\Request;
12+
use PHPUnit\Framework\MockObject\MockObject;
13+
use Magento\Framework\Webapi\Rest\Request\DeserializerInterface;
14+
use Magento\Framework\Webapi\Rest\Request\Deserializer\Json as DeserializerJson;
15+
use Magento\Framework\Webapi\Rest\Request\Deserializer\Xml as DeserializerXml;
16+
use Magento\Framework\App\State;
17+
use Magento\Framework\Json\Decoder;
18+
use Magento\Framework\Serialize\Serializer\Json as SerializerJson;
19+
use Magento\Framework\Xml\Parser as ParserXml;
20+
21+
class RequestTypeBasedDeserializerTest extends \PHPUnit\Framework\TestCase
22+
{
23+
/** @var RequestTypeBasedDeserializer */
24+
private $requestTypeBasedDeserializer;
25+
/**
26+
* @var DeserializerFactory|MockObject
27+
*/
28+
private $deserializeFactoryMock;
29+
30+
/**
31+
* @var Request|MockObject
32+
*/
33+
private $requestMock;
34+
35+
public function setUp(): void
36+
{
37+
/** @var DeserializerFactory|MockObject $deserializeFactoryMock */
38+
$this->deserializeFactoryMock = $this->createMock(DeserializerFactory::class);
39+
/** @var Request|MockObject $requestMock */
40+
$this->requestMock = $this->createMock(Request::class);
41+
/** @var requestTypeBasedDeserializer */
42+
$this->requestTypeBasedDeserializer = new RequestTypeBasedDeserializer(
43+
$this->deserializeFactoryMock,
44+
$this->requestMock
45+
);
46+
}
47+
48+
/**
49+
* Test RequestTypeBasedDeserializer::deserializeMethod()
50+
*
51+
* @dataProvider getDeserializerDataProvider
52+
* @param string $body
53+
* @param string $contentType
54+
* @param DeserializerInterface $deserializer
55+
* @param array $expectedResult
56+
* @throws \Magento\Framework\Exception\InputException
57+
* @throws \Magento\Framework\Webapi\Exception
58+
*/
59+
public function testDeserialize(
60+
string $body,
61+
string $contentType,
62+
DeserializerInterface $deserializer,
63+
array $expectedResult
64+
): void {
65+
$this->requestMock->method('getContentType')
66+
->willReturn($contentType);
67+
$this->deserializeFactoryMock->expects($this->any())
68+
->method('get')
69+
->with($contentType)
70+
->willReturn($deserializer);
71+
$this->assertEquals($expectedResult, $this->requestTypeBasedDeserializer->deserialize($body));
72+
}
73+
74+
public function getDeserializerDataProvider(): array
75+
{
76+
return [
77+
'request body with xml data' => [
78+
'body' => '<products>
79+
<product>
80+
<sku>testSku1</sku>
81+
<name>testName1</name>
82+
<weight>10</weight>
83+
<attribute_set_id>4</attribute_set_id>
84+
<status>1</status>
85+
</product>
86+
</products>',
87+
'content-type' => 'application/xml',
88+
'deserializer' => $this->prepareXmlDeserializer(),
89+
'expectedResult' => [
90+
'product' => [
91+
'sku' => 'testSku1',
92+
'name' => 'testName1',
93+
'weight' => '10',
94+
'attribute_set_id' => '4',
95+
'status' => '1'
96+
]
97+
]
98+
],
99+
'request body with json data' => [
100+
'body' => '{
101+
"product": {
102+
"sku": "testSku2",
103+
"name": "testName2",
104+
"weight": 5,
105+
"attribute_set_id": 4,
106+
"status": 0
107+
}
108+
}',
109+
'content-type' => 'application/json',
110+
'deserializer' => $this->prepareJsonDeserializer(),
111+
'expectedResult' => [
112+
'product' => [
113+
'sku' => 'testSku2',
114+
'name' => 'testName2',
115+
'weight' => 5,
116+
'attribute_set_id' => 4,
117+
'status' => 0
118+
]
119+
]
120+
]
121+
];
122+
}
123+
124+
/**
125+
* Creates Json Deserializer instance with some mocked parameters
126+
*
127+
* @return DeserializerJson
128+
*/
129+
private function prepareJsonDeserializer(): DeserializerJson
130+
{
131+
/** @var Decoder|MockObject $decoder */
132+
$decoder = $this->createMock(Decoder::class);
133+
/** @var State|MockObject $appStateMock */
134+
$appStateMock = $this->createMock(State::class);
135+
$serializer = new SerializerJson();
136+
return new DeserializerJson($decoder, $appStateMock, $serializer);
137+
}
138+
139+
/**
140+
* Creates XML Deserializer instance with some mocked parameters
141+
*
142+
* @return DeserializerXml
143+
*/
144+
private function prepareXmlDeserializer(): DeserializerXml
145+
{
146+
$parserXml = new ParserXml();
147+
/** @var State|MockObject $appStateMock */
148+
$appStateMock = $this->createMock(State::class);
149+
return new DeserializerXml($parserXml, $appStateMock);
150+
}
151+
}

app/code/Magento/Catalog/etc/webapi_rest/di.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
</type>
3838
<type name="Magento\Catalog\Model\Product\Webapi\ProductOutputProcessor">
3939
<arguments>
40-
<argument name="deserializer" xsi:type="object">Magento\Framework\Webapi\Rest\Request\Deserializer\Json</argument>
40+
<argument name="deserializer" xsi:type="object">Magento\Catalog\Model\Product\Webapi\Rest\RequestTypeBasedDeserializer</argument>
4141
</arguments>
4242
</type>
4343
</config>

app/code/Magento/Checkout/Controller/Sidebar/RemoveItem.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
use Exception;
1111
use Magento\Checkout\Model\Sidebar;
12+
use Magento\Framework\App\Action\Action;
13+
use Magento\Framework\App\Action\Context;
1214
use Magento\Framework\App\Action\HttpPostActionInterface;
1315
use Magento\Framework\App\RequestInterface;
1416
use Magento\Framework\Controller\Result\JsonFactory as ResultJsonFactory;
@@ -17,7 +19,7 @@
1719
use Magento\Framework\Exception\LocalizedException;
1820
use Psr\Log\LoggerInterface;
1921

20-
class RemoveItem implements HttpPostActionInterface
22+
class RemoveItem extends Action implements HttpPostActionInterface
2123
{
2224
/**
2325
* @var RequestInterface
@@ -32,7 +34,7 @@ class RemoveItem implements HttpPostActionInterface
3234
/**
3335
* @var ResultRedirectFactory
3436
*/
35-
private $resultRedirectFactory;
37+
protected $resultRedirectFactory;
3638

3739
/**
3840
* @var Sidebar
@@ -50,6 +52,7 @@ class RemoveItem implements HttpPostActionInterface
5052
protected $logger;
5153

5254
/**
55+
* @param Context $context
5356
* @param RequestInterface $request
5457
* @param ResultJsonFactory $resultJsonFactory
5558
* @param ResultRedirectFactory $resultRedirectFactory
@@ -58,13 +61,15 @@ class RemoveItem implements HttpPostActionInterface
5861
* @param LoggerInterface $logger
5962
*/
6063
public function __construct(
64+
Context $context,
6165
RequestInterface $request,
6266
ResultJsonFactory $resultJsonFactory,
6367
ResultRedirectFactory $resultRedirectFactory,
6468
Sidebar $sidebar,
6569
Validator $formKeyValidator,
6670
LoggerInterface $logger
6771
) {
72+
parent::__construct($context);
6873
$this->request = $request;
6974
$this->resultJsonFactory = $resultJsonFactory;
7075
$this->resultRedirectFactory = $resultRedirectFactory;

app/code/Magento/Cms/Controller/Page/View.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
namespace Magento\Cms\Controller\Page;
99

1010
use Magento\Cms\Helper\Page as PageHelper;
11+
use Magento\Framework\App\Action\Action;
12+
use Magento\Framework\App\Action\Context;
1113
use Magento\Framework\App\Action\HttpGetActionInterface;
1214
use Magento\Framework\App\Action\HttpPostActionInterface;
1315
use Magento\Framework\App\RequestInterface;
@@ -17,7 +19,7 @@
1719
/**
1820
* Custom page for storefront. Needs to be accessible by POST because of the store switching.
1921
*/
20-
class View implements HttpGetActionInterface, HttpPostActionInterface
22+
class View extends Action implements HttpGetActionInterface, HttpPostActionInterface
2123
{
2224
/**
2325
* @var ForwardFactory
@@ -35,15 +37,18 @@ class View implements HttpGetActionInterface, HttpPostActionInterface
3537
private $pageHelper;
3638

3739
/**
40+
* @param Context $context
3841
* @param RequestInterface $request
3942
* @param PageHelper $pageHelper
4043
* @param ForwardFactory $resultForwardFactory
4144
*/
4245
public function __construct(
46+
Context $context,
4347
RequestInterface $request,
4448
PageHelper $pageHelper,
4549
ForwardFactory $resultForwardFactory
4650
) {
51+
parent::__construct($context);
4752
$this->request = $request;
4853
$this->pageHelper = $pageHelper;
4954
$this->resultForwardFactory = $resultForwardFactory;

app/code/Magento/Eav/etc/db_schema.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,6 @@
486486
referenceColumn="attribute_id" onDelete="CASCADE"/>
487487
<constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label"
488488
column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/>
489-
<constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID_UNIQUE">
490-
<column name="store_id"/>
491-
<column name="attribute_id"/>
492-
</constraint>
493489
<index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree">
494490
<column name="store_id"/>
495491
</index>

0 commit comments

Comments
 (0)