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