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