Revert "[CLEANUP] Rework/simplify copyright header and remove @package"
[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 use TYPO3\CMS\Core\Utility\DebugUtility;
25 use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
26
27 /**
28 * Test case
29 */
30 class MvcPropertyMappingConfigurationServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
31
32 /**
33 * Data provider for generating the list of trusted properties
34 *
35 * @return array
36 */
37 public function dataProviderForgenerateTrustedPropertiesToken() {
38 return array(
39 'Simple Case - Empty' => array(
40 array(),
41 array(),
42 ),
43 'Simple Case - Single Value' => array(
44 array('field1'),
45 array('field1' => 1),
46 ),
47 'Simple Case - Two Values' => array(
48 array('field1', 'field2'),
49 array(
50 'field1' => 1,
51 'field2' => 1
52 ),
53 ),
54 'Recursion' => array(
55 array('field1', 'field[subfield1]', 'field[subfield2]'),
56 array(
57 'field1' => 1,
58 'field' => array(
59 'subfield1' => 1,
60 'subfield2' => 1
61 )
62 ),
63 ),
64 'recursion with duplicated field name' => array(
65 array('field1', 'field[subfield1]', 'field[subfield2]', 'field1'),
66 array(
67 'field1' => 1,
68 'field' => array(
69 'subfield1' => 1,
70 'subfield2' => 1
71 )
72 ),
73 ),
74 'Recursion with un-named fields at the end (...[]). There, they should be made explicit by increasing the counter' => array(
75 array('field1', 'field[subfield1][]', 'field[subfield1][]', 'field[subfield2]'),
76 array(
77 'field1' => 1,
78 'field' => array(
79 'subfield1' => array(
80 0 => 1,
81 1 => 1
82 ),
83 'subfield2' => 1
84 )
85 ),
86 ),
87 );
88 }
89
90 /**
91 * Data Provider for invalid values in generating the list of trusted properties,
92 * which should result in an exception
93 *
94 * @return array
95 */
96 public function dataProviderForgenerateTrustedPropertiesTokenWithUnallowedValues() {
97 return array(
98 'Overriding form fields (string overridden by array) - 1' => array(
99 array('field1', 'field2', 'field2[bla]', 'field2[blubb]'),
100 ),
101 'Overriding form fields (string overridden by array) - 2' => array(
102 array('field1', 'field2[bla]', 'field2[bla][blubb][blubb]'),
103 ),
104 'Overriding form fields (array overridden by string) - 1' => array(
105 array('field1', 'field2[bla]', 'field2[blubb]', 'field2'),
106 ),
107 'Overriding form fields (array overridden by string) - 2' => array(
108 array('field1', 'field2[bla][blubb][blubb]', 'field2[bla]'),
109 ),
110 'Empty [] not as last argument' => array(
111 array('field1', 'field2[][bla]'),
112 )
113
114 );
115 }
116
117 /**
118 * @test
119 * @dataProvider dataProviderForgenerateTrustedPropertiesToken
120 */
121 public function generateTrustedPropertiesTokenGeneratesTheCorrectHashesInNormalOperation($input, $expected) {
122 $requestHashService = $this->getMock('TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService', 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 $requestHashService = $this->getMock('TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService', array('serializeAndHashFormFieldArray'));
134 $requestHashService->generateTrustedPropertiesToken($input);
135 }
136
137 /**
138 * @test
139 */
140 public function serializeAndHashFormFieldArrayWorks() {
141 $formFieldArray = array(
142 'bla' => array(
143 'blubb' => 1,
144 'hu' => 1
145 )
146 );
147 $mockHash = '12345';
148
149 $hashService = $this->getMock($this->buildAccessibleProxy('TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService'), array('appendHmac'));
150 $hashService->expects($this->once())->method('appendHmac')->with(serialize($formFieldArray))->will($this->returnValue(serialize($formFieldArray) . $mockHash));
151
152 $requestHashService = $this->getMock($this->buildAccessibleProxy('TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService'), array('dummy'));
153 $requestHashService->_set('hashService', $hashService);
154
155 $expected = serialize($formFieldArray) . $mockHash;
156 $actual = $requestHashService->_call('serializeAndHashFormFieldArray', $formFieldArray);
157 $this->assertEquals($expected, $actual);
158 }
159
160 /**
161 * @test
162 */
163 public function initializePropertyMappingConfigurationDoesNothingIfTrustedPropertiesAreNotSet() {
164 $request = $this->getMockBuilder('TYPO3\CMS\Extbase\Mvc\Request')->setMethods(array('getInternalArgument'))->disableOriginalConstructor()->getMock();
165 $request->expects($this->any())->method('getInternalArgument')->with('__trustedProperties')->will($this->returnValue(NULL));
166 $arguments = new \TYPO3\CMS\Extbase\Mvc\Controller\Arguments();
167
168 $requestHashService = new \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService;
169 $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments);
170 }
171
172 /**
173 * @test
174 */
175 public function initializePropertyMappingConfigurationReturnsEarlyIfNoTrustedPropertiesAreSet() {
176 $trustedProperties = array(
177 'foo' => 1
178 );
179 $this->initializePropertyMappingConfiguration($trustedProperties);
180 }
181
182 /**
183 * @test
184 */
185 public function initializePropertyMappingConfigurationReturnsEarlyIfArgumentIsUnknown() {
186 $trustedProperties = array(
187 'nonExistingArgument' => 1
188 );
189 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
190 $this->assertFalse($arguments->hasArgument('nonExistingArgument'));
191 }
192
193 /**
194 * @test
195 */
196 public function initializePropertyMappingConfigurationSetsModificationAllowedIfIdentityPropertyIsSet() {
197 $trustedProperties = array(
198 'foo' => array(
199 '__identity' => 1,
200 'nested' => array(
201 '__identity' => 1,
202 )
203 )
204 );
205 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
206 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
207 $this->assertTrue($propertyMappingConfiguration->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED), 'ConfigurationValue is not CONFIGURATION_MODIFICATION_ALLOWED at line ' . __LINE__);
208 $this->assertNull($propertyMappingConfiguration->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED), 'ConfigurationValue is not NULL at line ' . __LINE__);
209 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'), 'Value is not FALSE at line ' . __LINE__);
210
211 $this->assertTrue($propertyMappingConfiguration->forProperty('nested')->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED), 'ConfigurationValue is not CONFIGURATION_MODIFICATION_ALLOWED at line ' . __LINE__);
212 $this->assertNull($propertyMappingConfiguration->forProperty('nested')->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED), 'ConfigurationValue is not NULL at line ' . __LINE__);
213 $this->assertFalse($propertyMappingConfiguration->forProperty('nested')->shouldMap('someProperty'), 'Value is not FALSE at line ' . __LINE__);
214 }
215
216 /**
217 * @test
218 */
219 public function initializePropertyMappingConfigurationSetsCreationAllowedIfIdentityPropertyIsNotSet() {
220 $trustedProperties = array(
221 'foo' => array(
222 'bar' => array()
223 )
224 );
225 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
226 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
227 $this->assertNull($propertyMappingConfiguration->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
228 $this->assertTrue($propertyMappingConfiguration->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
229 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
230
231 $this->assertNull($propertyMappingConfiguration->forProperty('bar')->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
232 $this->assertTrue($propertyMappingConfiguration->forProperty('bar')->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
233 $this->assertFalse($propertyMappingConfiguration->forProperty('bar')->shouldMap('someProperty'));
234 }
235
236 /**
237 * @test
238 */
239 public function initializePropertyMappingConfigurationSetsAllowedFields() {
240 $trustedProperties = array(
241 'foo' => array(
242 'bar' => 1
243 )
244 );
245 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
246 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
247 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
248 $this->assertTrue($propertyMappingConfiguration->shouldMap('bar'));
249 }
250
251 /**
252 * @test
253 */
254 public function initializePropertyMappingConfigurationSetsAllowedFieldsRecursively() {
255 $trustedProperties = array(
256 'foo' => array(
257 'bar' => array(
258 'foo' => 1
259 )
260 )
261 );
262 $arguments = $this->initializePropertyMappingConfiguration($trustedProperties);
263 $propertyMappingConfiguration = $arguments->getArgument('foo')->getPropertyMappingConfiguration();
264 $this->assertFalse($propertyMappingConfiguration->shouldMap('someProperty'));
265 $this->assertTrue($propertyMappingConfiguration->shouldMap('bar'));
266 $this->assertTrue($propertyMappingConfiguration->forProperty('bar')->shouldMap('foo'));
267 }
268
269 /**
270 * Helper which initializes the property mapping configuration and returns arguments
271 *
272 * @param array $trustedProperties
273 *
274 * @return \TYPO3\CMS\Extbase\Mvc\Controller\Arguments
275 */
276 protected function initializePropertyMappingConfiguration(array $trustedProperties) {
277 $request = $this->getMockBuilder('TYPO3\CMS\Extbase\Mvc\Request')->setMethods(array('getInternalArgument'))->disableOriginalConstructor()->getMock();
278 $request->expects($this->any())->method('getInternalArgument')->with('__trustedProperties')->will($this->returnValue('fooTrustedProperties'));
279
280 $mockHashService = $this->getMock('TYPO3\CMS\Extbase\Security\Cryptography\HashService', array('validateAndStripHmac'));
281 $mockHashService->expects($this->once())->method('validateAndStripHmac')->with('fooTrustedProperties')->will($this->returnValue(serialize($trustedProperties)));
282
283 $requestHashService = $this->getAccessibleMock('TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService', array('dummy'));
284 $requestHashService->_set('hashService', $mockHashService);
285
286 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
287 $mockArgument = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getName'), array(), '', FALSE);
288
289 $propertyMappingConfiguration = new \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfiguration();
290
291 $mockArgument->_set('propertyMappingConfiguration', $propertyMappingConfiguration);
292 $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('foo'));
293 $mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument')->will($this->returnValue($mockArgument));
294
295 $arguments = $this->getAccessibleMock('TYPO3\CMS\Extbase\Mvc\Controller\Arguments', array('dummy'));
296 $arguments->_set('objectManager', $mockObjectManager);
297 $arguments->addNewArgument('foo');
298
299 $requestHashService->initializePropertyMappingConfigurationFromRequest($request, $arguments);
300
301 return $arguments;
302 }
303 }