Skip to content

Commit 48ce78a

Browse files
author
Olexii Korshenko
committed
Merge pull request magento#1026 from magento-folks/combined
Bug Fixes: Api, Tango
2 parents 0ea6083 + ff389b8 commit 48ce78a

File tree

15 files changed

+127
-58
lines changed

15 files changed

+127
-58
lines changed

app/code/Magento/Backend/view/adminhtml/layout/adminhtml_auth_login.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
-->
77
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="empty" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
88
<body>
9+
<remove name="legal"/>
910
<referenceContainer name="main.content">
1011
<block class="Magento\Backend\Block\Template" name="content" template="admin/login.phtml">
1112
<block class="Magento\Backend\Block\Page\Copyright" name="copyright" as="copyright"/>

app/code/Magento/Catalog/view/adminhtml/layout/catalog_product_attribute_edit_popup.xml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44
* @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
55
*/
66
-->
7-
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
7+
<page layout="admin-empty" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
88
<body>
9-
<remove name="left"/>
10-
<referenceBlock name="attribute_edit_content">
11-
<arguments>
12-
<argument name="template" xsi:type="string">Magento_Catalog::catalog/product/attribute/form.phtml</argument>
13-
</arguments>
14-
<container name="form" label="Form">
15-
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Main" as="main"/>
16-
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Options" as="advanced-options"/>
17-
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Advanced" as="options"/>
18-
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Labels" as="labels"/>
19-
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Front" as="front-options"/>
20-
</container>
21-
</referenceBlock>
9+
<remove name="legal"/>
10+
<referenceContainer name="content">
11+
<block template="Magento_Catalog::catalog/product/attribute/form.phtml" class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit" name="attribute_edit_content">
12+
<container name="form" label="Form">
13+
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Main" as="main"/>
14+
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Options" as="advanced-options"/>
15+
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Advanced" as="options"/>
16+
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Labels" as="labels"/>
17+
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Front" as="front-options"/>
18+
</container>
19+
</block>
20+
<block class="Magento\Backend\Block\Template" name="attribute_edit_js" template="Magento_Catalog::catalog/product/attribute/js.phtml"/>
21+
</referenceContainer>
2222
</body>
2323
</page>

app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_attribute_edit_product_tab_variations_popup.xml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,6 @@
44
* @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
55
*/
66
-->
7-
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
8-
<body>
9-
<remove name="left"/>
10-
<referenceBlock name="attribute_edit_content">
11-
<arguments>
12-
<argument name="template" xsi:type="string">Magento_Catalog::catalog/product/attribute/form.phtml</argument>
13-
</arguments>
14-
<container name="form" label="Form">
15-
<block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Attribute\Edit\Tab\Variations\Main" as="main"/>
16-
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Options" as="advanced-options"/>
17-
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Advanced" as="options"/>
18-
<block class="Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\Labels" as="labels"/>
19-
<block class="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Front" as="front-options"/>
20-
</container>
21-
</referenceBlock>
22-
</body>
7+
<page layout="admin-empty" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
8+
<update handle="catalog_product_attribute_edit_popup"/>
239
</page>

app/code/Magento/Theme/view/adminhtml/layouts.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
-->
77
<page_layouts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/View/PageLayout/etc/layouts.xsd">
8+
<layout id="admin-empty">
9+
<label translate="true">Admin empty</label>
10+
</layout>
811
<layout id="admin-1column">
912
<label translate="true">Admin 1column</label>
1013
</layout>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
5+
*/
6+
-->
7+
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_layout.xsd">
8+
<container name="root">
9+
<container name="page.formkey" as="page.formkey"/>
10+
<container name="page.js.translate" as="page.js.translate"/>
11+
<container name="content" as="content"/>
12+
<container name="js" as="js" label="JavaScript"/>
13+
</container>
14+
</layout>

