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