[BUGFIX] EXT:form - wrong attribute handling
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / ContentObject / ContentObjectRendererTest.php
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
17 use Psr\Log\LoggerInterface;
18 use TYPO3\CMS\Core\Charset\CharsetConverter;
19 use TYPO3\CMS\Core\Core\ApplicationContext;
20 use TYPO3\CMS\Core\Log\LogManager;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
23 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
24
25 /**
26 * Testcase for TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
27 */
28 class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
29
30 /**
31 * @var array A backup of registered singleton instances
32 */
33 protected $singletonInstances = array();
34
35 /**
36 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
37 */
38 protected $subject = NULL;
39
40 /**
41 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
42 */
43 protected $typoScriptFrontendControllerMock = NULL;
44
45 /**
46 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\TypoScript\TemplateService
47 */
48 protected $templateServiceMock = NULL;
49
50 /**
51 * Default content object name -> class name map, shipped with TYPO3 CMS
52 *
53 * @var array
54 */
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
79 /**
80 * Set up
81 */
82 protected function setUp() {
83 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
84 $this->createMockedLoggerAndLogManager();
85
86 $this->templateServiceMock = $this->getMock(\TYPO3\CMS\Core\TypoScript\TemplateService::class, array('getFileName', 'linkData'));
87 $pageRepositoryMock = $this->getMock(\TYPO3\CMS\Frontend\Page\PageRepository::class, array('getRawRecord'));
88
89 $this->typoScriptFrontendControllerMock = $this->getAccessibleMock(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class, array('dummy'), array(), '', FALSE);
90 $this->typoScriptFrontendControllerMock->tmpl = $this->templateServiceMock;
91 $this->typoScriptFrontendControllerMock->config = array();
92 $this->typoScriptFrontendControllerMock->page = array();
93 $this->typoScriptFrontendControllerMock->sys_page = $pageRepositoryMock;
94 $this->typoScriptFrontendControllerMock->csConvObj = new CharsetConverter();
95 $this->typoScriptFrontendControllerMock->renderCharset = 'utf-8';
96 $GLOBALS['TSFE'] = $this->typoScriptFrontendControllerMock;
97
98 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection::class, array());
99 $GLOBALS['TYPO3_CONF_VARS']['SYS']['t3lib_cs_utils'] = 'mbstring';
100
101 $this->subject = $this->getAccessibleMock(
102 \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
103 array('getResourceFactory', 'getEnvironmentVariable'),
104 array($this->typoScriptFrontendControllerMock)
105 );
106 $this->subject->setContentObjectClassMap($this->contentObjectMap);
107 $this->subject->start(array(), 'tt_content');
108 }
109
110 protected function tearDown() {
111 GeneralUtility::resetSingletonInstances($this->singletonInstances);
112 parent::tearDown();
113 }
114
115 //////////////////////
116 // Utility functions
117 //////////////////////
118
119 /**
120 * Avoid logging to the file system (file writer is currently the only configured writer)
121 */
122 protected function createMockedLoggerAndLogManager() {
123 $logManagerMock = $this->getMock(LogManager::class);
124 $loggerMock = $this->getMock(LoggerInterface::class);
125 $logManagerMock->expects($this->any())
126 ->method('getLogger')
127 ->willReturn($loggerMock);
128 GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
129 }
130
131 /**
132 * Converts the subject and the expected result into the target charset.
133 *
134 * @param string $charset the target charset
135 * @param string $subject the subject, will be modified
136 * @param string $expected the expected result, will be modified
137 */
138 protected function handleCharset($charset, &$subject, &$expected) {
139 $GLOBALS['TSFE']->renderCharset = $charset;
140 $subject = $GLOBALS['TSFE']->csConvObj->conv($subject, 'iso-8859-1', $charset);
141 $expected = $GLOBALS['TSFE']->csConvObj->conv($expected, 'iso-8859-1', $charset);
142 }
143
144 /////////////////////////////////////////////
145 // Tests concerning the getImgResource hook
146 /////////////////////////////////////////////
147 /**
148 * @test
149 */
150 public function getImgResourceCallsGetImgResourcePostProcessHook() {
151 $this->templateServiceMock
152 ->expects($this->atLeastOnce())
153 ->method('getFileName')
154 ->with('typo3/clear.gif')
155 ->will($this->returnValue('typo3/clear.gif'));
156
157 $resourceFactory = $this->getMock(\TYPO3\CMS\Core\Resource\ResourceFactory::class, array(), array(), '', FALSE);
158 $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
159
160 $className = $this->getUniqueId('tx_coretest');
161 $getImgResourceHookMock = $this->getMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectGetImageResourceHookInterface::class, array('getImgResourcePostProcess'), array(), $className);
162 $getImgResourceHookMock
163 ->expects($this->once())
164 ->method('getImgResourcePostProcess')
165 ->will($this->returnCallback(array($this, 'isGetImgResourceHookCalledCallback')));
166 $getImgResourceHookObjects = array($getImgResourceHookMock);
167 $this->subject->_setRef('getImgResourceHookObjects', $getImgResourceHookObjects);
168 $this->subject->getImgResource('typo3/clear.gif', array());
169 }
170
171 /**
172 * Handles the arguments that have been sent to the getImgResource hook.
173 *
174 * @return array
175 * @see getImgResourceHookGetsCalled
176 */
177 public function isGetImgResourceHookCalledCallback() {
178 list($file, $fileArray, $imageResource, $parent) = func_get_args();
179 $this->assertEquals('typo3/clear.gif', $file);
180 $this->assertEquals('typo3/clear.gif', $imageResource['origFile']);
181 $this->assertTrue(is_array($fileArray));
182 $this->assertTrue($parent instanceof \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer);
183 return $imageResource;
184 }
185
186
187 //////////////////////////////////////
188 // Tests concerning getContentObject
189 //////////////////////////////////////
190
191 public function getContentObjectValidContentObjectsDataProvider() {
192 $dataProvider = array();
193 foreach ($this->contentObjectMap as $name => $className) {
194 $dataProvider[] = array($name, $className);
195 }
196 return $dataProvider;
197 }
198
199 /**
200 * @test
201 * @dataProvider getContentObjectValidContentObjectsDataProvider
202 * @param string $name TypoScript name of content object
203 * @param string $fullClassName Expected class name
204 */
205 public function getContentObjectCallsMakeInstanceForNewContentObjectInstance($name, $fullClassName) {
206 $contentObjectInstance = $this->getMock($fullClassName, array(), array(), '', FALSE);
207 \TYPO3\CMS\Core\Utility\GeneralUtility::addInstance($fullClassName, $contentObjectInstance);
208 $this->assertSame($contentObjectInstance, $this->subject->getContentObject($name));
209 }
210
211 /////////////////////////////////////////
212 // Tests concerning getQueryArguments()
213 /////////////////////////////////////////
214 /**
215 * @test
216 */
217 public function getQueryArgumentsExcludesParameters() {
218 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
219 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
220 );
221 $getQueryArgumentsConfiguration = array();
222 $getQueryArgumentsConfiguration['exclude'] = array();
223 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
224 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
225 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
226 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
227 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
228 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
229 $this->assertEquals($expectedResult, $actualResult);
230 }
231
232 /**
233 * @test
234 */
235 public function getQueryArgumentsExcludesGetParameters() {
236 $_GET = array(
237 'key1' => 'value1',
238 'key2' => 'value2',
239 'key3' => array(
240 'key31' => 'value31',
241 'key32' => array(
242 'key321' => 'value321',
243 'key322' => 'value322'
244 )
245 )
246 );
247 $getQueryArgumentsConfiguration = array();
248 $getQueryArgumentsConfiguration['method'] = 'GET';
249 $getQueryArgumentsConfiguration['exclude'] = array();
250 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
251 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
252 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
253 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
254 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
255 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
256 $this->assertEquals($expectedResult, $actualResult);
257 }
258
259 /**
260 * @test
261 */
262 public function getQueryArgumentsOverrulesSingleParameter() {
263 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
264 $this->returnValue('key1=value1')
265 );
266 $getQueryArgumentsConfiguration = array();
267 $overruleArguments = array(
268 // Should be overridden
269 'key1' => 'value1Overruled',
270 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
271 'key2' => 'value2Overruled'
272 );
273 $expectedResult = '&key1=value1Overruled';
274 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
275 $this->assertEquals($expectedResult, $actualResult);
276 }
277
278 /**
279 * @test
280 */
281 public function getQueryArgumentsOverrulesMultiDimensionalParameters() {
282 $_POST = array(
283 'key1' => 'value1',
284 'key2' => 'value2',
285 'key3' => array(
286 'key31' => 'value31',
287 'key32' => array(
288 'key321' => 'value321',
289 'key322' => 'value322'
290 )
291 )
292 );
293 $getQueryArgumentsConfiguration = array();
294 $getQueryArgumentsConfiguration['method'] = 'POST';
295 $getQueryArgumentsConfiguration['exclude'] = array();
296 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
297 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
298 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
299 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
300 $overruleArguments = array(
301 // Should be overriden
302 'key2' => 'value2Overruled',
303 'key3' => array(
304 'key32' => array(
305 // Shouldn't be set: Parameter is excluded and not forced
306 'key321' => 'value321Overruled',
307 // Should be overriden: Parameter is not excluded
308 'key322' => 'value322Overruled',
309 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
310 'key323' => 'value323Overruled'
311 )
312 )
313 );
314 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key322]=value322Overruled');
315 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
316 $this->assertEquals($expectedResult, $actualResult);
317 }
318
319 /**
320 * @test
321 */
322 public function getQueryArgumentsOverrulesMultiDimensionalForcedParameters() {
323 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
324 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
325 );
326 $_POST = array(
327 'key1' => 'value1',
328 'key2' => 'value2',
329 'key3' => array(
330 'key31' => 'value31',
331 'key32' => array(
332 'key321' => 'value321',
333 'key322' => 'value322'
334 )
335 )
336 );
337 $getQueryArgumentsConfiguration = array();
338 $getQueryArgumentsConfiguration['exclude'] = array();
339 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
340 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
341 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
342 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key322]';
343 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
344 $overruleArguments = array(
345 // Should be overriden
346 'key2' => 'value2Overruled',
347 'key3' => array(
348 'key32' => array(
349 // Should be set: Parameter is excluded but forced
350 'key321' => 'value321Overruled',
351 // Should be set: Parameter doesn't exist in source array but is forced
352 'key323' => 'value323Overruled'
353 )
354 )
355 );
356 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key321]=value321Overruled&key3[key32][key323]=value323Overruled');
357 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, TRUE);
358 $this->assertEquals($expectedResult, $actualResult);
359 $getQueryArgumentsConfiguration['method'] = 'POST';
360 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, TRUE);
361 $this->assertEquals($expectedResult, $actualResult);
362 }
363
364 /**
365 * @test
366 */
367 public function getQueryArgumentsWithMethodPostGetMergesParameters() {
368 $_POST = array(
369 'key1' => 'POST1',
370 'key2' => 'POST2',
371 'key3' => array(
372 'key31' => 'POST31',
373 'key32' => 'POST32',
374 'key33' => array(
375 'key331' => 'POST331',
376 'key332' => 'POST332',
377 )
378 )
379 );
380 $_GET = array(
381 'key2' => 'GET2',
382 'key3' => array(
383 'key32' => 'GET32',
384 'key33' => array(
385 'key331' => 'GET331',
386 )
387 )
388 );
389 $getQueryArgumentsConfiguration = array();
390 $getQueryArgumentsConfiguration['method'] = 'POST,GET';
391 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
392 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
393 $this->assertEquals($expectedResult, $actualResult);
394 }
395
396 /**
397 * @test
398 */
399 public function getQueryArgumentsWithMethodGetPostMergesParameters() {
400 $_GET = array(
401 'key1' => 'GET1',
402 'key2' => 'GET2',
403 'key3' => array(
404 'key31' => 'GET31',
405 'key32' => 'GET32',
406 'key33' => array(
407 'key331' => 'GET331',
408 'key332' => 'GET332',
409 )
410 )
411 );
412 $_POST = array(
413 'key2' => 'POST2',
414 'key3' => array(
415 'key32' => 'POST32',
416 'key33' => array(
417 'key331' => 'POST331',
418 )
419 )
420 );
421 $getQueryArgumentsConfiguration = array();
422 $getQueryArgumentsConfiguration['method'] = 'GET,POST';
423 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
424 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
425 $this->assertEquals($expectedResult, $actualResult);
426 }
427
428 /**
429 * Encodes square brackets in URL.
430 *
431 * @param string $string
432 * @return string
433 */
434 private function rawUrlEncodeSquareBracketsInUrl($string) {
435 return str_replace(array('[', ']'), array('%5B', '%5D'), $string);
436 }
437
438 //////////////////////////
439 // Tests concerning crop
440 //////////////////////////
441 /**
442 * @test
443 */
444 public function cropIsMultibyteSafe() {
445 $this->assertEquals('бла', $this->subject->crop('бла', '3|...'));
446 }
447
448 //////////////////////////////
449 // Tests concerning cropHTML
450 //////////////////////////////
451 /**
452 * This is the data provider for the tests of crop and cropHTML below. It provides all combinations
453 * of charset, text type, and configuration options to be tested.
454 *
455 * @return array two-dimensional array with the second level like this:
456 * @see cropHtmlWithDataProvider
457 */
458 public function cropHtmlDataProvider() {
459 $plainText = 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j implemented the original version of the crop function.';
460 $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.';
461 $textWithEntities = 'Kasper Sk&aring;rh&oslash;j implemented the; original ' . 'version of the crop function.';
462 $charsets = array('iso-8859-1', 'utf-8', 'ascii', 'big5');
463 $data = array();
464 foreach ($charsets as $charset) {
465 $data = array_merge($data, array(
466 $charset . ' plain text; 11|...' => array(
467 '11|...',
468 $plainText,
469 'Kasper Sk' . chr(229) . 'r...',
470 $charset
471 ),
472 $charset . ' plain text; -58|...' => array(
473 '-58|...',
474 $plainText,
475 '...h' . chr(248) . 'j implemented the original version of the crop function.',
476 $charset
477 ),
478 $charset . ' plain text; 4|...|1' => array(
479 '4|...|1',
480 $plainText,
481 'Kasp...',
482 $charset
483 ),
484 $charset . ' plain text; 20|...|1' => array(
485 '20|...|1',
486 $plainText,
487 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j...',
488 $charset
489 ),
490 $charset . ' plain text; -5|...|1' => array(
491 '-5|...|1',
492 $plainText,
493 '...tion.',
494 $charset
495 ),
496 $charset . ' plain text; -49|...|1' => array(
497 '-49|...|1',
498 $plainText,
499 '...the original version of the crop function.',
500 $charset
501 ),
502 $charset . ' text with markup; 11|...' => array(
503 '11|...',
504 $textWithMarkup,
505 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'r...</a></strong>',
506 $charset
507 ),
508 $charset . ' text with markup; 13|...' => array(
509 '13|...',
510 $textWithMarkup,
511 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . '...</a></strong>',
512 $charset
513 ),
514 $charset . ' text with markup; 14|...' => array(
515 '14|...',
516 $textWithMarkup,
517 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
518 $charset
519 ),
520 $charset . ' text with markup; 15|...' => array(
521 '15|...',
522 $textWithMarkup,
523 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> ...</strong>',
524 $charset
525 ),
526 $charset . ' text with markup; 29|...' => array(
527 '29|...',
528 $textWithMarkup,
529 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> th...',
530 $charset
531 ),
532 $charset . ' text with markup; -58|...' => array(
533 '-58|...',
534 $textWithMarkup,
535 '<strong><a href="mailto:kasper@typo3.org">...h' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.',
536 $charset
537 ),
538 $charset . ' text with markup 4|...|1' => array(
539 '4|...|1',
540 $textWithMarkup,
541 '<strong><a href="mailto:kasper@typo3.org">Kasp...</a></strong>',
542 $charset
543 ),
544 $charset . ' text with markup; 11|...|1' => array(
545 '11|...|1',
546 $textWithMarkup,
547 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>',
548 $charset
549 ),
550 $charset . ' text with markup; 13|...|1' => array(
551 '13|...|1',
552 $textWithMarkup,
553 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>',
554 $charset
555 ),
556 $charset . ' text with markup; 14|...|1' => array(
557 '14|...|1',
558 $textWithMarkup,
559 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
560 $charset
561 ),
562 $charset . ' text with markup; 15|...|1' => array(
563 '15|...|1',
564 $textWithMarkup,
565 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
566 $charset
567 ),
568 $charset . ' text with markup; 29|...|1' => array(
569 '29|...|1',
570 $textWithMarkup,
571 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong>...',
572 $charset
573 ),
574 $charset . ' text with markup; -66|...|1' => array(
575 '-66|...|1',
576 $textWithMarkup,
577 '<strong><a href="mailto:kasper@typo3.org">...Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.',
578 $charset
579 ),
580 $charset . ' text with entities 9|...' => array(
581 '9|...',
582 $textWithEntities,
583 'Kasper Sk...',
584 $charset
585 ),
586 $charset . ' text with entities 10|...' => array(
587 '10|...',
588 $textWithEntities,
589 'Kasper Sk&aring;...',
590 $charset
591 ),
592 $charset . ' text with entities 11|...' => array(
593 '11|...',
594 $textWithEntities,
595 'Kasper Sk&aring;r...',
596 $charset
597 ),
598 $charset . ' text with entities 13|...' => array(
599 '13|...',
600 $textWithEntities,
601 'Kasper Sk&aring;rh&oslash;...',
602 $charset
603 ),
604 $charset . ' text with entities 14|...' => array(
605 '14|...',
606 $textWithEntities,
607 'Kasper Sk&aring;rh&oslash;j...',
608 $charset
609 ),
610 $charset . ' text with entities 15|...' => array(
611 '15|...',
612 $textWithEntities,
613 'Kasper Sk&aring;rh&oslash;j ...',
614 $charset
615 ),
616 $charset . ' text with entities 16|...' => array(
617 '16|...',
618 $textWithEntities,
619 'Kasper Sk&aring;rh&oslash;j i...',
620 $charset
621 ),
622 $charset . ' text with entities -57|...' => array(
623 '-57|...',
624 $textWithEntities,
625 '...j implemented the; original version of the crop function.',
626 $charset
627 ),
628 $charset . ' text with entities -58|...' => array(
629 '-58|...',
630 $textWithEntities,
631 '...&oslash;j implemented the; original version of the crop function.',
632 $charset
633 ),
634 $charset . ' text with entities -59|...' => array(
635 '-59|...',
636 $textWithEntities,
637 '...h&oslash;j implemented the; original version of the crop function.',
638 $charset
639 ),
640 $charset . ' text with entities 4|...|1' => array(
641 '4|...|1',
642 $textWithEntities,
643 'Kasp...',
644 $charset
645 ),
646 $charset . ' text with entities 9|...|1' => array(
647 '9|...|1',
648 $textWithEntities,
649 'Kasper...',
650 $charset
651 ),
652 $charset . ' text with entities 10|...|1' => array(
653 '10|...|1',
654 $textWithEntities,
655 'Kasper...',
656 $charset
657 ),
658 $charset . ' text with entities 11|...|1' => array(
659 '11|...|1',
660 $textWithEntities,
661 'Kasper...',
662 $charset
663 ),
664 $charset . ' text with entities 13|...|1' => array(
665 '13|...|1',
666 $textWithEntities,
667 'Kasper...',
668 $charset
669 ),
670 $charset . ' text with entities 14|...|1' => array(
671 '14|...|1',
672 $textWithEntities,
673 'Kasper Sk&aring;rh&oslash;j...',
674 $charset
675 ),
676 $charset . ' text with entities 15|...|1' => array(
677 '15|...|1',
678 $textWithEntities,
679 'Kasper Sk&aring;rh&oslash;j...',
680 $charset
681 ),
682 $charset . ' text with entities 16|...|1' => array(
683 '16|...|1',
684 $textWithEntities,
685 'Kasper Sk&aring;rh&oslash;j...',
686 $charset
687 ),
688 $charset . ' text with entities -57|...|1' => array(
689 '-57|...|1',
690 $textWithEntities,
691 '...implemented the; original version of the crop function.',
692 $charset
693 ),
694 $charset . ' text with entities -58|...|1' => array(
695 '-58|...|1',
696 $textWithEntities,
697 '...implemented the; original version of the crop function.',
698 $charset
699 ),
700 $charset . ' text with entities -59|...|1' => array(
701 '-59|...|1',
702 $textWithEntities,
703 '...implemented the; original version of the crop function.',
704 $charset
705 ),
706 $charset . ' text with dash in html-element 28|...|1' => array(
707 '28|...|1',
708 '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',
709 'Some text with a link to <link email.address@example.org - mail "Open email window">my...</link>',
710 $charset
711 ),
712 $charset . ' html elements with dashes in attributes' => array(
713 '9',
714 '<em data-foo="x">foobar</em>foobaz',
715 '<em data-foo="x">foobar</em>foo',
716 $charset
717 ),
718 ));
719 }
720 return $data;
721 }
722
723 /**
724 * Checks if stdWrap.cropHTML works with plain text cropping from left
725 *
726 * @test
727 * @dataProvider cropHtmlDataProvider
728 * @param string $settings
729 * @param string $subject the string to crop
730 * @param string $expected the expected cropped result
731 * @param string $charset the charset that will be set as renderCharset
732 */
733 public function cropHtmlWithDataProvider($settings, $subject, $expected, $charset) {
734 $this->handleCharset($charset, $subject, $expected);
735 $this->assertEquals($expected, $this->subject->cropHTML($subject, $settings), 'cropHTML failed with settings: "' . $settings . '" and charset "' . $charset . '"');
736 }
737
738 /**
739 * Checks if stdWrap.cropHTML works with a complex content with many tags. Currently cropHTML
740 * counts multiple invisible characters not as one (as the browser will output the content).
741 *
742 * @test
743 */
744 public function cropHtmlWorksWithComplexContent() {
745 $GLOBALS['TSFE']->renderCharset = 'iso-8859-1';
746 $input =
747 '<h1>Blog Example</h1>' . LF .
748 '<hr>' . LF .
749 '<div class="csc-header csc-header-n1">' . LF .
750 ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
751 '</div>' . LF .
752 '<p class="bodytext">' . LF .
753 ' 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 .
754 '</p>' . LF .
755 '<div class="tx-blogexample-list-container">' . LF .
756 ' <p class="bodytext">' . LF .
757 ' Below are the most recent posts:' . LF .
758 ' </p>' . LF .
759 ' <ul>' . LF .
760 ' <li data-element="someId">' . LF .
761 ' <h3>' . LF .
762 ' <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 .
763 ' </h3>' . LF .
764 ' <p class="bodytext">' . LF .
765 ' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...' . LF .
766 ' </p>' . LF .
767 ' <p class="metadata">' . LF .
768 ' Published on 26.08.2009 by Jochen Rau' . LF .
769 ' </p>' . LF .
770 ' <p>' . LF .
771 ' Tags: [MVC]&nbsp;[Domain Driven Design]&nbsp;<br>' . LF .
772 ' <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 .
773 ' <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 .
774 ' </p>' . LF .
775 ' </li>' . LF .
776 ' </ul>' . LF .
777 ' <p>' . LF .
778 ' <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 .
779 ' </p>' . LF .
780 '</div>' . LF .
781 '<hr>' . LF .
782 '<p>' . LF .
783 ' ? TYPO3 Association' . LF .
784 '</p>';
785
786 $result = $this->subject->cropHTML($input, '300');
787
788 $expected =
789 '<h1>Blog Example</h1>' . LF .
790 '<hr>' . LF .
791 '<div class="csc-header csc-header-n1">' . LF .
792 ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
793 '</div>' . LF .
794 '<p class="bodytext">' . LF .
795 ' 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 .
796 '</p>' . LF .
797 '<div class="tx-blogexample-list-container">' . LF .
798 ' <p class="bodytext">' . LF .
799 ' Below are the most recent posts:' . LF .
800 ' </p>' . LF .
801 ' <ul>' . LF .
802 ' <li data-element="someId">' . LF .
803 ' <h3>' . LF .
804 ' <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>';
805
806 $this->assertEquals($expected, $result);
807
808 $result = $this->subject->cropHTML($input, '-100');
809
810 $expected =
811 '<div class="tx-blogexample-list-container"><ul><li data-element="someId"><p> Design]&nbsp;<br>' . LF .
812 ' <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 .
813 ' <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 .
814 ' </p>' . LF .
815 ' </li>' . LF .
816 ' </ul>' . LF .
817 ' <p>' . LF .
818 ' <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 .
819 ' </p>' . LF .
820 '</div>' . LF .
821 '<hr>' . LF .
822 '<p>' . LF .
823 ' ? TYPO3 Association' . LF .
824 '</p>';
825
826 $this->assertEquals($expected, $result);
827 }
828
829 /**
830 * @return array
831 */
832 public function stdWrap_roundDataProvider() {
833 return array(
834 'rounding off without any configuration' => array(
835 1.123456789,
836 array(),
837 1
838 ),
839 'rounding up without any configuration' => array(
840 1.523456789,
841 array(),
842 2
843 ),
844 'regular rounding (off) to two decimals' => array(
845 0.123456789,
846 array(
847 'decimals' => 2
848 ),
849 0.12
850 ),
851 'regular rounding (up) to two decimals' => array(
852 0.1256789,
853 array(
854 'decimals' => 2
855 ),
856 0.13
857 ),
858 'rounding up to integer with type ceil' => array(
859 0.123456789,
860 array(
861 'roundType' => 'ceil'
862 ),
863 1
864 ),
865 'rounding down to integer with type floor' => array(
866 2.3481,
867 array(
868 'roundType' => 'floor'
869 ),
870 2
871 )
872 );
873 }
874
875 /**
876 * Checks if stdWrap.cropHTML handles linebreaks correctly (by ignoring them)
877 *
878 * @test
879 */
880 public function cropHtmlWorksWithLinebreaks() {
881 $subject = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";
882 $expected = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna";
883 $result = $this->subject->cropHTML($subject, '121');
884 $this->assertEquals($expected, $result);
885 }
886
887 /**
888 * Test for the stdWrap function "round"
889 *
890 * @param float $float
891 * @param array $conf
892 * @param float $expected
893 * @return void
894 * @dataProvider stdWrap_roundDataProvider
895 * @test
896 */
897 public function stdWrap_round($float, $conf, $expected) {
898 $conf = array(
899 'round.' => $conf
900 );
901 $result = $this->subject->stdWrap_round($float, $conf);
902 $this->assertEquals($expected, $result);
903 }
904
905 /**
906 * @return array
907 */
908 public function stdWrap_trimDataProvider() {
909 return array(
910 'trimstring' => array(
911 'trimstring',
912 'trimstring',
913 ),
914 'trim string with space inside' => array(
915 'trim string',
916 'trim string',
917 ),
918 'trim string with space at the begin and end' => array(
919 ' trim string ',
920 'trim string',
921 ),
922 );
923 }
924
925 /**
926 * Test for the stdWrap function "trim"
927 *
928 * @param string $content
929 * @param string $expected
930 *
931 * @dataProvider stdWrap_trimDataProvider
932 * @test
933 */
934 public function stdWrap_trim($content, $expected) {
935 $result = $this->subject->stdWrap_trim($content);
936 $this->assertEquals($expected, $result);
937 }
938
939 /**
940 * @return array
941 */
942 public function stdWrap_intvalDataProvider() {
943 return array(
944 'number' => array(
945 '123',
946 123,
947 ),
948 'float' => array(
949 '123.45',
950 123,
951 ),
952 'string' => array(
953 'string',
954 0,
955 ),
956 'zero' => array(
957 '0',
958 0,
959 ),
960 'empty' => array(
961 '',
962 0,
963 ),
964 'NULL' => array(
965 NULL,
966 0,
967 ),
968 'bool TRUE' => array(
969 TRUE,
970 1,
971 ),
972 'bool FALSE' => array(
973 FALSE,
974 0,
975 ),
976 );
977 }
978
979 /**
980 * Test for the stdWrap function "intval"
981 *
982 * @param string $content
983 * @param int $expected
984 *
985 * @dataProvider stdWrap_intvalDataProvider
986 * @test
987 */
988 public function stdWrap_intval($content, $expected) {
989 $result = $this->subject->stdWrap_intval($content);
990 $this->assertEquals($expected, $result);
991 }
992
993 /**
994 * @return array
995 */
996 public function stdWrap_strPadDataProvider() {
997 return array(
998 'pad string with default settings and length 10' => array(
999 'Alien',
1000 array(
1001 'length' => '10',
1002 ),
1003 'Alien ',
1004 ),
1005 'pad string with padWith -= and type left and length 10' => array(
1006 'Alien',
1007 array(
1008 'length' => '10',
1009 'padWith' => '-=',
1010 'type' => 'left',
1011 ),
1012 '-=-=-Alien',
1013 ),
1014 'pad string with padWith _ and type both and length 10' => array(
1015 'Alien',
1016 array(
1017 'length' => '10',
1018 'padWith' => '_',
1019 'type' => 'both',
1020 ),
1021 '__Alien___',
1022 ),
1023 'pad string with padWith 0 and type both and length 10' => array(
1024 'Alien',
1025 array(
1026 'length' => '10',
1027 'padWith' => '0',
1028 'type' => 'both',
1029 ),
1030 '00Alien000',
1031 ),
1032 'pad string with padWith ___ and type both and length 6' => array(
1033 'Alien',
1034 array(
1035 'length' => '6',
1036 'padWith' => '___',
1037 'type' => 'both',
1038 ),
1039 'Alien_',
1040 ),
1041 'pad string with padWith _ and type both and length 12, using stdWrap for length' => array(
1042 'Alien',
1043 array(
1044 'length' => '1',
1045 'length.' => array(
1046 'wrap' => '|2',
1047 ),
1048 'padWith' => '_',
1049 'type' => 'both',
1050 ),
1051 '___Alien____',
1052 ),
1053 'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => array(
1054 'Alien',
1055 array(
1056 'length' => '12',
1057 'padWith' => '_',
1058 'padWith.' => array(
1059 'wrap' => '-|=',
1060 ),
1061 'type' => 'both',
1062 ),
1063 '-_=Alien-_=-',
1064 ),
1065 'pad string with padWith _ and type both and length 12, using stdWrap for type' => array(
1066 'Alien',
1067 array(
1068 'length' => '12',
1069 'padWith' => '_',
1070 'type' => 'both',
1071 // make type become "left"
1072 'type.' => array(
1073 'substring' => '2,1',
1074 'wrap' => 'lef|',
1075 ),
1076 ),
1077 '_______Alien',
1078 ),
1079 );
1080 }
1081
1082 /**
1083 * Test for the stdWrap function "strPad"
1084 *
1085 * @param string $content
1086 * @param array $conf
1087 * @param string $expected
1088 *
1089 * @dataProvider stdWrap_strPadDataProvider
1090 * @test
1091 */
1092 public function stdWrap_strPad($content, $conf, $expected) {
1093 $conf = array(
1094 'strPad.' => $conf
1095 );
1096 $result = $this->subject->stdWrap_strPad($content, $conf);
1097 $this->assertEquals($expected, $result);
1098 }
1099
1100 /**
1101 * Data provider for the hash test
1102 *
1103 * @return array multi-dimensional array with the second level like this:
1104 * @see hash
1105 */
1106 public function hashDataProvider() {
1107 $data = array(
1108 'testing md5' => array(
1109 'joh316',
1110 array(
1111 'hash' => 'md5'
1112 ),
1113 'bacb98acf97e0b6112b1d1b650b84971'
1114 ),
1115 'testing sha1' => array(
1116 'joh316',
1117 array(
1118 'hash' => 'sha1'
1119 ),
1120 '063b3d108bed9f88fa618c6046de0dccadcf3158'
1121 ),
1122 'testing non-existing hashing algorithm' => array(
1123 'joh316',
1124 array(
1125 'hash' => 'non-existing'
1126 ),
1127 ''
1128 ),
1129 'testing stdWrap capability' => array(
1130 'joh316',
1131 array(
1132 'hash.' => array(
1133 'cObject' => 'TEXT',
1134 'cObject.' => array(
1135 'value' => 'md5'
1136 )
1137 )
1138 ),
1139 'bacb98acf97e0b6112b1d1b650b84971'
1140 )
1141 );
1142 return $data;
1143 }
1144
1145 /**
1146 * Test for the stdWrap function "hash"
1147 *
1148 * @param string $text
1149 * @param array $conf
1150 * @param string $expected
1151 * @return void
1152 * @dataProvider hashDataProvider
1153 * @test
1154 */
1155 public function stdWrap_hash($text, array $conf, $expected) {
1156 $result = $this->subject->stdWrap_hash($text, $conf);
1157 $this->assertEquals($expected, $result);
1158 }
1159
1160 /**
1161 * @test
1162 */
1163 public function recursiveStdWrapProperlyRendersBasicString() {
1164 $stdWrapConfiguration = array(
1165 'noTrimWrap' => '|| 123|',
1166 'stdWrap.' => array(
1167 'wrap' => '<b>|</b>'
1168 )
1169 );
1170 $this->assertSame(
1171 '<b>Test</b> 123',
1172 $this->subject->stdWrap('Test', $stdWrapConfiguration)
1173 );
1174 }
1175
1176 /**
1177 * @test
1178 */
1179 public function recursiveStdWrapIsOnlyCalledOnce() {
1180 $stdWrapConfiguration = array(
1181 'append' => 'TEXT',
1182 'append.' => array(
1183 'data' => 'register:Counter'
1184 ),
1185 'stdWrap.' => array(
1186 'append' => 'LOAD_REGISTER',
1187 'append.' => array(
1188 'Counter.' => array(
1189 'prioriCalc' => 'intval',
1190 'cObject' => 'TEXT',
1191 'cObject.' => array(
1192 'data' => 'register:Counter',
1193 'wrap' => '|+1',
1194 )
1195 )
1196 )
1197 )
1198 );
1199 $this->assertSame(
1200 'Counter:1',
1201 $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
1202 );
1203 }
1204
1205 /**
1206 * Data provider for the numberFormat test
1207 *
1208 * @return array multi-dimensional array with the second level like this:
1209 * @see numberFormat
1210 */
1211 public function numberFormatDataProvider() {
1212 $data = array(
1213 'testing decimals' => array(
1214 0.8,
1215 array(
1216 'decimals' => 2
1217 ),
1218 '0.80'
1219 ),
1220 'testing decimals with input as string' => array(
1221 '0.8',
1222 array(
1223 'decimals' => 2
1224 ),
1225 '0.80'
1226 ),
1227 'testing dec_point' => array(
1228 0.8,
1229 array(
1230 'decimals' => 1,
1231 'dec_point' => ','
1232 ),
1233 '0,8'
1234 ),
1235 'testing thousands_sep' => array(
1236 999.99,
1237 array(
1238 'decimals' => 0,
1239 'thousands_sep.' => array(
1240 'char' => 46
1241 )
1242 ),
1243 '1.000'
1244 ),
1245 'testing mixture' => array(
1246 1281731.45,
1247 array(
1248 'decimals' => 1,
1249 'dec_point.' => array(
1250 'char' => 44
1251 ),
1252 'thousands_sep.' => array(
1253 'char' => 46
1254 )
1255 ),
1256 '1.281.731,5'
1257 )
1258 );
1259 return $data;
1260 }
1261
1262 /**
1263 * Check if stdWrap.numberFormat and all of its properties work properly
1264 *
1265 * @dataProvider numberFormatDataProvider
1266 * @test
1267 */
1268 public function numberFormat($float, $formatConf, $expected) {
1269 $result = $this->subject->numberFormat($float, $formatConf);
1270 $this->assertEquals($expected, $result);
1271 }
1272
1273 /**
1274 * Data provider for the replacement test
1275 *
1276 * @return array multi-dimensional array with the second level like this:
1277 * @see replacement
1278 */
1279 public function replacementDataProvider() {
1280 $data = array(
1281 'multiple replacements, including regex' => array(
1282 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
1283 array(
1284 'replacement.' => array(
1285 '120.' => array(
1286 'search' => 'in da hood',
1287 'replace' => 'around the block'
1288 ),
1289 '20.' => array(
1290 'search' => '_',
1291 'replace.' => array('char' => '32')
1292 ),
1293 '130.' => array(
1294 'search' => '#a (Cat|Dog|Tiger)#i',
1295 'replace' => 'an animal',
1296 'useRegExp' => '1'
1297 )
1298 )
1299 ),
1300 'There is an animal, an animal and an animal around the block! Yeah!'
1301 ),
1302 'replacement with optionSplit, normal pattern' => array(
1303 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
1304 array(
1305 'replacement.' => array(
1306 '10.' => array(
1307 'search' => '_',
1308 'replace' => '1 || 2 || 3',
1309 'useOptionSplitReplace' => '1'
1310 ),
1311 )
1312 ),
1313 'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!'
1314 ),
1315 'replacement with optionSplit, using regex' => array(
1316 'There is a cat, a dog and a tiger in da hood! Yeah!',
1317 array(
1318 'replacement.' => array(
1319 '10.' => array(
1320 'search' => '#(a) (Cat|Dog|Tiger)#i',
1321 'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
1322 'useOptionSplitReplace' => '1',
1323 'useRegExp' => '1'
1324 )
1325 )
1326 ),
1327 'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!'
1328 ),
1329 );
1330 return $data;
1331 }
1332
1333 /**
1334 * Check if stdWrap.replacement and all of its properties work properly
1335 *
1336 * @dataProvider replacementDataProvider
1337 * @test
1338 */
1339 public function replacement($input, $conf, $expected) {
1340 $result = $this->subject->stdWrap_replacement($input, $conf);
1341 $this->assertEquals($expected, $result);
1342 }
1343
1344 /**
1345 * Data provider for the getQuery test
1346 *
1347 * @return array multi-dimensional array with the second level like this:
1348 * @see getQuery
1349 */
1350 public function getQueryDataProvider() {
1351 $data = array(
1352 'testing empty conf' => array(
1353 'tt_content',
1354 array(),
1355 array(
1356 'SELECT' => '*'
1357 )
1358 ),
1359 'testing #17284: adding uid/pid for workspaces' => array(
1360 'tt_content',
1361 array(
1362 'selectFields' => 'header,bodytext'
1363 ),
1364 array(
1365 'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
1366 )
1367 ),
1368 'testing #17284: no need to add' => array(
1369 'tt_content',
1370 array(
1371 'selectFields' => 'tt_content.*'
1372 ),
1373 array(
1374 'SELECT' => 'tt_content.*'
1375 )
1376 ),
1377 'testing #17284: no need to add #2' => array(
1378 'tt_content',
1379 array(
1380 'selectFields' => '*'
1381 ),
1382 array(
1383 'SELECT' => '*'
1384 )
1385 ),
1386 'testing #29783: joined tables, prefix tablename' => array(
1387 'tt_content',
1388 array(
1389 'selectFields' => 'tt_content.header,be_users.username',
1390 'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
1391 ),
1392 array(
1393 'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
1394 )
1395 ),
1396 'testing #34152: single count(*), add nothing' => array(
1397 'tt_content',
1398 array(
1399 'selectFields' => 'count(*)'
1400 ),
1401 array(
1402 'SELECT' => 'count(*)'
1403 )
1404 ),
1405 'testing #34152: single max(crdate), add nothing' => array(
1406 'tt_content',
1407 array(
1408 'selectFields' => 'max(crdate)'
1409 ),
1410 array(
1411 'SELECT' => 'max(crdate)'
1412 )
1413 ),
1414 'testing #34152: single min(crdate), add nothing' => array(
1415 'tt_content',
1416 array(
1417 'selectFields' => 'min(crdate)'
1418 ),
1419 array(
1420 'SELECT' => 'min(crdate)'
1421 )
1422 ),
1423 'testing #34152: single sum(is_siteroot), add nothing' => array(
1424 'tt_content',
1425 array(
1426 'selectFields' => 'sum(is_siteroot)'
1427 ),
1428 array(
1429 'SELECT' => 'sum(is_siteroot)'
1430 )
1431 ),
1432 'testing #34152: single avg(crdate), add nothing' => array(
1433 'tt_content',
1434 array(
1435 'selectFields' => 'avg(crdate)'
1436 ),
1437 array(
1438 'SELECT' => 'avg(crdate)'
1439 )
1440 )
1441 );
1442 return $data;
1443 }
1444
1445 /**
1446 * Check if sanitizeSelectPart works as expected
1447 *
1448 * @dataProvider getQueryDataProvider
1449 * @test
1450 */
1451 public function getQuery($table, $conf, $expected) {
1452 $GLOBALS['TCA'] = array(
1453 'pages' => array(
1454 'ctrl' => array(
1455 'enablecolumns' => array(
1456 'disabled' => 'hidden'
1457 )
1458 )
1459 ),
1460 'tt_content' => array(
1461 'ctrl' => array(
1462 'enablecolumns' => array(
1463 'disabled' => 'hidden'
1464 ),
1465 'versioningWS' => 2
1466 )
1467 ),
1468 );
1469 $result = $this->subject->getQuery($table, $conf, TRUE);
1470 foreach ($expected as $field => $value) {
1471 $this->assertEquals($value, $result[$field]);
1472 }
1473 }
1474
1475 /**
1476 * @test
1477 */
1478 public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet() {
1479 $GLOBALS['TCA'] = array(
1480 'pages' => array(
1481 'ctrl' => array(
1482 'enablecolumns' => array(
1483 'disabled' => 'hidden'
1484 )
1485 )
1486 ),
1487 'tt_content' => array(
1488 'ctrl' => array(
1489 'enablecolumns' => array(
1490 'disabled' => 'hidden'
1491 )
1492 )
1493 ),
1494 );
1495 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
1496 $this->subject->start(array(), 'tt_content');
1497 $conf = array(
1498 'recursive' => '15',
1499 'pidInList' => '16, -35'
1500 );
1501 $this->subject->expects($this->at(0))
1502 ->method('getTreeList')
1503 ->with(-16, 15)
1504 ->will($this->returnValue('15,16'));
1505 $this->subject->expects($this->at(1))
1506 ->method('getTreeList')
1507 ->with(-35, 15)
1508 ->will($this->returnValue('15,35'));
1509 $this->subject->getQuery('tt_content', $conf, TRUE);
1510 }
1511
1512 /**
1513 * @test
1514 */
1515 public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet() {
1516 $GLOBALS['TCA'] = array(
1517 'pages' => array(
1518 'ctrl' => array(
1519 'enablecolumns' => array(
1520 'disabled' => 'hidden'
1521 )
1522 )
1523 ),
1524 'tt_content' => array(
1525 'ctrl' => array(
1526 'enablecolumns' => array(
1527 'disabled' => 'hidden'
1528 )
1529 )
1530 ),
1531 );
1532 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
1533 $GLOBALS['TSFE']->id = 27;
1534 $this->subject->start(array(), 'tt_content');
1535 $conf = array(
1536 'pidInList' => 'this',
1537 'recursive' => '4'
1538 );
1539 $this->subject->expects($this->once())
1540 ->method('getTreeList')
1541 ->with(-27)
1542 ->will($this->returnValue('27'));
1543 $this->subject->getQuery('tt_content', $conf, TRUE);
1544 }
1545
1546 /**
1547 * Data provider for the stdWrap_strftime test
1548 *
1549 * @return array multi-dimensional array with the second level like this:
1550 * @see stdWrap_strftime
1551 */
1552 public function stdWrap_strftimeReturnsFormattedStringDataProvider() {
1553 $data = array(
1554 'given timestamp' => array(
1555 1346500800, // This is 2012-09-01 12:00 in UTC/GMT
1556 array(
1557 'strftime' => '%d-%m-%Y',
1558 ),
1559 ),
1560 'empty string' => array(
1561 '',
1562 array(
1563 'strftime' => '%d-%m-%Y',
1564 ),
1565 ),
1566 'testing null' => array(
1567 NULL,
1568 array(
1569 'strftime' => '%d-%m-%Y',
1570 ),
1571 ),
1572 );
1573 return $data;
1574 }
1575
1576 /**
1577 * @test
1578 * @dataProvider stdWrap_strftimeReturnsFormattedStringDataProvider
1579 */
1580 public function stdWrap_strftimeReturnsFormattedString($content, $conf) {
1581 // Set exec_time to a hard timestamp
1582 $GLOBALS['EXEC_TIME'] = 1346500800;
1583 // Save current timezone and set to UTC to make the system under test behave
1584 // the same in all server timezone settings
1585 $timezoneBackup = date_default_timezone_get();
1586 date_default_timezone_set('UTC');
1587
1588 $result = $this->subject->stdWrap_strftime($content, $conf);
1589
1590 // Reset timezone
1591 date_default_timezone_set($timezoneBackup);
1592
1593 $this->assertEquals('01-09-2012', $result);
1594 }
1595
1596 /**
1597 * Data provider for the stdWrap_strtotime test
1598 *
1599 * @return array
1600 * @see stdWrap_strtotime
1601 */
1602 public function stdWrap_strtotimeReturnsTimestampDataProvider() {
1603 return array(
1604 'date from content' => array(
1605 '2014-12-04',
1606 array(
1607 'strtotime' => '1',
1608 ),
1609 1417651200,
1610 ),
1611 'manipulation of date from content' => array(
1612 '2014-12-04',
1613 array(
1614 'strtotime' => '+ 2 weekdays',
1615 ),
1616 1417996800,
1617 ),
1618 'date from configuration' => array(
1619 '',
1620 array(
1621 'strtotime' => '2014-12-04',
1622 ),
1623 1417651200,
1624 ),
1625 'manipulation of date from configuration' => array(
1626 '',
1627 array(
1628 'strtotime' => '2014-12-04 + 2 weekdays',
1629 ),
1630 1417996800,
1631 ),
1632 'empty input' => array(
1633 '',
1634 array(
1635 'strtotime' => '1',
1636 ),
1637 FALSE,
1638 ),
1639 'date from content and configuration' => array(
1640 '2014-12-04',
1641 array(
1642 'strtotime' => '2014-12-05',
1643 ),
1644 FALSE,
1645 ),
1646 );
1647 }
1648
1649 /**
1650 * @param string|NULL $content
1651 * @param array $configuration
1652 * @param int $expected
1653 * @dataProvider stdWrap_strtotimeReturnsTimestampDataProvider
1654 * @test
1655 */
1656 public function stdWrap_strtotimeReturnsTimestamp($content, $configuration, $expected) {
1657 // Set exec_time to a hard timestamp
1658 $GLOBALS['EXEC_TIME'] = 1417392000;
1659 // Save current timezone and set to UTC to make the system under test behave
1660 // the same in all server timezone settings
1661 $timezoneBackup = date_default_timezone_get();
1662 date_default_timezone_set('UTC');
1663
1664 $result = $this->subject->stdWrap_strtotime($content, $configuration);
1665
1666 // Reset timezone
1667 date_default_timezone_set($timezoneBackup);
1668
1669 $this->assertEquals($expected, $result);
1670 }
1671
1672 /**
1673 * Data provider for stdWrap_stdWrapValue test
1674 *
1675 * @return array
1676 */
1677 public function stdWrap_stdWrapValueDataProvider() {
1678 return array(
1679 'only key returns value' => array(
1680 'ifNull',
1681 array(
1682 'ifNull' => '1',
1683 ),
1684 '',
1685 '1',
1686 ),
1687 'array without key returns empty string' => array(
1688 'ifNull',
1689 array(
1690 'ifNull.' => '1',
1691 ),
1692 '',
1693 '',
1694 ),
1695 'array without key returns default' => array(
1696 'ifNull',
1697 array(
1698 'ifNull.' => '1',
1699 ),
1700 'default',
1701 'default',
1702 ),
1703 'non existing key returns default' => array(
1704 'ifNull',
1705 array(
1706 'noTrimWrap' => 'test',
1707 'noTrimWrap.' => '1',
1708 ),
1709 'default',
1710 'default',
1711 ),
1712 'existing key and array returns stdWrap' => array(
1713 'test',
1714 array(
1715 'test' => 'value',
1716 'test.' => array('case' => 'upper'),
1717 ),
1718 'default',
1719 'VALUE'
1720 ),
1721 );
1722 }
1723
1724 /**
1725 * @param string $key
1726 * @param array $configuration
1727 * @param string $defaultValue
1728 * @param string $expected
1729 * @dataProvider stdWrap_stdWrapValueDataProvider
1730 * @test
1731 */
1732 public function stdWrap_stdWrapValue($key, array $configuration, $defaultValue, $expected) {
1733 $result = $this->subject->stdWrapValue($key, $configuration, $defaultValue);
1734 $this->assertEquals($expected, $result);
1735 }
1736
1737 /**
1738 * @param string|NULL $content
1739 * @param array $configuration
1740 * @param string $expected
1741 * @dataProvider stdWrap_ifNullDeterminesNullValuesDataProvider
1742 * @test
1743 */
1744 public function stdWrap_ifNullDeterminesNullValues($content, array $configuration, $expected) {
1745 $result = $this->subject->stdWrap_ifNull($content, $configuration);
1746 $this->assertEquals($expected, $result);
1747 }
1748
1749 /**
1750 * Data provider for stdWrap_ifNullDeterminesNullValues test
1751 *
1752 * @return array
1753 */
1754 public function stdWrap_ifNullDeterminesNullValuesDataProvider() {
1755 return array(
1756 'null value' => array(
1757 NULL,
1758 array(
1759 'ifNull' => '1',
1760 ),
1761 '1',
1762 ),
1763 'zero value' => array(
1764 '0',
1765 array(
1766 'ifNull' => '1',
1767 ),
1768 '0',
1769 ),
1770 );
1771 }
1772
1773 /**
1774 * Data provider for stdWrap_ifEmptyDeterminesEmptyValues test
1775 *
1776 * @return array
1777 */
1778 public function stdWrap_ifEmptyDeterminesEmptyValuesDataProvider() {
1779 return array(
1780 'null value' => array(
1781 NULL,
1782 array(
1783 'ifEmpty' => '1',
1784 ),
1785 '1',
1786 ),
1787 'empty value' => array(
1788 '',
1789 array(
1790 'ifEmpty' => '1',
1791 ),
1792 '1',
1793 ),
1794 'string value' => array(
1795 'string',
1796 array(
1797 'ifEmpty' => '1',
1798 ),
1799 'string',
1800 ),
1801 'empty string value' => array(
1802 ' ',
1803 array(
1804 'ifEmpty' => '1',
1805 ),
1806 '1',
1807 ),
1808 );
1809 }
1810
1811 /**
1812 * @param string|NULL $content
1813 * @param array $configuration
1814 * @param string $expected
1815 * @dataProvider stdWrap_ifEmptyDeterminesEmptyValuesDataProvider
1816 * @test
1817 */
1818 public function stdWrap_ifEmptyDeterminesEmptyValues($content, array $configuration, $expected) {
1819 $result = $this->subject->stdWrap_ifEmpty($content, $configuration);
1820 $this->assertEquals($expected, $result);
1821 }
1822
1823 /**
1824 * @param $content
1825 * @param array $configuration
1826 * @param $expected
1827 * @dataProvider stdWrap_noTrimWrapAcceptsSplitCharDataProvider
1828 * @test
1829 */
1830 public function stdWrap_noTrimWrapAcceptsSplitChar($content, array $configuration, $expected) {
1831 $result = $this->subject->stdWrap_noTrimWrap($content, $configuration);
1832 $this->assertEquals($expected, $result);
1833 }
1834
1835 /**
1836 * Data provider for stdWrap_noTrimWrapAcceptsSplitChar test
1837 *
1838 * @return array
1839 */
1840 public function stdWrap_noTrimWrapAcceptsSplitCharDataProvider() {
1841 return array(
1842 'No char given' => array(
1843 'middle',
1844 array(
1845 'noTrimWrap' => '| left | right |',
1846 ),
1847 ' left middle right '
1848 ),
1849 'Zero char given' => array(
1850 'middle',
1851 array(
1852 'noTrimWrap' => '0 left 0 right 0',
1853 'noTrimWrap.' => array('splitChar' => '0'),
1854
1855 ),
1856 ' left middle right '
1857 ),
1858 'Default char given' => array(
1859 'middle',
1860 array(
1861 'noTrimWrap' => '| left | right |',
1862 'noTrimWrap.' => array('splitChar' => '|'),
1863 ),
1864 ' left middle right '
1865 ),
1866 'Split char is a' => array(
1867 'middle',
1868 array(
1869 'noTrimWrap' => 'a left a right a',
1870 'noTrimWrap.' => array('splitChar' => 'a'),
1871 ),
1872 ' left middle right '
1873 ),
1874 'Split char is multi-char (ab)' => array(
1875 'middle',
1876 array(
1877 'noTrimWrap' => 'ab left ab right ab',
1878 'noTrimWrap.' => array('splitChar' => 'ab'),
1879 ),
1880 ' left middle right '
1881 ),
1882 'Split char accepts stdWrap' => array(
1883 'middle',
1884 array(
1885 'noTrimWrap' => 'abc left abc right abc',
1886 'noTrimWrap.' => array(
1887 'splitChar' => 'b',
1888 'splitChar.' => array('wrap' => 'a|c'),
1889 ),
1890 ),
1891 ' left middle right '
1892 ),
1893 );
1894 }
1895
1896 /**
1897 * @param array $expectedTags
1898 * @param array $configuration
1899 * @test
1900 * @dataProvider stdWrap_addPageCacheTagsAddsPageTagsDataProvider
1901 */
1902 public function stdWrap_addPageCacheTagsAddsPageTags(array $expectedTags, array $configuration) {
1903 $this->subject->stdWrap_addPageCacheTags('', $configuration);
1904 $this->assertEquals($expectedTags, $this->typoScriptFrontendControllerMock->_get('pageCacheTags'));
1905 }
1906
1907 /**
1908 * @return array
1909 */
1910 public function stdWrap_addPageCacheTagsAddsPageTagsDataProvider() {
1911 return array(
1912 'No Tag' => array(
1913 array(),
1914 array('addPageCacheTags' => ''),
1915 ),
1916 'Two expectedTags' => array(
1917 array('tag1', 'tag2'),
1918 array('addPageCacheTags' => 'tag1,tag2'),
1919 ),
1920 'Two expectedTags plus one with stdWrap' => array(
1921 array('tag1', 'tag2', 'tag3'),
1922 array(
1923 'addPageCacheTags' => 'tag1,tag2',
1924 'addPageCacheTags.' => array('wrap' => '|,tag3')
1925 ),
1926 ),
1927 );
1928 }
1929
1930 /**
1931 * Data provider for stdWrap_encodeForJavaScriptValue test
1932 *
1933 * @return array multi-dimensional array with the second level like this:
1934 * @see encodeForJavaScriptValue
1935 */
1936 public function stdWrap_encodeForJavaScriptValueDataProvider() {
1937 return array(
1938 'double quote in string' => array(
1939 'double quote"',
1940 array(),
1941 '\'double\u0020quote\u0022\''
1942 ),
1943 'backslash in string' => array(
1944 'backslash \\',
1945 array(),
1946 '\'backslash\u0020\u005C\''
1947 ),
1948 'exclamation mark' => array(
1949 'exclamation!',
1950 array(),
1951 '\'exclamation\u0021\''
1952 ),
1953 'whitespace tab, newline and carriage return' => array(
1954 "white\tspace\ns\r",
1955 array(),
1956 '\'white\u0009space\u000As\u000D\''
1957 ),
1958 'single quote in string' => array(
1959 'single quote \'',
1960 array(),
1961 '\'single\u0020quote\u0020\u0027\''
1962 ),
1963 'tag' => array(
1964 '<tag>',
1965 array(),
1966 '\'\u003Ctag\u003E\''
1967 ),
1968 'ampersand in string' => array(
1969 'amper&sand',
1970 array(),
1971 '\'amper\u0026sand\''
1972 ),
1973 );
1974 }
1975
1976 /**
1977 * Check if encodeForJavaScriptValue works properly
1978 *
1979 * @dataProvider stdWrap_encodeForJavaScriptValueDataProvider
1980 * @test
1981 */
1982 public function stdWrap_encodeForJavaScriptValue($input, $conf, $expected) {
1983 $result = $this->subject->stdWrap_encodeForJavaScriptValue($input, $conf);
1984 $this->assertEquals($expected, $result);
1985 }
1986
1987
1988 ///////////////////////////////
1989 // Tests concerning getData()
1990 ///////////////////////////////
1991
1992 /**
1993 * @return array
1994 */
1995 public function getDataWithTypeGpDataProvider() {
1996 return array(
1997 'Value in get-data' => array('onlyInGet', 'GetValue'),
1998 'Value in post-data' => array('onlyInPost', 'PostValue'),
1999 'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
2000 );
2001 }
2002
2003 /**
2004 * Checks if getData() works with type "gp"
2005 *
2006 * @test
2007 * @dataProvider getDataWithTypeGpDataProvider
2008 */
2009 public function getDataWithTypeGp($key, $expectedValue) {
2010 $_GET = array(
2011 'onlyInGet' => 'GetValue',
2012 'inGetAndPost' => 'ValueInGet',
2013 );
2014 $_POST = array(
2015 'onlyInPost' => 'PostValue',
2016 'inGetAndPost' => 'ValueInPost',
2017 );
2018 $this->assertEquals($expectedValue, $this->subject->getData('gp:' . $key));
2019 }
2020
2021 /**
2022 * Checks if getData() works with type "tsfe"
2023 *
2024 * @test
2025 */
2026 public function getDataWithTypeTsfe() {
2027 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->subject->getData('tsfe:renderCharset'));
2028 }
2029
2030 /**
2031 * Checks if getData() works with type "getenv"
2032 *
2033 * @test
2034 */
2035 public function getDataWithTypeGetenv() {
2036 $envName = $this->getUniqueId('frontendtest');
2037 $value = $this->getUniqueId('someValue');
2038 putenv($envName . '=' . $value);
2039 $this->assertEquals($value, $this->subject->getData('getenv:' . $envName));
2040 }
2041
2042 /**
2043 * Checks if getData() works with type "getindpenv"
2044 *
2045 * @test
2046 */
2047 public function getDataWithTypeGetindpenv() {
2048 $this->subject->expects($this->once())->method('getEnvironmentVariable')
2049 ->with($this->equalTo('SCRIPT_FILENAME'))->will($this->returnValue('dummyPath'));
2050 $this->assertEquals('dummyPath', $this->subject->getData('getindpenv:SCRIPT_FILENAME'));
2051 }
2052
2053 /**
2054 * Checks if getData() works with type "field"
2055 *
2056 * @test
2057 */
2058 public function getDataWithTypeField() {
2059 $key = 'someKey';
2060 $value = 'someValue';
2061 $field = array($key => $value);
2062
2063 $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
2064 }
2065
2066 /**
2067 * Checks if getData() works with type "field" of the field content
2068 * is multi-dimensional (e.g. an array)
2069 *
2070 * @test
2071 */
2072 public function getDataWithTypeFieldAndFieldIsMultiDimensional() {
2073 $key = 'somekey|level1|level2';
2074 $value = 'somevalue';
2075 $field = array('somekey' => array('level1' => array('level2' => 'somevalue')));
2076
2077 $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
2078 }
2079
2080 /**
2081 * Basic check if getData gets the uid of a file object
2082 *
2083 * @test
2084 */
2085 public function getDataWithTypeFileReturnsUidOfFileObject() {
2086 $uid = $this->getUniqueId();
2087 $file = $this->getMock(\TYPO3\CMS\Core\Resource\File::class, array(), array(), '', FALSE);
2088 $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
2089 $this->subject->setCurrentFile($file);
2090 $this->assertEquals($uid, $this->subject->getData('file:current:uid'));
2091 }
2092
2093 /**
2094 * Checks if getData() works with type "parameters"
2095 *
2096 * @test
2097 */
2098 public function getDataWithTypeParameters() {
2099 $key = $this->getUniqueId('someKey');
2100 $value = $this->getUniqueId('someValue');
2101 $this->subject->parameters[$key] = $value;
2102
2103 $this->assertEquals($value, $this->subject->getData('parameters:' . $key));
2104 }
2105
2106 /**
2107 * Checks if getData() works with type "register"
2108 *
2109 * @test
2110 */
2111 public function getDataWithTypeRegister() {
2112 $key = $this->getUniqueId('someKey');
2113 $value = $this->getUniqueId('someValue');
2114 $GLOBALS['TSFE']->register[$key] = $value;
2115
2116 $this->assertEquals($value, $this->subject->getData('register:' . $key));
2117 }
2118
2119 /**
2120 * Checks if getData() works with type "level"
2121 *
2122 * @test
2123 */
2124 public function getDataWithTypeLevel() {
2125 $rootline = array(
2126 0 => array('uid' => 1, 'title' => 'title1'),
2127 1 => array('uid' => 2, 'title' => 'title2'),
2128 2 => array('uid' => 3, 'title' => 'title3'),
2129 );
2130
2131 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2132 $this->assertEquals(2, $this->subject->getData('level'));
2133 }
2134
2135 /**
2136 * Checks if getData() works with type "global"
2137 *
2138 * @test
2139 */
2140 public function getDataWithTypeGlobal() {
2141 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->subject->getData('global:TSFE|renderCharset'));
2142 }
2143
2144 /**
2145 * Checks if getData() works with type "leveltitle"
2146 *
2147 * @test
2148 */
2149 public function getDataWithTypeLeveltitle() {
2150 $rootline = array(
2151 0 => array('uid' => 1, 'title' => 'title1'),
2152 1 => array('uid' => 2, 'title' => 'title2'),
2153 2 => array('uid' => 3, 'title' => ''),
2154 );
2155
2156 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2157 $this->assertEquals('', $this->subject->getData('leveltitle:-1'));
2158 // since "title3" is not set, it will slide to "title2"
2159 $this->assertEquals('title2', $this->subject->getData('leveltitle:-1,slide'));
2160 }
2161
2162 /**
2163 * Checks if getData() works with type "levelmedia"
2164 *
2165 * @test
2166 */
2167 public function getDataWithTypeLevelmedia() {
2168 $rootline = array(
2169 0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
2170 1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
2171 2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
2172 );
2173
2174 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2175 $this->assertEquals('', $this->subject->getData('levelmedia:-1'));
2176 // since "title3" is not set, it will slide to "title2"
2177 $this->assertEquals('media2', $this->subject->getData('levelmedia:-1,slide'));
2178 }
2179
2180 /**
2181 * Checks if getData() works with type "leveluid"
2182 *
2183 * @test
2184 */
2185 public function getDataWithTypeLeveluid() {
2186 $rootline = array(
2187 0 => array('uid' => 1, 'title' => 'title1'),
2188 1 => array('uid' => 2, 'title' => 'title2'),
2189 2 => array('uid' => 3, 'title' => 'title3'),
2190 );
2191
2192 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2193 $this->assertEquals(3, $this->subject->getData('leveluid:-1'));
2194 // every element will have a uid - so adding slide doesn't really make sense, just for completeness
2195 $this->assertEquals(3, $this->subject->getData('leveluid:-1,slide'));
2196 }
2197
2198 /**
2199 * Checks if getData() works with type "levelfield"
2200 *
2201 * @test
2202 */
2203 public function getDataWithTypeLevelfield() {
2204 $rootline = array(
2205 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2206 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
2207 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
2208 );
2209
2210 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2211 $this->assertEquals('', $this->subject->getData('levelfield:-1,testfield'));
2212 $this->assertEquals('field2', $this->subject->getData('levelfield:-1,testfield,slide'));
2213 }
2214
2215 /**
2216 * Checks if getData() works with type "fullrootline"
2217 *
2218 * @test
2219 */
2220 public function getDataWithTypeFullrootline() {
2221 $rootline1 = array(
2222 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2223 );
2224 $rootline2 = array(
2225 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
2226 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
2227 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
2228 );
2229
2230 $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
2231 $GLOBALS['TSFE']->rootLine = $rootline2;
2232 $this->assertEquals('field2', $this->subject->getData('fullrootline:-1,testfield'));
2233 }
2234
2235 /**
2236 * Checks if getData() works with type "date"
2237 *
2238 * @test
2239 */
2240 public function getDataWithTypeDate() {
2241 $format = 'Y-M-D';
2242 $defaultFormat = 'd/m Y';
2243
2244 $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->subject->getData('date:' . $format));
2245 $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->subject->getData('date'));
2246 }
2247
2248 /**
2249 * Checks if getData() works with type "page"
2250 *
2251 * @test
2252 */
2253 public function getDataWithTypePage() {
2254 $uid = rand();
2255 $GLOBALS['TSFE']->page['uid'] = $uid;
2256 $this->assertEquals($uid, $this->subject->getData('page:uid'));
2257 }
2258
2259 /**
2260 * Checks if getData() works with type "current"
2261 *
2262 * @test
2263 */
2264 public function getDataWithTypeCurrent() {
2265 $key = $this->getUniqueId('someKey');
2266 $value = $this->getUniqueId('someValue');
2267 $this->subject->data[$key] = $value;
2268 $this->subject->currentValKey = $key;
2269 $this->assertEquals($value, $this->subject->getData('current'));
2270 }
2271
2272 /**
2273 * Checks if getData() works with type "db"
2274 *
2275 * @test
2276 */
2277 public function getDataWithTypeDb() {
2278 $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
2279
2280 $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
2281 $this->assertEquals($dummyRecord['title'], $this->subject->getData('db:tt_content:106:title'));
2282 }
2283
2284 /**
2285 * Checks if getData() works with type "lll"
2286 *
2287 * @test
2288 */
2289 public function getDataWithTypeLll() {
2290 $key = $this->getUniqueId('someKey');
2291 $value = $this->getUniqueId('someValue');
2292 $language = $this->getUniqueId('someLanguage');
2293 $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
2294 $GLOBALS['TSFE']->lang = $language;
2295
2296 $this->assertEquals($value, $this->subject->getData('lll:' . $key));
2297 }
2298
2299 /**
2300 * Checks if getData() works with type "path"
2301 *
2302 * @test
2303 */
2304 public function getDataWithTypePath() {
2305 $filenameIn = $this->getUniqueId('someValue');
2306 $filenameOut = $this->getUniqueId('someValue');
2307 $this->templateServiceMock->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
2308 $this->assertEquals($filenameOut, $this->subject->getData('path:' . $filenameIn));
2309 }
2310
2311 /**
2312 * Checks if getData() works with type "parentRecordNumber"
2313 *
2314 * @test
2315 */
2316 public function getDataWithTypeParentRecordNumber() {
2317 $recordNumber = rand();
2318 $this->subject->parentRecordNumber = $recordNumber;
2319 $this->assertEquals($recordNumber, $this->subject->getData('cobj:parentRecordNumber'));
2320 }
2321
2322 /**
2323 * Checks if getData() works with type "debug:rootLine"
2324 *
2325 * @test
2326 */
2327 public function getDataWithTypeDebugRootline() {
2328 $rootline = array(
2329 0 => array('uid' => 1, 'title' => 'title1'),
2330 1 => array('uid' => 2, 'title' => 'title2'),
2331 2 => array('uid' => 3, 'title' => ''),
2332 );
2333 $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)';
2334 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
2335
2336 $result = $this->subject->getData('debug:rootLine');
2337 $cleanedResult = strip_tags($result);
2338 $cleanedResult = str_replace("\r", '', $cleanedResult);
2339 $cleanedResult = str_replace("\n", '', $cleanedResult);
2340 $cleanedResult = str_replace("\t", '', $cleanedResult);
2341 $cleanedResult = str_replace(' ', '', $cleanedResult);
2342
2343 $this->assertEquals($expectedResult, $cleanedResult);
2344 }
2345
2346 /**
2347 * Checks if getData() works with type "debug:fullRootLine"
2348 *
2349 * @test
2350 */
2351 public function getDataWithTypeDebugFullRootline() {
2352 $rootline = array(
2353 0 => array('uid' => 1, 'title' => 'title1'),
2354 1 => array('uid' => 2, 'title' => 'title2'),
2355 2 => array('uid' => 3, 'title' => ''),
2356 );
2357 $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)';
2358 $GLOBALS['TSFE']->rootLine = $rootline;
2359
2360 $result = $this->subject->getData('debug:fullRootLine');
2361 $cleanedResult = strip_tags($result);
2362 $cleanedResult = str_replace("\r", '', $cleanedResult);
2363 $cleanedResult = str_replace("\n", '', $cleanedResult);
2364 $cleanedResult = str_replace("\t", '', $cleanedResult);
2365 $cleanedResult = str_replace(' ', '', $cleanedResult);
2366
2367 $this->assertEquals($expectedResult, $cleanedResult);
2368 }
2369
2370 /**
2371 * Checks if getData() works with type "debug:data"
2372 *
2373 * @test
2374 */
2375 public function getDataWithTypeDebugData() {
2376 $key = $this->getUniqueId('someKey');
2377 $value = $this->getUniqueId('someValue');
2378 $this->subject->data = array($key => $value);
2379
2380 $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
2381
2382 $result = $this->subject->getData('debug:data');
2383 $cleanedResult = strip_tags($result);
2384 $cleanedResult = str_replace("\r", '', $cleanedResult);
2385 $cleanedResult = str_replace("\n", '', $cleanedResult);
2386 $cleanedResult = str_replace("\t", '', $cleanedResult);
2387 $cleanedResult = str_replace(' ', '', $cleanedResult);
2388
2389 $this->assertEquals($expectedResult, $cleanedResult);
2390 }
2391
2392 /**
2393 * Checks if getData() works with type "debug:register"
2394 *
2395 * @test
2396 */
2397 public function getDataWithTypeDebugRegister() {
2398 $key = $this->getUniqueId('someKey');
2399 $value = $this->getUniqueId('someValue');
2400 $GLOBALS['TSFE']->register = array($key => $value);
2401
2402 $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
2403
2404 $result = $this->subject->getData('debug:register');
2405 $cleanedResult = strip_tags($result);
2406 $cleanedResult = str_replace("\r", '', $cleanedResult);
2407 $cleanedResult = str_replace("\n", '', $cleanedResult);
2408 $cleanedResult = str_replace("\t", '', $cleanedResult);
2409 $cleanedResult = str_replace(' ', '', $cleanedResult);
2410
2411 $this->assertEquals($expectedResult, $cleanedResult);
2412 }
2413
2414 /**
2415 * Checks if getData() works with type "data:page"
2416 *
2417 * @test
2418 */
2419 public function getDataWithTypeDebugPage() {
2420 $uid = rand();
2421 $GLOBALS['TSFE']->page = array('uid' => $uid);
2422
2423 $expectedResult = 'array(1item)uid=>' . $uid . '(integer)';
2424
2425 $result = $this->subject->getData('debug:page');
2426 $cleanedResult = strip_tags($result);
2427 $cleanedResult = str_replace("\r", '', $cleanedResult);
2428 $cleanedResult = str_replace("\n", '', $cleanedResult);
2429 $cleanedResult = str_replace("\t", '', $cleanedResult);
2430 $cleanedResult = str_replace(' ', '', $cleanedResult);
2431
2432 $this->assertEquals($expectedResult, $cleanedResult);
2433 }
2434
2435 /**
2436 * @test
2437 */
2438 public function getTreeListReturnsChildPageUids() {
2439 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
2440 $GLOBALS['TSFE']->sys_page
2441 ->expects($this->any())
2442 ->method('getRawRecord')
2443 ->will(
2444 $this->onConsecutiveCalls(
2445 array('uid' => 17),
2446 array('uid' => 321),
2447 array('uid' => 719),
2448 array('uid' => 42)
2449 )
2450 );
2451
2452 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
2453 $GLOBALS['TYPO3_DB']
2454 ->expects($this->any())
2455 ->method('exec_SELECTgetRows')
2456 ->will(
2457 $this->onConsecutiveCalls(
2458 array(
2459 array('uid' => 321)
2460 ),
2461 array(
2462 array('uid' => 719)
2463 ),
2464 array(
2465 array('uid' => 42)
2466 )
2467 )
2468 );
2469 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2470 // 17 is positive, we expect 17 NOT to be included in result
2471 $result = $this->subject->getTreeList(17, 5, 0, TRUE);
2472 $expectedResult = '42,719,321';
2473 $this->assertEquals($expectedResult, $result);
2474 }
2475
2476 /**
2477 * @test
2478 */
2479 public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue() {
2480 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
2481 $GLOBALS['TSFE']->sys_page
2482 ->expects($this->any())
2483 ->method('getRawRecord')
2484 ->will(
2485 $this->onConsecutiveCalls(
2486 array('uid' => 17),
2487 array('uid' => 321),
2488 array('uid' => 719),
2489 array('uid' => 42)
2490 )
2491 );
2492
2493 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
2494 $GLOBALS['TYPO3_DB']
2495 ->expects($this->any())
2496 ->method('exec_SELECTgetRows')
2497 ->will(
2498 $this->onConsecutiveCalls(
2499 array(
2500 array('uid' => 321)
2501 ),
2502 array(
2503 array('uid' => 719)
2504 ),
2505 array(
2506 array('uid' => 42)
2507 )
2508 )
2509 );
2510 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2511 // 17 is negative, we expect 17 to be included in result
2512 $result = $this->subject->getTreeList(-17, 5, 0, TRUE);
2513 $expectedResult = '42,719,321,17';
2514 $this->assertEquals($expectedResult, $result);
2515 }
2516
2517 /**
2518 * @test
2519 */
2520 public function aTagParamsHasLeadingSpaceIfNotEmpty() {
2521 $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2522 $this->assertEquals(' data-test="testdata"', $aTagParams );
2523 }
2524
2525 /**
2526 * @test
2527 */
2528 public function aTagParamsHaveSpaceBetweenLocalAndGlobalParams() {
2529 $GLOBALS['TSFE']->ATagParams = 'data-global="dataglobal"';
2530 $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2531 $this->assertEquals(' data-global="dataglobal" data-test="testdata"', $aTagParams );
2532 }
2533
2534 /**
2535 * @test
2536 */
2537 public function aTagParamsHasNoLeadingSpaceIfEmpty() {
2538 // make sure global ATagParams are empty
2539 $GLOBALS['TSFE']->ATagParams = '';
2540 $aTagParams = $this->subject->getATagParams(array('ATagParams' => ''));
2541 $this->assertEquals('', $aTagParams);
2542 }
2543
2544 /**
2545 * @return array
2546 */
2547 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider() {
2548 return array(
2549 array(NULL, NULL),
2550 array('', NULL),
2551 array('', array()),
2552 array('fooo', array('foo' => 'bar'))
2553 );
2554 }
2555
2556 /**
2557 * Make sure that the rendering falls back to the classic <img style if nothing else is found
2558 *
2559 * @test
2560 * @dataProvider getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider
2561 * @param string $key
2562 * @param array $configuration
2563 */
2564 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFound($key, $configuration) {
2565 $defaultImgTagTemplate = '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
2566 $result = $this->subject->getImageTagTemplate($key, $configuration);
2567 $this->assertEquals($result, $defaultImgTagTemplate);
2568 }
2569
2570 /**
2571 * @return array
2572 */
2573 public function getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider() {
2574 return array(
2575 array(
2576 'foo',
2577 array(
2578 'layout.' => array(
2579 'foo.' => array(
2580 'element' => '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2581 )
2582 )
2583 ),
2584 '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2585 )
2586
2587 );
2588 }
2589
2590 /**
2591 * Assure if a layoutKey and layout is given the selected layout is returned
2592 *
2593 * @test
2594 * @dataProvider getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider
2595 * @param string $key
2596 * @param array $configuration
2597 * @param string $expectation
2598 */
2599 public function getImageTagTemplateReturnTemplateElementIdentifiedByKey($key, $configuration, $expectation) {
2600 $result = $this->subject->getImageTagTemplate($key, $configuration);
2601 $this->assertEquals($result, $expectation);
2602 }
2603
2604 /**
2605 * @return array
2606 */
2607 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider() {
2608 return array(
2609 array(NULL, NULL, NULL),
2610 array('foo', NULL, NULL),
2611 array('foo', array('sourceCollection.' => 1), 'bar')
2612 );
2613 }
2614
2615 /**
2616 * Make sure the source collection is empty if no valid configuration or source collection is defined
2617 *
2618 * @test
2619 * @dataProvider getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider
2620 * @param string $layoutKey
2621 * @param array $configuration
2622 * @param string $file
2623 */
2624 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefined($layoutKey, $configuration, $file) {
2625 $result = $this->subject->getImageSourceCollection($layoutKey, $configuration, $file);
2626 $this->assertSame($result, '');
2627 }
2628
2629 /**
2630 * Make sure the generation of subimages calls the generation of the subimages and uses the layout -> source template
2631 *
2632 * @test
2633 */
2634 public function getImageSourceCollectionRendersDefinedSources() {
2635 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2636 $cObj = $this->getMock(
2637 \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
2638 array('stdWrap','getImgResource')
2639 );
2640 $cObj->start(array(), 'tt_content');
2641
2642 $layoutKey = 'test';
2643
2644 $configuration = array(
2645 'layoutKey' => 'test',
2646 'layout.' => array (
2647 'test.' => array(
2648 'element' => '<img ###SRC### ###SRCCOLLECTION### ###SELFCLOSINGTAGSLASH###>',
2649 'source' => '---###SRC###---'
2650 )
2651 ),
2652 'sourceCollection.' => array(
2653 '1.' => array(
2654 'width' => '200'
2655 )
2656 )
2657 );
2658
2659 $file = 'testImageName';
2660
2661 // Avoid calling of stdWrap
2662 $cObj
2663 ->expects($this->any())
2664 ->method('stdWrap')
2665 ->will($this->returnArgument(0));
2666
2667 // Avoid calling of imgResource
2668 $cObj
2669 ->expects($this->exactly(1))
2670 ->method('getImgResource')
2671 ->with($this->equalTo('testImageName'))
2672 ->will($this->returnValue(array(100, 100, NULL, 'bar')));
2673
2674 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2675
2676 $this->assertEquals('---bar---', $result);
2677 }
2678
2679 /**
2680 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyDefault test
2681 *
2682 * @return array multi-dimensional array with the second level like this:
2683 * @see getImageSourceCollectionRendersDefinedLayoutKeyDefault
2684 */
2685 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider() {
2686 /**
2687 * @see css_styled_content/static/setup.txt
2688 */
2689 $sourceCollectionArray = array(
2690 'small.' => array(
2691 'width' => '200',
2692 'srcsetCandidate' => '600w',
2693 'mediaQuery' => '(max-device-width: 600px)',
2694 'dataKey' => 'small',
2695 ),
2696 'smallRetina.' => array(
2697 'if.directReturn' => 0,
2698 'width' => '200',
2699 'pixelDensity' => '2',
2700 'srcsetCandidate' => '600w 2x',
2701 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2702 'dataKey' => 'smallRetina',
2703 )
2704 );
2705 return array(
2706 array(
2707 'default',
2708 array(
2709 'layoutKey' => 'default',
2710 'layout.' => array (
2711 'default.' => array(
2712 'element' => '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>',
2713 'source' => ''
2714 )
2715 ),
2716 'sourceCollection.' => $sourceCollectionArray
2717 )
2718 ),
2719 );
2720 }
2721
2722 /**
2723 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2724 *
2725 * @test
2726 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider
2727 * @param string $layoutKey
2728 * @param array $configuration
2729 */
2730 public function getImageSourceCollectionRendersDefinedLayoutKeyDefault($layoutKey , $configuration) {
2731 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2732 $cObj = $this->getMock(
2733 \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
2734 array('stdWrap','getImgResource')
2735 );
2736 $cObj->start(array(), 'tt_content');
2737
2738 $file = 'testImageName';
2739
2740 // Avoid calling of stdWrap
2741 $cObj
2742 ->expects($this->any())
2743 ->method('stdWrap')
2744 ->will($this->returnArgument(0));
2745
2746 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2747
2748 $this->assertEmpty($result);
2749 }
2750
2751 /**
2752 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyData test
2753 *
2754 * @return array multi-dimensional array with the second level like this:
2755 * @see getImageSourceCollectionRendersDefinedLayoutKeyData
2756 */
2757 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider() {
2758 /**
2759 * @see css_styled_content/static/setup.txt
2760 */
2761 $sourceCollectionArray = array(
2762 'small.' => array(
2763 'width' => '200',
2764 'srcsetCandidate' => '600w',
2765 'mediaQuery' => '(max-device-width: 600px)',
2766 'dataKey' => 'small',
2767 ),
2768 'smallRetina.' => array(
2769 'if.directReturn' => 1,
2770 'width' => '200',
2771 'pixelDensity' => '2',
2772 'srcsetCandidate' => '600w 2x',
2773 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2774 'dataKey' => 'smallRetina',
2775 )
2776 );
2777 return array(
2778 array(
2779 'srcset',
2780 array(
2781 'layoutKey' => 'srcset',
2782 'layout.' => array (
2783 'srcset.' => array(
2784 'element' => '<img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2785 'source' => '|*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###'
2786 )
2787 ),
2788 'sourceCollection.' => $sourceCollectionArray
2789 ),
2790 'xhtml_strict',
2791 'bar-file.jpg 600w,bar-file.jpg 600w 2x',
2792 ),
2793 array(
2794 'picture',
2795 array(
2796 'layoutKey' => 'picture',
2797 'layout.' => array (
2798 'picture.' => array(
2799 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2800 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2801 )
2802 ),
2803 'sourceCollection.' => $sourceCollectionArray,
2804 ),
2805 'xhtml_strict',
2806 '<source src="bar-file.jpg" media="(max-device-width: 600px)" /><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)" />',
2807 ),
2808 array(
2809 'picture',
2810 array(
2811 'layoutKey' => 'picture',
2812 'layout.' => array (
2813 'picture.' => array(
2814 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2815 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2816 )
2817 ),
2818 'sourceCollection.' => $sourceCollectionArray,
2819 ),
2820 '',
2821 '<source src="bar-file.jpg" media="(max-device-width: 600px)"><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)">',
2822 ),
2823 array(
2824 'data',
2825 array(
2826 'layoutKey' => 'data',
2827 'layout.' => array (
2828 'data.' => array(
2829 'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2830 'source' => 'data-###DATAKEY###="###SRC###"'
2831 )
2832 ),
2833 'sourceCollection.' => $sourceCollectionArray
2834 ),
2835 'xhtml_strict',
2836 'data-small="bar-file.jpg"data-smallRetina="bar-file.jpg"',
2837 ),
2838 );
2839 }
2840
2841 /**
2842 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2843 *
2844 * @test
2845 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider
2846 * @param string $layoutKey
2847 * @param array $configuration
2848 * @param string $xhtmlDoctype