[TASK] Deprecate BackendUtility::getTCAtypes
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Utility / BackendUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\Unit\Utility;
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 Prophecy\Prophecy\ObjectProphecy;
19 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\LabelFromItemListMergedReturnsCorrectFieldsFixture;
20 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForGroupWithMultipleAllowedTablesFixture;
21 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForGroupWithOneAllowedTableFixture;
22 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForSelectWithMMRelationFixture;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
24 use TYPO3\CMS\Core\Database\Connection;
25 use TYPO3\CMS\Core\Database\ConnectionPool;
26 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
27 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
28 use TYPO3\CMS\Core\Database\Query\Restriction\DefaultRestrictionContainer;
29 use TYPO3\CMS\Core\Database\RelationHandler;
30 use TYPO3\CMS\Core\Localization\LanguageService;
31 use TYPO3\CMS\Core\Utility\GeneralUtility;
32
33 /**
34 * Test case
35 */
36 class BackendUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
37 {
38 ///////////////////////////////////////
39 // Tests concerning calcAge
40 ///////////////////////////////////////
41 /**
42 * Data provider for calcAge function
43 *
44 * @return array
45 */
46 public function calcAgeDataProvider()
47 {
48 return [
49 'Single year' => [
50 'seconds' => 60 * 60 * 24 * 365,
51 'expectedLabel' => '1 year'
52 ],
53 'Plural years' => [
54 'seconds' => 60 * 60 * 24 * 365 * 2,
55 'expectedLabel' => '2 yrs'
56 ],
57 'Single negative year' => [
58 'seconds' => 60 * 60 * 24 * 365 * -1,
59 'expectedLabel' => '-1 year'
60 ],
61 'Plural negative years' => [
62 'seconds' => 60 * 60 * 24 * 365 * 2 * -1,
63 'expectedLabel' => '-2 yrs'
64 ],
65 'Single day' => [
66 'seconds' => 60 * 60 * 24,
67 'expectedLabel' => '1 day'
68 ],
69 'Plural days' => [
70 'seconds' => 60 * 60 * 24 * 2,
71 'expectedLabel' => '2 days'
72 ],
73 'Single negative day' => [
74 'seconds' => 60 * 60 * 24 * -1,
75 'expectedLabel' => '-1 day'
76 ],
77 'Plural negative days' => [
78 'seconds' => 60 * 60 * 24 * 2 * -1,
79 'expectedLabel' => '-2 days'
80 ],
81 'Single hour' => [
82 'seconds' => 60 * 60,
83 'expectedLabel' => '1 hour'
84 ],
85 'Plural hours' => [
86 'seconds' => 60 * 60 * 2,
87 'expectedLabel' => '2 hrs'
88 ],
89 'Single negative hour' => [
90 'seconds' => 60 * 60 * -1,
91 'expectedLabel' => '-1 hour'
92 ],
93 'Plural negative hours' => [
94 'seconds' => 60 * 60 * 2 * -1,
95 'expectedLabel' => '-2 hrs'
96 ],
97 'Single minute' => [
98 'seconds' => 60,
99 'expectedLabel' => '1 min'
100 ],
101 'Plural minutes' => [
102 'seconds' => 60 * 2,
103 'expectedLabel' => '2 min'
104 ],
105 'Single negative minute' => [
106 'seconds' => 60 * -1,
107 'expectedLabel' => '-1 min'
108 ],
109 'Plural negative minutes' => [
110 'seconds' => 60 * 2 * -1,
111 'expectedLabel' => '-2 min'
112 ],
113 'Zero seconds' => [
114 'seconds' => 0,
115 'expectedLabel' => '0 min'
116 ]
117 ];
118 }
119
120 /**
121 * @test
122 * @dataProvider calcAgeDataProvider
123 *
124 * @param int $seconds
125 * @param string $expectedLabel
126 */
127 public function calcAgeReturnsExpectedValues($seconds, $expectedLabel)
128 {
129 $this->assertSame($expectedLabel, BackendUtility::calcAge($seconds));
130 }
131
132 ///////////////////////////////////////
133 // Tests concerning getProcessedValue
134 ///////////////////////////////////////
135 /**
136 * @test
137 * @see http://forge.typo3.org/issues/20994
138 */
139 public function getProcessedValueForZeroStringIsZero()
140 {
141 $GLOBALS['TCA'] = [
142 'tt_content' => [
143 'columns' => [
144 'header' => [
145 'config' => [
146 'type' => 'input',
147 ],
148 ],
149 ],
150 ],
151 ];
152 $GLOBALS['LANG'] = [];
153 $this->assertEquals('0', BackendUtility::getProcessedValue('tt_content', 'header', '0'));
154 }
155
156 /**
157 * @test
158 */
159 public function getProcessedValueForGroup()
160 {
161 $GLOBALS['TCA'] = [
162 'tt_content' => [
163 'columns' => [
164 'multimedia' => [
165 'config' => [
166 'type' => 'group',
167 ],
168 ],
169 ],
170 ],
171 ];
172 $GLOBALS['LANG'] = [];
173 $this->assertSame('1, 2', BackendUtility::getProcessedValue('tt_content', 'multimedia', '1,2'));
174 }
175
176 /**
177 * @test
178 */
179 public function getProcessedValueForGroupWithOneAllowedTable()
180 {
181 $GLOBALS['TCA'] = [
182 'tt_content' => [
183 'columns' => [
184 'pages' => [
185 'config' => [
186 'type' => 'group',
187 'allowed' => 'pages',
188 'internal_type' => 'db',
189 'maxitems' => 22,
190 'minitems' => 0,
191 'size' => 3,
192 ],
193 ],
194 ],
195 ],
196 ];
197 $GLOBALS['LANG'] = [];
198 $this->assertSame('Page 1, Page 2', ProcessedValueForGroupWithOneAllowedTableFixture::getProcessedValue('tt_content', 'pages', '1,2'));
199 }
200
201 /**
202 * @test
203 */
204 public function getProcessedValueForGroupWithMultipleAllowedTables()
205 {
206 $GLOBALS['TCA'] = [
207 'index_config' => [
208 'columns' => [
209 'indexcfgs' => [
210 'config' => [
211 'type' => 'group',
212 'internal_type' => 'db',
213 'allowed' => 'index_config,pages',
214 'size' => 5,
215 ],
216 ],
217 ],
218 ],
219 ];
220 $GLOBALS['LANG'] = [];
221 $this->assertSame('Page 1, Configuration 2', ProcessedValueForGroupWithMultipleAllowedTablesFixture::getProcessedValue('index_config', 'indexcfgs', 'pages_1,index_config_2'));
222 }
223
224 /**
225 * Prepare a mock database setup for a Doctrine connection
226 * and return an array of all prophets to set expectations upon.
227 *
228 * @param string $tableName
229 * @return array
230 */
231 protected function mockDatabaseConnection($tableName = 'sys_category')
232 {
233 $connectionProphet = $this->prophesize(Connection::class);
234 $connectionProphet->quote(Argument::cetera())->will(function ($arguments) {
235 return "'" . $arguments[0] . "'";
236 });
237 $connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($arguments) {
238 return '`' . $arguments[0] . '`';
239 });
240
241 $restrictionProphet = $this->prophesize(DefaultRestrictionContainer::class);
242 $restrictionProphet->removeAll()->willReturn($restrictionProphet->reveal());
243 $restrictionProphet->add(Argument::cetera())->willReturn($restrictionProphet->reveal());
244
245 $queryBuilderProphet = $this->prophesize(QueryBuilder::class);
246 $queryBuilderProphet->expr()->willReturn(
247 GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal())
248 );
249 $queryBuilderProphet->getRestrictions()->willReturn($restrictionProphet->reveal());
250 $queryBuilderProphet->quoteIdentifier(Argument::cetera())->will(function ($arguments) {
251 return '`' . $arguments[0] . '`';
252 });
253
254 $connectionPoolProphet = $this->prophesize(ConnectionPool::class);
255 $connectionPoolProphet->getConnectionForTable($tableName)
256 ->willReturn($connectionProphet->reveal());
257 $connectionPoolProphet->getQueryBuilderForTable($tableName)
258 ->shouldBeCalled()
259 ->willReturn($queryBuilderProphet->reveal());
260
261 return [$queryBuilderProphet, $connectionPoolProphet, $connectionProphet, $restrictionProphet];
262 }
263
264 /**
265 * @test
266 */
267 public function getProcessedValueForSelectWithMMRelation()
268 {
269 /** @var RelationHandler|ObjectProphecy $relationHandlerProphet */
270 $relationHandlerProphet = $this->prophesize(RelationHandler::class);
271 $relationHandlerProphet->start(Argument::cetera())->shouldBeCalled();
272
273 $relationHandlerInstance = $relationHandlerProphet->reveal();
274 $relationHandlerInstance->tableArray['sys_category'] = [1, 2];
275
276 list($queryBuilderProphet, $connectionPoolProphet) = $this->mockDatabaseConnection('sys_category');
277 $statementProphet = $this->prophesize(\Doctrine\DBAL\Driver\Statement::class);
278 $statementProphet->fetch()->shouldBeCalled()->willReturn(
279 [
280 'uid' => 1,
281 'title' => 'Category 1',
282 ],
283 [
284 'uid' => 2,
285 'title' => 'Category 2',
286 ],
287 false
288 );
289
290 /** @var QueryBuilder|ObjectProphecy $queryBuilderProphet */
291 $queryBuilderProphet->select('uid', 'sys_category.title')->willReturn($queryBuilderProphet->reveal());
292 $queryBuilderProphet->from('sys_category')->willReturn($queryBuilderProphet->reveal());
293 $queryBuilderProphet->where('`uid` IN (:dcValue1)')->willReturn($queryBuilderProphet->reveal());
294 $queryBuilderProphet->createNamedParameter([1, 2], Connection::PARAM_INT_ARRAY)->willReturn(':dcValue1');
295 $queryBuilderProphet->execute()->willReturn($statementProphet->reveal());
296
297 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerInstance);
298 GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
299
300 $GLOBALS['TCA'] = [
301 'pages' => [
302 'columns' => [
303 'categories' => [
304 'config' => [
305 'type' => 'select',
306 'foreign_table' => 'sys_category',
307 'MM' => 'sys_category_record_mm',
308 'MM_match_fields' => [
309 'fieldname' => 'categories',
310 'tablesnames' => 'pages',
311 ],
312 'MM_opposite_field' => 'items',
313 ],
314 ],
315 ],
316 ],
317 'sys_category' => [
318 'ctrl' => ['label' => 'title'],
319 'columns' => [
320 'items' => [
321 'config' => [
322 'type' => 'group',
323 'internal_type' => 'db',
324 'allowed' => '*',
325 'MM' => 'sys_category_record_mm',
326 'MM_oppositeUsage' => [],
327 ]
328 ]
329 ],
330 ],
331 ];
332 $GLOBALS['LANG'] = [];
333
334 $this->assertSame(
335 'Category 1; Category 2',
336 ProcessedValueForSelectWithMMRelationFixture::getProcessedValue(
337 'pages',
338 'categories',
339 '2',
340 0,
341 false,
342 false,
343 1
344 )
345 );
346 }
347
348 /**
349 * @test
350 */
351 public function getProcessedValueDisplaysAgeForDateInputFieldsIfSettingAbsent()
352 {
353 /** @var ObjectProphecy $languageServiceProphecy */
354 $languageServiceProphecy = $this->prophesize(LanguageService::class);
355 $languageServiceProphecy->sL(Argument::cetera())->willReturn(' min| hrs| days| yrs| min| hour| day| year');
356 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
357
358 $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 8, 30, 2015);
359
360 $GLOBALS['TCA'] = [
361 'tt_content' => [
362 'columns' => [
363 'date' => [
364 'config' => [
365 'type' => 'input',
366 'eval' => 'date',
367 ],
368 ],
369 ],
370 ],
371 ];
372 $this->assertSame('28-08-15 (-2 days)', BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
373 }
374
375 /**
376 * @return array
377 */
378 public function inputTypeDateDisplayOptions()
379 {
380 return [
381 'typeSafe Setting' => [
382 true,
383 '28-08-15',
384 ],
385 'non typesafe setting' => [
386 1,
387 '28-08-15',
388 ],
389 'setting disabled typesafe' => [
390 false,
391 '28-08-15 (-2 days)',
392 ],
393 'setting disabled not typesafe' => [
394 0,
395 '28-08-15 (-2 days)',
396 ],
397 ];
398 }
399
400 /**
401 * @test
402 *
403 * @dataProvider inputTypeDateDisplayOptions
404 *
405 * @param string $input
406 * @param string $expected
407 */
408 public function getProcessedValueHandlesAgeDisplayCorrectly($input, $expected)
409 {
410 /** @var ObjectProphecy $languageServiceProphecy */
411 $languageServiceProphecy = $this->prophesize(LanguageService::class);
412 $languageServiceProphecy->sL(Argument::cetera())->willReturn(' min| hrs| days| yrs| min| hour| day| year');
413 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
414
415 $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 8, 30, 2015);
416
417 $GLOBALS['TCA'] = [
418 'tt_content' => [
419 'columns' => [
420 'date' => [
421 'config' => [
422 'type' => 'input',
423 'eval' => 'date',
424 'disableAgeDisplay' => $input,
425 ],
426 ],
427 ],
428 ],
429 ];
430 $this->assertSame($expected, BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
431 }
432
433 /**
434 * Tests concerning getCommonSelectFields
435 */
436
437 /**
438 * Data provider for getCommonSelectFieldsReturnsCorrectFields
439 *
440 * @return array The test data with $table, $prefix, $presetFields, $tca, $expectedFields
441 */
442 public function getCommonSelectFieldsReturnsCorrectFieldsDataProvider()
443 {
444 return [
445 'only uid' => [
446 'table' => 'test_table',
447 'prefix' => '',
448 'presetFields' => [],
449 'tca' => [],
450 'expectedFields' => 'uid'
451 ],
452 'label set' => [
453 'table' => 'test_table',
454 'prefix' => '',
455 'presetFields' => [],
456 'tca' => [
457 'ctrl' => [
458 'label' => 'label'
459 ]
460 ],
461 'expectedFields' => 'uid,label'
462 ],
463 'label_alt set' => [
464 'table' => 'test_table',
465 'prefix' => '',
466 'presetFields' => [],
467 'tca' => [
468 'ctrl' => [
469 'label_alt' => 'label,label2'
470 ]
471 ],
472 'expectedFields' => 'uid,label,label2'
473 ],
474 'versioningWS set' => [
475 'table' => 'test_table',
476 'prefix' => '',
477 'presetFields' => [],
478 'tca' => [
479 'ctrl' => [
480 'versioningWS' => true
481 ]
482 ],
483 'expectedFields' => 'uid,t3ver_id,t3ver_state,t3ver_wsid,t3ver_count'
484 ],
485 'selicon_field set' => [
486 'table' => 'test_table',
487 'prefix' => '',
488 'presetFields' => [],
489 'tca' => [
490 'ctrl' => [
491 'selicon_field' => 'field'
492 ]
493 ],
494 'expectedFields' => 'uid,field'
495 ],
496 'typeicon_column set' => [
497 'table' => 'test_table',
498 'prefix' => '',
499 'presetFields' => [],
500 'tca' => [
501 'ctrl' => [
502 'typeicon_column' => 'field'
503 ]
504 ],
505 'expectedFields' => 'uid,field'
506 ],
507 'enablecolumns set' => [
508 'table' => 'test_table',
509 'prefix' => '',
510 'presetFields' => [],
511 'tca' => [
512 'ctrl' => [
513 'enablecolumns' => [
514 'disabled' => 'hidden',
515 'starttime' => 'start',
516 'endtime' => 'stop',
517 'fe_group' => 'groups'
518 ]
519 ]
520 ],
521 'expectedFields' => 'uid,hidden,start,stop,groups'
522 ],
523 'label set to uid' => [
524 'table' => 'test_table',
525 'prefix' => '',
526 'presetFields' => [],
527 'tca' => [
528 'ctrl' => [
529 'label' => 'uid'
530 ]
531 ],
532 'expectedFields' => 'uid'
533 ]
534 ];
535 }
536
537 /**
538 * @test
539 * @dataProvider getCommonSelectFieldsReturnsCorrectFieldsDataProvider
540 *
541 * @param string $table
542 * @param string $prefix
543 * @param array $presetFields
544 * @param array $tca
545 * @param string $expectedFields
546 */
547 public function getCommonSelectFieldsReturnsCorrectFields($table, $prefix = '', array $presetFields, array $tca, $expectedFields = '')
548 {
549 $GLOBALS['TCA'][$table] = $tca;
550 $selectFields = BackendUtility::getCommonSelectFields($table, $prefix, $presetFields);
551 $this->assertEquals($selectFields, $expectedFields);
552 }
553
554 /**
555 * Tests concerning getLabelFromItemlist
556 */
557
558 /**
559 * Data provider for getLabelFromItemlistReturnsCorrectFields
560 *
561 * @return array The test data with $table, $col, $key, $expectedLabel
562 */
563 public function getLabelFromItemlistReturnsCorrectFieldsDataProvider()
564 {
565 return [
566 'item set' => [
567 'table' => 'tt_content',
568 'col' => 'menu_type',
569 'key' => '1',
570 'tca' => [
571 'columns' => [
572 'menu_type' => [
573 'config' => [
574 'items' => [
575 ['Item 1', '0'],
576 ['Item 2', '1'],
577 ['Item 3', '3']
578 ]
579 ]
580 ]
581 ]
582 ],
583 'expectedLabel' => 'Item 2'
584 ],
585 'item set twice' => [
586 'table' => 'tt_content',
587 'col' => 'menu_type',
588 'key' => '1',
589 'tca' => [
590 'columns' => [
591 'menu_type' => [
592 'config' => [
593 'items' => [
594 ['Item 1', '0'],
595 ['Item 2a', '1'],
596 ['Item 2b', '1'],
597 ['Item 3', '3']
598 ]
599 ]
600 ]
601 ]
602 ],
603 'expectedLabel' => 'Item 2a'
604 ],
605 'item not found' => [
606 'table' => 'tt_content',
607 'col' => 'menu_type',
608 'key' => '5',
609 'tca' => [
610 'columns' => [
611 'menu_type' => [
612 'config' => [
613 'items' => [
614 ['Item 1', '0'],
615 ['Item 2', '1'],
616 ['Item 3', '2']
617 ]
618 ]
619 ]
620 ]
621 ],
622 'expectedLabel' => null
623 ]
624 ];
625 }
626
627 /**
628 * @test
629 * @dataProvider getLabelFromItemlistReturnsCorrectFieldsDataProvider
630 *
631 * @param string $table
632 * @param string $col
633 * @param string $key
634 * @param array $tca
635 * @param string $expectedLabel
636 */
637 public function getLabelFromItemlistReturnsCorrectFields($table, $col = '', $key = '', array $tca, $expectedLabel = '')
638 {
639 $GLOBALS['TCA'][$table] = $tca;
640 $label = BackendUtility::getLabelFromItemlist($table, $col, $key);
641 $this->assertEquals($label, $expectedLabel);
642 }
643
644 /**
645 * Tests concerning getLabelFromItemListMerged
646 */
647
648 /**
649 * Data provider for getLabelFromItemListMerged
650 *
651 * @return array The test data with $pageId, $table, $column, $key, $expectedLabel
652 */
653 public function getLabelFromItemListMergedReturnsCorrectFieldsDataProvider()
654 {
655 return [
656 'no field found' => [
657 'pageId' => '123',
658 'table' => 'tt_content',
659 'col' => 'menu_type',
660 'key' => '10',
661 'tca' => [
662 'columns' => [
663 'menu_type' => [
664 'config' => [
665 'items' => [
666 ['Item 1', '0'],
667 ['Item 2', '1'],
668 ['Item 3', '3']
669 ]
670 ]
671 ]
672 ]
673 ],
674 'expectedLabel' => ''
675 ],
676 'no tsconfig set' => [
677 'pageId' => '123',
678 'table' => 'tt_content',
679 'col' => 'menu_type',
680 'key' => '1',
681 'tca' => [
682 'columns' => [
683 'menu_type' => [
684 'config' => [
685 'items' => [
686 ['Item 1', '0'],
687 ['Item 2', '1'],
688 ['Item 3', '3']
689 ]
690 ]
691 ]
692 ]
693 ],
694 'expectedLabel' => 'Item 2'
695 ]
696 ];
697 }
698
699 /**
700 * @test
701 * @dataProvider getLabelFromItemListMergedReturnsCorrectFieldsDataProvider
702 *
703 * @param int $pageId
704 * @param string $table
705 * @param string $column
706 * @param string $key
707 * @param array $tca
708 * @param string $expectedLabel
709 */
710 public function getLabelFromItemListMergedReturnsCorrectFields($pageId, $table, $column = '', $key = '', array $tca, $expectedLabel = '')
711 {
712 $GLOBALS['TCA'][$table] = $tca;
713
714 $this->assertEquals($expectedLabel, LabelFromItemListMergedReturnsCorrectFieldsFixture::getLabelFromItemListMerged($pageId, $table, $column, $key));
715 }
716
717 /**
718 * Tests concerning getFuncCheck
719 */
720
721 /**
722 * @test
723 */
724 public function getFuncCheckReturnsInputTagWithValueAttribute()
725 {
726 $this->assertStringMatchesFormat('<input %Svalue="1"%S/>', BackendUtility::getFuncCheck('params', 'test', true));
727 }
728
729 /*
730 * Tests concerning getLabelsFromItemsList
731 */
732
733 /**
734 * @return array
735 */
736 public function getLabelsFromItemsListDataProvider()
737 {
738 return [
739 'return value if found' => [
740 'foobar', // table
741 'someColumn', // col
742 'foo, bar', // keyList
743 [ // TCA
744 'columns' => [
745 'someColumn' => [
746 'config' => [
747 'items' => [
748 '0' => ['aFooLabel', 'foo'],
749 '1' => ['aBarLabel', 'bar']
750 ]
751 ]
752 ]
753 ]
754 ],
755 [], // page TSconfig
756 'aFooLabel, aBarLabel' // expected
757 ],
758 'page TSconfig overrules TCA' => [
759 'foobar', // table
760 'someColumn', // col
761 'foo,bar, add', // keyList
762 [ // TCA
763 'columns' => [
764 'someColumn' => [
765 'config' => [
766 'items' => [
767 '0' => ['aFooLabel', 'foo'],
768 '1' => ['aBarLabel', 'bar']
769 ]
770 ]
771 ]
772 ]
773 ],
774 [ // page TSconfig
775 'addItems.' => ['add' => 'aNewLabel'],
776 'altLabels.' => ['bar' => 'aBarDiffLabel'],
777 ],
778 'aFooLabel, aBarDiffLabel, aNewLabel' // expected
779 ]
780 ];
781 }
782
783 /**
784 * @test
785 * @dataProvider getLabelsFromItemsListDataProvider
786 *
787 * @param string $table
788 * @param string $col
789 * @param string $keyList
790 * @param array $tca
791 * @param array $pageTsConfig
792 * @param string $expectedLabel
793 */
794 public function getLabelsFromItemsListReturnsCorrectValue($table, $col, $keyList, $tca, array $pageTsConfig, $expectedLabel)
795 {
796 // Stub LanguageService and let sL() return the same value that came in again
797 $GLOBALS['LANG'] = $this->createMock(LanguageService::class);
798 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
799
800 $GLOBALS['TCA'][$table] = $tca;
801 $label = BackendUtility::getLabelsFromItemsList($table, $col, $keyList, $pageTsConfig);
802 $this->assertEquals($expectedLabel, $label);
803 }
804
805 /**
806 * @test
807 */
808 public function getProcessedValueReturnsLabelsForExistingValuesSolely()
809 {
810 $table = 'foobar';
811 $col = 'someColumn';
812 $tca = [
813 'columns' => [
814 'someColumn' => [
815 'config' => [
816 'type' => 'select',
817 'items' => [
818 '0' => ['aFooLabel', 'foo'],
819 '1' => ['aBarLabel', 'bar']
820 ]
821 ]
822 ]
823 ]
824 ];
825 // Stub LanguageService and let sL() return the same value that came in again
826 $GLOBALS['LANG'] = $this->createMock(LanguageService::class);
827 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
828
829 $GLOBALS['TCA'][$table] = $tca;
830 $label = BackendUtility::getProcessedValue($table, $col, 'foo,invalidKey,bar');
831 $this->assertEquals('aFooLabel, aBarLabel', $label);
832 }
833
834 /**
835 * @test
836 */
837 public function getProcessedValueReturnsPlainValueIfItemIsNotFound()
838 {
839 $table = 'foobar';
840 $col = 'someColumn';
841 $tca = [
842 'columns' => [
843 'someColumn' => [
844 'config' => [
845 'type' => 'select',
846 'items' => [
847 '0' => ['aFooLabel', 'foo']
848 ]
849 ]
850 ]
851 ]
852 ];
853 // Stub LanguageService and let sL() return the same value that came in again
854 $GLOBALS['LANG'] = $this->createMock(LanguageService::class);
855 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
856
857 $GLOBALS['TCA'][$table] = $tca;
858 $label = BackendUtility::getProcessedValue($table, $col, 'invalidKey');
859 $this->assertEquals('invalidKey', $label);
860 }
861
862 /**
863 * Tests concerning viewOnClick
864 */
865
866 /**
867 * @test
868 */
869 public function viewOnClickReturnsOnClickCodeWithAlternativeUrl()
870 {
871 // Make sure the hook inside viewOnClick is not fired. This may be removed if unit tests
872 // bootstrap does not initialize TYPO3_CONF_VARS anymore.
873 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['viewOnClickClass']);
874
875 $alternativeUrl = 'https://typo3.org/about/typo3-the-cms/the-history-of-typo3/#section';
876 $onclickCode = 'var previewWin = window.open(' . GeneralUtility::quoteJSvalue($alternativeUrl) . ',\'newTYPO3frontendWindow\');' . LF
877 . 'if (previewWin.location.href === ' . GeneralUtility::quoteJSvalue($alternativeUrl) . ') { previewWin.location.reload(); };';
878 $this->assertStringMatchesFormat(
879 $onclickCode,
880 BackendUtility::viewOnClick(null, null, null, null, $alternativeUrl, null, false)
881 );
882 }
883
884 /**
885 * @test
886 */
887 public function dateTimeAgeReturnsCorrectValues()
888 {
889 /** @var ObjectProphecy|LanguageService $languageServiceProphecy */
890 $languageServiceProphecy = $this->prophesize(LanguageService::class);
891 $languageServiceProphecy->sL(Argument::cetera())->willReturn(' min| hrs| days| yrs| min| hour| day| year');
892 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
893 $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 3, 23, 2016);
894
895 $this->assertSame('24-03-16 00:00 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400));
896 $this->assertSame('24-03-16 (-1 day)', BackendUtility::dateTimeAge($GLOBALS['EXEC_TIME'] + 86400, 1, 'date'));
897 }
898
899 /**
900 * @test
901 */
902 public function purgeComputedPropertyNamesRemovesPropertiesStartingWithUnderscore()
903 {
904 $propertyNames = [
905 'uid',
906 'pid',
907 '_ORIG_PID'
908 ];
909 $computedPropertyNames = BackendUtility::purgeComputedPropertyNames($propertyNames);
910 self::assertSame(['uid', 'pid'], $computedPropertyNames);
911 }
912
913 /**
914 * @test
915 */
916 public function purgeComputedPropertiesFromRecordRemovesPropertiesStartingWithUnderscore()
917 {
918 $record = [
919 'uid' => 1,
920 'pid' => 2,
921 '_ORIG_PID' => 1
922 ];
923 $expected = [
924 'uid' => 1,
925 'pid' => 2
926 ];
927 $computedProperties = BackendUtility::purgeComputedPropertiesFromRecord($record);
928 self::assertSame($expected, $computedProperties);
929 }
930
931 public function splitTableUidDataProvider()
932 {
933 return [
934 'simple' => [
935 'pages_23',
936 ['pages', '23']
937 ],
938 'complex' => [
939 'tt_content_13',
940 ['tt_content', '13']
941 ],
942 'multiple underscores' => [
943 'tx_runaway_domain_model_crime_scene_1234',
944 ['tx_runaway_domain_model_crime_scene', '1234']
945 ]
946 ];
947 }
948
949 /**
950 * @test
951 * @dataProvider splitTableUidDataProvider
952 */
953 public function splitTableUid($input, $expected)
954 {
955 $result = BackendUtility::splitTable_Uid($input);
956 self::assertSame($expected, $result);
957 }
958 }