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