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