app/code/Magento/Webapi/Controller/Rest/Request/Deserializer/Json.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function __construct(\Magento\Core\Helper\Data $helper, State $appState)
3636
* @param string $encodedBody Posted content from request.
3737
* @return array|null Return NULL if content is invalid.
3838
* @throws \InvalidArgumentException
39-
* @throws \Magento\Webapi\Exception If decoding error occurs or in case of empty argument type
39+
* @throws \Magento\Webapi\Exception If decoding error was encountered.
4040
*/
4141
public function deserialize($encodedBody)
4242
{
@@ -45,9 +45,6 @@ public function deserialize($encodedBody)
4545
sprintf('"%s" data type is invalid. String is expected.', gettype($encodedBody))
4646
);
4747
}
48-
if (empty($encodedBody)) {
49-
throw new \Magento\Webapi\Exception(__('Request body should not be empty.'));
50-
}
5148
try {
5249
$decodedBody = $this->_helper->jsonDecode($encodedBody);
5350
} catch (\Zend_Json_Exception $e) {

app/code/Magento/Webapi/Controller/Rest/Request/Deserializer/Xml.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(\Magento\Framework\Xml\Parser $xmlParser, State $app
4141
* @param string $xmlRequestBody XML document
4242
* @return array Data converted from XML document to array. Root node is excluded from response.
4343
* @throws \InvalidArgumentException In case of invalid argument type.
44-
* @throws \Magento\Webapi\Exception If decoding error occurs or in case of empty argument type
44+
* @throws \Magento\Webapi\Exception If decoding error occurs.
4545
*/
4646
public function deserialize($xmlRequestBody)
4747
{
@@ -50,9 +50,6 @@ public function deserialize($xmlRequestBody)
5050
sprintf('"%s" data type is invalid. String is expected.', gettype($xmlRequestBody))
5151
);
5252
}
53-
if (empty($xmlRequestBody)) {
54-
throw new \Magento\Webapi\Exception(__('Request body is expected.'));
55-
}
5653
/** Disable external entity loading to prevent possible vulnerability */
5754
$previousLoaderState = libxml_disable_entity_loader(true);
5855
set_error_handler([$this, 'handleErrors']);

app/code/Magento/Webapi/Controller/ServiceArgsSerializer.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Framework\Api\AttributeValue;
1111
use Magento\Framework\Api\Config\Reader as ServiceConfigReader;
1212
use Magento\Framework\Api\SimpleDataObjectConverter;
13+
use Magento\Framework\Exception\InputException;
1314
use Magento\Framework\Exception\SerializationException;
1415
use Magento\Framework\Reflection\TypeProcessor;
1516
use Magento\Framework\Serialization\DataBuilderFactory;
@@ -71,6 +72,7 @@ public function __construct(
7172
* @param string $serviceMethodName name of the method that we are trying to call
7273
* @param array $inputArray data to send to method in key-value format
7374
* @return array list of parameters that can be used to call the service method
75+
* @throws InputException if no value is provided for required parameters
7476
*/
7577
public function getInputData($serviceClassName, $serviceMethodName, array $inputArray)
7678
{
@@ -82,6 +84,7 @@ public function getInputData($serviceClassName, $serviceMethodName, array $input
8284
$params = $serviceMethod->getParameters();
8385

8486
$inputData = [];
87+
$inputError = [];
8588
foreach ($params as $param) {
8689
$paramName = $param->getName();
8790
$snakeCaseParamName = strtolower(preg_replace("/(?<=\\w)(?=[A-Z])/", "_$1", $paramName));
@@ -93,7 +96,21 @@ public function getInputData($serviceClassName, $serviceMethodName, array $input
9396
$paramType = $this->getParamType($param);
9497
$inputData[] = $this->_convertValue($paramValue, $paramType);
9598
} else {
96-
$inputData[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
99+
if ($param->isDefaultValueAvailable()) {
100+
$inputData[] = $param->getDefaultValue();
101+
} else {
102+
$inputError[] = $paramName;
103+
}
104+
}
105+
}
106+
107+
if (!empty($inputError)) {
108+
$exception = new InputException();
109+
foreach ($inputError as $errorParamField) {
110+
$exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => $errorParamField]);
111+
}
112+
if ($exception->wasErrorAdded()) {
113+
throw $exception;
97114
}
98115
}
99116

dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRestInterface.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ public function update(\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $en
4141
/**
4242
* Update existing item.
4343
*
44-
* @param string $firstId
45-
* @param string $secondId
44+
* @param string $parentId
45+
* @param string $entityId
4646
* @param \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
4747
* @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
4848
*/
4949
public function nestedUpdate(
50-
$firstId,
51-
$secondId,
50+
$parentId,
51+
$entityId,
5252
\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
5353
);
5454
}

dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,42 @@ public function testValidateResetPasswordLinkTokenInvalidToken()
323323
}
324324
}
325325

326+
public function testInitiatePasswordMissingRequiredFields()
327+
{
328+
$this->_markTestAsRestOnly('Soap clients explicitly check for required fields based on WSDL.');
329+
$serviceInfo = [
330+
'rest' => [
331+
'resourcePath' => self::RESOURCE_PATH . '/password',
332+
'httpMethod' => RestConfig::HTTP_METHOD_PUT,
333+
]
334+
];
335+
336+
try {
337+
$this->_webApiCall($serviceInfo);
338+
} catch (\Exception $e) {
339+
$this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
340+
$exceptionData = $this->processRestExceptionResult($e);
341+
$expectedExceptionData = [
342+
'message' => InputException::DEFAULT_MESSAGE,
343+
'errors' => [
344+
[
345+
'message' => InputException::REQUIRED_FIELD,
346+
'parameters' => [
347+
'fieldName' => 'email',
348+
],
349+
],
350+
[
351+
'message' => InputException::REQUIRED_FIELD,
352+
'parameters' => [
353+
'fieldName' => 'template',
354+
]
355+
],
356+
],
357+
];
358+
$this->assertEquals($expectedExceptionData, $exceptionData);
359+
}
360+
}
361+
326362
public function testInitiatePasswordReset()
327363
{
328364
$customerData = $this->_createCustomer();

dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Magento\Customer\Api\Data\CustomerInterface as Customer;
88
use Magento\Framework\Api\SearchCriteria;
9+
use Magento\Framework\Exception\InputException;
910
use Magento\TestFramework\Helper\Bootstrap;
1011
use Magento\TestFramework\Helper\Customer as CustomerHelper;
1112
use Magento\TestFramework\TestCase\WebapiAbstract;
@@ -392,6 +393,33 @@ public function testSearchCustomersUsingGET()
392393
$this->assertEquals($customerData[Customer::ID], $searchResults['items'][0][Customer::ID]);
393394
}
394395

396+
/**
397+
* Test with empty GET based filter
398+
*/
399+
public function testSearchCustomersUsingGETEmptyFilter()
400+
{
401+
$this->_markTestAsRestOnly('Soap clients explicitly check for required fields based on WSDL.');
402+
$serviceInfo = [
403+
'rest' => [
404+
'resourcePath' => self::RESOURCE_PATH . '/search',
405+
'httpMethod' => RestConfig::HTTP_METHOD_GET,
406+
],
407+
];
408+
try {
409+
$this->_webApiCall($serviceInfo);
410+
} catch (\Exception $e) {
411+
$this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
412+
$exceptionData = $this->processRestExceptionResult($e);
413+
$expectedExceptionData = [
414+
'message' => InputException::REQUIRED_FIELD,
415+
'parameters' => [
416+
'fieldName' => 'searchCriteria'
417+
],
418+
];
419+
$this->assertEquals($expectedExceptionData, $exceptionData);
420+
}
421+
}
422+
395423
/**
396424
* Test using multiple filters
397425
*/

dev/tests/api-functional/testsuite/Magento/Webapi/DeserializationTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ public function testPostRequestWithEmptyBody()
3838
'httpMethod' => RestConfig::HTTP_METHOD_POST,
3939
],
4040
];
41-
$expectedMessage = 'Request body should not be empty.';
41+
$expectedMessage = '{"message":"%fieldName is a required field.","parameters":{"fieldName":"item"}}';
4242
try {
4343
$this->_webApiCall($serviceInfo, CurlClient::EMPTY_REQUEST_BODY);
4444
} catch (\Exception $e) {
45+
$this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
4546
$this->assertContains(
4647
$expectedMessage,
4748
$e->getMessage(),
@@ -63,10 +64,11 @@ public function testPutRequestWithEmptyBody()
6364
'httpMethod' => RestConfig::HTTP_METHOD_PUT,
6465
],
6566
];
66-
$expectedMessage = 'Request body should not be empty.';
67+
$expectedMessage = '{"message":"%fieldName is a required field.","parameters":{"fieldName":"entityItem"}}';
6768
try {
6869
$this->_webApiCall($serviceInfo, CurlClient::EMPTY_REQUEST_BODY);
6970
} catch (\Exception $e) {
71+
$this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
7072
$this->assertContains(
7173
$expectedMessage,
7274
$e->getMessage(),

dev/tests/unit/testsuite/Magento/Webapi/Controller/Rest/Request/Deserializer/JsonTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,6 @@ public function testDeserializerInvalidArgumentException()
4747
$this->_jsonDeserializer->deserialize(false);
4848
}
4949

50-
public function testDeserializerOauthInputException()
51-
{
52-
$this->setExpectedException('\Magento\Webapi\Exception', 'Request body should not be empty.');
53-
$this->_jsonDeserializer->deserialize('');
54-
}
55-
5650
public function testDeserialize()
5751
{
5852
/** Prepare mocks for SUT constructor. */
@@ -82,7 +76,7 @@ public function testDeserializeInvalidEncodedBodyExceptionDeveloperModeOff()
8276
/** Prepare mocks for SUT constructor. */
8377
$this->_helperMock->expects($this->once())
8478
->method('jsonDecode')
85-
->will($this->throwException(new \Zend_Json_Exception()));
79+
->will($this->throwException(new \Zend_Json_Exception));
8680
$this->_appStateMock->expects($this->once())
8781
->method('getMode')
8882
->will($this->returnValue('production'));

dev/tests/unit/testsuite/Magento/Webapi/Controller/Rest/Request/Deserializer/XmlTest.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ public function testDeserializeInvalidArgumentException()
4242
$this->_xmlDeserializer->deserialize(false);
4343
}
4444

45-
public function testDeserializerOauthInputException()
46-
{
47-
$this->setExpectedException('\Magento\Webapi\Exception', 'Request body is expected.');
48-
$this->_xmlDeserializer->deserialize('');
49-
}
50-
5145
public function testDeserialize()
5246
{
5347
/** Prepare mocks for SUT constructor. */

0 commit comments

Comments
 (0)