[TASK] Make TYPO3 Core PSR-2 standard compliant
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Mvc / Controller / MvcPropertyMappingConfigurationServiceTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Controller;
3
4 /* *
5 * This script belongs to the Extbase framework *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23
24 /**
25 * Test case
26 */
27 class MvcPropertyMappingConfigurationServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
28 {
29 /**
30 * Data provider for generating the list of trusted properties
31 *
32 * @return array
33 */
34 public function dataProviderForgenerateTrustedPropertiesToken()
35 {
36 return array(
37 'Simple Case - Empty' => array(
38 array(),
39 array(),
40 ),
41 'Simple Case - Single Value' => array(
42 array('field1'),
43 array('field1' => 1),
44 ),
45 'Simple Case - Two Values' => array(
46 array('field1', 'field2'),
47 array(
48 'field1' => 1,
49 'field2' => 1
50 ),
51 ),
52 'Recursion' => array(
53 array('field1', 'field[subfield1]', 'field[subfield2]'),
54 array(
55 'field1' => 1,
56 'field' => array(
57 'subfield1' => 1,
58 'subfield2' => 1
59 )
60 ),
61 ),
62 'recursion with duplicated field name' => array(
63 array('field1', 'field[subfield1]', 'field[subfield2]', 'field1'),
64 array(
65 'field1' => 1,
66 'field' => array(
67 'subfield1' => 1,
68 'subfield2' => 1
69 )
70 ),
71 ),
72 'Recursion with un-named fields at the end (...[]). There, they should be made explicit by increasing the counter' => array(
73 array('field1', 'field[subfield1][]', 'field[subfield1][]', 'field[subfield2]'),
74 array(
75 'field1' => 1,
76 'field' => array(
77 'subfield1' => array(
78 0 => 1,
79 1 => 1
80 ),
81 'subfield2' => 1
82 )
83 ),
84 ),
85 );
86 }
87
88 /**
89 * Data Provider for invalid values in generating the list of trusted properties,
90 * which should result in an exception
91 *
92 * @return array
93 */
94 public function dataProviderForgenerateTrustedPropertiesTokenWithUnallowedValues()
95 {
96 return array(
97 'Overriding form fields (string overridden by array) - 1' => array(
98 array('field1', 'field2', 'field2[bla]', 'field2[blubb]'),
99 ),
100 'Overriding form fields (string overridden by array) - 2' => array(
101 array('field1', 'field2[bla]', 'field2[bla][blubb][blubb]'),
102 ),
103 'Overriding form fields (array overridden by string) - 1' => array(
104 array('field1', 'field2[bla]', 'field2[blubb]', 'field2'),
105 ),
106 'Overriding form fields (array overridden by string) - 2' => array(
107 array('field1', 'field2[bla][blubb][blubb]', 'field2[bla]'),
108 ),
109 'Empty [] not as last argument' => array(
110 array('field1', 'field2[][bla]'),
111 )
112
113 );
114 }
115
116 /**
117 * @test
118 * @dataProvider dataProviderForgenerateTrustedPropertiesToken
119 */
120 public function generateTrustedPropertiesTokenGeneratesTheCorrectHashesInNormalOperation($input, $expected)
121 {
122 $requestHashService = $this->getMock(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class, array('serializeAndHashFormFieldArray'));
123 $requestHashService->expects($this->once())->method('serializeAndHashFormFieldArray')->with($expected);
124 $requestHashService->generateTrustedPropertiesToken($input);
125 }
126
127 /**
128 * @test
129 * @dataProvider dataProviderForgenerateTrustedPropertiesTokenWithUnallowedValues
130 * @expectedException \TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException
131 */
132 public function generateTrustedPropertiesTokenThrowsExceptionInWrongCases($input)
133 {
134 $requestHashService = $this->getMock(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class, array('serializeAndHashFormFieldArray'));
135 $requestHashService->generateTrustedPropertiesToken($input);
136 }
137
138 /**
139 * @test
140 */
141 public function serializeAndHashFormFieldArrayWorks()
142 {
143 $formFieldArray = array(
144 'bla' => array(
145 'blubb' => 1,
146 'hu' => 1
147 )
148 );
149 $mockHash = '12345';
150
151 $hashService = $this->getMock($this->buildAccessibleProxy(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class), array('appendHmac'));
152 $hashService->expects($this->once())->method('appendHmac')->with(serialize($formFieldArray))->will($this->returnValue(serialize($formFieldArray) . $mockHash));
153
154 $requestHashService = $this->getMock($this->buildAccessibleProxy(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class), array('dummy'));
155 $requestHashService->_set('hashService', $hashService);
156
157 $expected = serialize($formFieldArray) . $mockHash;
158 $actual = $requestHashService->_call('serializeAndHashFormFieldArray', $formFieldArray);
159 $this->assertEquals($expected, $actual);
160 }
161
162 /**
163 * @test
164 */
165 public function initializePropertyMappingConfigurationDoesNothingIfTrustedPropertiesAreNotSet()
166 {
167 $request = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\Request::class)->setMethods(array('getInternalArgument'))->disableOriginalConstructor()->getMock();
168 $request->expects($this->any())->method('getInternalArgument')->with('__trustedProperties')->will($this->returnValue(null));
169 $arguments = new \TYPO3\CMS\Extbase\Mvc\Controller\Arguments();
170
171 $requestHashService = new \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService;
172 $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments);
173 }
174
175 /**
176 * @test
177 */
178 public function initializePropertyMappingConfigurationReturnsEarlyIfNoTrustedPropertiesAreSet()
179 {
180 $trustedProperties = array(
181 'foo' => 1
182 );
183 $this->initializePropertyMappingConfiguration($trustedProperties);
184 }
185
186 /**
187 * @test
188 */
189 public function initializePropertyMappingConfigurationReturnsEarlyIfArgumentIsUnknown()
190 {
191 $trustedProperties = array(
192 'nonExistingArgument' => 1
193 );
194 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
195 $this->assertFalse($arguments->hasArgument('nonExistingArgument'));
196 }
197
198 /**
199 * @test
200 */
201 public function initializePropertyMappingConfigurationSetsModificationAllowedIfIdentityPropertyIsSet()
202 {
203 $trustedProperties = array(
204 'foo' => array(
205 '__identity' => 1,
206 'nested' => array(
207 '__identity' => 1,
208 )
209 )
210 );
211 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
212 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
213 $this->assertTrue($propertyMappingConfiguration->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED), 'ConfigurationValue is not CONFIGURATION_MODIFICATION_ALLOWED at line ' . __LINE__);
214 $this->assertNull($propertyMappingConfiguration->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED), 'ConfigurationValue is not NULL at line ' . __LINE__);
215 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'), 'Value is not FALSE at line ' . __LINE__);
216
217 $this->assertTrue($propertyMappingConfiguration->forProperty('nested')->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED), 'ConfigurationValue is not CONFIGURATION_MODIFICATION_ALLOWED at line ' . __LINE__);
218 $this->assertNull($propertyMappingConfiguration->forProperty('nested')->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED), 'ConfigurationValue is not NULL at line ' . __LINE__);
219 $this->assertFalse($propertyMappingConfiguration->forProperty('nested')->shouldMap('someProperty'), 'Value is not FALSE at line ' . __LINE__);
220 }
221
222 /**
223 * @test
224 */
225 public function initializePropertyMappingConfigurationSetsCreationAllowedIfIdentityPropertyIsNotSet()
226 {
227 $trustedProperties = array(
228 'foo' => array(
229 'bar' => array()
230 )
231 );
232 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
233 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
234 $this->assertNull($propertyMappingConfiguration->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
235 $this->assertTrue($propertyMappingConfiguration->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
236 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
237
238 $this->assertNull($propertyMappingConfiguration->forProperty('bar')->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
239 $this->assertTrue($propertyMappingConfiguration->forProperty('bar')->getConfigurationValue(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
240 $this->assertFalse($propertyMappingConfiguration->forProperty('bar')->shouldMap('someProperty'));
241 }
242
243 /**
244 * @test
245 */
246 public function initializePropertyMappingConfigurationSetsAllowedFields()
247 {
248 $trustedProperties = array(
249 'foo' => array(
250 'bar' => 1
251 )
252 );
253 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
254 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
255 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
256 $this->assertTrue($propertyMappingConfiguration->shouldMap('bar'));
257 }
258
259 /**
260 * @test
261 */
262 public function initializePropertyMappingConfigurationSetsAllowedFieldsRecursively()
263 {
264 $trustedProperties = array(
265 'foo' => array(
266 'bar' => array(
267 'foo' => 1
268 )
269 )
270 );
271 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
272 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
273 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
274 $this->assertTrue($propertyMappingConfiguration->shouldMap('bar'));
275 $this->assertTrue($propertyMappingConfiguration->forProperty('bar')->shouldMap('foo'));
276 }
277
278 /**
279 * Helper which initializes the property mapping configuration and returns arguments
280 *
281 * @param array $trustedProperties
282 *
283 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Arguments
284 */
285 protected function initializePropertyMappingConfiguration(array $trustedProperties)
286 {
287 $request = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\Request::class)->setMethods(array('getInternalArgument'))->disableOriginalConstructor()->getMock();
288 $request->expects($this->any())->method('getInternalArgument')->with('__trustedProperties')->will($this->returnValue('fooTrustedProperties'));
289
290 $mockHashService = $this->getMock(\TYPO3\CMS\Extbase\Security\Cryptography\HashService::class, array('validateAndStripHmac'));
291 $mockHashService->expects($this->once())->method('validateAndStripHmac')->with('fooTrustedProperties')->will($this->returnValue(serialize($trustedProperties)));
292
293 $requestHashService = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class, array('dummy'));
294 $requestHashService->_set('hashService', $mockHashService);
295
296 $mockObjectManager = $this->getMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
297 $mockArgument = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\Argument::class, array('getName'), array(), '', false);
298
299 $propertyMappingConfiguration = new \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration();
300
301 $mockArgument->_set('propertyMappingConfiguration', $propertyMappingConfiguration);
302 $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('foo'));
303 $mockObjectManager->expects($this->once())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Controller\Argument::class)->will($this->returnValue($mockArgument));
304
305 $arguments = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class, array('dummy'));
306 $arguments->_set('objectManager', $mockObjectManager);
307 $arguments->addNewArgument('foo');
308
309 $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments);
310
311 return $arguments;
312 }
313 }