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