6902dba3cfaa2318fb5e52927f62260889c4c6eb
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / NodeFactoryTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\Unit\Form;
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\Prophecy\ObjectProphecy;
18 use TYPO3\CMS\Backend\Form\AbstractNode;
19 use TYPO3\CMS\Backend\Form\Element;
20 use TYPO3\CMS\Core\Tests\UnitTestCase;
21 use TYPO3\CMS\Backend\Form\NodeFactory;
22 use TYPO3\CMS\Backend\Form\NodeInterface;
23 use TYPO3\CMS\Backend\Form\NodeResolverInterface;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * Test case
28 */
29 class NodeFactoryTest extends UnitTestCase {
30
31 /**
32 * @test
33 * @expectedException \TYPO3\CMS\Backend\Form\Exception
34 * @expectedExceptionCode 1432207533
35 */
36 public function constructThrowsExceptionIfOverrideMissesNodeNameKey() {
37 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
38 1433089391 => array(
39 'class' => 'foo',
40 'priority' => 23,
41 ),
42 );
43 new NodeFactory();
44 }
45
46 /**
47 * @test
48 * @expectedException \TYPO3\CMS\Backend\Form\Exception
49 * @expectedExceptionCode 1432207533
50 */
51 public function constructThrowsExceptionIfOverrideMissesPriorityKey() {
52 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
53 1433089393 => array(
54 'nodeName' => 'foo',
55 'class' => 'bar',
56 ),
57 );
58 new NodeFactory();
59 }
60
61 /**
62 * @test
63 * @expectedException \TYPO3\CMS\Backend\Form\Exception
64 * @expectedExceptionCode 1432207533
65 */
66 public function constructThrowsExceptionIfOverrideMissesClassKey() {
67 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
68 1433089392 => array(
69 'nodeName' => 'foo',
70 'priority' => 23,
71 ),
72 );
73 new NodeFactory();
74 }
75
76 /**
77 * @test
78 * @expectedException \TYPO3\CMS\Backend\Form\Exception
79 * @expectedExceptionCode 1432223531
80 */
81 public function constructThrowsExceptionIfOverridePriorityIsLowerThanZero() {
82 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
83 1433089394 => array(
84 'nodeName' => 'foo',
85 'class' => 'bar',
86 'priority' => -23,
87 ),
88 );
89 new NodeFactory();
90
91 }
92 /**
93 * @test
94 * @expectedException \TYPO3\CMS\Backend\Form\Exception
95 * @expectedExceptionCode 1432223531
96 */
97 public function constructThrowsExceptionIfOverridePriorityIsHigherThanHundred() {
98 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
99 1433089395 => array(
100 'nodeName' => 'foo',
101 'class' => 'bar',
102 'priority' => 142,
103 ),
104 );
105 new NodeFactory();
106 }
107
108 /**
109 * @test
110 * @expectedException \TYPO3\CMS\Backend\Form\Exception
111 * @expectedExceptionCode 1432223893
112 */
113 public function constructorThrowsExceptionIfOverrideTwoNodesWithSamePriorityAndSameNodeNameAreRegistered() {
114 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
115 1433089396 => array(
116 'nodeName' => 'foo',
117 'priority' => 20,
118 'class' => 'fooClass',
119 ),
120 1433089397 => array(
121 'nodeName' => 'foo',
122 'priority' => 20,
123 'class' => 'barClass',
124 ),
125 );
126 new NodeFactory();
127 }
128
129 /**
130 * @test
131 * @expectedException \TYPO3\CMS\Backend\Form\Exception
132 * @expectedExceptionCode 1433155522
133 */
134 public function constructThrowsExceptionIfResolverMissesNodeNameKey() {
135 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
136 1433154905 => array(
137 'class' => 'foo',
138 'priority' => 23,
139 ),
140 );
141 new NodeFactory();
142 }
143
144 /**
145 * @test
146 * @expectedException \TYPO3\CMS\Backend\Form\Exception
147 * @expectedExceptionCode 1433155522
148 */
149 public function constructThrowsExceptionIfResolverMissesPriorityKey() {
150 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
151 1433154905 => array(
152 'nodeName' => 'foo',
153 'class' => 'bar',
154 ),
155 );
156 new NodeFactory();
157 }
158
159 /**
160 * @test
161 * @expectedException \TYPO3\CMS\Backend\Form\Exception
162 * @expectedExceptionCode 1433155522
163 */
164 public function constructThrowsExceptionIfResolverMissesClassKey() {
165 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
166 1433154906 => array(
167 'nodeName' => 'foo',
168 'priority' => 23,
169 ),
170 );
171 new NodeFactory();
172 }
173
174 /**
175 * @test
176 * @expectedException \TYPO3\CMS\Backend\Form\Exception
177 * @expectedExceptionCode 1433155563
178 */
179 public function constructThrowsExceptionIfResolverPriorityIsLowerThanZero() {
180 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
181 1433154907 => array(
182 'nodeName' => 'foo',
183 'class' => 'bar',
184 'priority' => -23,
185 ),
186 );
187 new NodeFactory();
188
189 }
190 /**
191 * @test
192 * @expectedException \TYPO3\CMS\Backend\Form\Exception
193 * @expectedExceptionCode 1433155563
194 */
195 public function constructThrowsExceptionIfResolverPriorityIsHigherThanHundred() {
196 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
197 1433154908 => array(
198 'nodeName' => 'foo',
199 'class' => 'bar',
200 'priority' => 142,
201 ),
202 );
203 new NodeFactory();
204 }
205
206 /**
207 * @test
208 * @expectedException \TYPO3\CMS\Backend\Form\Exception
209 * @expectedExceptionCode 1433155705
210 */
211 public function constructorThrowsExceptionIfResolverTwoNodesWithSamePriorityAndSameNodeNameAreRegistered() {
212 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
213 1433154909 => array(
214 'nodeName' => 'foo',
215 'priority' => 20,
216 'class' => 'fooClass',
217 ),
218 1433154910 => array(
219 'nodeName' => 'foo',
220 'priority' => 20,
221 'class' => 'barClass',
222 ),
223 );
224 new NodeFactory();
225 }
226
227 /**
228 * @test
229 */
230 public function constructorThrowsNoExceptionIfResolverWithSamePriorityButDifferentNodeNameAreRegistered() {
231 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
232 1433154909 => array(
233 'nodeName' => 'foo',
234 'priority' => 20,
235 'class' => 'fooClass',
236 ),
237 1433154910 => array(
238 'nodeName' => 'bar',
239 'priority' => 20,
240 'class' => 'barClass',
241 ),
242 );
243 new NodeFactory();
244 }
245
246 /**
247 * @test
248 * @expectedException \TYPO3\CMS\Backend\Form\Exception
249 * @expectedExceptionCode 1431452406
250 */
251 public function createThrowsExceptionIfRenderTypeIsNotGiven() {
252 $subject = new NodeFactory();
253 $subject->create(array());
254 }
255
256 /**
257 * @test
258 * @expectedException \TYPO3\CMS\Backend\Form\Exception
259 * @expectedExceptionCode 1431872546
260 */
261 public function createThrowsExceptionIfNodeDoesNotImplementNodeInterface() {
262 $mockNode = new \stdClass();
263 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
264 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'), array(), '', FALSE);
265 $mockSubject->expects($this->once())->method('instantiate')->will($this->returnValue($mockNode));
266 $mockSubject->create(array('renderType' => 'foo'));
267 }
268
269 /**
270 * @test
271 */
272 public function createReturnsInstanceOfUnknownElementIfTypeIsNotRegistered() {
273 $subject = new NodeFactory();
274 $this->assertInstanceOf(Element\UnknownElement::class, $subject->create(array('renderType' => 'foo')));
275 }
276
277 /**
278 * @test
279 */
280 public function createReturnsInstanceOfSelectTreeElementIfNeeded() {
281 $data = array(
282 'renderType' => 'select',
283 'parameterArray' => array(
284 'fieldConf' => array(
285 'config' => array(
286 'renderMode' => 'tree',
287 ),
288 ),
289 ),
290 );
291 $subject = new NodeFactory();
292 $this->assertInstanceOf(Element\SelectTreeElement::class, $subject->create($data));
293 }
294
295 /**
296 * @test
297 */
298 public function createReturnsInstanceOfSelectSingleElementIfNeeded() {
299 $data = array(
300 'renderType' => 'select',
301 'parameterArray' => array(
302 'fieldConf' => array(
303 'config' => array(
304 'maxitems' => 1,
305 ),
306 ),
307 ),
308 );
309 $subject = new NodeFactory();
310 $this->assertInstanceOf(Element\SelectSingleElement::class, $subject->create($data));
311 }
312
313 /**
314 * @test
315 */
316 public function createReturnsInstanceOfSelectSingleElementIfSelectboxIsConfiguredButMaxitemsIsOne() {
317 $data = array(
318 'renderType' => 'select',
319 'parameterArray' => array(
320 'fieldConf' => array(
321 'config' => array(
322 'renderMode' => 'singlebox',
323 'maxitems' => 1,
324 ),
325 ),
326 ),
327 );
328 $subject = new NodeFactory();
329 $this->assertInstanceOf(Element\SelectSingleElement::class, $subject->create($data));
330 }
331
332 /**
333 * @test
334 */
335 public function createReturnsInstanceOfSelectSingleElementIfCheckboxIsConfiguredButMaxitemsIsOne() {
336 $data = array(
337 'renderType' => 'select',
338 'parameterArray' => array(
339 'fieldConf' => array(
340 'config' => array(
341 'renderMode' => 'checkbox',
342 'maxitems' => 1,
343 ),
344 ),
345 ),
346 );
347 $subject = new NodeFactory();
348 $this->assertInstanceOf(Element\SelectSingleElement::class, $subject->create($data));
349 }
350
351 /**
352 * @test
353 */
354 public function createReturnsInstanceOfSelectSingleBoxElementIfNeeded() {
355 $data = array(
356 'renderType' => 'select',
357 'parameterArray' => array(
358 'fieldConf' => array(
359 'config' => array(
360 'renderMode' => 'singlebox',
361 'maxitems' => 2,
362 ),
363 ),
364 ),
365 );
366 $subject = new NodeFactory();
367 $this->assertInstanceOf(Element\SelectSingleBoxElement::class, $subject->create($data));
368 }
369
370 /**
371 * @test
372 */
373 public function createReturnsInstanceOfSelectCheckBoxElementIfNeeded() {
374 $data = array(
375 'renderType' => 'select',
376 'parameterArray' => array(
377 'fieldConf' => array(
378 'config' => array(
379 'renderMode' => 'checkbox',
380 'maxitems' => 2,
381 ),
382 ),
383 ),
384 );
385 $subject = new NodeFactory();
386 $this->assertInstanceOf(Element\SelectCheckBoxElement::class, $subject->create($data));
387 }
388
389 /**
390 * @test
391 */
392 public function createReturnsInstanceOfSelectMultipleSideBySideElementIfNeeded() {
393 $data = array(
394 'renderType' => 'select',
395 'parameterArray' => array(
396 'fieldConf' => array(
397 'config' => array(
398 'maxitems' => 2,
399 ),
400 ),
401 ),
402 );
403 $subject = new NodeFactory();
404 $this->assertInstanceOf(Element\SelectMultipleSideBySideElement::class, $subject->create($data));
405 }
406
407 /**
408 * @test
409 */
410 public function createInstantiatesNewRegisteredElement() {
411 $data = array('renderType' => 'foo');
412 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
413 array(
414 'nodeName' => 'foo',
415 'priority' => 20,
416 'class' => \stdClass::class,
417 ),
418 );
419 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
420 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
421 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
422 $mockSubject->expects($this->once())->method('instantiate')->with('stdClass')->will($this->returnValue($mockNode));
423 $mockSubject->create($data);
424 }
425
426 /**
427 * @test
428 */
429 public function createInstantiatesElementRegisteredWithHigherPriorityWithOneGivenOrder() {
430 $data = array('renderType' => 'foo');
431 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
432 1433089467 => array(
433 'nodeName' => 'foo',
434 'priority' => 20,
435 'class' => 'foo1Class',
436 ),
437 1433089468 => array(
438 'nodeName' => 'foo',
439 'priority' => 30,
440 'class' => 'foo2Class',
441 ),
442 );
443 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
444 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
445 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
446 $mockSubject->expects($this->once())->method('instantiate')->with('foo2Class')->will($this->returnValue($mockNode));
447 $mockSubject->create($data);
448 }
449
450 /**
451 * @test
452 */
453 public function createInstantiatesElementRegisteredWithHigherPriorityWithOtherGivenOrder() {
454 $data = array('renderType' => 'foo');
455 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
456 1433089469 => array(
457 'nodeName' => 'foo',
458 'priority' => 30,
459 'class' => 'foo2Class',
460 ),
461 1433089470 => array(
462 'nodeName' => 'foo',
463 'priority' => 20,
464 'class' => 'foo1Class',
465 ),
466 );
467 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
468 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
469 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
470 $mockSubject->expects($this->once())->method('instantiate')->with('foo2Class')->will($this->returnValue($mockNode));
471 $mockSubject->create($data);
472 }
473
474 /**
475 * @test
476 * @expectedException \TYPO3\CMS\Backend\Form\Exception
477 * @expectedExceptionCode 1433157422
478 */
479 public function createThrowsExceptionIfResolverDoesNotImplementNodeResolverInterface() {
480 $data = array('renderType' => 'foo');
481 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
482 1433156887 => array(
483 'nodeName' => 'foo',
484 'priority' => 10,
485 'class' => 'fooClass',
486 ),
487 );
488 $mockResolver = $this->getMock(\stdClass::class);
489
490 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
491 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
492 $mockSubject->expects($this->at(0))->method('instantiate')->will($this->returnValue($mockResolver));
493 $mockSubject->create($data);
494 }
495
496 /**
497 * @test
498 */
499 public function createInstantiatesResolverWithHighestPriorityFirstWithOneGivenOrder() {
500 $data = array('renderType' => 'foo');
501 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
502 array(
503 'nodeName' => 'foo',
504 'priority' => 20,
505 'class' => \stdClass::class,
506 ),
507 );
508 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
509
510 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
511 1433156887 => array(
512 'nodeName' => 'foo',
513 'priority' => 10,
514 'class' => 'foo1Class',
515 ),
516 1433156888 => array(
517 'nodeName' => 'foo',
518 'priority' => 30,
519 'class' => 'foo2Class',
520 ),
521 );
522 $mockResolver1 = $this->getMock(NodeResolverInterface::class);
523 $mockResolver2 = $this->getMock(NodeResolverInterface::class);
524
525 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
526 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
527 $mockSubject->expects($this->at(0))->method('instantiate')->with('foo2Class')->will($this->returnValue($mockResolver2));
528 $mockSubject->expects($this->at(1))->method('instantiate')->with('foo1Class')->will($this->returnValue($mockResolver1));
529 $mockSubject->expects($this->at(2))->method('instantiate')->will($this->returnValue($mockNode));
530 $mockSubject->create($data);
531 }
532
533 /**
534 * @test
535 */
536 public function createInstantiatesResolverWithHighestPriorityFirstWithOtherGivenOrder() {
537 $data = array('renderType' => 'foo');
538 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
539 array(
540 'nodeName' => 'foo',
541 'priority' => 20,
542 'class' => \stdClass::class,
543 ),
544 );
545 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
546
547 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
548 1433156887 => array(
549 'nodeName' => 'foo',
550 'priority' => 30,
551 'class' => 'foo1Class',
552 ),
553 1433156888 => array(
554 'nodeName' => 'foo',
555 'priority' => 10,
556 'class' => 'foo2Class',
557 ),
558 );
559 $mockResolver1 = $this->getMock(NodeResolverInterface::class);
560 $mockResolver2 = $this->getMock(NodeResolverInterface::class);
561
562 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
563 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
564 $mockSubject->expects($this->at(0))->method('instantiate')->with('foo1Class')->will($this->returnValue($mockResolver1));
565 $mockSubject->expects($this->at(1))->method('instantiate')->with('foo2Class')->will($this->returnValue($mockResolver2));
566 $mockSubject->expects($this->at(2))->method('instantiate')->will($this->returnValue($mockNode));
567 $mockSubject->create($data);
568 }
569
570 /**
571 * @test
572 */
573 public function createInstantiatesNodeClassReturnedByResolver() {
574 $data = array('renderType' => 'foo');
575 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
576 array(
577 'nodeName' => 'foo',
578 'priority' => 20,
579 'class' => \stdClass::class,
580 ),
581 );
582 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
583
584 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
585 1433156887 => array(
586 'nodeName' => 'foo',
587 'priority' => 30,
588 'class' => 'foo1Class',
589 ),
590 );
591 $mockResolver1 = $this->getMock(NodeResolverInterface::class);
592 $mockResolver1->expects($this->once())->method('resolve')->will($this->returnValue('fooNodeClass'));
593
594 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
595 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
596 $mockSubject->expects($this->at(0))->method('instantiate')->will($this->returnValue($mockResolver1));
597 $mockSubject->expects($this->at(1))->method('instantiate')->with('fooNodeClass')->will($this->returnValue($mockNode));
598 $mockSubject->create($data);
599 }
600
601 /**
602 * @test
603 */
604 public function createDoesNotCallSecondResolverWithLowerPriorityIfFirstResolverReturnedClassName() {
605 $data = array('renderType' => 'foo');
606 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'] = array(
607 array(
608 'nodeName' => 'foo',
609 'priority' => 20,
610 'class' => \stdClass::class,
611 ),
612 );
613 $mockNode = $this->getMock(NodeInterface::class, array(), array(), '', FALSE);
614
615 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'] = array(
616 1433156887 => array(
617 'nodeName' => 'foo',
618 'priority' => 30,
619 'class' => 'foo1Class',
620 ),
621 1433156888 => array(
622 'nodeName' => 'foo',
623 'priority' => 10,
624 'class' => 'foo2Class',
625 ),
626 );
627 $mockResolver1 = $this->getMock(NodeResolverInterface::class);
628 $mockResolver1->expects($this->once())->method('resolve')->will($this->returnValue('fooNodeClass'));
629
630 /** @var NodeFactory|\PHPUnit_Framework_MockObject_MockObject $mockSubject */
631 $mockSubject = $this->getMock(NodeFactory::class, array('instantiate'));
632 $mockSubject->expects($this->at(0))->method('instantiate')->with('foo1Class')->will($this->returnValue($mockResolver1));
633 $mockSubject->expects($this->at(1))->method('instantiate')->with('fooNodeClass')->will($this->returnValue($mockNode));
634 $mockSubject->create($data);
635 }
636
637 }