Skip to content

Commit 5eb9b37

Browse files
author
Bryant Luk
committed
MAGETWO-36063: Update REST and SOAP controllers to filter out attributes based on ACL
- Add more unit tests
1 parent 5e5213a commit 5eb9b37

10 files changed

+509
-14
lines changed

lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ public function buildOutputDataArray($dataObject, $dataObjectType)
8484
}
8585

8686
$value = $dataObject->{$methodName}();
87-
$isMethodRequired = $this->methodsMapProcessor->isMethodRequired($dataObjectType, $methodName);
88-
if ($value === null && !$isMethodRequired) {
87+
$isMethodReturnValueRequired = $this->methodsMapProcessor->isMethodReturnValueRequired(
88+
$dataObjectType,
89+
$methodName
90+
);
91+
if ($value === null && !$isMethodReturnValueRequired) {
8992
continue;
9093
}
9194

lib/internal/Magento/Framework/Reflection/ExtensionAttributesProcessor.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ public function buildOutputDataArray(ExtensionAttributesInterface $dataObject, $
112112
continue;
113113
}
114114

115-
// should write field?
116-
// isWriterValid
117-
// what value should be written
118-
119115
$returnType = $this->methodsMapProcessor->getMethodReturnType($dataObjectType, $methodName);
120116

121117
if (is_object($value) && !($value instanceof Phrase)) {

lib/internal/Magento/Framework/Reflection/FieldNamer.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Zend\Code\Reflection\MethodReflection;
1515

1616
/**
17-
* Determines the name to use for fields given metadata.
17+
* Determines the name to use for fields in a data output array given method metadata.
1818
*/
1919
class FieldNamer
2020
{
@@ -23,6 +23,8 @@ class FieldNamer
2323
const GETTER_PREFIX = 'get';
2424

2525
/**
26+
* Converts a method's name into a data field name.
27+
*
2628
* @param string $methodName
2729
* @return string|null
2830
*/

lib/internal/Magento/Framework/Reflection/MethodsMap.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Zend\Code\Reflection\MethodReflection;
1111

1212
/**
13-
* Determines method metadata information.
13+
* Gathers method metadata information.
1414
*/
1515
class MethodsMap
1616
{
@@ -56,15 +56,15 @@ public function __construct(
5656
}
5757

5858
/**
59-
* Get return type by interface name and method
59+
* Get return type by type name and method name.
6060
*
61-
* @param string $interfaceName
61+
* @param string $typeName
6262
* @param string $methodName
6363
* @return string
6464
*/
65-
public function getMethodReturnType($interfaceName, $methodName)
65+
public function getMethodReturnType($typeName, $methodName)
6666
{
67-
return $this->getMethodsMap($interfaceName)[$methodName]['type'];
67+
return $this->getMethodsMap($typeName)[$methodName]['type'];
6868
}
6969

7070
/**
@@ -142,6 +142,8 @@ private function isSuitableMethod($method)
142142
}
143143

144144
/**
145+
* Determines if the given method's on the given type is suitable for an output data array.
146+
*
145147
* @param string $type
146148
* @param string $methodName
147149
* @return bool
@@ -164,11 +166,13 @@ public function isMethodValidForDataField($type, $methodName)
164166
}
165167

166168
/**
169+
* If the method has only non-null return types
170+
*
167171
* @param string $type
168172
* @param string $methodName
169173
* @return bool
170174
*/
171-
public function isMethodRequired($type, $methodName)
175+
public function isMethodReturnValueRequired($type, $methodName)
172176
{
173177
$methods = $this->getMethodsMap($type);
174178
return $methods[$methodName]['isRequired'];
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\Reflection\Test\Unit;
7+
8+
use Magento\Framework\Api\ExtensionAttributesInterface;
9+
10+
/**
11+
* Dummy data object to be used by ExtensionAttributesProcessorTest
12+
*/
13+
class ExtensionAttributesObject implements ExtensionAttributesInterface
14+
{
15+
/**
16+
* @return string
17+
*/
18+
public function getAttrName()
19+
{
20+
return 'attrName';
21+
}
22+
23+
/**
24+
* @return bool
25+
*/
26+
public function isActive()
27+
{
28+
return false;
29+
}
30+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Framework\Reflection\Test\Unit;
8+
9+
use Magento\Framework\Api\Config\Converter;
10+
use Magento\Framework\Api\Config\Reader;
11+
use Magento\Framework\AuthorizationInterface;
12+
use Magento\Framework\Reflection\ExtensionAttributesProcessor;
13+
use Magento\Framework\Reflection\FieldNamer;
14+
use Magento\Framework\Reflection\MethodsMap;
15+
use Magento\Framework\Reflection\TypeCaster;
16+
use Magento\Framework\Reflection\TypeProcessor;
17+
18+
/**
19+
* ExtensionAttributesProcessor test
20+
*/
21+
class ExtensionsAttributesProcessorTest extends \PHPUnit_Framework_TestCase
22+
{
23+
/**
24+
* @var ExtensionAttributesProcessor
25+
*/
26+
private $model;
27+
28+
/**
29+
* @var DataObjectProcessor
30+
*/
31+
private $dataObjectProcessor;
32+
33+
/**
34+
* @var MethodsMap
35+
*/
36+
private $methodsMapProcessor;
37+
38+
/**
39+
* @var FieldNamer
40+
*/
41+
private $fieldNamerMock;
42+
43+
/**
44+
* @var TypeCaster
45+
*/
46+
private $typeCasterMock;
47+
48+
/**
49+
* @var Reader
50+
*/
51+
private $configReaderMock;
52+
53+
/**
54+
* @var AuthorizationInterface
55+
*/
56+
private $authorizationMock;
57+
/**
58+
* Set up helper.
59+
*/
60+
public function setUp()
61+
{
62+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
63+
64+
$this->dataObjectProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\DataObjectProcessor')
65+
->disableOriginalConstructor()
66+
->getMock();
67+
$this->methodsMapProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\MethodsMap')
68+
->disableOriginalConstructor()
69+
->getMock();
70+
$this->typeCasterMock = $this->getMockBuilder('Magento\Framework\Reflection\TypeCaster')
71+
->disableOriginalConstructor()
72+
->getMock();
73+
$this->fieldNamerMock = $this->getMockBuilder('Magento\Framework\Reflection\FieldNamer')
74+
->disableOriginalConstructor()
75+
->getMock();
76+
$this->configReaderMock = $this->getMockBuilder('Magento\Framework\Api\Config\Reader')
77+
->disableOriginalConstructor()
78+
->getMock();
79+
$this->authorizationMock = $this->getMockBuilder('Magento\Framework\AuthorizationInterface')
80+
->disableOriginalConstructor()
81+
->getMock();
82+
83+
$this->model = $objectManager->getObject(
84+
'Magento\Framework\Reflection\ExtensionAttributesProcessor',
85+
[
86+
'dataObjectProcessor' => $this->dataObjectProcessorMock,
87+
'methodsMapProcessor' => $this->methodsMapProcessorMock,
88+
'typeCaster' => $this->typeCasterMock,
89+
'fieldNamer' => $this->fieldNamerMock,
90+
'authorization' => $this->authorizationMock,
91+
'configReader' => $this->configReaderMock,
92+
'isPermissionChecked' => true,
93+
]
94+
);
95+
}
96+
97+
/**
98+
* @param bool $isPermissionAllowed
99+
* @param array $expectedValue
100+
* @dataProvider buildOutputDataArrayWithPermissionProvider
101+
*/
102+
public function testBuildOutputDataArrayWithPermission($isPermissionAllowed, $expectedValue)
103+
{
104+
$dataObject = new \Magento\Framework\Reflection\Test\Unit\ExtensionAttributesObject();
105+
$dataObjectType = 'Magento\Framework\Reflection\Test\Unit\ExtensionAttributesObject';
106+
$methodName = 'getAttrName';
107+
$attributeName = 'attr_name';
108+
$attributeValue = 'attrName';
109+
110+
$this->methodsMapProcessorMock->expects($this->once())
111+
->method('getMethodsMap')
112+
->with($dataObjectType)
113+
->will($this->returnValue([$methodName => []]));
114+
$this->methodsMapProcessorMock->expects($this->once())
115+
->method('isMethodValidForDataField')
116+
->with($dataObjectType, $methodName)
117+
->will($this->returnValue(true));
118+
$this->fieldNamerMock->expects($this->once())
119+
->method('getFieldNameForMethodName')
120+
->with($methodName)
121+
->will($this->returnValue($attributeName));
122+
$permissionName = 'Magento_Permission';
123+
$this->configReaderMock->expects($this->once())
124+
->method('read')
125+
->will($this->returnValue([
126+
$dataObjectType => [
127+
$attributeName => [ Converter::RESOURCE_PERMISSIONS => [ $permissionName ] ]
128+
]
129+
]));
130+
$this->authorizationMock->expects($this->once())
131+
->method('isAllowed')
132+
->with($permissionName)
133+
->will($this->returnValue($isPermissionAllowed));
134+
135+
if ($isPermissionAllowed) {
136+
$this->methodsMapProcessorMock->expects($this->once())
137+
->method('getMethodReturnType')
138+
->with($dataObjectType, $methodName)
139+
->will($this->returnValue('string'));
140+
$this->typeCasterMock->expects($this->once())
141+
->method('castValueToType')
142+
->with($attributeValue, 'string')
143+
->will($this->returnValue($attributeValue));
144+
}
145+
146+
$value = $this->model->buildOutputDataArray(
147+
$dataObject,
148+
$dataObjectType
149+
);
150+
151+
$this->assertEquals(
152+
$value,
153+
$expectedValue
154+
);
155+
}
156+
157+
public function buildOutputDataArrayWithPermissionProvider()
158+
{
159+
return [
160+
'permission allowed' => [
161+
true,
162+
[
163+
'attr_name' => 'attrName',
164+
],
165+
],
166+
'permission not allowed' => [
167+
false,
168+
[],
169+
],
170+
];
171+
}
172+
173+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\Reflection\Test\Unit;
7+
8+
use Magento\Framework\Reflection\FieldNamer;
9+
10+
/**
11+
* Field namer Test
12+
*/
13+
class FieldNamerTest extends \PHPUnit_Framework_TestCase
14+
{
15+
/**
16+
* @var FieldNamer
17+
*/
18+
private $model;
19+
20+
/**
21+
* Set up helper.
22+
*/
23+
public function setUp()
24+
{
25+
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
26+
$this->model = $objectManager->getObject('Magento\Framework\Reflection\FieldNamer');
27+
}
28+
29+
/**
30+
* @param string $methodName
31+
* @param string $expectedName
32+
* @dataProvider methodNameProvider
33+
*/
34+
public function testGetFieldNameForMethodName($methodName, $expectedName)
35+
{
36+
$value = $this->model->getFieldNameForMethodName($methodName);
37+
$this->assertEquals($value, $expectedName);
38+
}
39+
40+
/**
41+
* @return array
42+
*/
43+
public function methodNameProvider()
44+
{
45+
return [
46+
'isMethod' => ['isValid', 'valid'],
47+
'getMethod' => ['getValue', 'value'],
48+
'hasMethod' => ['hasStuff', 'stuff'],
49+
'randomMethod' => ['randomMethod', null],
50+
];
51+
}
52+
}

0 commit comments

Comments
 (0)