[FEATURE] EXT:form - integrate new form framework
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Tests / Unit / Controller / FormManagerControllerTest.php
1 <?php
2 namespace TYPO3\CMS\Form\Tests\Unit\Controller;
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 Prophecy\Argument;
18 use TYPO3\CMS\Core\Resource\Folder;
19 use TYPO3\CMS\Core\Resource\ResourceStorage;
20 use TYPO3\CMS\Core\Tests\UnitTestCase;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
23 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
24 use TYPO3\CMS\Extbase\Object\ObjectManager;
25 use TYPO3\CMS\Form\Controller\FormManagerController;
26 use TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManager;
27 use TYPO3\CMS\Form\Service\TranslationService;
28 use TYPO3\CMS\Form\Tests\Unit\Controller\Fixtures\BackendUtilityFixture;
29
30 /**
31 * Test case
32 */
33 class FormManagerControllerTest extends UnitTestCase
34 {
35
36 /**
37 * @var array A backup of registered singleton instances
38 */
39 protected $singletonInstances = [];
40
41 /**
42 * Set up
43 */
44 public function setUp()
45 {
46 $this->singletonInstances = GeneralUtility::getSingletonInstances();
47 }
48
49 /**
50 * Tear down
51 */
52 public function tearDown()
53 {
54 GeneralUtility::resetSingletonInstances($this->singletonInstances);
55 parent::tearDown();
56 }
57
58 /**
59 * @test
60 */
61 public function getAccessibleFormStorageFoldersReturnsProcessedArray()
62 {
63 $mockController = $this->getAccessibleMock(FormManagerController::class, [
64 'dummy'
65 ], [], '', false);
66
67 $formPersistenceManagerProphecy = $this->prophesize(FormPersistenceManager::class);
68
69 $mockStorage = $this->getMockBuilder(ResourceStorage::class)
70 ->disableOriginalConstructor()
71 ->getMock();
72 $mockController->_set('formPersistenceManager', $formPersistenceManagerProphecy->reveal());
73
74 $folder1 = new Folder($mockStorage, '/user_upload/', 'user_upload');
75 $folder2 = new Folder($mockStorage, '/forms/', 'forms');
76
77 $formPersistenceManagerProphecy->getAccessibleFormStorageFolders(Argument::cetera())->willReturn([
78 '1:/user_upload/' => $folder1,
79 '2:/forms/' => $folder2,
80 ]);
81
82 $expected = [
83 0 => [
84 'label' => 'user_upload',
85 'value' => '1:/user_upload/',
86 ],
87 1 => [
88 'label' => 'forms',
89 'value' => '2:/forms/',
90 ],
91 ];
92
93 $this->assertSame($expected, $mockController->_call('getAccessibleFormStorageFolders'));
94 }
95
96 /**
97 * @test
98 */
99 public function getFormManagerAppInitialDataReturnsProcessedArray()
100 {
101 $objectMangerProphecy = $this->prophesize(ObjectManager::class);
102 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectMangerProphecy->reveal());
103
104 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
105 'translateValuesRecursive'
106 ], [], '', false);
107
108 $mockTranslationService
109 ->expects($this->any())
110 ->method('translateValuesRecursive')
111 ->willReturnArgument(0);
112
113 $objectMangerProphecy
114 ->get(TranslationService::class)
115 ->willReturn($mockTranslationService);
116
117 $mockController = $this->getAccessibleMock(FormManagerController::class, [
118 'getAccessibleFormStorageFolders'
119 ], [], '', false);
120
121 $mockUriBuilder = $this->createMock(UriBuilder::class);
122 $mockControllerContext = $this->createMock(ControllerContext::class);
123 $mockControllerContext
124 ->expects($this->any())
125 ->method('getUriBuilder')
126 ->will($this->returnValue($mockUriBuilder));
127
128 $mockController->_set('controllerContext', $mockControllerContext);
129
130 $mockController->_set('formSettings', [
131 'formManager' => [
132 'selectablePrototypesConfiguration' => [],
133 ],
134 ]);
135
136 $mockUriBuilder->expects($this->any())->method('uriFor')->willReturn(
137 '/typo3/index.php?some=param'
138 );
139
140 $mockController
141 ->expects($this->any())
142 ->method('getAccessibleFormStorageFolders')
143 ->willReturn([
144 0 => [
145 'label' => 'user_upload',
146 'value' => '1:/user_upload/',
147 ],
148 ]);
149
150 $expected = [
151 'selectablePrototypesConfiguration' => [],
152 'accessibleFormStorageFolders' => [
153 0 => [
154 'label' => 'user_upload',
155 'value' => '1:/user_upload/',
156 ],
157 ],
158 'endpoints' => [
159 'create' => '/typo3/index.php?some=param',
160 'duplicate' => '/typo3/index.php?some=param',
161 'delete' => '/typo3/index.php?some=param',
162 'references' => '/typo3/index.php?some=param',
163 ],
164 ];
165
166 $this->assertSame(json_encode($expected), $mockController->_call('getFormManagerAppInitialData'));
167 }
168
169 /**
170 * @test
171 */
172 public function getAvailableFormDefinitionsReturnsProcessedArray()
173 {
174 $mockController = $this->getAccessibleMock(FormManagerController::class, [
175 'getReferences'
176 ], [], '', false);
177
178 $formPersistenceManagerProphecy = $this->prophesize(FormPersistenceManager::class);
179 $mockController->_set('formPersistenceManager', $formPersistenceManagerProphecy->reveal());
180
181 $formPersistenceManagerProphecy->listForms(Argument::cetera())->willReturn([
182 0 => [
183 'identifier' => 'ext-form-identifier',
184 'name' => 'some name',
185 'persistenceIdentifier' => '1:/user_uploads/someFormName.yaml',
186 'readOnly' => false,
187 'location' => 'storage',
188 'duplicateIdentifier' => false,
189 ],
190 ]);
191
192 $mockController
193 ->expects($this->any())
194 ->method('getReferences')
195 ->willReturn([
196 'someRow',
197 'anotherRow',
198 ]);
199
200 $expected = [
201 0 => [
202 'identifier' => 'ext-form-identifier',
203 'name' => 'some name',
204 'persistenceIdentifier' => '1:/user_uploads/someFormName.yaml',
205 'readOnly' => false,
206 'location' => 'storage',
207 'duplicateIdentifier' => false,
208 'referenceCount' => 2,
209 ],
210 ];
211
212 $this->assertSame($expected, $mockController->_call('getAvailableFormDefinitions'));
213 }
214
215 /**
216 * @test
217 */
218 public function getProcessedReferencesRowsThrowsExceptionIfPersistenceIdentifierIsEmpty()
219 {
220 $this->expectException(\InvalidArgumentException::class);
221 $this->expectExceptionCode(1477071939);
222
223 $mockController = $this->getAccessibleMock(FormManagerController::class, [
224 'dummy'
225 ], [], '', false);
226
227 $mockController->_call('getProcessedReferencesRows', '');
228 }
229
230 /**
231 * @test
232 */
233 public function getProcessedReferencesRowsReturnsProcessedArray()
234 {
235 $mockController = $this->getAccessibleMock(FormManagerController::class, [
236 'getReferences',
237 'getBackendUtility',
238 ], [], '', false);
239
240 $mockController
241 ->expects($this->any())
242 ->method('getBackendUtility')
243 ->willReturn(BackendUtilityFixture::class);
244
245 $mockController
246 ->expects($this->any())
247 ->method('getReferences')
248 ->willReturn([
249 0 => [
250 'tablename' => 'tt_content',
251 'recuid' => -1,
252 ],
253 ]);
254
255 $expected = [
256 0 => [
257 'recordPageTitle' => 'record title',
258 'recordTitle' => 'record title',
259 'recordIcon' =>
260 '<span class="t3js-icon icon icon-size-small icon-state-default icon-default-not-found" data-identifier="default-not-found">
261 <span class="icon-markup">
262 <img src="typo3/sysext/core/Resources/Public/Icons/T3Icons/default/default-not-found.svg" width="16" height="16" />
263 </span>
264
265 </span>',
266 'recordUid' => -1,
267 'recordEditUrl' => '/typo3/index.php?some=param',
268 ],
269 ];
270
271 $this->assertSame($expected, $mockController->_call('getProcessedReferencesRows', 'fake'));
272 }
273
274 /**
275 * @test
276 */
277 public function isValidTemplatePathReturnsTrueIfTemplateIsDefinedAndExists()
278 {
279 $mockController = $this->getAccessibleMock(FormManagerController::class, [
280 'dummy'
281 ], [], '', false);
282
283 $mockController->_set('formSettings', [
284 'formManager' => [
285 'selectablePrototypesConfiguration' => [
286 0 => [
287 'identifier' => 'standard',
288 'label' => 'some label',
289 'newFormTemplates' => [
290 0 => [
291 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/BlankForm.yaml',
292 'label' => 'some label',
293 ],
294 1 => [
295 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml',
296 'label' => 'some other label',
297 ],
298 ],
299 ],
300 ],
301 ],
302 ]);
303
304 $this->assertTrue($mockController->_call('isValidTemplatePath', 'standard', 'EXT:form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml'));
305 }
306
307 /**
308 * @test
309 */
310 public function isValidTemplatePathReturnsFalseIfTemplateIsDefinedButNotExists()
311 {
312 $mockController = $this->getAccessibleMock(FormManagerController::class, [
313 'dummy'
314 ], [], '', false);
315
316 $mockController->_set('formSettings', [
317 'formManager' => [
318 'selectablePrototypesConfiguration' => [
319 0 => [
320 'identifier' => 'standard',
321 'label' => 'some label',
322 'newFormTemplates' => [
323 0 => [
324 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/BlankForm.yaml',
325 'label' => 'some label',
326 ],
327 1 => [
328 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml',
329 'label' => 'some other label',
330 ],
331 ],
332 ],
333 ],
334 ],
335 ]);
336
337 $this->assertFalse($mockController->_call('isValidTemplatePath', 'standard', 'EXT:form/Tests/Unit/Controller/Fixtures/NonExistingForm.yaml'));
338 }
339
340 /**
341 * @test
342 */
343 public function isValidTemplatePathReturnsFalseIfTemplateIsNotDefinedAndExists()
344 {
345 $mockController = $this->getAccessibleMock(FormManagerController::class, [
346 'dummy'
347 ], [], '', false);
348
349 $mockController->_set('formSettings', [
350 'formManager' => [
351 'selectablePrototypesConfiguration' => [
352 0 => [
353 'identifier' => 'standard',
354 'label' => 'some label',
355 'newFormTemplates' => [
356 0 => [
357 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/BlankForm.yaml',
358 'label' => 'some label',
359 ],
360 1 => [
361 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml',
362 'label' => 'some other label',
363 ],
364 ],
365 ],
366 1 => [
367 'identifier' => 'other',
368 'label' => 'some label',
369 'newFormTemplates' => [
370 0 => [
371 'templatePath' => 'EXT:form/Tests/Unit/Controller/Fixtures/BlankForm.yaml',
372 'label' => 'some label',
373 ],
374 ],
375 ],
376 ],
377 ],
378 ]);
379
380 $this->assertFalse($mockController->_call('isValidTemplatePath', 'other', 'EXT:form/Tests/Unit/Controller/Fixtures/SimpleContactForm.yaml'));
381 }
382
383 /**
384 * @test
385 */
386 public function convertFormNameToIdentifierRemoveSpaces()
387 {
388 $mockController = $this->getAccessibleMock(FormManagerController::class, [
389 'dummy'
390 ], [], '', false);
391
392 $input = 'test form';
393 $expected = 'testform';
394 $this->assertSame($expected, $mockController->_call('convertFormNameToIdentifier', $input));
395 }
396
397 /**
398 * @test
399 */
400 public function convertFormNameToIdentifierRemoveSpecialChars()
401 {
402 $mockController = $this->getAccessibleMock(FormManagerController::class, [
403 'dummy'
404 ], [], '', false);
405
406 $input = 'test form รค#!_-01';
407 $expected = 'testform_-01';
408 $this->assertSame($expected, $mockController->_call('convertFormNameToIdentifier', $input));
409 }
410 }