[TASK] Use real ObjectManager stubs in unit tests
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Tests / Unit / Domain / Configuration / FormDefinitionValidationServiceTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Form\Tests\Unit\Domain\Configuration;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Extbase\Object\ObjectManager;
20 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
21 use TYPO3\CMS\Form\Domain\Configuration\Exception\PropertyException;
22 use TYPO3\CMS\Form\Domain\Configuration\FormDefinition\Validators\ValidationDto;
23 use TYPO3\CMS\Form\Domain\Configuration\FormDefinitionValidationService;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25
26 class FormDefinitionValidationServiceTest extends UnitTestCase
27 {
28 protected function setUp()
29 {
30 parent::setUp();
31 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = '12345';
32 }
33
34 /**
35 * @test
36 */
37 public function validateAllFormElementPropertyValuesByHmacThrowsExceptionIfHmacIsInvalid()
38 {
39 $this->expectException(PropertyException::class);
40 $this->expectExceptionCode(1528588036);
41
42 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
43
44 $prototypeName = 'standard';
45 $identifier = 'some-text';
46
47 $sessionToken = '123';
48
49 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier);
50
51 $input = [
52 'label' => 'xxx',
53 '_orig_label' => [
54 'value' => 'aaa',
55 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'label', 'aaa']), $sessionToken),
56 ],
57 ];
58
59 $typeConverter->_call('validateAllFormElementPropertyValuesByHmac', $input, $sessionToken, $validationDto);
60 }
61
62 /**
63 * @test
64 */
65 public function validateAllFormElementPropertyValuesByHmacThrowsExceptionIfHmacDoesNotExists()
66 {
67 $this->expectException(PropertyException::class);
68 $this->expectExceptionCode(1528588037);
69
70 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
71
72 $prototypeName = 'standard';
73 $identifier = 'some-text';
74
75 $sessionToken = '123';
76
77 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier);
78
79 $input = [
80 'label' => 'xxx',
81 ];
82
83 $typeConverter->_call('validateAllFormElementPropertyValuesByHmac', $input, $sessionToken, $validationDto);
84 }
85
86 /**
87 * @test
88 */
89 public function validateAllFormElementPropertyValuesByHmacThrowsNoExceptionIfHmacIsValid()
90 {
91 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
92
93 $prototypeName = 'standard';
94 $identifier = 'some-text';
95
96 $sessionToken = '123';
97
98 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier);
99
100 $input = [
101 'label' => 'aaa',
102 '_orig_label' => [
103 'value' => 'aaa',
104 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'label', 'aaa']), $sessionToken),
105 ],
106 ];
107
108 $failed = false;
109 try {
110 $typeConverter->_call(
111 'validateAllFormElementPropertyValuesByHmac',
112 $input,
113 $sessionToken,
114 $validationDto
115 );
116 } catch (PropertyException $e) {
117 $failed = true;
118 }
119 $this->assertFalse($failed);
120 }
121
122 /**
123 * @test
124 */
125 public function validateAllPropertyCollectionElementValuesByHmacThrowsExceptionIfHmacIsInvalid()
126 {
127 $this->expectException(PropertyException::class);
128 $this->expectExceptionCode(1528591586);
129
130 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
131
132 $prototypeName = 'standard';
133 $identifier = 'some-text';
134
135 $sessionToken = '123';
136
137 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier, null, 'validators');
138
139 $input = [
140 'identifier' => 'StringLength',
141 '_orig_identifier' => [
142 'value' => 'StringLength',
143 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'identifier', 'StringLength']), $sessionToken),
144 ],
145 'options' => [
146 'test' => 'xxx',
147 '_orig_test' => [
148 'value' => 'aaa',
149 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'options.test', 'aaa']), $sessionToken),
150 ],
151 ],
152 ];
153
154 $typeConverter->_call(
155 'validateAllPropertyCollectionElementValuesByHmac',
156 $input,
157 $sessionToken,
158 $validationDto
159 );
160 }
161
162 /**
163 * @test
164 */
165 public function validateAllPropertyCollectionElementValuesByHmacThrowsExceptionIfHmacDoesNotExists()
166 {
167 $this->expectException(PropertyException::class);
168 $this->expectExceptionCode(1528591585);
169
170 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
171
172 $prototypeName = 'standard';
173 $identifier = 'some-text';
174
175 $sessionToken = '123';
176
177 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier, null, 'validators');
178
179 $input = [
180 'identifier' => 'StringLength',
181 '_orig_identifier' => [
182 'value' => 'StringLength',
183 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'identifier', 'StringLength']), $sessionToken),
184 ],
185 'options' => [
186 'test' => 'xxx',
187 ],
188 ];
189
190 $typeConverter->_call(
191 'validateAllPropertyCollectionElementValuesByHmac',
192 $input,
193 $sessionToken,
194 $validationDto
195 );
196 }
197
198 /**
199 * @test
200 */
201 public function validateAllPropertyCollectionElementValuesByHmacThrowsNoExceptionIfHmacIsValid()
202 {
203 $typeConverter = $this->getAccessibleMock(FormDefinitionValidationService::class, ['dummy'], [], '', false);
204
205 $prototypeName = 'standard';
206 $identifier = 'some-text';
207
208 $sessionToken = '123';
209
210 $validationDto = new ValidationDto($prototypeName, 'Text', $identifier, null, 'validators');
211
212 $input = [
213 'identifier' => 'StringLength',
214 '_orig_identifier' => [
215 'value' => 'StringLength',
216 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'identifier', 'StringLength']), $sessionToken),
217 ],
218 'options' => [
219 'test' => 'aaa',
220 '_orig_test' => [
221 'value' => 'aaa',
222 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'options.test', 'aaa']), $sessionToken),
223 ],
224 ],
225 ];
226
227 $failed = false;
228 try {
229 $typeConverter->_call(
230 'validateAllPropertyCollectionElementValuesByHmac',
231 $input,
232 $sessionToken,
233 $validationDto
234 );
235 } catch (PropertyException $e) {
236 $failed = true;
237 }
238 $this->assertFalse($failed);
239 }
240
241 /**
242 * @test
243 * @dataProvider validateAllPropertyValuesFromCreatableFormElementDataProvider
244 * @param array $mockConfiguration
245 * @param array $formElement
246 * @param string $sessionToken
247 * @param int $exceptionCode
248 * @param ValidationDto $validationDto
249 */
250 public function validateAllPropertyValuesFromCreatableFormElement(
251 array $mockConfiguration,
252 array $formElement,
253 string $sessionToken,
254 int $exceptionCode,
255 ValidationDto $validationDto
256 ) {
257 $typeConverter = $this->getAccessibleMock(
258 FormDefinitionValidationService::class,
259 ['getConfigurationService'],
260 [],
261 '',
262 false
263 );
264
265 $configurationService = $this->createMock(ConfigurationService::class);
266 $configurationService->expects($this->any())
267 ->method('isFormElementPropertyDefinedInFormEditorSetup')
268 ->willReturn($mockConfiguration['isFormElementPropertyDefinedInFormEditorSetup']);
269 $configurationService->expects($this->any())->method(
270 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup'
271 )->willReturn($mockConfiguration['isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup']);
272 $configurationService->expects($this->any())
273 ->method('getFormElementPredefinedDefaultValueFromFormEditorSetup')
274 ->willReturn($mockConfiguration['getFormElementPredefinedDefaultValueFromFormEditorSetup']);
275 $typeConverter->expects($this->any())->method('getConfigurationService')->willReturn($configurationService);
276 $formDefinitionValidationService = $this->getAccessibleMock(FormDefinitionValidationService::class, ['getConfigurationService']);
277 $formDefinitionValidationService->expects($this->any())->method('getConfigurationService')->willReturn($configurationService);
278 GeneralUtility::setSingletonInstance(FormDefinitionValidationService::class, $formDefinitionValidationService);
279 $objectManager = $this->createMock(ObjectManager::class);
280 $objectManager->expects($this->once())->method('get')->with(ConfigurationService::class)->willReturn($configurationService);
281 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManager);
282
283 $returnedExceptionCode = -1;
284 try {
285 $typeConverter->_call(
286 'validateAllPropertyValuesFromCreatableFormElement',
287 $formElement,
288 $sessionToken,
289 $validationDto
290 );
291 } catch (PropertyException $e) {
292 $returnedExceptionCode = $e->getCode();
293 }
294 $this->assertEquals($returnedExceptionCode, $exceptionCode);
295 }
296
297 /**
298 * @test
299 * @dataProvider validateAllPropertyValuesFromCreatablePropertyCollectionElementDataProvider
300 * @param array $mockConfiguration
301 * @param array $formElement
302 * @param string $sessionToken
303 * @param int $exceptionCode
304 * @param ValidationDto $validationDto
305 */
306 public function validateAllPropertyValuesFromCreatablePropertyCollectionElement(
307 array $mockConfiguration,
308 array $formElement,
309 string $sessionToken,
310 int $exceptionCode,
311 ValidationDto $validationDto
312 ) {
313 $typeConverter = $this->getAccessibleMock(
314 FormDefinitionValidationService::class,
315 ['getConfigurationService'],
316 [],
317 '',
318 false
319 );
320
321 $configurationService = $this->createMock(ConfigurationService::class);
322 $configurationService->expects($this->any())
323 ->method('isPropertyCollectionPropertyDefinedInFormEditorSetup')
324 ->willReturn($mockConfiguration['isPropertyCollectionPropertyDefinedInFormEditorSetup']);
325 $configurationService->expects($this->any())->method(
326 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup'
327 )->willReturn($mockConfiguration['isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup']);
328 $configurationService->expects($this->any())->method(
329 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup'
330 )->willReturn($mockConfiguration['getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup']);
331 $typeConverter->expects($this->any())->method('getConfigurationService')->willReturn($configurationService);
332 $formDefinitionValidationService = $this->getAccessibleMock(FormDefinitionValidationService::class, ['getConfigurationService']);
333 $formDefinitionValidationService->expects($this->any())->method('getConfigurationService')->willReturn($configurationService);
334 GeneralUtility::setSingletonInstance(FormDefinitionValidationService::class, $formDefinitionValidationService);
335 $objectManager = $this->createMock(ObjectManager::class);
336 $objectManager->expects($this->once())->method('get')->with(ConfigurationService::class)->willReturn($configurationService);
337 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManager);
338
339 $returnedExceptionCode = -1;
340 try {
341 $typeConverter->_call(
342 'validateAllPropertyValuesFromCreatablePropertyCollectionElement',
343 $formElement,
344 $sessionToken,
345 $validationDto
346 );
347 } catch (PropertyException $e) {
348 $returnedExceptionCode = $e->getCode();
349 }
350 $this->assertEquals($returnedExceptionCode, $exceptionCode);
351 }
352
353 /**
354 * @return array
355 */
356 public function validateAllPropertyValuesFromCreatableFormElementDataProvider(): array
357 {
358 $encryptionKeyBackup = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
359 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = '12345';
360
361 $sessionToken = '54321';
362 $identifier = 'text-1';
363
364 $validationDto = new ValidationDto('standard', 'Text', $identifier);
365 $formElement = [
366 'test' => 'xxx',
367 '_orig_test' => [
368 'value' => 'xxx',
369 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'test', 'xxx']), $sessionToken),
370 ],
371 ];
372
373 $invalidFormElement = [
374 'test' => 'xxx1',
375 '_orig_test' => [
376 'value' => 'xxx',
377 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'test', 'xxx']), $sessionToken),
378 ],
379 ];
380
381 // be aware that backup globals does not impact globals used in data providers as these are called before the setUp/tearDown is done
382 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = $encryptionKeyBackup;
383
384 return [
385 [
386 [
387 'isFormElementPropertyDefinedInFormEditorSetup' => true,
388 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
389 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => '',
390 ],
391 $formElement,
392 $sessionToken,
393 -1,
394 $validationDto
395 ],
396 [
397 [
398 'isFormElementPropertyDefinedInFormEditorSetup' => false,
399 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
400 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
401 ],
402 $formElement,
403 $sessionToken,
404 -1,
405 $validationDto
406 ],
407 [
408 [
409 'isFormElementPropertyDefinedInFormEditorSetup' => false,
410 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
411 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
412 ],
413 ['test' => 'xxx'],
414 $sessionToken,
415 1528588037,
416 $validationDto
417 ],
418 [
419 [
420 'isFormElementPropertyDefinedInFormEditorSetup' => false,
421 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
422 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
423 ],
424 ['test' => 'xxx', '_orig_test' => []],
425 $sessionToken,
426 1528538222,
427 $validationDto
428 ],
429 [
430 [
431 'isFormElementPropertyDefinedInFormEditorSetup' => false,
432 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
433 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
434 ],
435 ['test' => 'xxx', '_orig_test' => ['hmac' => '4242']],
436 $sessionToken,
437 1528538252,
438 $validationDto
439 ],
440 [
441 [
442 'isFormElementPropertyDefinedInFormEditorSetup' => false,
443 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
444 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
445 ],
446 $invalidFormElement,
447 $sessionToken,
448 1528588036,
449 $validationDto
450 ],
451
452 [
453 [
454 'isFormElementPropertyDefinedInFormEditorSetup' => false,
455 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => true,
456 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'xxx',
457 ],
458 $formElement,
459 $sessionToken,
460 -1,
461 $validationDto
462 ],
463 [
464 [
465 'isFormElementPropertyDefinedInFormEditorSetup' => false,
466 'isFormElementPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => true,
467 'getFormElementPredefinedDefaultValueFromFormEditorSetup' => 'default',
468 ],
469 $formElement,
470 $sessionToken,
471 1528588035,
472 $validationDto
473 ],
474 ];
475 }
476
477 /**
478 * @return array
479 */
480 public function validateAllPropertyValuesFromCreatablePropertyCollectionElementDataProvider(): array
481 {
482 $encryptionKeyBackup = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
483 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = '12345';
484
485 $sessionToken = '54321';
486 $identifier = 'text-1';
487
488 $validationDto = new ValidationDto('standard', 'Text', $identifier, null, 'validators', 'StringLength');
489 $formElement = [
490 'test' => 'xxx',
491 '_orig_test' => [
492 'value' => 'xxx',
493 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'test', 'xxx']), $sessionToken),
494 ],
495 ];
496
497 $invalidFormElement = [
498 'test' => 'xxx1',
499 '_orig_test' => [
500 'value' => 'xxx',
501 'hmac' => GeneralUtility::hmac(serialize([$identifier, 'validators', 'StringLength', 'test', 'xxx']), $sessionToken),
502 ],
503 ];
504
505 // be aware that backup globals does not impact globals used in data providers as these are called before the setUp/tearDown is done
506 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = $encryptionKeyBackup;
507
508 return [
509 [
510 [
511 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => true,
512 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
513 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
514 ],
515 $formElement,
516 $sessionToken,
517 -1,
518 $validationDto
519 ],
520 [
521 [
522 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
523 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
524 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
525 ],
526 $formElement,
527 $sessionToken,
528 -1,
529 $validationDto
530 ],
531 [
532 [
533 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
534 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
535 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
536 ],
537 ['test' => 'xxx'],
538 $sessionToken,
539 1528591585,
540 $validationDto
541 ],
542 [
543 [
544 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
545 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
546 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
547 ],
548 ['test' => 'xxx', '_orig_test' => []],
549 $sessionToken,
550 1528538222,
551 $validationDto
552 ],
553 [
554 [
555 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
556 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
557 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
558 ],
559 ['test' => 'xxx', '_orig_test' => ['hmac' => '4242']],
560 $sessionToken,
561 1528538252,
562 $validationDto
563 ],
564 [
565 [
566 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
567 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => false,
568 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
569 ],
570 $invalidFormElement,
571 $sessionToken,
572 1528591586,
573 $validationDto
574 ],
575
576 [
577 [
578 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
579 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => true,
580 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'xxx',
581 ],
582 $formElement,
583 $sessionToken,
584 -1,
585 $validationDto
586 ],
587 [
588 [
589 'isPropertyCollectionPropertyDefinedInFormEditorSetup' => false,
590 'isPropertyCollectionPropertyDefinedInPredefinedDefaultsInFormEditorSetup' => true,
591 'getPropertyCollectionPredefinedDefaultValueFromFormEditorSetup' => 'default',
592 ],
593 $formElement,
594 $sessionToken,
595 1528591502,
596 $validationDto
597 ],
598 ];
599 }
600
601 public function tearDown()
602 {
603 GeneralUtility::resetSingletonInstances([]);
604 parent::tearDown();
605 }
606 }