5836c9c0551571b4d17d83ecf1a9061f7edd7f8f
[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\Utility\BackendUtility;
20 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForGroupWithOneAllowedTableFixture;
21 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForGroupWithMultipleAllowedTablesFixture;
22 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ProcessedValueForSelectWithMMRelationFixture;
23 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\LabelFromItemListMergedReturnsCorrectFieldsFixture;
24 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ExcludeFieldsReturnsCorrectFieldListFixture;
25 use TYPO3\CMS\Backend\Tests\Unit\Utility\Fixtures\ExcludeFieldsReturnsCorrectListWithFlexFormFieldsFixture;
26 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
27 use TYPO3\CMS\Core\Charset\CharsetConverter;
28 use TYPO3\CMS\Core\Database\DatabaseConnection;
29 use TYPO3\CMS\Core\Tests\UnitTestCase;
30 use TYPO3\CMS\Core\Utility\GeneralUtility;
31 use TYPO3\CMS\Lang\LanguageService;
32
33 /**
34 * Test case
35 */
36 class BackendUtilityTest extends 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 return array(
48 'Single year' => array(
49 'seconds' => 60 * 60 * 24 * 365,
50 'expectedLabel' => '1 year'
51 ),
52 'Plural years' => array(
53 'seconds' => 60 * 60 * 24 * 365 * 2,
54 'expectedLabel' => '2 yrs'
55 ),
56 'Single negative year' => array(
57 'seconds' => 60 * 60 * 24 * 365 * -1,
58 'expectedLabel' => '-1 year'
59 ),
60 'Plural negative years' => array(
61 'seconds' => 60 * 60 * 24 * 365 * 2 * -1,
62 'expectedLabel' => '-2 yrs'
63 ),
64 'Single day' => array(
65 'seconds' => 60 * 60 * 24,
66 'expectedLabel' => '1 day'
67 ),
68 'Plural days' => array(
69 'seconds' => 60 * 60 * 24 * 2,
70 'expectedLabel' => '2 days'
71 ),
72 'Single negative day' => array(
73 'seconds' => 60 * 60 * 24 * -1,
74 'expectedLabel' => '-1 day'
75 ),
76 'Plural negative days' => array(
77 'seconds' => 60 * 60 * 24 * 2 * -1,
78 'expectedLabel' => '-2 days'
79 ),
80 'Single hour' => array(
81 'seconds' => 60 * 60,
82 'expectedLabel' => '1 hour'
83 ),
84 'Plural hours' => array(
85 'seconds' => 60 * 60 * 2,
86 'expectedLabel' => '2 hrs'
87 ),
88 'Single negative hour' => array(
89 'seconds' => 60 * 60 * -1,
90 'expectedLabel' => '-1 hour'
91 ),
92 'Plural negative hours' => array(
93 'seconds' => 60 * 60 * 2 * -1,
94 'expectedLabel' => '-2 hrs'
95 ),
96 'Single minute' => array(
97 'seconds' => 60,
98 'expectedLabel' => '1 min'
99 ),
100 'Plural minutes' => array(
101 'seconds' => 60 * 2,
102 'expectedLabel' => '2 min'
103 ),
104 'Single negative minute' => array(
105 'seconds' => 60 * -1,
106 'expectedLabel' => '-1 min'
107 ),
108 'Plural negative minutes' => array(
109 'seconds' => 60 * 2 * -1,
110 'expectedLabel' => '-2 min'
111 ),
112 'Zero seconds' => array(
113 'seconds' => 0,
114 'expectedLabel' => '0 min'
115 )
116 );
117 }
118
119 /**
120 * @test
121 * @dataProvider calcAgeDataProvider
122 *
123 * @param int $seconds
124 * @param string $expectedLabel
125 */
126 public function calcAgeReturnsExpectedValues($seconds, $expectedLabel) {
127 $this->assertSame($expectedLabel, BackendUtility::calcAge($seconds));
128 }
129
130 ///////////////////////////////////////
131 // Tests concerning getProcessedValue
132 ///////////////////////////////////////
133 /**
134 * @test
135 * @see http://forge.typo3.org/issues/20994
136 */
137 public function getProcessedValueForZeroStringIsZero() {
138 $GLOBALS['TCA'] = array(
139 'tt_content' => array(
140 'columns' => array(
141 'header' => array(
142 'config' => array(
143 'type' => 'input',
144 ),
145 ),
146 ),
147 ),
148 );
149 $this->assertEquals('0', BackendUtility::getProcessedValue('tt_content', 'header', '0'));
150 }
151
152 /**
153 * @test
154 */
155 public function getProcessedValueForGroup() {
156 $GLOBALS['TCA'] = array(
157 'tt_content' => array(
158 'columns' => array(
159 'multimedia' => array(
160 'config' => array(
161 'type' => 'group',
162 ),
163 ),
164 ),
165 ),
166 );
167 $this->assertSame('1, 2', BackendUtility::getProcessedValue('tt_content', 'multimedia', '1,2'));
168 }
169
170 /**
171 * @test
172 */
173 public function getProcessedValueForGroupWithOneAllowedTable() {
174 $GLOBALS['TCA'] = array(
175 'tt_content' => array(
176 'columns' => array(
177 'pages' => array(
178 'config' => array(
179 'type' => 'group',
180 'allowed' => 'pages',
181 'internal_type' => 'db',
182 'maxitems' => 22,
183 'minitems' => 0,
184 'show_thumbs' => 1,
185 'size' => 3,
186 ),
187 ),
188 ),
189 ),
190 );
191
192 $this->assertSame('Page 1, Page 2', ProcessedValueForGroupWithOneAllowedTableFixture::getProcessedValue('tt_content', 'pages', '1,2'));
193 }
194
195 /**
196 * @test
197 */
198 public function getProcessedValueForGroupWithMultipleAllowedTables() {
199 $GLOBALS['TCA'] = array(
200 'index_config' => array(
201 'columns' => array(
202 'indexcfgs' => array(
203 'config' => array(
204 'type' => 'group',
205 'internal_type' => 'db',
206 'allowed' => 'index_config,pages',
207 'size' => 5,
208 ),
209 ),
210 ),
211 ),
212 );
213
214 $this->assertSame('Page 1, Configuration 2', ProcessedValueForGroupWithMultipleAllowedTablesFixture::getProcessedValue('index_config', 'indexcfgs', 'pages_1,index_config_2'));
215 }
216
217 /**
218 * @test
219 */
220 public function getProcessedValueForSelectWithMMRelation() {
221 $GLOBALS['TYPO3_DB'] = $this->getMock(DatabaseConnection::class, array(), array(), '', FALSE);
222 $GLOBALS['TYPO3_DB']->expects($this->any())->method('fullQuoteStr')
223 ->will($this->returnCallback(
224 function ($quoteStr) {
225 return "'" . $quoteStr . "'";
226 }
227 )
228 );
229 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTquery')->will($this->returnValue(0));
230 $GLOBALS['TYPO3_DB']->expects($this->any())->method('sql_free_result');
231 $GLOBALS['TYPO3_DB']->expects($this->any())->method('sql_fetch_assoc')
232 ->will($this->returnCallback(
233 function () {
234 static $called = 0;
235 ++$called;
236 switch ($called) {
237 // SELECT * FROM sys_category_record_mm
238 case 1:
239 return array(
240 'uid_local' => 1, // uid of a sys_category record
241 'uid_foreign' => 1, // uid of a pages record
242 );
243 case 2:
244 return array(
245 'uid_local' => 2, // uid of a sys_category record
246 'uid_foreign' => 1, // uid of a pages record
247 );
248 case 3:
249 return NULL;
250 // SELECT * FROM sys_catgory
251 case 4:
252 return array(
253 'uid' => 1,
254 'title' => 'Category 1',
255 );
256 case 5:
257 return array(
258 'uid' => 2,
259 'title' => 'Category 2',
260 );
261 case 6:
262 return NULL;
263 }
264 return NULL;
265 }
266 )
267 );
268
269 $GLOBALS['TCA'] = array(
270 'pages' => array(
271 'columns' => array(
272 'categories' => array(
273 'config' => array(
274 'type' => 'select',
275 'foreign_table' => 'sys_category',
276 'MM' => 'sys_category_record_mm',
277 'MM_match_fields' => array(
278 'fieldname' => 'categories',
279 'tablesnames' => 'pages',
280 ),
281 'MM_opposite_field' => 'items',
282 ),
283 ),
284 ),
285 ),
286 'sys_category' => array(
287 'columns' => array(
288 'items' => array(
289 'config' => array(
290 'type' => 'group',
291 'internal_type' => 'db',
292 'allowed' => '*',
293 'MM' => 'sys_category_record_mm',
294 'MM_oppositeUsage' => array(),
295 )
296 )
297 ),
298 ),
299 );
300
301 $this->assertSame('Category 1; Category 2', ProcessedValueForSelectWithMMRelationFixture::getProcessedValue('pages', 'categories', '2', 0, FALSE, FALSE, 1));
302 }
303
304 /**
305 * @test
306 */
307 public function getProcessedValueDisplaysAgeForDateInputFieldsIfSettingAbsent() {
308 /** @var ObjectProphecy $languageServiceProphecy */
309 $languageServiceProphecy = $this->prophesize(LanguageService::class);
310 $languageServiceProphecy->sL(Argument::cetera())->willReturn(' min| hrs| days| yrs| min| hour| day| year');
311 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
312
313 $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 8, 30, 2015);
314
315 $GLOBALS['TCA'] = [
316 'tt_content' => [
317 'columns' => [
318 'date' => [
319 'config' => [
320 'type' => 'input',
321 'eval' => 'date',
322 ],
323 ],
324 ],
325 ],
326 ];
327 $this->assertSame('28-08-15 (-2 days)', BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
328 }
329
330 /**
331 * @return array
332 */
333 public function inputTypeDateDisplayOptions() {
334 return [
335 'typeSafe Setting' => [
336 TRUE,
337 '28-08-15',
338 ],
339 'non typesafe setting' => [
340 1,
341 '28-08-15',
342 ],
343 'setting disabled typesafe' => [
344 FALSE,
345 '28-08-15 (-2 days)',
346 ],
347 'setting disabled not typesafe' => [
348 0,
349 '28-08-15 (-2 days)',
350 ],
351 ];
352 }
353
354 /**
355 * @test
356 *
357 * @dataProvider inputTypeDateDisplayOptions
358 *
359 * @param string $input
360 * @param string $expected
361 */
362 public function getProcessedValueHandlesAgeDisplayCorrectly($input, $expected) {
363 /** @var ObjectProphecy $languageServiceProphecy */
364 $languageServiceProphecy = $this->prophesize(LanguageService::class);
365 $languageServiceProphecy->sL(Argument::cetera())->willReturn(' min| hrs| days| yrs| min| hour| day| year');
366 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
367
368 $GLOBALS['EXEC_TIME'] = mktime(0, 0, 0, 8, 30, 2015);
369
370 $GLOBALS['TCA'] = [
371 'tt_content' => [
372 'columns' => [
373 'date' => [
374 'config' => [
375 'type' => 'input',
376 'eval' => 'date',
377 'disableAgeDisplay' => $input,
378 ],
379 ],
380 ],
381 ],
382 ];
383 $this->assertSame($expected, BackendUtility::getProcessedValue('tt_content', 'date', mktime(0, 0, 0, 8, 28, 2015)));
384 }
385
386 /**
387 * Tests concerning getCommonSelectFields
388 */
389
390 /**
391 * Data provider for getCommonSelectFieldsReturnsCorrectFields
392 *
393 * @return array The test data with $table, $prefix, $presetFields, $tca, $expectedFields
394 */
395 public function getCommonSelectFieldsReturnsCorrectFieldsDataProvider() {
396 return array(
397 'only uid' => array(
398 'table' => 'test_table',
399 'prefix' => '',
400 'presetFields' => array(),
401 'tca' => array(),
402 'expectedFields' => 'uid'
403 ),
404 'label set' => array(
405 'table' => 'test_table',
406 'prefix' => '',
407 'presetFields' => array(),
408 'tca' => array(
409 'ctrl' => array(
410 'label' => 'label'
411 )
412 ),
413 'expectedFields' => 'uid,label'
414 ),
415 'label_alt set' => array(
416 'table' => 'test_table',
417 'prefix' => '',
418 'presetFields' => array(),
419 'tca' => array(
420 'ctrl' => array(
421 'label_alt' => 'label,label2'
422 )
423 ),
424 'expectedFields' => 'uid,label,label2'
425 ),
426 'versioningWS set' => array(
427 'table' => 'test_table',
428 'prefix' => '',
429 'presetFields' => array(),
430 'tca' => array(
431 'ctrl' => array(
432 'versioningWS' => '2'
433 )
434 ),
435 'expectedFields' => 'uid,t3ver_id,t3ver_state,t3ver_wsid,t3ver_count'
436 ),
437 'selicon_field set' => array(
438 'table' => 'test_table',
439 'prefix' => '',
440 'presetFields' => array(),
441 'tca' => array(
442 'ctrl' => array(
443 'selicon_field' => 'field'
444 )
445 ),
446 'expectedFields' => 'uid,field'
447 ),
448 'typeicon_column set' => array(
449 'table' => 'test_table',
450 'prefix' => '',
451 'presetFields' => array(),
452 'tca' => array(
453 'ctrl' => array(
454 'typeicon_column' => 'field'
455 )
456 ),
457 'expectedFields' => 'uid,field'
458 ),
459 'enablecolumns set' => array(
460 'table' => 'test_table',
461 'prefix' => '',
462 'presetFields' => array(),
463 'tca' => array(
464 'ctrl' => array(
465 'enablecolumns' => array(
466 'disabled' => 'hidden',
467 'starttime' => 'start',
468 'endtime' => 'stop',
469 'fe_group' => 'groups'
470 )
471 )
472 ),
473 'expectedFields' => 'uid,hidden,start,stop,groups'
474 ),
475 'label set to uid' => array(
476 'table' => 'test_table',
477 'prefix' => '',
478 'presetFields' => array(),
479 'tca' => array(
480 'ctrl' => array(
481 'label' => 'uid'
482 )
483 ),
484 'expectedFields' => 'uid'
485 )
486 );
487 }
488
489 /**
490 * @test
491 * @dataProvider getCommonSelectFieldsReturnsCorrectFieldsDataProvider
492 *
493 * @param string $table
494 * @param string $prefix
495 * @param array $presetFields
496 * @param array $tca
497 * @param string $expectedFields
498 */
499 public function getCommonSelectFieldsReturnsCorrectFields($table, $prefix = '', array $presetFields, array $tca, $expectedFields = '') {
500 $GLOBALS['TCA'][$table] = $tca;
501 $selectFields = BackendUtility::getCommonSelectFields($table, $prefix, $presetFields);
502 $this->assertEquals($selectFields, $expectedFields);
503 }
504
505 /**
506 * Tests concerning getLabelFromItemlist
507 */
508
509 /**
510 * Data provider for getLabelFromItemlistReturnsCorrectFields
511 *
512 * @return array The test data with $table, $col, $key, $expectedLabel
513 */
514 public function getLabelFromItemlistReturnsCorrectFieldsDataProvider() {
515 return array(
516 'item set' => array(
517 'table' => 'tt_content',
518 'col' => 'menu_type',
519 'key' => '1',
520 'tca' => array(
521 'columns' => array(
522 'menu_type' => array(
523 'config' => array(
524 'items' => array(
525 array('Item 1', '0'),
526 array('Item 2', '1'),
527 array('Item 3', '3')
528 )
529 )
530 )
531 )
532 ),
533 'expectedLabel' => 'Item 2'
534 ),
535 'item set twice' => array(
536 'table' => 'tt_content',
537 'col' => 'menu_type',
538 'key' => '1',
539 'tca' => array(
540 'columns' => array(
541 'menu_type' => array(
542 'config' => array(
543 'items' => array(
544 array('Item 1', '0'),
545 array('Item 2a', '1'),
546 array('Item 2b', '1'),
547 array('Item 3', '3')
548 )
549 )
550 )
551 )
552 ),
553 'expectedLabel' => 'Item 2a'
554 ),
555 'item not found' => array(
556 'table' => 'tt_content',
557 'col' => 'menu_type',
558 'key' => '5',
559 'tca' => array(
560 'columns' => array(
561 'menu_type' => array(
562 'config' => array(
563 'items' => array(
564 array('Item 1', '0'),
565 array('Item 2', '1'),
566 array('Item 3', '2')
567 )
568 )
569 )
570 )
571 ),
572 'expectedLabel' => NULL
573 )
574 );
575 }
576
577 /**
578 * @test
579 * @dataProvider getLabelFromItemlistReturnsCorrectFieldsDataProvider
580 *
581 * @param string $table
582 * @param string $col
583 * @param string $key
584 * @param array $tca
585 * @param string $expectedLabel
586 */
587 public function getLabelFromItemlistReturnsCorrectFields($table, $col = '', $key = '', array $tca, $expectedLabel = '') {
588 $GLOBALS['TCA'][$table] = $tca;
589 $label = BackendUtility::getLabelFromItemlist($table, $col, $key);
590 $this->assertEquals($label, $expectedLabel);
591 }
592
593 /**
594 * Tests concerning getLabelFromItemListMerged
595 */
596
597 /**
598 * Data provider for getLabelFromItemListMerged
599 *
600 * @return array The test data with $pageId, $table, $column, $key, $expectedLabel
601 */
602 public function getLabelFromItemListMergedReturnsCorrectFieldsDataProvider() {
603 return array(
604 'no field found' => array(
605 'pageId' => '123',
606 'table' => 'tt_content',
607 'col' => 'menu_type',
608 'key' => '10',
609 'tca' => array(
610 'columns' => array(
611 'menu_type' => array(
612 'config' => array(
613 'items' => array(
614 array('Item 1', '0'),
615 array('Item 2', '1'),
616 array('Item 3', '3')
617 )
618 )
619 )
620 )
621 ),
622 'expectedLabel' => ''
623 ),
624 'no tsconfig set' => array(
625 'pageId' => '123',
626 'table' => 'tt_content',
627 'col' => 'menu_type',
628 'key' => '1',
629 'tca' => array(
630 'columns' => array(
631 'menu_type' => array(
632 'config' => array(
633 'items' => array(
634 array('Item 1', '0'),
635 array('Item 2', '1'),
636 array('Item 3', '3')
637 )
638 )
639 )
640 )
641 ),
642 'expectedLabel' => 'Item 2'
643 )
644 );
645 }
646
647 /**
648 * @test
649 * @dataProvider getLabelFromItemListMergedReturnsCorrectFieldsDataProvider
650 *
651 * @param int $pageId
652 * @param string $table
653 * @param string $column
654 * @param string $key
655 * @param array $tca
656 * @param string $expectedLabel
657 */
658 public function getLabelFromItemListMergedReturnsCorrectFields($pageId, $table, $column = '', $key = '', array $tca, $expectedLabel = '') {
659 $GLOBALS['TCA'][$table] = $tca;
660
661 $this->assertEquals($expectedLabel, LabelFromItemListMergedReturnsCorrectFieldsFixture::getLabelFromItemListMerged($pageId, $table, $column, $key));
662 }
663
664 /**
665 * Tests concerning getFuncCheck
666 */
667
668 /**
669 * @test
670 */
671 public function getFuncCheckReturnsInputTagWithValueAttribute() {
672 $this->assertStringMatchesFormat('<input %Svalue="1"%S/>', BackendUtility::getFuncCheck('params', 'test', TRUE));
673 }
674
675 /*
676 * Tests concerning getLabelsFromItemsList
677 */
678
679 /**
680 * @return array
681 */
682 public function getLabelsFromItemsListDataProvider() {
683 return array(
684 'return value if found' => array(
685 'foobar', // table
686 'someColumn', // col
687 'foo, bar', // keyList
688 array( // TCA
689 'columns' => array(
690 'someColumn' => array(
691 'config' => array(
692 'items' => array(
693 '0' => array('aFooLabel', 'foo'),
694 '1' => array('aBarLabel', 'bar')
695 )
696 )
697 )
698 )
699 ),
700 array(), // page TSconfig
701 'aFooLabel, aBarLabel' // expected
702 ),
703 'page TSconfig overrules TCA' => array(
704 'foobar', // table
705 'someColumn', // col
706 'foo,bar, add', // keyList
707 array( // TCA
708 'columns' => array(
709 'someColumn' => array(
710 'config' => array(
711 'items' => array(
712 '0' => array('aFooLabel', 'foo'),
713 '1' => array('aBarLabel', 'bar')
714 )
715 )
716 )
717 )
718 ),
719 array( // page TSconfig
720 'addItems.' => array('add' => 'aNewLabel'),
721 'altLabels.' => array('bar' => 'aBarDiffLabel'),
722 ),
723 'aFooLabel, aBarDiffLabel, aNewLabel' // expected
724 )
725 );
726 }
727
728 /**
729 * @test
730 * @dataProvider getLabelsFromItemsListDataProvider
731 *
732 * @param string $table
733 * @param string $col
734 * @param string $keyList
735 * @param array $tca
736 * @param array $pageTsConfig
737 * @param string $expectedLabel
738 */
739 public function getLabelsFromItemsListReturnsCorrectValue($table, $col, $keyList, $tca, array $pageTsConfig, $expectedLabel) {
740 // Stub LanguageService and let sL() return the same value that came in again
741 $GLOBALS['LANG'] = $this->getMock(LanguageService::class, array(), array(), '', FALSE);
742 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
743
744 $GLOBALS['TCA'][$table] = $tca;
745 $label = BackendUtility::getLabelsFromItemsList($table, $col, $keyList, $pageTsConfig);
746 $this->assertEquals($expectedLabel, $label);
747 }
748
749 /**
750 * @test
751 */
752 public function getProcessedValueReturnsLabelsForExistingValuesSolely() {
753 $table = 'foobar';
754 $col = 'someColumn';
755 $tca = array(
756 'columns' => array(
757 'someColumn' => array(
758 'config' => array(
759 'type' => 'select',
760 'items' => array(
761 '0' => array('aFooLabel', 'foo'),
762 '1' => array('aBarLabel', 'bar')
763 )
764 )
765 )
766 )
767 );
768 // Stub LanguageService and let sL() return the same value that came in again
769 $GLOBALS['LANG'] = $this->getMock(LanguageService::class, array(), array(), '', FALSE);
770 $GLOBALS['LANG']->charSet = 'utf-8';
771 $GLOBALS['LANG']->csConvObj = $this->getMock(CharsetConverter::class);
772 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
773
774 $GLOBALS['LANG']->csConvObj->expects($this->any())->method('crop')->will($this->returnArgument(1));
775
776 $GLOBALS['TCA'][$table] = $tca;
777 $label = BackendUtility::getProcessedValue($table, $col, 'foo,invalidKey,bar');
778 $this->assertEquals('aFooLabel, aBarLabel', $label);
779 }
780
781 /**
782 * @test
783 */
784 public function getProcessedValueReturnsPlainValueIfItemIsNotFound() {
785 $table = 'foobar';
786 $col = 'someColumn';
787 $tca = array(
788 'columns' => array(
789 'someColumn' => array(
790 'config' => array(
791 'type' => 'select',
792 'items' => array(
793 '0' => array('aFooLabel', 'foo')
794 )
795 )
796 )
797 )
798 );
799 // Stub LanguageService and let sL() return the same value that came in again
800 $GLOBALS['LANG'] = $this->getMock(LanguageService::class, array(), array(), '', FALSE);
801 $GLOBALS['LANG']->charSet = 'utf-8';
802 $GLOBALS['LANG']->csConvObj = $this->getMock(CharsetConverter::class);
803 $GLOBALS['LANG']->expects($this->any())->method('sL')->will($this->returnArgument(0));
804
805 $GLOBALS['LANG']->csConvObj->expects($this->any())->method('crop')->will($this->returnArgument(1));
806
807 $GLOBALS['TCA'][$table] = $tca;
808 $label = BackendUtility::getProcessedValue($table, $col, 'invalidKey');
809 $this->assertEquals('invalidKey', $label);
810 }
811
812 /**
813 * Tests concerning viewOnClick
814 */
815
816 /**
817 * @test
818 */
819 public function viewOnClickReturnsOnClickCodeWithAlternativeUrl() {
820 // Make sure the hook inside viewOnClick is not fired. This may be removed if unit tests
821 // bootstrap does not initialize TYPO3_CONF_VARS anymore.
822 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_befunc.php']['viewOnClickClass']);
823
824 $alternativeUrl = 'https://typo3.org/about/typo3-the-cms/the-history-of-typo3/#section';
825 $onclickCode = 'var previewWin = window.open(' . GeneralUtility::quoteJSvalue($alternativeUrl) . ',\'newTYPO3frontendWindow\');';
826 $this->assertStringMatchesFormat(
827 $onclickCode,
828 BackendUtility::viewOnClick(NULL, NULL, NULL, NULL, $alternativeUrl, NULL, FALSE)
829 );
830 }
831
832 /**
833 * @test
834 */
835 public function getModTSconfigIgnoresValuesFromUserTsConfigIfNoSet() {
836 $completeConfiguration = array(
837 'value' => 'bar',
838 'properties' => array(
839 'permissions.' => array(
840 'file.' => array(
841 'default.' => array('readAction' => '1'),
842 '1.' => array('writeAction' => '1'),
843 '0.' => array('readAction' => '0'),
844 ),
845 )
846 )
847 );
848
849 $GLOBALS['BE_USER'] = $this->getMock(BackendUserAuthentication::class, array(), array(), '', FALSE);
850 $GLOBALS['BE_USER']->expects($this->at(0))->method('getTSConfig')->will($this->returnValue($completeConfiguration));
851 $GLOBALS['BE_USER']->expects($this->at(1))->method('getTSConfig')->will($this->returnValue(array('value' => NULL, 'properties' => NULL)));
852
853 $className = $this->getUniqueId('BackendUtility');
854 /** @var \PHPUnit_Framework_MockObject_MockObject|BackendUtility $subject */
855 $subject = __NAMESPACE__ . '\\' . $className;
856 eval(
857 'namespace ' . __NAMESPACE__ . ';' .
858 'class ' . $className . ' extends \\TYPO3\\CMS\\Backend\\Utility\\BackendUtility {' .
859 ' static public function getPagesTSconfig($id, $rootLine = NULL, $returnPartArray = false) {' .
860 ' return array();' .
861 ' }' .
862 '}'
863 );
864
865 $this->assertSame($completeConfiguration, $subject::getModTSconfig(42, 'notrelevant'));
866 }
867
868 /**
869 * Data provider for replaceL10nModeFieldsReplacesFields
870 *
871 * @return array
872 */
873 public function replaceL10nModeFieldsReplacesFieldsDataProvider() {
874 return array(
875 'same table: mergeIfNotBlank' => array(
876 'foo',
877 array(
878 'origUid' => 1,
879 'field2' => 'fdas',
880 'field3' => 'trans',
881 ),
882 array(
883 'foo' => array(
884 'ctrl' => array(
885 'transOrigPointerTable' => '',
886 'transOrigPointerField' => 'origUid'
887 ),
888 'columns' => array(
889 'field2' => array('l10n_mode' => 'mergeIfNotBlank'),
890 'field3' => array('l10n_mode' => 'mergeIfNotBlank')
891 )
892 )
893 ),
894 array(
895 'origUid' => 0,
896 'field2' => 'basic',
897 'field3' => '',
898 ),
899 array(
900 'origUid' => 1,
901 'field2' => 'fdas',
902 'field3' => 'trans',
903 )
904 ),
905 'other table: mergeIfNotBlank' => array(
906 'foo',
907 array(
908 'origUid' => 1,
909 'field2' => '',
910 'field3' => 'trans',
911 ),
912 array(
913 'foo' => array(
914 'ctrl' => array(
915 'transOrigPointerTable' => 'bar',
916 'transOrigPointerField' => 'origUid'
917 )
918 ),
919 'bar' => array(
920 'columns' => array(
921 'field2' => array('l10n_mode' => 'mergeIfNotBlank'),
922 'field3' => array('l10n_mode' => 'mergeIfNotBlank')
923 )
924 )
925 ),
926 array(
927 'origUid' => 0,
928 'field2' => 'basic',
929 'field3' => '',
930 ),
931 array(
932 'origUid' => 1,
933 'field2' => 'basic',
934 'field3' => 'trans',
935 )
936 ),
937 'same table: exclude' => array(
938 'foo',
939 array(
940 'origUid' => 1,
941 'field2' => 'fdas',
942 'field3' => 'trans',
943 ),
944 array(
945 'foo' => array(
946 'ctrl' => array(
947 'transOrigPointerTable' => '',
948 'transOrigPointerField' => 'origUid'
949 ),
950 'columns' => array(
951 'field2' => array('l10n_mode' => 'exclude'),
952 'field3' => array('l10n_mode' => 'exclude')
953 )
954 )
955 ),
956 array(
957 'origUid' => 0,
958 'field2' => 'basic',
959 'field3' => '',
960 ),
961 array(
962 'origUid' => 1,
963 'field2' => 'basic',
964 'field3' => '',
965 )
966 ),
967 'other table: exclude' => array(
968 'foo',
969 array(
970 'origUid' => 1,
971 'field2' => 'fdas',
972 'field3' => 'trans',
973 ),
974 array(
975 'foo' => array(
976 'ctrl' => array(
977 'transOrigPointerTable' => 'bar',
978 'transOrigPointerField' => 'origUid'
979 )
980 ),
981 'bar' => array(
982 'columns' => array(
983 'field2' => array('l10n_mode' => 'exclude'),
984 'field3' => array('l10n_mode' => 'exclude')
985 )
986 )
987 ),
988 array(
989 'origUid' => 0,
990 'field2' => 'basic',
991 'field3' => '',
992 ),
993 array(
994 'origUid' => 1,
995 'field2' => 'basic',
996 'field3' => '',
997 )
998 ),
999 );
1000 }
1001
1002 /**
1003 * @test
1004 * @dataProvider replaceL10nModeFieldsReplacesFieldsDataProvider
1005 *
1006 * @param string $table
1007 * @param array $row
1008 * @param array $tca
1009 * @param array $originalRow
1010 * @param array $expected
1011 *
1012 * @throws \InvalidArgumentException
1013 * @throws \PHPUnit_Framework_Exception
1014 */
1015 public function replaceL10nModeFieldsReplacesFields($table, array $row, array $tca, array $originalRow, $expected) {
1016 $GLOBALS['TCA'] = $tca;
1017 $GLOBALS['TYPO3_DB'] = $this->getMock(DatabaseConnection::class);
1018 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->will($this->returnValue($originalRow));
1019
1020 /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|BackendUtility $subject */
1021 $subject = $this->getAccessibleMock(BackendUtility::class, array('dummy'));
1022 $this->assertSame($expected, $subject->_call('replaceL10nModeFields', $table, $row));
1023 }
1024
1025 /**
1026 * @test
1027 */
1028 public function getRecordTitleHavingLabelUserFuncCachesValue() {
1029 $table = 'tx_mytable';
1030 $row = ['uid' => 1];
1031
1032 $mock = $this->getMock('stdClass', ['labelUserFunc']);
1033 $mock->expects($this->once())->method('labelUserFunc')->willReturn('Test');
1034
1035 // Use wrapping closure for GeneralUtility::callUserFunction()
1036 $GLOBALS['TCA'][$table]['ctrl']['label_userFunc'] = function(&$parameters) use ($mock) {
1037 $parameters['title'] = $mock->labelUserFunc();
1038 };
1039
1040 $this->assertEquals('Test', BackendUtility::getRecordTitle($table, $row));
1041
1042 // Call a second time to make sure labelUserFunc is not called again ($this->once())
1043 $this->assertEquals('Test', BackendUtility::getRecordTitle($table, $row));
1044 }
1045
1046 /**
1047 * @test
1048 */
1049 public function getSpecConfPartsSplitsDefaultExtras() {
1050 $defaultExtras = 'nowrap:wizards[foo|bar]:anotherDefaultExtras:some[other|setting|with|parameters]';
1051 $expected = array(
1052 'nowrap' => 1,
1053 'wizards' => array(
1054 'parameters' => array(
1055 0 => 'foo',
1056 1 => 'bar',
1057 ),
1058 ),
1059 'anotherDefaultExtras' => 1,
1060 'some' => array(
1061 'parameters' => array(
1062 0 => 'other',
1063 1 => 'setting',
1064 2 => 'with',
1065 3 => 'parameters',
1066 ),
1067 ),
1068 );
1069 $this->assertEquals($expected, BackendUtility::getSpecConfParts($defaultExtras));
1070 }
1071 }