TYPO3  7.6
ContentObjectRendererTest.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject;
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 
24 
28 class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
29 {
33  protected $singletonInstances = array();
34 
38  protected $subject = null;
39 
44 
48  protected $templateServiceMock = null;
49 
55  protected $contentObjectMap = array(
56  'TEXT' => \TYPO3\CMS\Frontend\ContentObject\TextContentObject::class,
57  'CASE' => \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class,
58  'COBJ_ARRAY' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject::class,
59  'COA' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject::class,
60  'COA_INT' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayInternalContentObject::class,
61  'USER' => \TYPO3\CMS\Frontend\ContentObject\UserContentObject::class,
62  'USER_INT' => \TYPO3\CMS\Frontend\ContentObject\UserInternalContentObject::class,
63  'FILE' => \TYPO3\CMS\Frontend\ContentObject\FileContentObject::class,
64  'FILES' => \TYPO3\CMS\Frontend\ContentObject\FilesContentObject::class,
65  'IMAGE' => \TYPO3\CMS\Frontend\ContentObject\ImageContentObject::class,
66  'IMG_RESOURCE' => \TYPO3\CMS\Frontend\ContentObject\ImageResourceContentObject::class,
67  'CONTENT' => \TYPO3\CMS\Frontend\ContentObject\ContentContentObject::class,
68  'RECORDS' => \TYPO3\CMS\Frontend\ContentObject\RecordsContentObject::class,
69  'HMENU' => \TYPO3\CMS\Frontend\ContentObject\HierarchicalMenuContentObject::class,
70  'CASEFUNC' => \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class,
71  'LOAD_REGISTER' => \TYPO3\CMS\Frontend\ContentObject\LoadRegisterContentObject::class,
72  'RESTORE_REGISTER' => \TYPO3\CMS\Frontend\ContentObject\RestoreRegisterContentObject::class,
73  'TEMPLATE' => \TYPO3\CMS\Frontend\ContentObject\TemplateContentObject::class,
74  'FLUIDTEMPLATE' => \TYPO3\CMS\Frontend\ContentObject\FluidTemplateContentObject::class,
75  'SVG' => \TYPO3\CMS\Frontend\ContentObject\ScalableVectorGraphicsContentObject::class,
76  'EDITPANEL' => \TYPO3\CMS\Frontend\ContentObject\EditPanelContentObject::class
77  );
78 
82  protected function setUp()
83  {
84  $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
86 
87  $this->templateServiceMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('getFileName', 'linkData'));
88  $pageRepositoryMock = $this->getMock(\TYPO3\CMS\Frontend\Page\PageRepository::class, array('getRawRecord'));
89 
90  $this->typoScriptFrontendControllerMock = $this->getAccessibleMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array('dummy'), array(), '', false);
91  $this->typoScriptFrontendControllerMock->tmpl = $this->templateServiceMock;
92  $this->typoScriptFrontendControllerMock->config = array();
93  $this->typoScriptFrontendControllerMock->page = array();
94  $this->typoScriptFrontendControllerMock->sys_page = $pageRepositoryMock;
95  $this->typoScriptFrontendControllerMock->csConvObj = new CharsetConverter();
96  $this->typoScriptFrontendControllerMock->renderCharset = 'utf-8';
98 
99  $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array());
100  $GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] = 'mbstring';
101 
102  $this->subject = $this->getAccessibleMock(
103  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
104  array('getResourceFactory', 'getEnvironmentVariable'),
105  array($this->typoScriptFrontendControllerMock)
106  );
107  $this->subject->setContentObjectClassMap($this->contentObjectMap);
108  $this->subject->start(array(), 'tt_content');
109  }
110 
111  protected function tearDown()
112  {
113  GeneralUtility::resetSingletonInstances($this->singletonInstances);
114  parent::tearDown();
115  }
116 
118  // Utility functions
120 
124  protected function createMockedLoggerAndLogManager()
125  {
126  $logManagerMock = $this->getMock(LogManager::class);
127  $loggerMock = $this->getMock(LoggerInterface::class);
128  $logManagerMock->expects($this->any())
129  ->method('getLogger')
130  ->willReturn($loggerMock);
131  GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
132  }
133 
141  protected function handleCharset($charset, &$subject, &$expected)
142  {
143  $GLOBALS['TSFE']->renderCharset = $charset;
144  $subject = $GLOBALS['TSFE']->csConvObj->conv($subject, 'iso-8859-1', $charset);
145  $expected = $GLOBALS['TSFE']->csConvObj->conv($expected, 'iso-8859-1', $charset);
146  }
147 
149  // Tests concerning the getImgResource hook
151 
155  {
156  $this->templateServiceMock
157  ->expects($this->atLeastOnce())
158  ->method('getFileName')
159  ->with('typo3/clear.gif')
160  ->will($this->returnValue('typo3/clear.gif'));
161 
162  $resourceFactory = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceFactory::class, array(), array(), '', false);
163  $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
164 
165  $className = $this->getUniqueId('tx_coretest');
166  $getImgResourceHookMock = $this->getMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectGetImageResourceHookInterface::class, array('getImgResourcePostProcess'), array(), $className);
167  $getImgResourceHookMock
168  ->expects($this->once())
169  ->method('getImgResourcePostProcess')
170  ->will($this->returnCallback(array($this, 'isGetImgResourceHookCalledCallback')));
171  $getImgResourceHookObjects = array($getImgResourceHookMock);
172  $this->subject->_setRef('getImgResourceHookObjects', $getImgResourceHookObjects);
173  $this->subject->getImgResource('typo3/clear.gif', array());
174  }
175 
183  {
184  list($file, $fileArray, $imageResource, $parent) = func_get_args();
185  $this->assertEquals('typo3/clear.gif', $file);
186  $this->assertEquals('typo3/clear.gif', $imageResource['origFile']);
187  $this->assertTrue(is_array($fileArray));
188  $this->assertTrue($parent instanceof \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer);
189  return $imageResource;
190  }
191 
192 
194  // Tests concerning getContentObject
196 
198  {
199  $dataProvider = array();
200  foreach ($this->contentObjectMap as $name => $className) {
201  $dataProvider[] = array($name, $className);
202  }
203  return $dataProvider;
204  }
205 
213  {
214  $contentObjectInstance = $this->getMock($fullClassName, array(), array(), '', false);
215  \TYPO3\CMS\Core\Utility\GeneralUtility::addInstance($fullClassName, $contentObjectInstance);
216  $this->assertSame($contentObjectInstance, $this->subject->getContentObject($name));
217  }
218 
220  // Tests concerning getQueryArguments()
222 
226  {
227  $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
228  $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
229  );
230  $getQueryArgumentsConfiguration = array();
231  $getQueryArgumentsConfiguration['exclude'] = array();
232  $getQueryArgumentsConfiguration['exclude'][] = 'key1';
233  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
234  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
235  $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
236  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
237  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
238  $this->assertEquals($expectedResult, $actualResult);
239  }
240 
245  {
246  $_GET = array(
247  'key1' => 'value1',
248  'key2' => 'value2',
249  'key3' => array(
250  'key31' => 'value31',
251  'key32' => array(
252  'key321' => 'value321',
253  'key322' => 'value322'
254  )
255  )
256  );
257  $getQueryArgumentsConfiguration = array();
258  $getQueryArgumentsConfiguration['method'] = 'GET';
259  $getQueryArgumentsConfiguration['exclude'] = array();
260  $getQueryArgumentsConfiguration['exclude'][] = 'key1';
261  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
262  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
263  $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
264  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
265  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
266  $this->assertEquals($expectedResult, $actualResult);
267  }
268 
273  {
274  $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
275  $this->returnValue('key1=value1')
276  );
277  $getQueryArgumentsConfiguration = array();
278  $overruleArguments = array(
279  // Should be overridden
280  'key1' => 'value1Overruled',
281  // Shouldn't be set: Parameter doesn't exist in source array and is not forced
282  'key2' => 'value2Overruled'
283  );
284  $expectedResult = '&key1=value1Overruled';
285  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
286  $this->assertEquals($expectedResult, $actualResult);
287  }
288 
293  {
294  $_POST = array(
295  'key1' => 'value1',
296  'key2' => 'value2',
297  'key3' => array(
298  'key31' => 'value31',
299  'key32' => array(
300  'key321' => 'value321',
301  'key322' => 'value322'
302  )
303  )
304  );
305  $getQueryArgumentsConfiguration = array();
306  $getQueryArgumentsConfiguration['method'] = 'POST';
307  $getQueryArgumentsConfiguration['exclude'] = array();
308  $getQueryArgumentsConfiguration['exclude'][] = 'key1';
309  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
310  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
311  $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
312  $overruleArguments = array(
313  // Should be overriden
314  'key2' => 'value2Overruled',
315  'key3' => array(
316  'key32' => array(
317  // Shouldn't be set: Parameter is excluded and not forced
318  'key321' => 'value321Overruled',
319  // Should be overriden: Parameter is not excluded
320  'key322' => 'value322Overruled',
321  // Shouldn't be set: Parameter doesn't exist in source array and is not forced
322  'key323' => 'value323Overruled'
323  )
324  )
325  );
326  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key322]=value322Overruled');
327  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
328  $this->assertEquals($expectedResult, $actualResult);
329  }
330 
335  {
336  $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
337  $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
338  );
339  $_POST = array(
340  'key1' => 'value1',
341  'key2' => 'value2',
342  'key3' => array(
343  'key31' => 'value31',
344  'key32' => array(
345  'key321' => 'value321',
346  'key322' => 'value322'
347  )
348  )
349  );
350  $getQueryArgumentsConfiguration = array();
351  $getQueryArgumentsConfiguration['exclude'] = array();
352  $getQueryArgumentsConfiguration['exclude'][] = 'key1';
353  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
354  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
355  $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key322]';
356  $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
357  $overruleArguments = array(
358  // Should be overriden
359  'key2' => 'value2Overruled',
360  'key3' => array(
361  'key32' => array(
362  // Should be set: Parameter is excluded but forced
363  'key321' => 'value321Overruled',
364  // Should be set: Parameter doesn't exist in source array but is forced
365  'key323' => 'value323Overruled'
366  )
367  )
368  );
369  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key321]=value321Overruled&key3[key32][key323]=value323Overruled');
370  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
371  $this->assertEquals($expectedResult, $actualResult);
372  $getQueryArgumentsConfiguration['method'] = 'POST';
373  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
374  $this->assertEquals($expectedResult, $actualResult);
375  }
376 
381  {
382  $_POST = array(
383  'key1' => 'POST1',
384  'key2' => 'POST2',
385  'key3' => array(
386  'key31' => 'POST31',
387  'key32' => 'POST32',
388  'key33' => array(
389  'key331' => 'POST331',
390  'key332' => 'POST332',
391  )
392  )
393  );
394  $_GET = array(
395  'key2' => 'GET2',
396  'key3' => array(
397  'key32' => 'GET32',
398  'key33' => array(
399  'key331' => 'GET331',
400  )
401  )
402  );
403  $getQueryArgumentsConfiguration = array();
404  $getQueryArgumentsConfiguration['method'] = 'POST,GET';
405  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
406  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
407  $this->assertEquals($expectedResult, $actualResult);
408  }
409 
414  {
415  $_GET = array(
416  'key1' => 'GET1',
417  'key2' => 'GET2',
418  'key3' => array(
419  'key31' => 'GET31',
420  'key32' => 'GET32',
421  'key33' => array(
422  'key331' => 'GET331',
423  'key332' => 'GET332',
424  )
425  )
426  );
427  $_POST = array(
428  'key2' => 'POST2',
429  'key3' => array(
430  'key32' => 'POST32',
431  'key33' => array(
432  'key331' => 'POST331',
433  )
434  )
435  );
436  $getQueryArgumentsConfiguration = array();
437  $getQueryArgumentsConfiguration['method'] = 'GET,POST';
438  $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
439  $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
440  $this->assertEquals($expectedResult, $actualResult);
441  }
442 
449  private function rawUrlEncodeSquareBracketsInUrl($string)
450  {
451  return str_replace(array('[', ']'), array('%5B', '%5D'), $string);
452  }
453 
455  // Tests concerning crop
457 
460  public function cropIsMultibyteSafe()
461  {
462  $this->assertEquals('бла', $this->subject->crop('бла', '3|...'));
463  }
464 
466  // Tests concerning cropHTML
468 
475  public function cropHtmlDataProvider()
476  {
477  $plainText = 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j implemented the original version of the crop function.';
478  $textWithMarkup = '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>' . ' implemented</strong> the original version of the crop function.';
479  $textWithEntities = 'Kasper Sk&aring;rh&oslash;j implemented the; original ' . 'version of the crop function.';
480  $charsets = array('iso-8859-1', 'utf-8', 'ascii', 'big5');
481  $data = array();
482  foreach ($charsets as $charset) {
483  $data = array_merge($data, array(
484  $charset . ' plain text; 11|...' => array(
485  '11|...',
486  $plainText,
487  'Kasper Sk' . chr(229) . 'r...',
488  $charset
489  ),
490  $charset . ' plain text; -58|...' => array(
491  '-58|...',
492  $plainText,
493  '...h' . chr(248) . 'j implemented the original version of the crop function.',
494  $charset
495  ),
496  $charset . ' plain text; 4|...|1' => array(
497  '4|...|1',
498  $plainText,
499  'Kasp...',
500  $charset
501  ),
502  $charset . ' plain text; 20|...|1' => array(
503  '20|...|1',
504  $plainText,
505  'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j...',
506  $charset
507  ),
508  $charset . ' plain text; -5|...|1' => array(
509  '-5|...|1',
510  $plainText,
511  '...tion.',
512  $charset
513  ),
514  $charset . ' plain text; -49|...|1' => array(
515  '-49|...|1',
516  $plainText,
517  '...the original version of the crop function.',
518  $charset
519  ),
520  $charset . ' text with markup; 11|...' => array(
521  '11|...',
522  $textWithMarkup,
523  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'r...</a></strong>',
524  $charset
525  ),
526  $charset . ' text with markup; 13|...' => array(
527  '13|...',
528  $textWithMarkup,
529  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . '...</a></strong>',
530  $charset
531  ),
532  $charset . ' text with markup; 14|...' => array(
533  '14|...',
534  $textWithMarkup,
535  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
536  $charset
537  ),
538  $charset . ' text with markup; 15|...' => array(
539  '15|...',
540  $textWithMarkup,
541  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> ...</strong>',
542  $charset
543  ),
544  $charset . ' text with markup; 29|...' => array(
545  '29|...',
546  $textWithMarkup,
547  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> th...',
548  $charset
549  ),
550  $charset . ' text with markup; -58|...' => array(
551  '-58|...',
552  $textWithMarkup,
553  '<strong><a href="mailto:kasper@typo3.org">...h' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.',
554  $charset
555  ),
556  $charset . ' text with markup 4|...|1' => array(
557  '4|...|1',
558  $textWithMarkup,
559  '<strong><a href="mailto:kasper@typo3.org">Kasp...</a></strong>',
560  $charset
561  ),
562  $charset . ' text with markup; 11|...|1' => array(
563  '11|...|1',
564  $textWithMarkup,
565  '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>',
566  $charset
567  ),
568  $charset . ' text with markup; 13|...|1' => array(
569  '13|...|1',
570  $textWithMarkup,
571  '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>',
572  $charset
573  ),
574  $charset . ' text with markup; 14|...|1' => array(
575  '14|...|1',
576  $textWithMarkup,
577  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
578  $charset
579  ),
580  $charset . ' text with markup; 15|...|1' => array(
581  '15|...|1',
582  $textWithMarkup,
583  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
584  $charset
585  ),
586  $charset . ' text with markup; 29|...|1' => array(
587  '29|...|1',
588  $textWithMarkup,
589  '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong>...',
590  $charset
591  ),
592  $charset . ' text with markup; -66|...|1' => array(
593  '-66|...|1',
594  $textWithMarkup,
595  '<strong><a href="mailto:kasper@typo3.org">...Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.',
596  $charset
597  ),
598  $charset . ' text with entities 9|...' => array(
599  '9|...',
600  $textWithEntities,
601  'Kasper Sk...',
602  $charset
603  ),
604  $charset . ' text with entities 10|...' => array(
605  '10|...',
606  $textWithEntities,
607  'Kasper Sk&aring;...',
608  $charset
609  ),
610  $charset . ' text with entities 11|...' => array(
611  '11|...',
612  $textWithEntities,
613  'Kasper Sk&aring;r...',
614  $charset
615  ),
616  $charset . ' text with entities 13|...' => array(
617  '13|...',
618  $textWithEntities,
619  'Kasper Sk&aring;rh&oslash;...',
620  $charset
621  ),
622  $charset . ' text with entities 14|...' => array(
623  '14|...',
624  $textWithEntities,
625  'Kasper Sk&aring;rh&oslash;j...',
626  $charset
627  ),
628  $charset . ' text with entities 15|...' => array(
629  '15|...',
630  $textWithEntities,
631  'Kasper Sk&aring;rh&oslash;j ...',
632  $charset
633  ),
634  $charset . ' text with entities 16|...' => array(
635  '16|...',
636  $textWithEntities,
637  'Kasper Sk&aring;rh&oslash;j i...',
638  $charset
639  ),
640  $charset . ' text with entities -57|...' => array(
641  '-57|...',
642  $textWithEntities,
643  '...j implemented the; original version of the crop function.',
644  $charset
645  ),
646  $charset . ' text with entities -58|...' => array(
647  '-58|...',
648  $textWithEntities,
649  '...&oslash;j implemented the; original version of the crop function.',
650  $charset
651  ),
652  $charset . ' text with entities -59|...' => array(
653  '-59|...',
654  $textWithEntities,
655  '...h&oslash;j implemented the; original version of the crop function.',
656  $charset
657  ),
658  $charset . ' text with entities 4|...|1' => array(
659  '4|...|1',
660  $textWithEntities,
661  'Kasp...',
662  $charset
663  ),
664  $charset . ' text with entities 9|...|1' => array(
665  '9|...|1',
666  $textWithEntities,
667  'Kasper...',
668  $charset
669  ),
670  $charset . ' text with entities 10|...|1' => array(
671  '10|...|1',
672  $textWithEntities,
673  'Kasper...',
674  $charset
675  ),
676  $charset . ' text with entities 11|...|1' => array(
677  '11|...|1',
678  $textWithEntities,
679  'Kasper...',
680  $charset
681  ),
682  $charset . ' text with entities 13|...|1' => array(
683  '13|...|1',
684  $textWithEntities,
685  'Kasper...',
686  $charset
687  ),
688  $charset . ' text with entities 14|...|1' => array(
689  '14|...|1',
690  $textWithEntities,
691  'Kasper Sk&aring;rh&oslash;j...',
692  $charset
693  ),
694  $charset . ' text with entities 15|...|1' => array(
695  '15|...|1',
696  $textWithEntities,
697  'Kasper Sk&aring;rh&oslash;j...',
698  $charset
699  ),
700  $charset . ' text with entities 16|...|1' => array(
701  '16|...|1',
702  $textWithEntities,
703  'Kasper Sk&aring;rh&oslash;j...',
704  $charset
705  ),
706  $charset . ' text with entities -57|...|1' => array(
707  '-57|...|1',
708  $textWithEntities,
709  '...implemented the; original version of the crop function.',
710  $charset
711  ),
712  $charset . ' text with entities -58|...|1' => array(
713  '-58|...|1',
714  $textWithEntities,
715  '...implemented the; original version of the crop function.',
716  $charset
717  ),
718  $charset . ' text with entities -59|...|1' => array(
719  '-59|...|1',
720  $textWithEntities,
721  '...implemented the; original version of the crop function.',
722  $charset
723  ),
724  $charset . ' text with dash in html-element 28|...|1' => array(
725  '28|...|1',
726  'Some text with a link to <link email.address@example.org - mail "Open email window">my email.address@example.org</link> and text after it',
727  'Some text with a link to <link email.address@example.org - mail "Open email window">my...</link>',
728  $charset
729  ),
730  $charset . ' html elements with dashes in attributes' => array(
731  '9',
732  '<em data-foo="x">foobar</em>foobaz',
733  '<em data-foo="x">foobar</em>foo',
734  $charset
735  ),
736  $charset . ' html elements with iframe embedded 24|...|1' => array(
737  '24|...|1',
738  'Text with iframe <iframe src="//what.ever/"></iframe> and text after it',
739  'Text with iframe <iframe src="//what.ever/"></iframe> and...',
740  $charset
741  ),
742  $charset . ' html elements with script tag embedded 24|...|1' => array(
743  '24|...|1',
744  'Text with script <script>alert(\'foo\');</script> and text after it',
745  'Text with script <script>alert(\'foo\');</script> and...',
746  $charset
747  ),
748  ));
749  }
750  return $data;
751  }
752 
763  public function cropHtmlWithDataProvider($settings, $subject, $expected, $charset)
764  {
765  $this->handleCharset($charset, $subject, $expected);
766  $this->assertEquals($expected, $this->subject->cropHTML($subject, $settings), 'cropHTML failed with settings: "' . $settings . '" and charset "' . $charset . '"');
767  }
768 
776  {
777  $GLOBALS['TSFE']->renderCharset = 'iso-8859-1';
778  $input =
779  '<h1>Blog Example</h1>' . LF .
780  '<hr>' . LF .
781  '<div class="csc-header csc-header-n1">' . LF .
782  ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
783  '</div>' . LF .
784  '<p class="bodytext">' . LF .
785  ' A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.' . LF .
786  '</p>' . LF .
787  '<div class="tx-blogexample-list-container">' . LF .
788  ' <p class="bodytext">' . LF .
789  ' Below are the most recent posts:' . LF .
790  ' </p>' . LF .
791  ' <ul>' . LF .
792  ' <li data-element="someId">' . LF .
793  ' <h3>' . LF .
794  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Post #1</a>' . LF .
795  ' </h3>' . LF .
796  ' <p class="bodytext">' . LF .
797  ' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...' . LF .
798  ' </p>' . LF .
799  ' <p class="metadata">' . LF .
800  ' Published on 26.08.2009 by Jochen Rau' . LF .
801  ' </p>' . LF .
802  ' <p>' . LF .
803  ' Tags: [MVC]&nbsp;[Domain Driven Design]&nbsp;<br>' . LF .
804  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>' . LF .
805  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>' . LF .
806  ' </p>' . LF .
807  ' </li>' . LF .
808  ' </ul>' . LF .
809  ' <p>' . LF .
810  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>' . LF .
811  ' </p>' . LF .
812  '</div>' . LF .
813  '<hr>' . LF .
814  '<p>' . LF .
815  ' ? TYPO3 Association' . LF .
816  '</p>';
817 
818  $result = $this->subject->cropHTML($input, '300');
819 
820  $expected =
821  '<h1>Blog Example</h1>' . LF .
822  '<hr>' . LF .
823  '<div class="csc-header csc-header-n1">' . LF .
824  ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
825  '</div>' . LF .
826  '<p class="bodytext">' . LF .
827  ' A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.' . LF .
828  '</p>' . LF .
829  '<div class="tx-blogexample-list-container">' . LF .
830  ' <p class="bodytext">' . LF .
831  ' Below are the most recent posts:' . LF .
832  ' </p>' . LF .
833  ' <ul>' . LF .
834  ' <li data-element="someId">' . LF .
835  ' <h3>' . LF .
836  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Post</a></h3></li></ul></div>';
837 
838  $this->assertEquals($expected, $result);
839 
840  $result = $this->subject->cropHTML($input, '-100');
841 
842  $expected =
843  '<div class="tx-blogexample-list-container"><ul><li data-element="someId"><p> Design]&nbsp;<br>' . LF .
844  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>' . LF .
845  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>' . LF .
846  ' </p>' . LF .
847  ' </li>' . LF .
848  ' </ul>' . LF .
849  ' <p>' . LF .
850  ' <a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>' . LF .
851  ' </p>' . LF .
852  '</div>' . LF .
853  '<hr>' . LF .
854  '<p>' . LF .
855  ' ? TYPO3 Association' . LF .
856  '</p>';
857 
858  $this->assertEquals($expected, $result);
859  }
860 
866  public function cropHtmlWorksWithLinebreaks()
867  {
868  $subject = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";
869  $expected = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna";
870  $result = $this->subject->cropHTML($subject, '121');
871  $this->assertEquals($expected, $result);
872  }
873 
877  public function stdWrap_roundDataProvider()
878  {
879  return array(
880  'rounding off without any configuration' => array(
881  1.123456789,
882  array(),
883  1
884  ),
885  'rounding up without any configuration' => array(
886  1.523456789,
887  array(),
888  2
889  ),
890  'regular rounding (off) to two decimals' => array(
891  0.123456789,
892  array(
893  'decimals' => 2
894  ),
895  0.12
896  ),
897  'regular rounding (up) to two decimals' => array(
898  0.1256789,
899  array(
900  'decimals' => 2
901  ),
902  0.13
903  ),
904  'rounding up to integer with type ceil' => array(
905  0.123456789,
906  array(
907  'roundType' => 'ceil'
908  ),
909  1
910  ),
911  'rounding down to integer with type floor' => array(
912  2.3481,
913  array(
914  'roundType' => 'floor'
915  ),
916  2
917  )
918  );
919  }
920 
931  public function stdWrap_round($float, $conf, $expected)
932  {
933  $conf = array(
934  'round.' => $conf
935  );
936  $result = $this->subject->stdWrap_round($float, $conf);
937  $this->assertEquals($expected, $result);
938  }
939 
944  {
945  return array(
946  'testing decimals' => array(
947  0.8,
948  array(
949  'numberFormat.' => array(
950  'decimals' => 2
951  ),
952  ),
953  '0.80'
954  ),
955  'testing decimals with input as string' => array(
956  '0.8',
957  array(
958  'numberFormat.' => array(
959  'decimals' => 2
960  ),
961  ),
962  '0.80'
963  ),
964  'testing dec_point' => array(
965  0.8,
966  array(
967  'numberFormat.' => array(
968  'decimals' => 1,
969  'dec_point' => ','
970  ),
971  ),
972  '0,8'
973  ),
974  'testing thousands_sep' => array(
975  999.99,
976  array(
977  'numberFormat.' => array(
978  'decimals' => 0,
979  'thousands_sep.' => array(
980  'char' => 46
981  ),
982  ),
983  ),
984  '1.000'
985  ),
986  'testing mixture' => array(
987  1281731.45,
988  array(
989  'numberFormat.' => array(
990  'decimals' => 1,
991  'dec_point.' => array(
992  'char' => 44
993  ),
994  'thousands_sep.' => array(
995  'char' => 46
996  ),
997  ),
998  ),
999  '1.281.731,5'
1000  )
1001  );
1002  }
1003 
1014  public function stdWrap_numberFormat($float, $conf, $expected)
1015  {
1016  $result = $this->subject->stdWrap_numberFormat($float, $conf);
1017  $this->assertEquals($expected, $result);
1018  }
1019 
1024  {
1025  return array(
1026  'numbers' => array(
1027  '1,2,3',
1028  '1,2,3',
1029  ),
1030  'range' => array(
1031  '3-5',
1032  '3,4,5',
1033  ),
1034  'numbers and range' => array(
1035  '1,3-5,7',
1036  '1,3,4,5,7',
1037  ),
1038  );
1039  }
1040 
1050  public function stdWrap_expandList($content, $expected)
1051  {
1052  $result = $this->subject->stdWrap_expandList($content);
1053  $this->assertEquals($expected, $result);
1054  }
1055 
1059  public function stdWrap_trimDataProvider()
1060  {
1061  return array(
1062  'trimstring' => array(
1063  'trimstring',
1064  'trimstring',
1065  ),
1066  'trim string with space inside' => array(
1067  'trim string',
1068  'trim string',
1069  ),
1070  'trim string with space at the begin and end' => array(
1071  ' trim string ',
1072  'trim string',
1073  ),
1074  );
1075  }
1076 
1086  public function stdWrap_trim($content, $expected)
1087  {
1088  $result = $this->subject->stdWrap_trim($content);
1089  $this->assertEquals($expected, $result);
1090  }
1091 
1095  public function stdWrap_intvalDataProvider()
1096  {
1097  return array(
1098  'number' => array(
1099  '123',
1100  123,
1101  ),
1102  'float' => array(
1103  '123.45',
1104  123,
1105  ),
1106  'string' => array(
1107  'string',
1108  0,
1109  ),
1110  'zero' => array(
1111  '0',
1112  0,
1113  ),
1114  'empty' => array(
1115  '',
1116  0,
1117  ),
1118  'NULL' => array(
1119  null,
1120  0,
1121  ),
1122  'bool TRUE' => array(
1123  true,
1124  1,
1125  ),
1126  'bool FALSE' => array(
1127  false,
1128  0,
1129  ),
1130  );
1131  }
1132 
1142  public function stdWrap_intval($content, $expected)
1143  {
1144  $result = $this->subject->stdWrap_intval($content);
1145  $this->assertEquals($expected, $result);
1146  }
1147 
1151  public function stdWrap_strPadDataProvider()
1152  {
1153  return array(
1154  'pad string with default settings and length 10' => array(
1155  'Alien',
1156  array(
1157  'length' => '10',
1158  ),
1159  'Alien ',
1160  ),
1161  'pad string with padWith -= and type left and length 10' => array(
1162  'Alien',
1163  array(
1164  'length' => '10',
1165  'padWith' => '-=',
1166  'type' => 'left',
1167  ),
1168  '-=-=-Alien',
1169  ),
1170  'pad string with padWith _ and type both and length 10' => array(
1171  'Alien',
1172  array(
1173  'length' => '10',
1174  'padWith' => '_',
1175  'type' => 'both',
1176  ),
1177  '__Alien___',
1178  ),
1179  'pad string with padWith 0 and type both and length 10' => array(
1180  'Alien',
1181  array(
1182  'length' => '10',
1183  'padWith' => '0',
1184  'type' => 'both',
1185  ),
1186  '00Alien000',
1187  ),
1188  'pad string with padWith ___ and type both and length 6' => array(
1189  'Alien',
1190  array(
1191  'length' => '6',
1192  'padWith' => '___',
1193  'type' => 'both',
1194  ),
1195  'Alien_',
1196  ),
1197  'pad string with padWith _ and type both and length 12, using stdWrap for length' => array(
1198  'Alien',
1199  array(
1200  'length' => '1',
1201  'length.' => array(
1202  'wrap' => '|2',
1203  ),
1204  'padWith' => '_',
1205  'type' => 'both',
1206  ),
1207  '___Alien____',
1208  ),
1209  'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => array(
1210  'Alien',
1211  array(
1212  'length' => '12',
1213  'padWith' => '_',
1214  'padWith.' => array(
1215  'wrap' => '-|=',
1216  ),
1217  'type' => 'both',
1218  ),
1219  '-_=Alien-_=-',
1220  ),
1221  'pad string with padWith _ and type both and length 12, using stdWrap for type' => array(
1222  'Alien',
1223  array(
1224  'length' => '12',
1225  'padWith' => '_',
1226  'type' => 'both',
1227  // make type become "left"
1228  'type.' => array(
1229  'substring' => '2,1',
1230  'wrap' => 'lef|',
1231  ),
1232  ),
1233  '_______Alien',
1234  ),
1235  );
1236  }
1237 
1248  public function stdWrap_strPad($content, $conf, $expected)
1249  {
1250  $conf = array(
1251  'strPad.' => $conf
1252  );
1253  $result = $this->subject->stdWrap_strPad($content, $conf);
1254  $this->assertEquals($expected, $result);
1255  }
1256 
1263  public function hashDataProvider()
1264  {
1265  $data = array(
1266  'testing md5' => array(
1267  'joh316',
1268  array(
1269  'hash' => 'md5'
1270  ),
1271  'bacb98acf97e0b6112b1d1b650b84971'
1272  ),
1273  'testing sha1' => array(
1274  'joh316',
1275  array(
1276  'hash' => 'sha1'
1277  ),
1278  '063b3d108bed9f88fa618c6046de0dccadcf3158'
1279  ),
1280  'testing non-existing hashing algorithm' => array(
1281  'joh316',
1282  array(
1283  'hash' => 'non-existing'
1284  ),
1285  ''
1286  ),
1287  'testing stdWrap capability' => array(
1288  'joh316',
1289  array(
1290  'hash.' => array(
1291  'cObject' => 'TEXT',
1292  'cObject.' => array(
1293  'value' => 'md5'
1294  )
1295  )
1296  ),
1297  'bacb98acf97e0b6112b1d1b650b84971'
1298  )
1299  );
1300  return $data;
1301  }
1302 
1313  public function stdWrap_hash($text, array $conf, $expected)
1314  {
1315  $result = $this->subject->stdWrap_hash($text, $conf);
1316  $this->assertEquals($expected, $result);
1317  }
1318 
1323  {
1324  $stdWrapConfiguration = array(
1325  'noTrimWrap' => '|| 123|',
1326  'stdWrap.' => array(
1327  'wrap' => '<b>|</b>'
1328  )
1329  );
1330  $this->assertSame(
1331  '<b>Test</b> 123',
1332  $this->subject->stdWrap('Test', $stdWrapConfiguration)
1333  );
1334  }
1335 
1340  {
1341  $stdWrapConfiguration = array(
1342  'append' => 'TEXT',
1343  'append.' => array(
1344  'data' => 'register:Counter'
1345  ),
1346  'stdWrap.' => array(
1347  'append' => 'LOAD_REGISTER',
1348  'append.' => array(
1349  'Counter.' => array(
1350  'prioriCalc' => 'intval',
1351  'cObject' => 'TEXT',
1352  'cObject.' => array(
1353  'data' => 'register:Counter',
1354  'wrap' => '|+1',
1355  )
1356  )
1357  )
1358  )
1359  );
1360  $this->assertSame(
1361  'Counter:1',
1362  $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
1363  );
1364  }
1365 
1372  public function numberFormatDataProvider()
1373  {
1374  $data = array(
1375  'testing decimals' => array(
1376  0.8,
1377  array(
1378  'decimals' => 2
1379  ),
1380  '0.80'
1381  ),
1382  'testing decimals with input as string' => array(
1383  '0.8',
1384  array(
1385  'decimals' => 2
1386  ),
1387  '0.80'
1388  ),
1389  'testing dec_point' => array(
1390  0.8,
1391  array(
1392  'decimals' => 1,
1393  'dec_point' => ','
1394  ),
1395  '0,8'
1396  ),
1397  'testing thousands_sep' => array(
1398  999.99,
1399  array(
1400  'decimals' => 0,
1401  'thousands_sep.' => array(
1402  'char' => 46
1403  )
1404  ),
1405  '1.000'
1406  ),
1407  'testing mixture' => array(
1408  1281731.45,
1409  array(
1410  'decimals' => 1,
1411  'dec_point.' => array(
1412  'char' => 44
1413  ),
1414  'thousands_sep.' => array(
1415  'char' => 46
1416  )
1417  ),
1418  '1.281.731,5'
1419  )
1420  );
1421  return $data;
1422  }
1423 
1430  public function numberFormat($float, $formatConf, $expected)
1431  {
1432  $result = $this->subject->numberFormat($float, $formatConf);
1433  $this->assertEquals($expected, $result);
1434  }
1435 
1442  public function replacementDataProvider()
1443  {
1444  $data = array(
1445  'multiple replacements, including regex' => array(
1446  'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
1447  array(
1448  'replacement.' => array(
1449  '120.' => array(
1450  'search' => 'in da hood',
1451  'replace' => 'around the block'
1452  ),
1453  '20.' => array(
1454  'search' => '_',
1455  'replace.' => array('char' => '32')
1456  ),
1457  '130.' => array(
1458  'search' => '#a (Cat|Dog|Tiger)#i',
1459  'replace' => 'an animal',
1460  'useRegExp' => '1'
1461  )
1462  )
1463  ),
1464  'There is an animal, an animal and an animal around the block! Yeah!'
1465  ),
1466  'replacement with optionSplit, normal pattern' => array(
1467  'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
1468  array(
1469  'replacement.' => array(
1470  '10.' => array(
1471  'search' => '_',
1472  'replace' => '1 || 2 || 3',
1473  'useOptionSplitReplace' => '1'
1474  ),
1475  )
1476  ),
1477  'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!'
1478  ),
1479  'replacement with optionSplit, using regex' => array(
1480  'There is a cat, a dog and a tiger in da hood! Yeah!',
1481  array(
1482  'replacement.' => array(
1483  '10.' => array(
1484  'search' => '#(a) (Cat|Dog|Tiger)#i',
1485  'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
1486  'useOptionSplitReplace' => '1',
1487  'useRegExp' => '1'
1488  )
1489  )
1490  ),
1491  'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!'
1492  ),
1493  );
1494  return $data;
1495  }
1496 
1503  public function replacement($input, $conf, $expected)
1504  {
1505  $result = $this->subject->stdWrap_replacement($input, $conf);
1506  $this->assertEquals($expected, $result);
1507  }
1508 
1515  public function getQueryDataProvider()
1516  {
1517  $data = array(
1518  'testing empty conf' => array(
1519  'tt_content',
1520  array(),
1521  array(
1522  'SELECT' => '*'
1523  )
1524  ),
1525  'testing #17284: adding uid/pid for workspaces' => array(
1526  'tt_content',
1527  array(
1528  'selectFields' => 'header,bodytext'
1529  ),
1530  array(
1531  'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
1532  )
1533  ),
1534  'testing #17284: no need to add' => array(
1535  'tt_content',
1536  array(
1537  'selectFields' => 'tt_content.*'
1538  ),
1539  array(
1540  'SELECT' => 'tt_content.*'
1541  )
1542  ),
1543  'testing #17284: no need to add #2' => array(
1544  'tt_content',
1545  array(
1546  'selectFields' => '*'
1547  ),
1548  array(
1549  'SELECT' => '*'
1550  )
1551  ),
1552  'testing #29783: joined tables, prefix tablename' => array(
1553  'tt_content',
1554  array(
1555  'selectFields' => 'tt_content.header,be_users.username',
1556  'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
1557  ),
1558  array(
1559  'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
1560  )
1561  ),
1562  'testing #34152: single count(*), add nothing' => array(
1563  'tt_content',
1564  array(
1565  'selectFields' => 'count(*)'
1566  ),
1567  array(
1568  'SELECT' => 'count(*)'
1569  )
1570  ),
1571  'testing #34152: single max(crdate), add nothing' => array(
1572  'tt_content',
1573  array(
1574  'selectFields' => 'max(crdate)'
1575  ),
1576  array(
1577  'SELECT' => 'max(crdate)'
1578  )
1579  ),
1580  'testing #34152: single min(crdate), add nothing' => array(
1581  'tt_content',
1582  array(
1583  'selectFields' => 'min(crdate)'
1584  ),
1585  array(
1586  'SELECT' => 'min(crdate)'
1587  )
1588  ),
1589  'testing #34152: single sum(is_siteroot), add nothing' => array(
1590  'tt_content',
1591  array(
1592  'selectFields' => 'sum(is_siteroot)'
1593  ),
1594  array(
1595  'SELECT' => 'sum(is_siteroot)'
1596  )
1597  ),
1598  'testing #34152: single avg(crdate), add nothing' => array(
1599  'tt_content',
1600  array(
1601  'selectFields' => 'avg(crdate)'
1602  ),
1603  array(
1604  'SELECT' => 'avg(crdate)'
1605  )
1606  )
1607  );
1608  return $data;
1609  }
1610 
1617  public function getQuery($table, $conf, $expected)
1618  {
1619  $GLOBALS['TCA'] = array(
1620  'pages' => array(
1621  'ctrl' => array(
1622  'enablecolumns' => array(
1623  'disabled' => 'hidden'
1624  )
1625  )
1626  ),
1627  'tt_content' => array(
1628  'ctrl' => array(
1629  'enablecolumns' => array(
1630  'disabled' => 'hidden'
1631  ),
1632  'versioningWS' => true
1633  )
1634  ),
1635  );
1636  $result = $this->subject->getQuery($table, $conf, true);
1637  foreach ($expected as $field => $value) {
1638  $this->assertEquals($value, $result[$field]);
1639  }
1640  }
1641 
1646  {
1647  $GLOBALS['TCA'] = array(
1648  'pages' => array(
1649  'ctrl' => array(
1650  'enablecolumns' => array(
1651  'disabled' => 'hidden'
1652  )
1653  )
1654  ),
1655  'tt_content' => array(
1656  'ctrl' => array(
1657  'enablecolumns' => array(
1658  'disabled' => 'hidden'
1659  )
1660  )
1661  ),
1662  );
1663  $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
1664  $this->subject->start(array(), 'tt_content');
1665  $conf = array(
1666  'recursive' => '15',
1667  'pidInList' => '16, -35'
1668  );
1669  $this->subject->expects($this->at(0))
1670  ->method('getTreeList')
1671  ->with(-16, 15)
1672  ->will($this->returnValue('15,16'));
1673  $this->subject->expects($this->at(1))
1674  ->method('getTreeList')
1675  ->with(-35, 15)
1676  ->will($this->returnValue('15,35'));
1677  $this->subject->getQuery('tt_content', $conf, true);
1678  }
1679 
1684  {
1685  $GLOBALS['TCA'] = array(
1686  'pages' => array(
1687  'ctrl' => array(
1688  'enablecolumns' => array(
1689  'disabled' => 'hidden'
1690  )
1691  )
1692  ),
1693  'tt_content' => array(
1694  'ctrl' => array(
1695  'enablecolumns' => array(
1696  'disabled' => 'hidden'
1697  )
1698  )
1699  ),
1700  );
1701  $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
1702  $GLOBALS['TSFE']->id = 27;
1703  $this->subject->start(array(), 'tt_content');
1704  $conf = array(
1705  'pidInList' => 'this',
1706  'recursive' => '4'
1707  );
1708  $this->subject->expects($this->once())
1709  ->method('getTreeList')
1710  ->with(-27)
1711  ->will($this->returnValue('27'));
1712  $this->subject->getQuery('tt_content', $conf, true);
1713  }
1714 
1721  public function stdWrap_dateDataProvider()
1722  {
1723  return array(
1724  'given timestamp' => array(
1725  1443780000, // This is 2015-10-02 12:00
1726  array(
1727  'date' => 'd.m.Y',
1728  ),
1729  '02.10.2015',
1730  ),
1731  'empty string' => array(
1732  '',
1733  array(
1734  'date' => 'd.m.Y',
1735  ),
1736  '02.10.2015',
1737  ),
1738  'testing null' => array(
1739  null,
1740  array(
1741  'date' => 'd.m.Y',
1742  ),
1743  '02.10.2015',
1744  ),
1745  'given timestamp return GMT' => array(
1746  1443780000, // This is 2015-10-02 12:00
1747  array(
1748  'date' => 'd.m.Y H:i:s',
1749  'date.' => array(
1750  'GMT' => true,
1751  )
1752  ),
1753  '02.10.2015 10:00:00',
1754  ),
1755  );
1756  }
1757 
1765  public function stdWrap_date($content, $conf, $expected)
1766  {
1767  // Set exec_time to a hard timestamp
1768  $GLOBALS['EXEC_TIME'] = 1443780000;
1769 
1770  $result = $this->subject->stdWrap_date($content, $conf);
1771 
1772  $this->assertEquals($expected, $result);
1773  }
1774 
1782  {
1783  $data = array(
1784  'given timestamp' => array(
1785  1346500800, // This is 2012-09-01 12:00 in UTC/GMT
1786  array(
1787  'strftime' => '%d-%m-%Y',
1788  ),
1789  ),
1790  'empty string' => array(
1791  '',
1792  array(
1793  'strftime' => '%d-%m-%Y',
1794  ),
1795  ),
1796  'testing null' => array(
1797  null,
1798  array(
1799  'strftime' => '%d-%m-%Y',
1800  ),
1801  ),
1802  );
1803  return $data;
1804  }
1805 
1810  public function stdWrap_strftimeReturnsFormattedString($content, $conf)
1811  {
1812  // Set exec_time to a hard timestamp
1813  $GLOBALS['EXEC_TIME'] = 1346500800;
1814  // Save current timezone and set to UTC to make the system under test behave
1815  // the same in all server timezone settings
1816  $timezoneBackup = date_default_timezone_get();
1817  date_default_timezone_set('UTC');
1818 
1819  $result = $this->subject->stdWrap_strftime($content, $conf);
1820 
1821  // Reset timezone
1822  date_default_timezone_set($timezoneBackup);
1823 
1824  $this->assertEquals('01-09-2012', $result);
1825  }
1826 
1834  {
1835  return array(
1836  'date from content' => array(
1837  '2014-12-04',
1838  array(
1839  'strtotime' => '1',
1840  ),
1841  1417651200,
1842  ),
1843  'manipulation of date from content' => array(
1844  '2014-12-04',
1845  array(
1846  'strtotime' => '+ 2 weekdays',
1847  ),
1848  1417996800,
1849  ),
1850  'date from configuration' => array(
1851  '',
1852  array(
1853  'strtotime' => '2014-12-04',
1854  ),
1855  1417651200,
1856  ),
1857  'manipulation of date from configuration' => array(
1858  '',
1859  array(
1860  'strtotime' => '2014-12-04 + 2 weekdays',
1861  ),
1862  1417996800,
1863  ),
1864  'empty input' => array(
1865  '',
1866  array(
1867  'strtotime' => '1',
1868  ),
1869  false,
1870  ),
1871  'date from content and configuration' => array(
1872  '2014-12-04',
1873  array(
1874  'strtotime' => '2014-12-05',
1875  ),
1876  false,
1877  ),
1878  );
1879  }
1880 
1888  public function stdWrap_strtotimeReturnsTimestamp($content, $configuration, $expected)
1889  {
1890  // Set exec_time to a hard timestamp
1891  $GLOBALS['EXEC_TIME'] = 1417392000;
1892  // Save current timezone and set to UTC to make the system under test behave
1893  // the same in all server timezone settings
1894  $timezoneBackup = date_default_timezone_get();
1895  date_default_timezone_set('UTC');
1896 
1897  $result = $this->subject->stdWrap_strtotime($content, $configuration);
1898 
1899  // Reset timezone
1900  date_default_timezone_set($timezoneBackup);
1901 
1902  $this->assertEquals($expected, $result);
1903  }
1904 
1909  {
1910  $subject = $this->getMock(
1911  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
1912  array('calcAge')
1913  );
1914  // Set exec_time to a hard timestamp
1915  $GLOBALS['EXEC_TIME'] = 10;
1916  $subject->expects($this->once())->method('calcAge')->with(1, 'Min| Hrs| Days| Yrs');
1917  $subject->stdWrap_age(9, array('age' => 'Min| Hrs| Days| Yrs'));
1918  }
1919 
1927  {
1928  return array(
1929  'minutes' => array(
1930  120,
1931  ' min| hrs| days| yrs',
1932  '2 min',
1933  ),
1934  'hours' => array(
1935  7200,
1936  ' min| hrs| days| yrs',
1937  '2 hrs',
1938  ),
1939  'days' => array(
1940  604800,
1941  ' min| hrs| days| yrs',
1942  '7 days',
1943  ),
1944  'day with provided singular labels' => array(
1945  86400,
1946  ' min| hrs| days| yrs| min| hour| day| year',
1947  '1 day',
1948  ),
1949  'years' => array(
1950  1417997800,
1951  ' min| hrs| days| yrs',
1952  '45 yrs',
1953  ),
1954  'different labels' => array(
1955  120,
1956  ' Minutes| Hrs| Days| Yrs',
1957  '2 Minutes',
1958  ),
1959  'negative values' => array(
1960  -604800,
1961  ' min| hrs| days| yrs',
1962  '-7 days',
1963  ),
1964  'default label values for wrong label input' => array(
1965  121,
1966  10,
1967  '2 min',
1968  ),
1969  'default singular label values for wrong label input' => array(
1970  31536000,
1971  10,
1972  '1 year',
1973  )
1974  );
1975  }
1976 
1984  public function calcAgeCalculatesAgeOfTimestamp($timestamp, $labels, $expectation)
1985  {
1986  $result = $this->subject->calcAge($timestamp, $labels);
1987  $this->assertEquals($result, $expectation);
1988  }
1989 
1995  public function stdWrap_caseDataProvider()
1996  {
1997  return array(
1998  'lower case text to upper' => array(
1999  '<span>text</span>',
2000  array(
2001  'case' => 'upper',
2002  ),
2003  '<span>TEXT</span>',
2004  ),
2005  'upper case text to lower' => array(
2006  '<span>TEXT</span>',
2007  array(
2008  'case' => 'lower',
2009  ),
2010  '<span>text</span>',
2011  ),
2012  'capitalize text' => array(
2013  '<span>this is a text</span>',
2014  array(
2015  'case' => 'capitalize',
2016  ),
2017  '<span>This Is A Text</span>',
2018  ),
2019  'ucfirst text' => array(
2020  '<span>this is a text</span>',
2021  array(
2022  'case' => 'ucfirst',
2023  ),
2024  '<span>This is a text</span>',
2025  ),
2026  'lcfirst text' => array(
2027  '<span>This is a Text</span>',
2028  array(
2029  'case' => 'lcfirst',
2030  ),
2031  '<span>this is a Text</span>',
2032  ),
2033  'uppercamelcase text' => array(
2034  '<span>this_is_a_text</span>',
2035  array(
2036  'case' => 'uppercamelcase',
2037  ),
2038  '<span>ThisIsAText</span>',
2039  ),
2040  'lowercamelcase text' => array(
2041  '<span>this_is_a_text</span>',
2042  array(
2043  'case' => 'lowercamelcase',
2044  ),
2045  '<span>thisIsAText</span>',
2046  ),
2047  );
2048  }
2049 
2057  public function stdWrap_case($content, array $configuration, $expected)
2058  {
2059  $result = $this->subject->stdWrap_case($content, $configuration);
2060  $this->assertEquals($expected, $result);
2061  }
2062 
2069  {
2070  return array(
2071  'only key returns value' => array(
2072  'ifNull',
2073  array(
2074  'ifNull' => '1',
2075  ),
2076  '',
2077  '1',
2078  ),
2079  'array without key returns empty string' => array(
2080  'ifNull',
2081  array(
2082  'ifNull.' => '1',
2083  ),
2084  '',
2085  '',
2086  ),
2087  'array without key returns default' => array(
2088  'ifNull',
2089  array(
2090  'ifNull.' => '1',
2091  ),
2092  'default',
2093  'default',
2094  ),
2095  'non existing key returns default' => array(
2096  'ifNull',
2097  array(
2098  'noTrimWrap' => 'test',
2099  'noTrimWrap.' => '1',
2100  ),
2101  'default',
2102  'default',
2103  ),
2104  'existing key and array returns stdWrap' => array(
2105  'test',
2106  array(
2107  'test' => 'value',
2108  'test.' => array('case' => 'upper'),
2109  ),
2110  'default',
2111  'VALUE'
2112  ),
2113  );
2114  }
2115 
2124  public function stdWrap_stdWrapValue($key, array $configuration, $defaultValue, $expected)
2125  {
2126  $result = $this->subject->stdWrapValue($key, $configuration, $defaultValue);
2127  $this->assertEquals($expected, $result);
2128  }
2129 
2137  public function stdWrap_ifNullDeterminesNullValues($content, array $configuration, $expected)
2138  {
2139  $result = $this->subject->stdWrap_ifNull($content, $configuration);
2140  $this->assertEquals($expected, $result);
2141  }
2142 
2149  {
2150  return array(
2151  'null value' => array(
2152  null,
2153  array(
2154  'ifNull' => '1',
2155  ),
2156  '1',
2157  ),
2158  'zero value' => array(
2159  '0',
2160  array(
2161  'ifNull' => '1',
2162  ),
2163  '0',
2164  ),
2165  );
2166  }
2167 
2174  {
2175  return array(
2176  'null value' => array(
2177  null,
2178  array(
2179  'ifEmpty' => '1',
2180  ),
2181  '1',
2182  ),
2183  'empty value' => array(
2184  '',
2185  array(
2186  'ifEmpty' => '1',
2187  ),
2188  '1',
2189  ),
2190  'string value' => array(
2191  'string',
2192  array(
2193  'ifEmpty' => '1',
2194  ),
2195  'string',
2196  ),
2197  'empty string value' => array(
2198  ' ',
2199  array(
2200  'ifEmpty' => '1',
2201  ),
2202  '1',
2203  ),
2204  );
2205  }
2206 
2214  public function stdWrap_ifEmptyDeterminesEmptyValues($content, array $configuration, $expected)
2215  {
2216  $result = $this->subject->stdWrap_ifEmpty($content, $configuration);
2217  $this->assertEquals($expected, $result);
2218  }
2219 
2227  public function stdWrap_noTrimWrapAcceptsSplitChar($content, array $configuration, $expected)
2228  {
2229  $result = $this->subject->stdWrap_noTrimWrap($content, $configuration);
2230  $this->assertEquals($expected, $result);
2231  }
2232 
2239  {
2240  return array(
2241  'No char given' => array(
2242  'middle',
2243  array(
2244  'noTrimWrap' => '| left | right |',
2245  ),
2246  ' left middle right '
2247  ),
2248  'Zero char given' => array(
2249  'middle',
2250  array(
2251  'noTrimWrap' => '0 left 0 right 0',
2252  'noTrimWrap.' => array('splitChar' => '0'),
2253 
2254  ),
2255  ' left middle right '
2256  ),
2257  'Default char given' => array(
2258  'middle',
2259  array(
2260  'noTrimWrap' => '| left | right |',
2261  'noTrimWrap.' => array('splitChar' => '|'),
2262  ),
2263  ' left middle right '
2264  ),
2265  'Split char is a' => array(
2266  'middle',
2267  array(
2268  'noTrimWrap' => 'a left a right a',
2269  'noTrimWrap.' => array('splitChar' => 'a'),
2270  ),
2271  ' left middle right '
2272  ),
2273  'Split char is multi-char (ab)' => array(
2274  'middle',
2275  array(
2276  'noTrimWrap' => 'ab left ab right ab',
2277  'noTrimWrap.' => array('splitChar' => 'ab'),
2278  ),
2279  ' left middle right '
2280  ),
2281  'Split char accepts stdWrap' => array(
2282  'middle',
2283  array(
2284  'noTrimWrap' => 'abc left abc right abc',
2285  'noTrimWrap.' => array(
2286  'splitChar' => 'b',
2287  'splitChar.' => array('wrap' => 'a|c'),
2288  ),
2289  ),
2290  ' left middle right '
2291  ),
2292  );
2293  }
2294 
2301  public function stdWrap_addPageCacheTagsAddsPageTags(array $expectedTags, array $configuration)
2302  {
2303  $this->subject->stdWrap_addPageCacheTags('', $configuration);
2304  $this->assertEquals($expectedTags, $this->typoScriptFrontendControllerMock->_get('pageCacheTags'));
2305  }
2306 
2311  {
2312  return array(
2313  'No Tag' => array(
2314  array(),
2315  array('addPageCacheTags' => ''),
2316  ),
2317  'Two expectedTags' => array(
2318  array('tag1', 'tag2'),
2319  array('addPageCacheTags' => 'tag1,tag2'),
2320  ),
2321  'Two expectedTags plus one with stdWrap' => array(
2322  array('tag1', 'tag2', 'tag3'),
2323  array(
2324  'addPageCacheTags' => 'tag1,tag2',
2325  'addPageCacheTags.' => array('wrap' => '|,tag3')
2326  ),
2327  ),
2328  );
2329  }
2330 
2338  {
2339  return array(
2340  'double quote in string' => array(
2341  'double quote"',
2342  array(),
2343  '\'double\u0020quote\u0022\''
2344  ),
2345  'backslash in string' => array(
2346  'backslash \\',
2347  array(),
2348  '\'backslash\u0020\u005C\''
2349  ),
2350  'exclamation mark' => array(
2351  'exclamation!',
2352  array(),
2353  '\'exclamation\u0021\''
2354  ),
2355  'whitespace tab, newline and carriage return' => array(
2356  "white\tspace\ns\r",
2357  array(),
2358  '\'white\u0009space\u000As\u000D\''
2359  ),
2360  'single quote in string' => array(
2361  'single quote \'',
2362  array(),
2363  '\'single\u0020quote\u0020\u0027\''
2364  ),
2365  'tag' => array(
2366  '<tag>',
2367  array(),
2368  '\'\u003Ctag\u003E\''
2369  ),
2370  'ampersand in string' => array(
2371  'amper&sand',
2372  array(),
2373  '\'amper\u0026sand\''
2374  ),
2375  );
2376  }
2377 
2384  public function stdWrap_encodeForJavaScriptValue($input, $conf, $expected)
2385  {
2386  $result = $this->subject->stdWrap_encodeForJavaScriptValue($input, $conf);
2387  $this->assertEquals($expected, $result);
2388  }
2389 
2390 
2392  // Tests concerning getData()
2394 
2399  {
2400  return array(
2401  'Value in get-data' => array('onlyInGet', 'GetValue'),
2402  'Value in post-data' => array('onlyInPost', 'PostValue'),
2403  'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
2404  );
2405  }
2406 
2413  public function getDataWithTypeGp($key, $expectedValue)
2414  {
2415  $_GET = array(
2416  'onlyInGet' => 'GetValue',
2417  'inGetAndPost' => 'ValueInGet',
2418  );
2419  $_POST = array(
2420  'onlyInPost' => 'PostValue',
2421  'inGetAndPost' => 'ValueInPost',
2422  );
2423  $this->assertEquals($expectedValue, $this->subject->getData('gp:' . $key));
2424  }
2425 
2431  public function getDataWithTypeTsfe()
2432  {
2433  $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->subject->getData('tsfe:renderCharset'));
2434  }
2435 
2441  public function getDataWithTypeGetenv()
2442  {
2443  $envName = $this->getUniqueId('frontendtest');
2444  $value = $this->getUniqueId('someValue');
2445  putenv($envName . '=' . $value);
2446  $this->assertEquals($value, $this->subject->getData('getenv:' . $envName));
2447  }
2448 
2454  public function getDataWithTypeGetindpenv()
2455  {
2456  $this->subject->expects($this->once())->method('getEnvironmentVariable')
2457  ->with($this->equalTo('SCRIPT_FILENAME'))->will($this->returnValue('dummyPath'));
2458  $this->assertEquals('dummyPath', $this->subject->getData('getindpenv:SCRIPT_FILENAME'));
2459  }
2460 
2466  public function getDataWithTypeField()
2467  {
2468  $key = 'someKey';
2469  $value = 'someValue';
2470  $field = array($key => $value);
2471 
2472  $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
2473  }
2474 
2482  {
2483  $key = 'somekey|level1|level2';
2484  $value = 'somevalue';
2485  $field = array('somekey' => array('level1' => array('level2' => 'somevalue')));
2486 
2487  $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
2488  }
2489 
2496  {
2497  $uid = $this->getUniqueId();
2498  $file = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, array(), array(), '', false);
2499  $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
2500  $this->subject->setCurrentFile($file);
2501  $this->assertEquals($uid, $this->subject->getData('file:current:uid'));
2502  }
2503 
2509  public function getDataWithTypeParameters()
2510  {
2511  $key = $this->getUniqueId('someKey');
2512  $value = $this->getUniqueId('someValue');
2513  $this->subject->parameters[$key] = $value;
2514 
2515  $this->assertEquals($value, $this->subject->getData('parameters:' . $key));
2516  }
2517 
2523  public function getDataWithTypeRegister()
2524  {
2525  $key = $this->getUniqueId('someKey');
2526  $value = $this->getUniqueId('someValue');
2527  $GLOBALS['TSFE']->register[$key] = $value;
2528 
2529  $this->assertEquals($value, $this->subject->getData('register:' . $key));
2530  }
2531 
2537  public function getDataWithTypeLevel()
2538  {
2539  $rootline = array(
2540  0 => array('uid' => 1, 'title' => 'title1'),
2541  1 => array('uid' => 2, 'title' => 'title2'),
2542  2 => array('uid' => 3, 'title' => 'title3'),
2543  );
2544 
2545  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2546  $this->assertEquals(2, $this->subject->getData('level'));
2547  }
2548 
2554  public function getDataWithTypeGlobal()
2555  {
2556  $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->subject->getData('global:TSFE|renderCharset'));
2557  }
2558 
2564  public function getDataWithTypeLeveltitle()
2565  {
2566  $rootline = array(
2567  0 => array('uid' => 1, 'title' => 'title1'),
2568  1 => array('uid' => 2, 'title' => 'title2'),
2569  2 => array('uid' => 3, 'title' => ''),
2570  );
2571 
2572  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2573  $this->assertEquals('', $this->subject->getData('leveltitle:-1'));
2574  // since "title3" is not set, it will slide to "title2"
2575  $this->assertEquals('title2', $this->subject->getData('leveltitle:-1,slide'));
2576  }
2577 
2583  public function getDataWithTypeLevelmedia()
2584  {
2585  $rootline = array(
2586  0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
2587  1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
2588  2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
2589  );
2590 
2591  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2592  $this->assertEquals('', $this->subject->getData('levelmedia:-1'));
2593  // since "title3" is not set, it will slide to "title2"
2594  $this->assertEquals('media2', $this->subject->getData('levelmedia:-1,slide'));
2595  }
2596 
2602  public function getDataWithTypeLeveluid()
2603  {
2604  $rootline = array(
2605  0 => array('uid' => 1, 'title' => 'title1'),
2606  1 => array('uid' => 2, 'title' => 'title2'),
2607  2 => array('uid' => 3, 'title' => 'title3'),
2608  );
2609 
2610  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2611  $this->assertEquals(3, $this->subject->getData('leveluid:-1'));
2612  // every element will have a uid - so adding slide doesn't really make sense, just for completeness
2613  $this->assertEquals(3, $this->subject->getData('leveluid:-1,slide'));
2614  }
2615 
2621  public function getDataWithTypeLevelfield()
2622  {
2623  $rootline = array(
2624  0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2625  1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
2626  2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
2627  );
2628 
2629  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2630  $this->assertEquals('', $this->subject->getData('levelfield:-1,testfield'));
2631  $this->assertEquals('field2', $this->subject->getData('levelfield:-1,testfield,slide'));
2632  }
2633 
2640  {
2641  $rootline1 = array(
2642  0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2643  );
2644  $rootline2 = array(
2645  0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2646  1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
2647  2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
2648  );
2649 
2650  $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
2651  $GLOBALS['TSFE']->rootLine = $rootline2;
2652  $this->assertEquals('field2', $this->subject->getData('fullrootline:-1,testfield'));
2653  }
2654 
2660  public function getDataWithTypeDate()
2661  {
2662  $format = 'Y-M-D';
2663  $defaultFormat = 'd/m Y';
2664 
2665  $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->subject->getData('date:' . $format));
2666  $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->subject->getData('date'));
2667  }
2668 
2674  public function getDataWithTypePage()
2675  {
2676  $uid = rand();
2677  $GLOBALS['TSFE']->page['uid'] = $uid;
2678  $this->assertEquals($uid, $this->subject->getData('page:uid'));
2679  }
2680 
2686  public function getDataWithTypeCurrent()
2687  {
2688  $key = $this->getUniqueId('someKey');
2689  $value = $this->getUniqueId('someValue');
2690  $this->subject->data[$key] = $value;
2691  $this->subject->currentValKey = $key;
2692  $this->assertEquals($value, $this->subject->getData('current'));
2693  }
2694 
2700  public function getDataWithTypeDb()
2701  {
2702  $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
2703 
2704  $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
2705  $this->assertEquals($dummyRecord['title'], $this->subject->getData('db:tt_content:106:title'));
2706  }
2707 
2713  public function getDataWithTypeLll()
2714  {
2715  $key = $this->getUniqueId('someKey');
2716  $value = $this->getUniqueId('someValue');
2717  $language = $this->getUniqueId('someLanguage');
2718  $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
2719  $GLOBALS['TSFE']->lang = $language;
2720 
2721  $this->assertEquals($value, $this->subject->getData('lll:' . $key));
2722  }
2723 
2729  public function getDataWithTypePath()
2730  {
2731  $filenameIn = $this->getUniqueId('someValue');
2732  $filenameOut = $this->getUniqueId('someValue');
2733  $this->templateServiceMock->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
2734  $this->assertEquals($filenameOut, $this->subject->getData('path:' . $filenameIn));
2735  }
2736 
2743  {
2744  $recordNumber = rand();
2745  $this->subject->parentRecordNumber = $recordNumber;
2746  $this->assertEquals($recordNumber, $this->subject->getData('cobj:parentRecordNumber'));
2747  }
2748 
2755  {
2756  $rootline = array(
2757  0 => array('uid' => 1, 'title' => 'title1'),
2758  1 => array('uid' => 2, 'title' => 'title2'),
2759  2 => array('uid' => 3, 'title' => ''),
2760  );
2761  $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
2762  $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2763 
2764  $result = $this->subject->getData('debug:rootLine');
2765  $cleanedResult = strip_tags($result);
2766  $cleanedResult = str_replace("\r", '', $cleanedResult);
2767  $cleanedResult = str_replace("\n", '', $cleanedResult);
2768  $cleanedResult = str_replace("\t", '', $cleanedResult);
2769  $cleanedResult = str_replace(' ', '', $cleanedResult);
2770 
2771  $this->assertEquals($expectedResult, $cleanedResult);
2772  }
2773 
2780  {
2781  $rootline = array(
2782  0 => array('uid' => 1, 'title' => 'title1'),
2783  1 => array('uid' => 2, 'title' => 'title2'),
2784  2 => array('uid' => 3, 'title' => ''),
2785  );
2786  $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
2787  $GLOBALS['TSFE']->rootLine = $rootline;
2788 
2789  $result = $this->subject->getData('debug:fullRootLine');
2790  $cleanedResult = strip_tags($result);
2791  $cleanedResult = str_replace("\r", '', $cleanedResult);
2792  $cleanedResult = str_replace("\n", '', $cleanedResult);
2793  $cleanedResult = str_replace("\t", '', $cleanedResult);
2794  $cleanedResult = str_replace(' ', '', $cleanedResult);
2795 
2796  $this->assertEquals($expectedResult, $cleanedResult);
2797  }
2798 
2804  public function getDataWithTypeDebugData()
2805  {
2806  $key = $this->getUniqueId('someKey');
2807  $value = $this->getUniqueId('someValue');
2808  $this->subject->data = array($key => $value);
2809 
2810  $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
2811 
2812  $result = $this->subject->getData('debug:data');
2813  $cleanedResult = strip_tags($result);
2814  $cleanedResult = str_replace("\r", '', $cleanedResult);
2815  $cleanedResult = str_replace("\n", '', $cleanedResult);
2816  $cleanedResult = str_replace("\t", '', $cleanedResult);
2817  $cleanedResult = str_replace(' ', '', $cleanedResult);
2818 
2819  $this->assertEquals($expectedResult, $cleanedResult);
2820  }
2821 
2828  {
2829  $key = $this->getUniqueId('someKey');
2830  $value = $this->getUniqueId('someValue');
2831  $GLOBALS['TSFE']->register = array($key => $value);
2832 
2833  $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
2834 
2835  $result = $this->subject->getData('debug:register');
2836  $cleanedResult = strip_tags($result);
2837  $cleanedResult = str_replace("\r", '', $cleanedResult);
2838  $cleanedResult = str_replace("\n", '', $cleanedResult);
2839  $cleanedResult = str_replace("\t", '', $cleanedResult);
2840  $cleanedResult = str_replace(' ', '', $cleanedResult);
2841 
2842  $this->assertEquals($expectedResult, $cleanedResult);
2843  }
2844 
2850  public function getDataWithTypeDebugPage()
2851  {
2852  $uid = rand();
2853  $GLOBALS['TSFE']->page = array('uid' => $uid);
2854 
2855  $expectedResult = 'array(1item)uid=>' . $uid . '(integer)';
2856 
2857  $result = $this->subject->getData('debug:page');
2858  $cleanedResult = strip_tags($result);
2859  $cleanedResult = str_replace("\r", '', $cleanedResult);
2860  $cleanedResult = str_replace("\n", '', $cleanedResult);
2861  $cleanedResult = str_replace("\t", '', $cleanedResult);
2862  $cleanedResult = str_replace(' ', '', $cleanedResult);
2863 
2864  $this->assertEquals($expectedResult, $cleanedResult);
2865  }
2866 
2871  {
2872  $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
2873  $GLOBALS['TSFE']->sys_page
2874  ->expects($this->any())
2875  ->method('getRawRecord')
2876  ->will(
2877  $this->onConsecutiveCalls(
2878  array('uid' => 17),
2879  array('uid' => 321),
2880  array('uid' => 719),
2881  array('uid' => 42)
2882  )
2883  );
2884 
2885  $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
2886  $GLOBALS['TYPO3_DB']
2887  ->expects($this->any())
2888  ->method('exec_SELECTgetRows')
2889  ->will(
2890  $this->onConsecutiveCalls(
2891  array(
2892  array('uid' => 321)
2893  ),
2894  array(
2895  array('uid' => 719)
2896  ),
2897  array(
2898  array('uid' => 42)
2899  )
2900  )
2901  );
2902  // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2903  // 17 is positive, we expect 17 NOT to be included in result
2904  $result = $this->subject->getTreeList(17, 5, 0, true);
2905  $expectedResult = '42,719,321';
2906  $this->assertEquals($expectedResult, $result);
2907  }
2908 
2913  {
2914  $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
2915  $GLOBALS['TSFE']->sys_page
2916  ->expects($this->any())
2917  ->method('getRawRecord')
2918  ->will(
2919  $this->onConsecutiveCalls(
2920  array('uid' => 17),
2921  array('uid' => 321),
2922  array('uid' => 719),
2923  array('uid' => 42)
2924  )
2925  );
2926 
2927  $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
2928  $GLOBALS['TYPO3_DB']
2929  ->expects($this->any())
2930  ->method('exec_SELECTgetRows')
2931  ->will(
2932  $this->onConsecutiveCalls(
2933  array(
2934  array('uid' => 321)
2935  ),
2936  array(
2937  array('uid' => 719)
2938  ),
2939  array(
2940  array('uid' => 42)
2941  )
2942  )
2943  );
2944  // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2945  // 17 is negative, we expect 17 to be included in result
2946  $result = $this->subject->getTreeList(-17, 5, 0, true);
2947  $expectedResult = '42,719,321,17';
2948  $this->assertEquals($expectedResult, $result);
2949  }
2950 
2955  {
2956  $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2957  $this->assertEquals(' data-test="testdata"', $aTagParams);
2958  }
2959 
2964  {
2965  $GLOBALS['TSFE']->ATagParams = 'data-global="dataglobal"';
2966  $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2967  $this->assertEquals(' data-global="dataglobal" data-test="testdata"', $aTagParams);
2968  }
2969 
2974  {
2975  // make sure global ATagParams are empty
2976  $GLOBALS['TSFE']->ATagParams = '';
2977  $aTagParams = $this->subject->getATagParams(array('ATagParams' => ''));
2978  $this->assertEquals('', $aTagParams);
2979  }
2980 
2985  {
2986  return array(
2987  array(null, null),
2988  array('', null),
2989  array('', array()),
2990  array('fooo', array('foo' => 'bar'))
2991  );
2992  }
2993 
3003  {
3004  $defaultImgTagTemplate = '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
3005  $result = $this->subject->getImageTagTemplate($key, $configuration);
3006  $this->assertEquals($result, $defaultImgTagTemplate);
3007  }
3008 
3013  {
3014  return array(
3015  array(
3016  'foo',
3017  array(
3018  'layout.' => array(
3019  'foo.' => array(
3020  'element' => '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
3021  )
3022  )
3023  ),
3024  '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
3025  )
3026 
3027  );
3028  }
3029 
3039  public function getImageTagTemplateReturnTemplateElementIdentifiedByKey($key, $configuration, $expectation)
3040  {
3041  $result = $this->subject->getImageTagTemplate($key, $configuration);
3042  $this->assertEquals($result, $expectation);
3043  }
3044 
3049  {
3050  return array(
3051  array(null, null, null),
3052  array('foo', null, null),
3053  array('foo', array('sourceCollection.' => 1), 'bar')
3054  );
3055  }
3056 
3066  public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefined($layoutKey, $configuration, $file)
3067  {
3068  $result = $this->subject->getImageSourceCollection($layoutKey, $configuration, $file);
3069  $this->assertSame($result, '');
3070  }
3071 
3077  public function getImageSourceCollectionRendersDefinedSources()
3078  {
3080  $cObj = $this->getMock(
3081  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
3082  array('stdWrap', 'getImgResource')
3083  );
3084  $cObj->start(array(), 'tt_content');
3085 
3086  $layoutKey = 'test';
3087 
3088  $configuration = array(
3089  'layoutKey' => 'test',
3090  'layout.' => array(
3091  'test.' => array(
3092  'element' => '<img ###SRC### ###SRCCOLLECTION### ###SELFCLOSINGTAGSLASH###>',
3093  'source' => '---###SRC###---'
3094  )
3095  ),
3096  'sourceCollection.' => array(
3097  '1.' => array(
3098  'width' => '200'
3099  )
3100  )
3101  );
3102 
3103  $file = 'testImageName';
3104 
3105  // Avoid calling of stdWrap
3106  $cObj
3107  ->expects($this->any())
3108  ->method('stdWrap')
3109  ->will($this->returnArgument(0));
3110 
3111  // Avoid calling of imgResource
3112  $cObj
3113  ->expects($this->exactly(1))
3114  ->method('getImgResource')
3115  ->with($this->equalTo('testImageName'))
3116  ->will($this->returnValue(array(100, 100, null, 'bar')));
3117 
3118  $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
3119 
3120  $this->assertEquals('---bar---', $result);
3121  }
3122 
3130  {
3134  $sourceCollectionArray = array(
3135  'small.' => array(
3136  'width' => '200',
3137  'srcsetCandidate' => '600w',
3138  'mediaQuery' => '(max-device-width: 600px)',
3139  'dataKey' => 'small',
3140  ),
3141  'smallRetina.' => array(
3142  'if.directReturn' => 0,
3143  'width' => '200',
3144  'pixelDensity' => '2',
3145  'srcsetCandidate' => '600w 2x',
3146  'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
3147  'dataKey' => 'smallRetina',
3148  )
3149  );
3150  return array(
3151  array(
3152  'default',
3153  array(
3154  'layoutKey' => 'default',
3155  'layout.' => array(
3156  'default.' => array(
3157  'element' => '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>',
3158  'source' => ''
3159  )
3160  ),
3161  'sourceCollection.' => $sourceCollectionArray
3162  )
3163  ),
3164  );
3165  }
3166 
3175  public function getImageSourceCollectionRendersDefinedLayoutKeyDefault($layoutKey, $configuration)
3176  {
3178  $cObj = $this->getMock(
3179  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
3180  array('stdWrap', 'getImgResource')
3181  );
3182  $cObj->start(array(), 'tt_content');
3183 
3184  $file = 'testImageName';
3185 
3186  // Avoid calling of stdWrap
3187  $cObj
3188  ->expects($this->any())
3189  ->method('stdWrap')
3190  ->will($this->returnArgument(0));
3191 
3192  $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
3193 
3194  $this->assertEmpty($result);
3195  }
3196 
3204  {
3208  $sourceCollectionArray = array(
3209  'small.' => array(
3210  'width' => '200',
3211  'srcsetCandidate' => '600w',
3212  'mediaQuery' => '(max-device-width: 600px)',
3213  'dataKey' => 'small',
3214  ),
3215  'smallRetina.' => array(
3216  'if.directReturn' => 1,
3217  'width' => '200',
3218  'pixelDensity' => '2',
3219  'srcsetCandidate' => '600w 2x',
3220  'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
3221  'dataKey' => 'smallRetina',
3222  )
3223  );
3224  return array(
3225  array(
3226  'srcset',
3227  array(
3228  'layoutKey' => 'srcset',
3229  'layout.' => array(
3230  'srcset.' => array(
3231  'element' => '<img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
3232  'source' => '|*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###'
3233  )
3234  ),
3235  'sourceCollection.' => $sourceCollectionArray
3236  ),
3237  'xhtml_strict',
3238  'bar-file.jpg 600w,bar-file.jpg 600w 2x',
3239  ),
3240  array(
3241  'picture',
3242  array(
3243  'layoutKey' => 'picture',
3244  'layout.' => array(
3245  'picture.' => array(
3246  'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
3247  'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
3248  )
3249  ),
3250  'sourceCollection.' => $sourceCollectionArray,
3251  ),
3252  'xhtml_strict',
3253  '<source src="bar-file.jpg" media="(max-device-width: 600px)" /><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)" />',
3254  ),
3255  array(
3256  'picture',
3257  array(
3258  'layoutKey' => 'picture',
3259  'layout.' => array(
3260  'picture.' => array(
3261  'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
3262  'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
3263  )
3264  ),
3265  'sourceCollection.' => $sourceCollectionArray,
3266  ),
3267  '',
3268  '<source src="bar-file.jpg" media="(max-device-width: 600px)"><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)">',
3269  ),
3270  array(
3271  'data',
3272  array(
3273  'layoutKey' => 'data',
3274  'layout.' => array(
3275  'data.' => array(
3276  'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
3277  'source' => 'data-###DATAKEY###="###SRC###"'
3278  )
3279  ),
3280  'sourceCollection.' => $sourceCollectionArray
3281  ),
3282  'xhtml_strict',
3283  'data-small="bar-file.jpg"data-smallRetina="bar-file.jpg"',
3284  ),
3285  );
3286  }
3287 
3298  public function getImageSourceCollectionRendersDefinedLayoutKeyData($layoutKey, $configuration, $xhtmlDoctype, $expectedHtml)
3299  {
3301  $cObj = $this->getMock(
3302  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
3303  array('stdWrap', 'getImgResource')
3304  );
3305  $cObj->start(array(), 'tt_content');
3306 
3307  $file = 'testImageName';
3308 
3309  $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
3310 
3311  // Avoid calling of stdWrap
3312  $cObj
3313  ->expects($this->any())
3314  ->method('stdWrap')
3315  ->will($this->returnArgument(0));
3316 
3317  // Avoid calling of imgResource
3318  $cObj
3319  ->expects($this->exactly(2))
3320  ->method('getImgResource')
3321  ->with($this->equalTo('testImageName'))
3322  ->will($this->returnValue(array(100, 100, null, 'bar-file.jpg')));
3323 
3324  $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
3325 
3326  $this->assertEquals($expectedHtml, $result);
3327  }
3328 
3335  {
3336  $this->subject = $this->getAccessibleMock(
3337  \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
3338  array('getResourceFactory', 'stdWrap', 'getImgResource')
3339  );
3340  $this->subject->start(array(), 'tt_content');
3341 
3342  // Avoid calling stdwrap and getImgResource
3343  $this->subject->expects($this->any())
3344  ->method('stdWrap')
3345  ->will($this->returnArgument(0));
3346 
3347  $this->subject->expects($this->any())
3348  ->method('getImgResource')
3349  ->will($this->returnValue(array(100, 100, null, 'bar-file.jpg')));
3350 
3351  $resourceFactory = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceFactory::class, array(), array(), '', false);
3352  $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
3353 
3354  $className = $this->getUniqueId('tx_coretest_getImageSourceCollectionHookCalled');
3355  $getImageSourceCollectionHookMock = $this->getMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectOneSourceCollectionHookInterface::class, array('getOneSourceCollection'), array(), $className);
3356  $GLOBALS['T3_VAR']['getUserObj'][$className] = $getImageSourceCollectionHookMock;
3357  $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'][] = $className;
3358 
3359  $getImageSourceCollectionHookMock
3360  ->expects($this->exactly(1))
3361  ->method('getOneSourceCollection')
3362  ->will($this->returnCallback(array($this, 'isGetOneSourceCollectionCalledCallback')));
3363 
3364  $configuration = array(
3365  'layoutKey' => 'data',
3366  'layout.' => array(
3367  'data.' => array(
3368  'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
3369  'source' => 'data-###DATAKEY###="###SRC###"'
3370  )
3371  ),
3372  'sourceCollection.' => array(
3373  'small.' => array(
3374  'width' => '200',
3375  'srcsetCandidate' => '600w',
3376  'mediaQuery' => '(max-device-width: 600px)',
3377  'dataKey' => 'small',
3378  ),
3379  ),
3380  );
3381 
3382  $result = $this->subject->getImageSourceCollection('data', $configuration, $this->getUniqueId('testImage-'));
3383 
3384  $this->assertSame($result, 'isGetOneSourceCollectionCalledCallback');
3385  }
3386 
3394  {
3395  list($sourceRenderConfiguration, $sourceConfiguration, $oneSourceCollection, $parent) = func_get_args();
3396  $this->assertTrue(is_array($sourceRenderConfiguration));
3397  $this->assertTrue(is_array($sourceConfiguration));
3398  return 'isGetOneSourceCollectionCalledCallback';
3399  }
3400 
3408  public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl($expected, $url, array $configuration)
3409  {
3410  // Force hostname
3411  $this->subject->expects($this->any())->method('getEnvironmentVariable')->will($this->returnValueMap(
3412  array(
3413  array('HTTP_HOST', 'localhost'),
3414  array('TYPO3_SITE_PATH', '/'),
3415  )
3416  ));
3417  $GLOBALS['TSFE']->absRefPrefix = '';
3418 
3419  $this->assertEquals($expected, $this->subject->_call('forceAbsoluteUrl', $url, $configuration));
3420  }
3421 
3426  {
3427  return array(
3428  'Missing forceAbsoluteUrl leaves URL untouched' => array(
3429  'foo',
3430  'foo',
3431  array()
3432  ),
3433  'Absolute URL stays unchanged' => array(
3434  'http://example.org/',
3435  'http://example.org/',
3436  array(
3437  'forceAbsoluteUrl' => '1'
3438  )
3439  ),
3440  'Absolute URL stays unchanged 2' => array(
3441  'http://example.org/resource.html',
3442  'http://example.org/resource.html',
3443  array(
3444  'forceAbsoluteUrl' => '1'
3445  )
3446  ),
3447  'Scheme and host w/o ending slash stays unchanged' => array(
3448  'http://example.org',
3449  'http://example.org',
3450  array(
3451  'forceAbsoluteUrl' => '1'
3452  )
3453  ),
3454  'Scheme can be forced' => array(
3455  'typo3://example.org',
3456  'http://example.org',
3457  array(
3458  'forceAbsoluteUrl' => '1',
3459  'forceAbsoluteUrl.' => array(
3460  'scheme' => 'typo3'
3461  )
3462  )
3463  ),
3464  'Relative path old-style' => array(
3465  'http://localhost/fileadmin/dummy.txt',
3466  '/fileadmin/dummy.txt',
3467  array(
3468  'forceAbsoluteUrl' => '1',
3469  )
3470  ),
3471  'Relative path' => array(
3472  'http://localhost/fileadmin/dummy.txt',
3473  'fileadmin/dummy.txt',
3474  array(
3475  'forceAbsoluteUrl' => '1',
3476  )
3477  ),
3478  'Scheme can be forced with pseudo-relative path' => array(
3479  'typo3://localhost/fileadmin/dummy.txt',
3480  '/fileadmin/dummy.txt',
3481  array(
3482  'forceAbsoluteUrl' => '1',
3483  'forceAbsoluteUrl.' => array(
3484  'scheme' => 'typo3'
3485  )
3486  )
3487  ),
3488  'Hostname only is not treated as valid absolute URL' => array(
3489  'http://localhost/example.org',
3490  'example.org',
3491  array(
3492  'forceAbsoluteUrl' => '1'
3493  )
3494  ),
3495  'Scheme and host is added to local file path' => array(
3496  'typo3://localhost/fileadmin/my.pdf',
3497  'fileadmin/my.pdf',
3498  array(
3499  'forceAbsoluteUrl' => '1',
3500  'forceAbsoluteUrl.' => array(
3501  'scheme' => 'typo3'
3502  )
3503  )
3504  )
3505  );
3506  }
3507 
3514  {
3515  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3516  $this->subject->render($contentObjectFixture, array());
3517  }
3518 
3523  {
3524  $backupApplicationContext = GeneralUtility::getApplicationContext();
3525  Fixtures\GeneralUtilityFixture::setApplicationContext(new ApplicationContext('Production'));
3526 
3527  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3528  $this->subject->render($contentObjectFixture, array());
3529 
3530  Fixtures\GeneralUtilityFixture::setApplicationContext($backupApplicationContext);
3531  }
3532 
3537  {
3538  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3539 
3540  $configuration = array(
3541  'exceptionHandler' => '1'
3542  );
3543  $this->subject->render($contentObjectFixture, $configuration);
3544  }
3545 
3550  {
3551  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3552 
3553  $this->typoScriptFrontendControllerMock->config['config']['contentObjectExceptionHandler'] = '1';
3554  $this->subject->render($contentObjectFixture, array());
3555  }
3556 
3563  {
3564  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3565 
3566  $this->typoScriptFrontendControllerMock->config['config']['contentObjectExceptionHandler'] = '1';
3567  $configuration = array(
3568  'exceptionHandler' => '0'
3569  );
3570  $this->subject->render($contentObjectFixture, $configuration);
3571  }
3572 
3577  {
3578  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3579 
3580  $configuration = array(
3581  'exceptionHandler' => '1',
3582  'exceptionHandler.' => array(
3583  'errorMessage' => 'New message for testing',
3584  )
3585  );
3586 
3587  $this->assertSame('New message for testing', $this->subject->render($contentObjectFixture, $configuration));
3588  }
3589 
3594  {
3595  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3596 
3597  $this->typoScriptFrontendControllerMock
3598  ->config['config']['contentObjectExceptionHandler.'] = array(
3599  'errorMessage' => 'Global message for testing',
3600  );
3601  $configuration = array(
3602  'exceptionHandler' => '1',
3603  'exceptionHandler.' => array(
3604  'errorMessage' => 'New message for testing',
3605  )
3606  );
3607 
3608  $this->assertSame('New message for testing', $this->subject->render($contentObjectFixture, $configuration));
3609  }
3610 
3617  {
3618  $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
3619 
3620  $configuration = array(
3621  'exceptionHandler' => '1',
3622  'exceptionHandler.' => array(
3623  'ignoreCodes.' => array('10.' => '1414513947'),
3624  )
3625  );
3626 
3627  $this->subject->render($contentObjectFixture, $configuration);
3628  }
3629 
3634  {
3635  $contentObjectFixture = $this->getMock(AbstractContentObject::class, array(), array($this->subject));
3636  $contentObjectFixture->expects($this->once())
3637  ->method('render')
3638  ->willReturnCallback(function () {
3639  throw new \LogicException('Exception during rendering', 1414513947);
3640  });
3641  return $contentObjectFixture;
3642  }
3643 
3648  {
3649  // Force hostname and subfolder
3650  $this->subject->expects($this->any())->method('getEnvironmentVariable')->will($this->returnValueMap(
3651  array(
3652  array('HTTP_HOST', 'localhost'),
3653  array('TYPO3_SITE_PATH', '/subfolder/'),
3654  )
3655  ));
3656 
3657  $expected = 'http://localhost/subfolder/fileadmin/my.pdf';
3658  $url = 'fileadmin/my.pdf';
3659  $configuration = array(
3660  'forceAbsoluteUrl' => '1'
3661  );
3662 
3663  $this->assertEquals($expected, $this->subject->_call('forceAbsoluteUrl', $url, $configuration));
3664  }
3665 
3669  protected function getLibParseTarget()
3670  {
3671  return array(
3672  'override' => '',
3673  'override.' => array(
3674  'if.' => array(
3675  'isTrue.' => array(
3676  'data' => 'TSFE:dtdAllowsFrames',
3677  ),
3678  ),
3679  ),
3680  );
3681  }
3682 
3686  protected function getLibParseFunc()
3687  {
3688  return array(
3689  'makelinks' => '1',
3690  'makelinks.' => array(
3691  'http.' => array(
3692  'keep' => '{$styles.content.links.keep}',
3693  'extTarget' => '',
3694  'extTarget.' => $this->getLibParseTarget(),
3695  'mailto.' => array(
3696  'keep' => 'path',
3697  ),
3698  ),
3699  ),
3700  'tags' => array(
3701  'link' => 'TEXT',
3702  'link.' => array(
3703  'current' => '1',
3704  'typolink.' => array(
3705  'parameter.' => array(
3706  'data' => 'parameters : allParams',
3707  ),
3708  'extTarget.' => $this->getLibParseTarget(),
3709  'target.' => $this->getLibParseTarget(),
3710  ),
3711  'parseFunc.' => array(
3712  'constants' => '1',
3713  ),
3714  ),
3715  ),
3716 
3717  'allowTags' => 'a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var',
3718  'denyTags' => '*',
3719  'sword' => '<span class="csc-sword">|</span>',
3720  'constants' => '1',
3721  'nonTypoTagStdWrap.' => array(
3722  'HTMLparser' => '1',
3723  'HTMLparser.' => array(
3724  'keepNonMatchedTags' => '1',
3725  'htmlSpecialChars' => '2',
3726  ),
3727  ),
3728  );
3729  }
3730 
3734  protected function getLibParseFunc_RTE()
3735  {
3736  return array(
3737  'parseFunc' => '',
3738  'parseFunc.' => array(
3739  'allowTags' => 'a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var',
3740  'constants' => '1',
3741  'denyTags' => '*',
3742  'externalBlocks' => 'article, aside, blockquote, div, dd, dl, footer, header, nav, ol, section, table, ul',
3743  'externalBlocks.' => array(
3744  'article.' => array(
3745  'callRecursive' => '1',
3746  'stripNL' => '1',
3747  ),
3748  'aside.' => array(
3749  'callRecursive' => '1',
3750  'stripNL' => '1',
3751  ),
3752  'blockquote.' => array(
3753  'callRecursive' => '1',
3754  'stripNL' => '1',
3755  ),
3756  'dd.' => array(
3757  'callRecursive' => '1',
3758  'stripNL' => '1',
3759  ),
3760  'div.' => array(
3761  'callRecursive' => '1',
3762  'stripNL' => '1',
3763  ),
3764  'dl.' => array(
3765  'callRecursive' => '1',
3766  'stripNL' => '1',
3767  ),
3768  'footer.' => array(
3769  'callRecursive' => '1',
3770  'stripNL' => '1',
3771  ),
3772  'header.' => array(
3773  'callRecursive' => '1',
3774  'stripNL' => '1',
3775  ),
3776  'nav.' => array(
3777  'callRecursive' => '1',
3778  'stripNL' => '1',
3779  ),
3780  'ol.' => array(
3781  'callRecursive' => '1',
3782  'stripNL' => '1',
3783  ),
3784  'section.' => array(
3785  'callRecursive' => '1',
3786  'stripNL' => '1',
3787  ),
3788  'table.' => array(
3789  'HTMLtableCells' => '1',
3790  'HTMLtableCells.' => array(
3791  'addChr10BetweenParagraphs' => '1',
3792  'default.' => array(
3793  'stdWrap.' => array(
3794  'parseFunc' => '=< lib.parseFunc_RTE',
3795  'parseFunc.' => array(
3796  'nonTypoTagStdWrap.' => array(
3797  'encapsLines.' => array(
3798  'nonWrappedTag' => '',
3799  ),
3800  ),
3801  ),
3802  ),
3803  ),
3804  ),
3805  'stdWrap.' => array(
3806  'HTMLparser' => '1',
3807  'HTMLparser.' => array(
3808  'keepNonMatchedTags' => '1',
3809  'tags.' => array(
3810  'table.' => array(
3811  'fixAttrib.' => array(
3812  'class.' => array(
3813  'always' => '1',
3814  'default' => 'contenttable',
3815  'list' => 'contenttable',
3816  ),
3817  ),
3818  ),
3819  ),
3820  ),
3821  ),
3822  'stripNL' => '1',
3823  ),
3824  'ul.' => array(
3825  'callRecursive' => '1',
3826  'stripNL' => '1',
3827  ),
3828  ),
3829  'makelinks' => '1',
3830  'makelinks.' => array(
3831  'http.' => array(
3832  'extTarget.' => array(
3833  'override' => '_blank',
3834  'override.' => array(
3835  'if.' => array(
3836  'isTrue.' => array(
3837  'data' => 'TSFE:dtdAllowsFrames',
3838  ),
3839  ),
3840  ),
3841  ),
3842  'keep' => 'path',
3843  ),
3844  ),
3845  'nonTypoTagStdWrap.' => array(
3846  'encapsLines.' => array(
3847  'addAttributes.' => array(
3848  'P.' => array(
3849  'class' => 'bodytext',
3850  'class.' => array(
3851  'setOnly' => 'blank',
3852  ),
3853  ),
3854  ),
3855  'encapsTagList' => 'p,pre,h1,h2,h3,h4,h5,h6,hr,dt,li',
3856  'innerStdWrap_all.' => array(
3857  'ifBlank' => '&nbsp;',
3858  ),
3859  'nonWrappedTag' => 'P',
3860  'remapTag.' => array(
3861  'DIV' => 'P',
3862  ),
3863  ),
3864  'HTMLparser' => '1',
3865  'HTMLparser.' => array(
3866  'htmlSpecialChars' => '2',
3867  'keepNonMatchedTags' => '1',
3868  ),
3869  ),
3870  'sword' => '<span class="csc-sword">|</span>',
3871  'tags.' => array(
3872  'link' => 'TEXT',
3873  'link.' => array(
3874  'current' => '1',
3875  'parseFunc.' => array(
3876  'constants' => '1',
3877  ),
3878  'typolink.' => array(
3879  'extTarget.' => array(
3880  'override' => '',
3881  'override.' => array(
3882  'if.' => array(
3883  'isTrue.' => array(
3884  'data' => 'TSFE:dtdAllowsFrames',
3885  ),
3886  ),
3887  ),
3888  ),
3889  'parameter.' => array(
3890  'data' => 'parameters : allParams',
3891  ),
3892  'target.' => array(
3893  'override' => '',
3894  'override.' => array(
3895  'if.' => array(
3896  'isTrue.' => array(
3897  'data' => 'TSFE:dtdAllowsFrames',
3898  ),
3899  ),
3900  ),
3901  ),
3902  ),
3903  ),
3904  ),
3905  ),
3906  );
3907  }
3908 
3913  {
3914  return array(
3915  'Text without tag is wrapped with <p> tag' => array(
3916  'Text without tag',
3917  $this->getLibParseFunc_RTE(),
3918  '<p class="bodytext">Text without tag</p>',
3919  ),
3920  'Text wrapped with <p> tag remains the same' => array(
3921  '<p class="myclass">Text with &lt;p&gt; tag</p>',
3922  $this->getLibParseFunc_RTE(),
3923  '<p class="myclass">Text with &lt;p&gt; tag</p>',
3924  ),
3925  'Text with absolute external link' => array(
3926  'Text with <link http://example.com/foo/>external link</link>',
3927  $this->getLibParseFunc_RTE(),
3928  '<p class="bodytext">Text with <a href="http://example.com/foo/">external link</a></p>',
3929  ),
3930  );
3931  }
3932 
3940  public function stdWrap_parseFuncReturnsParsedHtml($value, $configuration, $expectedResult)
3941  {
3942  $this->assertEquals($expectedResult, $this->subject->stdWrap_parseFunc($value, $configuration));
3943  }
3944 
3949  {
3950  return array(
3951  'Link to url' => array(
3952  'TYPO3',
3953  array(
3954  'parameter' => 'http://typo3.org',
3955  ),
3956  '<a href="http://typo3.org">TYPO3</a>',
3957  ),
3958  'Link to url without link text' => array(
3959  '',
3960  array(
3961  'parameter' => 'http://typo3.org',
3962  ),
3963  '<a href="http://typo3.org">http://typo3.org</a>',
3964  ),
3965  'Link to url with attributes' => array(
3966  'TYPO3',
3967  array(
3968  'parameter' => 'http://typo3.org',
3969  'ATagParams' => 'class="url-class"',
3970  'extTarget' => '_blank',
3971  'title' => 'Open new window',
3972  ),
3973  '<a href="http://typo3.org" title="Open new window" target="_blank" class="url-class">TYPO3</a>',
3974  ),
3975  'Link to url with attributes in parameter' => array(
3976  'TYPO3',
3977  array(
3978  'parameter' => 'http://typo3.org _blank url-class "Open new window"',
3979  ),
3980  '<a href="http://typo3.org" title="Open new window" target="_blank" class="url-class">TYPO3</a>',
3981  ),
3982  'Link to url with script tag' => array(
3983  '',
3984  array(
3985  'parameter' => 'http://typo3.org<script>alert(123)</script>',
3986  ),
3987  '<a href="http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;">http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;</a>',
3988  ),
3989  'Link to email address' => array(
3990  'Email address',
3991  array(
3992  'parameter' => 'foo@bar.org',
3993  ),
3994  '<a href="mailto:foo@bar.org">Email address</a>',
3995  ),
3996  'Link to email address without link text' => array(
3997  '',
3998  array(
3999  'parameter' => 'foo@bar.org',
4000  ),
4001  '<a href="mailto:foo@bar.org">foo@bar.org</a>',
4002  ),
4003  'Link to email with attributes' => array(
4004  'Email address',
4005  array(
4006  'parameter' => 'foo@bar.org',
4007  'ATagParams' => 'class="email-class"',
4008  'title' => 'Write an email',
4009  ),
4010  '<a href="mailto:foo@bar.org" title="Write an email" class="email-class">Email address</a>',
4011  ),
4012  'Link to email with attributes in parameter' => array(
4013  'Email address',
4014  array(
4015  'parameter' => 'foo@bar.org - email-class "Write an email"',
4016  ),
4017  '<a href="mailto:foo@bar.org" title="Write an email" class="email-class">Email address</a>',
4018  ),
4019  );
4020  }
4021 
4029  public function typolinkReturnsCorrectLinksForEmailsAndUrls($linkText, $configuration, $expectedResult)
4030  {
4031  $templateServiceObjectMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('dummy'));
4032  $templateServiceObjectMock->setup = array(
4033  'lib.' => array(
4034  'parseFunc.' => $this->getLibParseFunc(),
4035  ),
4036  );
4037  $typoScriptFrontendControllerMockObject = $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', false);
4038  $typoScriptFrontendControllerMockObject->config = array(
4039  'config' => array(),
4040  'mainScript' => 'index.php',
4041  );
4042  $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
4043  $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
4044  $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
4045 
4046  $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
4047  }
4048 
4053  {
4054  return array(
4055  'Link to page' => array(
4056  'My page',
4057  array(
4058  'parameter' => 42,
4059  ),
4060  array(
4061  'uid' => 42,
4062  'title' => 'Page title',
4063  ),
4064  '<a href="index.php?id=42">My page</a>',
4065  ),
4066  'Link to page without link text' => array(
4067  '',
4068  array(
4069  'parameter' => 42,
4070  ),
4071  array(
4072  'uid' => 42,
4073  'title' => 'Page title',
4074  ),
4075  '<a href="index.php?id=42">Page title</a>',
4076  ),
4077  'Link to page with attributes' => array(
4078  'My page',
4079  array(
4080  'parameter' => '42',
4081  'ATagParams' => 'class="page-class"',
4082  'target' => '_self',
4083  'title' => 'Link to internal page',
4084  ),
4085  array(
4086  'uid' => 42,
4087  'title' => 'Page title',
4088  ),
4089  '<a href="index.php?id=42" title="Link to internal page" target="_self" class="page-class">My page</a>',
4090  ),
4091  'Link to page with attributes in parameter' => array(
4092  'My page',
4093  array(
4094  'parameter' => '42 _self page-class "Link to internal page"',
4095  ),
4096  array(
4097  'uid' => 42,
4098  'title' => 'Page title',
4099  ),
4100  '<a href="index.php?id=42" title="Link to internal page" target="_self" class="page-class">My page</a>',
4101  ),
4102  'Link to page with bold tag in title' => array(
4103  '',
4104  array(
4105  'parameter' => 42,
4106  ),
4107  array(
4108  'uid' => 42,
4109  'title' => 'Page <b>title</b>',
4110  ),
4111  '<a href="index.php?id=42">Page <b>title</b></a>',
4112  ),
4113  'Link to page with script tag in title' => array(
4114  '',
4115  array(
4116  'parameter' => 42,
4117  ),
4118  array(
4119  'uid' => 42,
4120  'title' => '<script>alert(123)</script>Page title',
4121  ),
4122  '<a href="index.php?id=42">&lt;script&gt;alert(123)&lt;/script&gt;Page title</a>',
4123  ),
4124  );
4125  }
4126 
4135  public function typolinkReturnsCorrectLinksForPages($linkText, $configuration, $pageArray, $expectedResult)
4136  {
4137  $pageRepositoryMockObject = $this->getMock(\TYPO3\CMS\Frontend\Page\PageRepository::class, array('getPage'));
4138  $pageRepositoryMockObject->expects($this->any())->method('getPage')->willReturn($pageArray);
4139  $templateServiceObjectMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('dummy'));
4140  $templateServiceObjectMock->setup = array(
4141  'lib.' => array(
4142  'parseFunc.' => $this->getLibParseFunc(),
4143  ),
4144  );
4145  $typoScriptFrontendControllerMockObject = $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', false);
4146  $typoScriptFrontendControllerMockObject->config = array(
4147  'config' => array(),
4148  'mainScript' => 'index.php',
4149  );
4150  $typoScriptFrontendControllerMockObject->sys_page = $pageRepositoryMockObject;
4151  $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
4152  $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
4153  $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
4154 
4155  $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
4156  }
4157 
4162  {
4163  return array(
4164  'Link to file' => array(
4165  'My file',
4166  array(
4167  'parameter' => 'fileadmin/foo.bar',
4168  ),
4169  '<a href="fileadmin/foo.bar">My file</a>',
4170  ),
4171  'Link to file without link text' => array(
4172  '',
4173  array(
4174  'parameter' => 'fileadmin/foo.bar',
4175  ),
4176  '<a href="fileadmin/foo.bar">fileadmin/foo.bar</a>',
4177  ),
4178  'Link to file with attributes' => array(
4179  'My file',
4180  array(
4181  'parameter' => 'fileadmin/foo.bar',
4182  'ATagParams' => 'class="file-class"',
4183  'fileTarget' => '_blank',
4184  'title' => 'Title of the file',
4185  ),
4186  '<a href="fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
4187  ),
4188  'Link to file with attributes in parameter' => array(
4189  'My file',
4190  array(
4191  'parameter' => 'fileadmin/foo.bar _blank file-class "Title of the file"',
4192  ),
4193  '<a href="fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
4194  ),
4195  'Link to file with script tag in name' => array(
4196  '',
4197  array(
4198  'parameter' => 'fileadmin/<script>alert(123)</script>',
4199  ),
4200  '<a href="fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;">fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;</a>',
4201  ),
4202  );
4203  }
4204 
4212  public function typolinkReturnsCorrectLinksFiles($linkText, $configuration, $expectedResult)
4213  {
4214  $templateServiceObjectMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('dummy'));
4215  $templateServiceObjectMock->setup = array(
4216  'lib.' => array(
4217  'parseFunc.' => $this->getLibParseFunc(),
4218  ),
4219  );
4220  $typoScriptFrontendControllerMockObject = $this->getMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array(), array(), '', false);
4221  $typoScriptFrontendControllerMockObject->config = array(
4222  'config' => array(),
4223  'mainScript' => 'index.php',
4224  );
4225  $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
4226  $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
4227  $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
4228 
4229  $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
4230  }
4231 
4236  {
4237  $conf = array(
4238  'token' => ',',
4239  'returnCount' => 1
4240  );
4241  $expectedResult = 5;
4242  $amountOfEntries = $this->subject->splitObj('1, 2, 3, 4, 5', $conf);
4243  $this->assertSame(
4244  $expectedResult,
4245  $amountOfEntries
4246  );
4247  }
4248 
4253  {
4254  return array(
4255  array(
4256  array(
4257  'tt_content' => array(
4258  'ctrl' => array(
4259  ),
4260  'columns' => array(
4261  )
4262  ),
4263  ),
4264  'tt_content',
4265  array(
4266  'uidInList' => '42',
4267  'pidInList' => 43,
4268  'where' => 'tt_content.cruser_id=5',
4269  'andWhere' => 'tt_content.crdate>0',
4270  'groupBy' => 'tt_content.title',
4271  'orderBy' => 'tt_content.sorting',
4272  ),
4273  'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 AND tt_content.crdate>0 GROUP BY tt_content.title ORDER BY tt_content.sorting',
4274  ),
4275  array(
4276  array(
4277  'tt_content' => array(
4278  'ctrl' => array(
4279  'delete' => 'deleted',
4280  'enablecolumns' => array(
4281  'disabled' => 'hidden',
4282  'starttime' => 'startdate',
4283  'endtime' => 'enddate',
4284  ),
4285  'languageField' => 'sys_language_uid',
4286  'transOrigPointerField' => 'l18n_parent',
4287  ),
4288  'columns' => array(
4289  )
4290  ),
4291  ),
4292  'tt_content',
4293  array(
4294  'uidInList' => 42,
4295  'pidInList' => 43,
4296  'where' => 'tt_content.cruser_id=5',
4297  'andWhere' => 'tt_content.crdate>0',
4298  'groupBy' => 'tt_content.title',
4299  'orderBy' => 'tt_content.sorting',
4300  ),
4301  'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 AND (tt_content.sys_language_uid = 13) AND tt_content.crdate>0 AND tt_content.deleted=0 AND tt_content.hidden=0 AND tt_content.startdate<=4242 AND (tt_content.enddate=0 OR tt_content.enddate>4242) GROUP BY tt_content.title ORDER BY tt_content.sorting',
4302  ),
4303  array(
4304  array(
4305  'tt_content' => array(
4306  'ctrl' => array(
4307  'languageField' => 'sys_language_uid',
4308  'transOrigPointerField' => 'l18n_parent',
4309  ),
4310  'columns' => array(
4311  )
4312  ),
4313  ),
4314  'tt_content',
4315  array(
4316  'uidInList' => 42,
4317  'pidInList' => 43,
4318  'where' => 'tt_content.cruser_id=5',
4319  'languageField' => 0,
4320  ),
4321  'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5',
4322  ),
4323  );
4324  }
4325 
4334  public function getWhereReturnCorrectQuery($tca, $table, $configuration, $expectedResult)
4335  {
4336  $GLOBALS['TCA'] = $tca;
4337  $GLOBALS['SIM_ACCESS_TIME'] = '4242';
4338  $GLOBALS['TSFE']->sys_language_content = 13;
4340  $contentObjectRenderer = $this->getMock(ContentObjectRenderer::class, array('checkPidArray'));
4341  $contentObjectRenderer->expects($this->any())->method('checkPidArray')->willReturn(explode(',', $configuration['pidInList']));
4342  $this->assertEquals($expectedResult, $contentObjectRenderer->getWhere($table, $configuration));
4343  }
4344 
4346  // Test concerning link generation
4348 
4353  {
4354  $fileNameAndPath = PATH_site . 'typo3temp/phpunitJumpUrlTestFile with spaces & amps.txt';
4355  file_put_contents($fileNameAndPath, 'Some test data');
4356  $relativeFileNameAndPath = substr($fileNameAndPath, strlen(PATH_site));
4357  $fileName = substr($fileNameAndPath, strlen(PATH_site . 'typo3temp/'));
4358 
4359  $expectedLink = str_replace('%2F', '/', rawurlencode($relativeFileNameAndPath));
4360  $result = $this->subject->filelink($fileName, array('path' => 'typo3temp/'));
4361  $this->assertEquals('<a href="' . $expectedLink . '">' . $fileName . '</a>', $result);
4362 
4363  \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($fileNameAndPath);
4364  }
4365 }