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