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