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