[SECURITY] Filter disallowed properties in form editor
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Tests / Unit / Mvc / Property / TypeConverter / FormDefinitionArrayConverterTest.php
1 <?php
2 namespace TYPO3\CMS\Form\Tests\Unit\Mvc\Property\TypeConverter;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Form\Domain\Configuration\Exception\PropertyException;
19 use TYPO3\CMS\Form\Domain\Configuration\FormDefinitionValidationService;
20 use TYPO3\CMS\Form\Mvc\Property\TypeConverter\FormDefinitionArrayConverter;
21 use TYPO3\CMS\Form\Type\FormDefinitionArray;
22 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
23
24 /**
25 * Test case for TYPO3\CMS\Form\Mvc\Property\TypeConverter\FormDefinitionArrayConverter
26 */
27 class FormDefinitionArrayConverterTest extends UnitTestCase
28 {
29 /**
30 * @var bool Reset singletons created by subject
31 */
32 protected $resetSingletonInstances = true;
33
34 /**
35 * Set up
36 */
37 public function setUp()
38 {
39 parent::setUp();
40 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 12345;
41 }
42
43 /**
44 * @test
45 */
46 public function convertsJsonStringToFormDefinitionArray()
47 {
48 $sessionToken = '123';
49
50 $data = [
51 'prototypeName' => 'standard',
52 'identifier' => 'test',
53 'type' => 'Text',
54 'enabled' => false,
55 'properties' => [
56 'options' => [
57 [
58 '_label' => 'label',
59 '_value' => 'value',
60 ],
61 ],
62 ],
63 '_orig_prototypeName' => [
64 'value' => 'standard',
65 'hmac' => GeneralUtility::hmac(serialize(['test', 'prototypeName', 'standard']), $sessionToken),
66 ],
67 '_orig_identifier' => [
68 'value' => 'test',
69 'hmac' => GeneralUtility::hmac(serialize(['test', 'identifier', 'test']), $sessionToken),
70 ],
71 ];
72
73 $typeConverter = $this->getAccessibleMock(FormDefinitionArrayConverter::class, ['getFormDefinitionValidationService', 'retrieveSessionToken'], [], '', false);
74 $formDefinitionValidationService = $this->getAccessibleMock(FormDefinitionValidationService::class, ['validateFormDefinitionProperties'], [], '', false);
75 $formDefinitionValidationService->expects($this->any())->method(
76 'validateFormDefinitionProperties'
77 )->willReturn(null);
78
79 $typeConverter->expects($this->any())->method(
80 'retrieveSessionToken'
81 )->willReturn($sessionToken);
82
83 $typeConverter->expects($this->any())->method(
84 'getFormDefinitionValidationService'
85 )->willReturn($formDefinitionValidationService);
86
87 $input = json_encode($data);
88 $expected = [
89 'prototypeName' => 'standard',
90 'identifier' => 'test',
91 'type' => 'Text',
92 'enabled' => false,
93 'properties' => [
94 'options' => [
95 'value' => 'label',
96 ],
97 ],
98 ];
99 $result = $typeConverter->convertFrom($input, FormDefinitionArray::class);
100
101 $this->assertInstanceOf(FormDefinitionArray::class, $result);
102 $this->assertSame($expected, $result->getArrayCopy());
103 }
104
105 /**
106 * @test
107 */
108 public function convertFromThrowsExceptionIfJsonIsInvalid()
109 {
110 $this->expectException(PropertyException::class);
111 $this->expectExceptionCode(1512578002);
112
113 $typeConverter = new FormDefinitionArrayConverter();
114 $input = '{"francine":"stan",';
115
116 $typeConverter->convertFrom($input, FormDefinitionArray::class);
117 }
118
119 /**
120 * @test
121 */
122 public function transformMultiValueElementsForFormFrameworkTransformValues()
123 {
124 $typeConverter = $this->getAccessibleMock(FormDefinitionArrayConverter::class, ['dummy'], [], '', false);
125
126 $input = [
127 'foo1' => 'bar',
128 'foo2' => [
129 'foo3' => [
130 [
131 '_label' => 'xxx1',
132 '_value' => 'yyy1',
133 ],
134 [
135 '_label' => 'xxx2',
136 '_value' => 'yyy2',
137 ],
138 [
139 '_label' => 'xxx3',
140 '_value' => 'yyy2',
141 ],
142 ],
143 '_label' => 'xxx',
144 '_value' => 'yyy',
145 ],
146 '_label' => 'xxx',
147 '_value' => 'yyy',
148 ];
149
150 $expected = [
151 'foo1' => 'bar',
152 'foo2' => [
153 'foo3' => [
154 'yyy1' => 'xxx1',
155 'yyy2' => 'xxx3',
156 ],
157 '_label' => 'xxx',
158 '_value' => 'yyy',
159 ],
160 '_label' => 'xxx',
161 '_value' => 'yyy',
162 ];
163
164 $this->assertSame($expected, $typeConverter->_call('transformMultiValueElementsForFormFramework', $input));
165 }
166
167 /**
168 * @test
169 */
170 public function convertFromThrowsExceptionIfPrototypeNameWasChanged()
171 {
172 $this->expectException(PropertyException::class);
173 $this->expectExceptionCode(1528538322);
174
175 $sessionToken = '123';
176 $typeConverter = $this->getAccessibleMock(FormDefinitionArrayConverter::class, ['retrieveSessionToken'], [], '', false);
177
178 $typeConverter->expects($this->any())->method(
179 'retrieveSessionToken'
180 )->willReturn($sessionToken);
181
182 $input = [
183 'prototypeName' => 'foo',
184 'identifier' => 'test',
185 '_orig_prototypeName' => [
186 'value' => 'standard',
187 'hmac' => GeneralUtility::hmac(serialize(['test', 'prototypeName', 'standard']), $sessionToken),
188 ],
189 '_orig_identifier' => [
190 'value' => 'test',
191 'hmac' => GeneralUtility::hmac(serialize(['test', 'identifier', 'test']), $sessionToken),
192 ],
193 ];
194
195 $typeConverter->convertFrom(json_encode($input), FormDefinitionArray::class);
196 }
197
198 /**
199 * @test
200 */
201 public function convertFromThrowsExceptionIfIdentifierWasChanged()
202 {
203 $this->expectException(PropertyException::class);
204 $this->expectExceptionCode(1528538322);
205
206 $sessionToken = '123';
207 $typeConverter = $this->getAccessibleMock(FormDefinitionArrayConverter::class, ['retrieveSessionToken'], [], '', false);
208
209 $typeConverter->expects($this->any())->method(
210 'retrieveSessionToken'
211 )->willReturn($sessionToken);
212
213 $input = [
214 'prototypeName' => 'standard',
215 'identifier' => 'xxx',
216 '_orig_prototypeName' => [
217 'value' => 'standard',
218 'hmac' => GeneralUtility::hmac(serialize(['test', 'prototypeName', 'standard']), $sessionToken),
219 ],
220 '_orig_identifier' => [
221 'value' => 'test',
222 'hmac' => GeneralUtility::hmac(serialize(['test', 'prototypeName', 'test']), $sessionToken),
223 ],
224 ];
225
226 $typeConverter->convertFrom(json_encode($input), FormDefinitionArray::class);
227 }
228 }