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