03222fbb8fc51fff4a740fd2d3e6b2ce57e6a728
[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 * Data provider for stdWrap_escapeJsValue test
1469 *
1470 * @return array multi-dimensional array with the second level like this:
1471 * @see escapeJsValue
1472 */
1473 public function stdWrap_escapeJsValueDataProvider() {
1474 return array(
1475 'double quote in string' => array(
1476 'double quote"',
1477 array(),
1478 'double\u0020quote\u0022'
1479 ),
1480 'backslash in string' => array(
1481 'backslash \\',
1482 array(),
1483 'backslash\u0020\u005C'
1484 ),
1485 'exclamation mark' => array(
1486 'exclamation!',
1487 array(),
1488 'exclamation\u0021'
1489 ),
1490 'whitespace tab, newline and carriage return' => array(
1491 "white\tspace\ns\r",
1492 array(),
1493 'white\u0009space\u000As\u000D'
1494 ),
1495 'single quote in string' => array(
1496 'single quote \'',
1497 array(),
1498 'single\u0020quote\u0020\u0027'
1499 ),
1500 'tag' => array(
1501 '<tag>',
1502 array(),
1503 '\u003Ctag\u003E'
1504 ),
1505 'ampersand in string' => array(
1506 'amper&sand',
1507 array(),
1508 'amper\u0026sand'
1509 ),
1510 );
1511 }
1512
1513 /**
1514 * Check if escapeJsValue works properly
1515 *
1516 * @dataProvider stdWrap_escapeJsValueDataProvider
1517 * @test
1518 */
1519 public function stdWrap_escapeJsValue($input, $conf, $expected) {
1520 $result = $this->cObj->stdWrap_escapeJsValue($input, $conf);
1521 $this->assertEquals($expected, $result);
1522 }
1523
1524
1525 /////////////////////////////
1526 // Tests concerning getData()
1527 /////////////////////////////
1528
1529 /**
1530 * @return array
1531 */
1532 public function getDataWithTypeGpDataProvider() {
1533 return array(
1534 'Value in get-data' => array('onlyInGet', 'GetValue'),
1535 'Value in post-data' => array('onlyInPost', 'PostValue'),
1536 'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
1537 );
1538 }
1539
1540 /**
1541 * Checks if getData() works with type "gp"
1542 *
1543 * @test
1544 * @dataProvider getDataWithTypeGpDataProvider
1545 */
1546 public function getDataWithTypeGp($key, $expectedValue) {
1547 $_GET = array(
1548 'onlyInGet' => 'GetValue',
1549 'inGetAndPost' => 'ValueInGet',
1550 );
1551 $_POST = array(
1552 'onlyInPost' => 'PostValue',
1553 'inGetAndPost' => 'ValueInPost',
1554 );
1555 $this->assertEquals($expectedValue, $this->cObj->getData('gp:' . $key));
1556 }
1557
1558 /**
1559 * Checks if getData() works with type "tsfe"
1560 *
1561 * @test
1562 */
1563 public function getDataWithTypeTsfe() {
1564 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->cObj->getData('tsfe:renderCharset'));
1565 }
1566
1567 /**
1568 * Checks if getData() works with type "getenv"
1569 *
1570 * @test
1571 */
1572 public function getDataWithTypeGetenv() {
1573 $envName = uniqid('frontendtest');
1574 $value = uniqid('someValue');
1575 putenv($envName . '=' . $value);
1576 $this->assertEquals($value, $this->cObj->getData('getenv:' . $envName));
1577 }
1578
1579 /**
1580 * Checks if getData() works with type "getindpenv"
1581 *
1582 * @test
1583 */
1584 public function getDataWithTypeGetindpenv() {
1585 $this->assertEquals(PATH_thisScript, $this->cObj->getData('getindpenv:SCRIPT_FILENAME'));
1586 }
1587
1588 /**
1589 * Checks if getData() works with type "getindpenv"
1590 *
1591 * @test
1592 */
1593 public function getDataWithTypeField() {
1594 $key = 'someKey';
1595 $value = 'someValue';
1596 $field = array($key => $value);
1597
1598 $this->assertEquals($value, $this->cObj->getData('field:' . $key, $field));
1599 }
1600
1601 /**
1602 * Basic check if getData gets the uid of a file object
1603 *
1604 * @test
1605 */
1606 public function getDataWithTypeFileReturnsUidOfFileObject() {
1607 $uid = uniqid();
1608 $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\File', array(), array(), '', FALSE);
1609 $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
1610 $this->cObj->setCurrentFile($file);
1611 $this->assertEquals($uid, $this->cObj->getData('file:current:uid'));
1612 }
1613
1614 /**
1615 * Checks if getData() works with type "parameters"
1616 *
1617 * @test
1618 */
1619 public function getDataWithTypeParameters() {
1620 $key = uniqid('someKey');
1621 $value = uniqid('someValue');
1622 $this->cObj->parameters[$key] = $value;
1623
1624 $this->assertEquals($value, $this->cObj->getData('parameters:' . $key));
1625 }
1626
1627 /**
1628 * Checks if getData() works with type "register"
1629 *
1630 * @test
1631 */
1632 public function getDataWithTypeRegister() {
1633 $key = uniqid('someKey');
1634 $value = uniqid('someValue');
1635 $GLOBALS['TSFE']->register[$key] = $value;
1636
1637 $this->assertEquals($value, $this->cObj->getData('register:' . $key));
1638 }
1639
1640 /**
1641 * Checks if getData() works with type "level"
1642 *
1643 * @test
1644 */
1645 public function getDataWithTypeLevel() {
1646 $rootline = array(
1647 0 => array('uid' => 1, 'title' => 'title1'),
1648 1 => array('uid' => 2, 'title' => 'title2'),
1649 2 => array('uid' => 3, 'title' => 'title3'),
1650 );
1651
1652 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1653 $this->assertEquals(2, $this->cObj->getData('level'));
1654 }
1655
1656 /**
1657 * Checks if getData() works with type "global"
1658 *
1659 * @test
1660 */
1661 public function getDataWithTypeGlobal() {
1662 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->cObj->getData('global:TSFE|renderCharset'));
1663 }
1664
1665 /**
1666 * Checks if getData() works with type "leveltitle"
1667 *
1668 * @test
1669 */
1670 public function getDataWithTypeLeveltitle() {
1671 $rootline = array(
1672 0 => array('uid' => 1, 'title' => 'title1'),
1673 1 => array('uid' => 2, 'title' => 'title2'),
1674 2 => array('uid' => 3, 'title' => ''),
1675 );
1676
1677 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1678 $this->assertEquals('', $this->cObj->getData('leveltitle:-1'));
1679 // since "title3" is not set, it will slide to "title2"
1680 $this->assertEquals('title2', $this->cObj->getData('leveltitle:-1,slide'));
1681 }
1682
1683 /**
1684 * Checks if getData() works with type "levelmedia"
1685 *
1686 * @test
1687 */
1688 public function getDataWithTypeLevelmedia() {
1689 $rootline = array(
1690 0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
1691 1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
1692 2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
1693 );
1694
1695 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1696 $this->assertEquals('', $this->cObj->getData('levelmedia:-1'));
1697 // since "title3" is not set, it will slide to "title2"
1698 $this->assertEquals('media2', $this->cObj->getData('levelmedia:-1,slide'));
1699 }
1700
1701 /**
1702 * Checks if getData() works with type "leveluid"
1703 *
1704 * @test
1705 */
1706 public function getDataWithTypeLeveluid() {
1707 $rootline = array(
1708 0 => array('uid' => 1, 'title' => 'title1'),
1709 1 => array('uid' => 2, 'title' => 'title2'),
1710 2 => array('uid' => 3, 'title' => 'title3'),
1711 );
1712
1713 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1714 $this->assertEquals(3, $this->cObj->getData('leveluid:-1'));
1715 // every element will have a uid - so adding slide doesn't really make sense, just for completeness
1716 $this->assertEquals(3, $this->cObj->getData('leveluid:-1,slide'));
1717 }
1718
1719 /**
1720 * Checks if getData() works with type "levelfield"
1721 *
1722 * @test
1723 */
1724 public function getDataWithTypeLevelfield() {
1725 $rootline = array(
1726 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1727 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
1728 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
1729 );
1730
1731 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1732 $this->assertEquals('', $this->cObj->getData('levelfield:-1,testfield'));
1733 $this->assertEquals('field2', $this->cObj->getData('levelfield:-1,testfield,slide'));
1734 }
1735
1736 /**
1737 * Checks if getData() works with type "fullrootline"
1738 *
1739 * @test
1740 */
1741 public function getDataWithTypeFullrootline() {
1742 $rootline1 = array(
1743 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1744 );
1745 $rootline2 = array(
1746 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1747 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
1748 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
1749 );
1750
1751 $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
1752 $GLOBALS['TSFE']->rootLine = $rootline2;
1753 $this->assertEquals('field2', $this->cObj->getData('fullrootline:-1,testfield'));
1754 }
1755
1756 /**
1757 * Checks if getData() works with type "date"
1758 *
1759 * @test
1760 */
1761 public function getDataWithTypeDate() {
1762 $format = 'Y-M-D';
1763 $defaultFormat = 'd/m Y';
1764
1765 $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->cObj->getData('date:' . $format));
1766 $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->cObj->getData('date'));
1767 }
1768
1769 /**
1770 * Checks if getData() works with type "page"
1771 *
1772 * @test
1773 */
1774 public function getDataWithTypePage() {
1775 $uid = rand();
1776 $GLOBALS['TSFE']->page['uid'] = $uid;
1777 $this->assertEquals($uid, $this->cObj->getData('page:uid'));
1778 }
1779
1780 /**
1781 * Checks if getData() works with type "current"
1782 *
1783 * @test
1784 */
1785 public function getDataWithTypeCurrent() {
1786 $key = uniqid('someKey');
1787 $value = uniqid('someValue');
1788 $this->cObj->data[$key] = $value;
1789 $this->cObj->currentValKey = $key;
1790 $this->assertEquals($value, $this->cObj->getData('current'));
1791 }
1792
1793 /**
1794 * Checks if getData() works with type "db"
1795 *
1796 * @test
1797 */
1798 public function getDataWithTypeDb() {
1799 $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
1800
1801 $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
1802 $this->assertEquals($dummyRecord['title'], $this->cObj->getData('db:tt_content:106:title'));
1803 }
1804
1805 /**
1806 * Checks if getData() works with type "lll"
1807 *
1808 * @test
1809 */
1810 public function getDataWithTypeLll() {
1811 $key = uniqid('someKey');
1812 $value = uniqid('someValue');
1813 $language = uniqid('someLanguage');
1814 $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
1815 $GLOBALS['TSFE']->lang = $language;
1816
1817 $this->assertEquals($value, $this->cObj->getData('lll:' . $key));
1818 }
1819
1820 /**
1821 * Checks if getData() works with type "path"
1822 *
1823 * @test
1824 */
1825 public function getDataWithTypePath() {
1826 $filenameIn = uniqid('someValue');
1827 $filenameOut = uniqid('someValue');
1828 $this->template->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
1829 $this->assertEquals($filenameOut, $this->cObj->getData('path:' . $filenameIn));
1830 }
1831
1832 /**
1833 * Checks if getData() works with type "parentRecordNumber"
1834 *
1835 * @test
1836 */
1837 public function getDataWithTypeParentRecordNumber() {
1838 $recordNumber = rand();
1839 $this->cObj->parentRecordNumber = $recordNumber;
1840 $this->assertEquals($recordNumber, $this->cObj->getData('cobj:parentRecordNumber'));
1841 }
1842
1843 /**
1844 * Checks if getData() works with type "debug:rootLine"
1845 *
1846 * @test
1847 */
1848 public function getDataWithTypeDebugRootline() {
1849 $rootline = array(
1850 0 => array('uid' => 1, 'title' => 'title1'),
1851 1 => array('uid' => 2, 'title' => 'title2'),
1852 2 => array('uid' => 3, 'title' => ''),
1853 );
1854 $expectedResult = '0uid1titletitle11uid2titletitle22uid3title';
1855 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1856
1857 $result = $this->cObj->getData('debug:rootLine');
1858 $cleanedResult = strip_tags($result);
1859 $cleanedResult = str_replace("\r", '', $cleanedResult);
1860 $cleanedResult = str_replace("\n", '', $cleanedResult);
1861 $cleanedResult = str_replace("\t", '', $cleanedResult);
1862 $cleanedResult = str_replace(' ', '', $cleanedResult);
1863
1864 $this->assertEquals($expectedResult, $cleanedResult);
1865 }
1866
1867 /**
1868 * Checks if getData() works with type "debug:fullRootLine"
1869 *
1870 * @test
1871 */
1872 public function getDataWithTypeDebugFullRootline() {
1873 $rootline = array(
1874 0 => array('uid' => 1, 'title' => 'title1'),
1875 1 => array('uid' => 2, 'title' => 'title2'),
1876 2 => array('uid' => 3, 'title' => ''),
1877 );
1878 $expectedResult = '0uid1titletitle11uid2titletitle22uid3title';
1879 $GLOBALS['TSFE']->rootLine = $rootline;
1880
1881 $result = $this->cObj->getData('debug:fullRootLine');
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 "debug:data"
1893 *
1894 * @test
1895 */
1896 public function getDataWithTypeDebugData() {
1897 $key = uniqid('someKey');
1898 $value = uniqid('someValue');
1899 $this->cObj->data = array($key => $value);
1900
1901 $expectedResult = $key . $value;
1902
1903 $result = $this->cObj->getData('debug:data');
1904 $cleanedResult = strip_tags($result);
1905 $cleanedResult = str_replace("\r", '', $cleanedResult);
1906 $cleanedResult = str_replace("\n", '', $cleanedResult);
1907 $cleanedResult = str_replace("\t", '', $cleanedResult);
1908 $cleanedResult = str_replace(' ', '', $cleanedResult);
1909
1910 $this->assertEquals($expectedResult, $cleanedResult);
1911 }
1912
1913 /**
1914 * Checks if getData() works with type "debug:register"
1915 *
1916 * @test
1917 */
1918 public function getDataWithTypeDebugRegister() {
1919 $key = uniqid('someKey');
1920 $value = uniqid('someValue');
1921 $GLOBALS['TSFE']->register = array($key => $value);
1922
1923 $expectedResult = $key . $value;
1924
1925 $result = $this->cObj->getData('debug:register');
1926 $cleanedResult = strip_tags($result);
1927 $cleanedResult = str_replace("\r", '', $cleanedResult);
1928 $cleanedResult = str_replace("\n", '', $cleanedResult);
1929 $cleanedResult = str_replace("\t", '', $cleanedResult);
1930 $cleanedResult = str_replace(' ', '', $cleanedResult);
1931
1932 $this->assertEquals($expectedResult, $cleanedResult);
1933 }
1934
1935 /**
1936 * Checks if getData() works with type "data:page"
1937 *
1938 * @test
1939 */
1940 public function getDataWithTypeDebugPage() {
1941 $uid = rand();
1942 $GLOBALS['TSFE']->page = array('uid' => $uid);
1943
1944 $expectedResult = 'uid' . $uid;
1945
1946 $result = $this->cObj->getData('debug:page');
1947 $cleanedResult = strip_tags($result);
1948 $cleanedResult = str_replace("\r", '', $cleanedResult);
1949 $cleanedResult = str_replace("\n", '', $cleanedResult);
1950 $cleanedResult = str_replace("\t", '', $cleanedResult);
1951 $cleanedResult = str_replace(' ', '', $cleanedResult);
1952
1953 $this->assertEquals($expectedResult, $cleanedResult);
1954 }
1955
1956 /**
1957 * @test
1958 */
1959 public function getTreeListReturnsChildPageUids() {
1960 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
1961 $GLOBALS['TSFE']->sys_page
1962 ->expects($this->any())
1963 ->method('getRawRecord')
1964 ->will(
1965 $this->onConsecutiveCalls(
1966 array('uid' => 17),
1967 array('uid' => 321),
1968 array('uid' => 719),
1969 array('uid' => 42)
1970 )
1971 );
1972
1973 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
1974 $GLOBALS['TYPO3_DB']
1975 ->expects($this->any())
1976 ->method('exec_SELECTgetRows')
1977 ->will(
1978 $this->onConsecutiveCalls(
1979 array(
1980 array('uid' => 321)
1981 ),
1982 array(
1983 array('uid' => 719)
1984 ),
1985 array(
1986 array('uid' => 42)
1987 )
1988 )
1989 );
1990 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
1991 // 17 is positive, we expect 17 NOT to be included in result
1992 $result = $this->cObj->getTreeList(17, 5, 0, TRUE);
1993 $expectedResult = '42,719,321';
1994 $this->assertEquals($expectedResult, $result);
1995 }
1996
1997 /**
1998 * @test
1999 */
2000 public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue() {
2001 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
2002 $GLOBALS['TSFE']->sys_page
2003 ->expects($this->any())
2004 ->method('getRawRecord')
2005 ->will(
2006 $this->onConsecutiveCalls(
2007 array('uid' => 17),
2008 array('uid' => 321),
2009 array('uid' => 719),
2010 array('uid' => 42)
2011 )
2012 );
2013
2014 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
2015 $GLOBALS['TYPO3_DB']
2016 ->expects($this->any())
2017 ->method('exec_SELECTgetRows')
2018 ->will(
2019 $this->onConsecutiveCalls(
2020 array(
2021 array('uid' => 321)
2022 ),
2023 array(
2024 array('uid' => 719)
2025 ),
2026 array(
2027 array('uid' => 42)
2028 )
2029 )
2030 );
2031 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2032 // 17 is negative, we expect 17 to be included in result
2033 $result = $this->cObj->getTreeList(-17, 5, 0, TRUE);
2034 $expectedResult = '42,719,321,17';
2035 $this->assertEquals($expectedResult, $result);
2036 }
2037
2038 /**
2039 * @test
2040 */
2041 public function aTagParamsHasLeadingSpaceIfNotEmpty() {
2042 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2043 $this->assertEquals(' data-test="testdata"', $aTagParams );
2044 }
2045
2046 /**
2047 * @test
2048 */
2049 public function aTagParamsHaveSpaceBetweenLocalAndGlobalParams() {
2050 $GLOBALS['TSFE']->ATagParams = 'data-global="dataglobal"';
2051 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2052 $this->assertEquals(' data-global="dataglobal" data-test="testdata"', $aTagParams );
2053 }
2054
2055 /**
2056 * @test
2057 */
2058 public function aTagParamsHasNoLeadingSpaceIfEmpty() {
2059 // make sure global ATagParams are empty
2060 $GLOBALS['TSFE']->ATagParams = '';
2061 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => ''));
2062 $this->assertEquals('', $aTagParams);
2063 }
2064
2065 /**
2066 * @return array
2067 */
2068 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider() {
2069 return array(
2070 array(NULL, NULL),
2071 array('', NULL),
2072 array('', array()),
2073 array('fooo', array('foo' => 'bar'))
2074 );
2075 }
2076
2077 /**
2078 * Make sure that the rendering falls back to the classic <img style if nothing else is found
2079 *
2080 * @test
2081 * @dataProvider getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider
2082 * @param string $key
2083 * @param array $configuration
2084 */
2085 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFound($key, $configuration) {
2086 $defaultImgTagTemplate = '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
2087 $result = $this->cObj->getImageTagTemplate($key, $configuration);
2088 $this->assertEquals($result, $defaultImgTagTemplate);
2089 }
2090
2091 /**
2092 * @return array
2093 */
2094 public function getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider() {
2095 return array(
2096 array(
2097 'foo',
2098 array(
2099 'layout.' => array(
2100 'foo.' => array(
2101 'element' => '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2102 )
2103 )
2104 ),
2105 '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2106 )
2107
2108 );
2109 }
2110
2111 /**
2112 * Assure if a layoutKey and layout is given the selected layout is returned
2113 *
2114 * @test
2115 * @dataProvider getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider
2116 * @param string $key
2117 * @param array $configuration
2118 * @param string $expectation
2119 */
2120 public function getImageTagTemplateReturnTemplateElementIdentifiedByKey($key, $configuration, $expectation) {
2121 $result = $this->cObj->getImageTagTemplate($key, $configuration);
2122 $this->assertEquals($result, $expectation);
2123 }
2124
2125 /**
2126 * @return array
2127 */
2128 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider() {
2129 return array(
2130 array(NULL, NULL, NULL),
2131 array('foo', NULL, NULL),
2132 array('foo', array('sourceCollection.' => 1), 'bar')
2133 );
2134 }
2135
2136 /**
2137 * Make sure the source collection is empty if no valid configuration or source collection is defined
2138 *
2139 * @test
2140 * @dataProvider getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider
2141 * @param string $layoutKey
2142 * @param array $configuration
2143 * @param string $file
2144 */
2145 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefined($layoutKey, $configuration, $file) {
2146 $result = $this->cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2147 $this->assertSame($result, '');
2148 }
2149
2150 /**
2151 * Make sure the generation of subimages calls the generation of the subimages and uses the layout -> source template
2152 *
2153 * @test
2154 */
2155 public function getImageSourceCollectionRendersDefinedSources() {
2156 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2157 $cObj = $this->getMock(
2158 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2159 array('stdWrap','getImgResource')
2160 );
2161 $cObj->start(array(), 'tt_content');
2162
2163 $layoutKey = 'test';
2164
2165 $configuration = array(
2166 'layoutKey' => 'test',
2167 'layout.' => array (
2168 'test.' => array(
2169 'element' => '<img ###SRC### ###SRCCOLLECTION### ###SELFCLOSINGTAGSLASH###>',
2170 'source' => '---###SRC###---'
2171 )
2172 ),
2173 'sourceCollection.' => array(
2174 '1.' => array(
2175 'width' => '200'
2176 )
2177 )
2178 );
2179
2180 $file = 'testImageName';
2181
2182 // Avoid calling of stdWrap
2183 $cObj
2184 ->expects($this->any())
2185 ->method('stdWrap')
2186 ->will($this->returnArgument(0));
2187
2188 // Avoid calling of imgResource
2189 $cObj
2190 ->expects($this->exactly(1))
2191 ->method('getImgResource')
2192 ->with($this->equalTo('testImageName'))
2193 ->will($this->returnValue(array(100, 100, NULL, 'bar')));
2194
2195 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2196
2197 $this->assertEquals('---bar---', $result);
2198 }
2199
2200 /**
2201 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyDefault test
2202 *
2203 * @return array multi-dimensional array with the second level like this:
2204 * @see getImageSourceCollectionRendersDefinedLayoutKeyDefault
2205 */
2206 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider() {
2207 /**
2208 * @see css_styled_content/static/setup.txt
2209 */
2210 $sourceCollectionArray = array(
2211 'small.' => array(
2212 'width' => '200',
2213 'srcsetCandidate' => '600w',
2214 'mediaQuery' => '(max-device-width: 600px)',
2215 'dataKey' => 'small',
2216 ),
2217 'smallRetina.' => array(
2218 'if.directReturn' => 0,
2219 'width' => '200',
2220 'pixelDensity' => '2',
2221 'srcsetCandidate' => '600w 2x',
2222 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2223 'dataKey' => 'smallRetina',
2224 )
2225 );
2226 return array(
2227 array(
2228 'default',
2229 array(
2230 'layoutKey' => 'default',
2231 'layout.' => array (
2232 'default.' => array(
2233 'element' => '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>',
2234 'source' => ''
2235 )
2236 ),
2237 'sourceCollection.' => $sourceCollectionArray
2238 )
2239 ),
2240 );
2241 }
2242
2243 /**
2244 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2245 *
2246 * @test
2247 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider
2248 * @param string $layoutKey
2249 * @param array $configuration
2250 */
2251 public function getImageSourceCollectionRendersDefinedLayoutKeyDefault($layoutKey , $configuration) {
2252 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2253 $cObj = $this->getMock(
2254 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2255 array('stdWrap','getImgResource')
2256 );
2257 $cObj->start(array(), 'tt_content');
2258
2259 $file = 'testImageName';
2260
2261 // Avoid calling of stdWrap
2262 $cObj
2263 ->expects($this->any())
2264 ->method('stdWrap')
2265 ->will($this->returnArgument(0));
2266
2267 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2268
2269 $this->assertEmpty($result);
2270 }
2271
2272 /**
2273 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyData test
2274 *
2275 * @return array multi-dimensional array with the second level like this:
2276 * @see getImageSourceCollectionRendersDefinedLayoutKeyData
2277 */
2278 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider() {
2279 /**
2280 * @see css_styled_content/static/setup.txt
2281 */
2282 $sourceCollectionArray = array(
2283 'small.' => array(
2284 'width' => '200',
2285 'srcsetCandidate' => '600w',
2286 'mediaQuery' => '(max-device-width: 600px)',
2287 'dataKey' => 'small',
2288 ),
2289 'smallRetina.' => array(
2290 'if.directReturn' => 1,
2291 'width' => '200',
2292 'pixelDensity' => '2',
2293 'srcsetCandidate' => '600w 2x',
2294 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2295 'dataKey' => 'smallRetina',
2296 )
2297 );
2298 return array(
2299 array(
2300 'srcset',
2301 array(
2302 'layoutKey' => 'srcset',
2303 'layout.' => array (
2304 'srcset.' => array(
2305 'element' => '<img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2306 'source' => '|*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###'
2307 )
2308 ),
2309 'sourceCollection.' => $sourceCollectionArray
2310 ),
2311 'xhtml_strict',
2312 'bar-file.jpg 600w,bar-file.jpg 600w 2x',
2313 ),
2314 array(
2315 'picture',
2316 array(
2317 'layoutKey' => 'picture',
2318 'layout.' => array (
2319 'picture.' => array(
2320 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2321 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2322 )
2323 ),
2324 'sourceCollection.' => $sourceCollectionArray,
2325 ),
2326 'xhtml_strict',
2327 '<source src="bar-file.jpg" media="(max-device-width: 600px)" /><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)" />',
2328 ),
2329 array(
2330 'picture',
2331 array(
2332 'layoutKey' => 'picture',
2333 'layout.' => array (
2334 'picture.' => array(
2335 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2336 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2337 )
2338 ),
2339 'sourceCollection.' => $sourceCollectionArray,
2340 ),
2341 '',
2342 '<source src="bar-file.jpg" media="(max-device-width: 600px)"><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)">',
2343 ),
2344 array(
2345 'data',
2346 array(
2347 'layoutKey' => 'data',
2348 'layout.' => array (
2349 'data.' => array(
2350 'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2351 'source' => 'data-###DATAKEY###="###SRC###"'
2352 )
2353 ),
2354 'sourceCollection.' => $sourceCollectionArray
2355 ),
2356 'xhtml_strict',
2357 'data-small="bar-file.jpg"data-smallRetina="bar-file.jpg"',
2358 ),
2359 );
2360 }
2361
2362 /**
2363 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2364 *
2365 * @test
2366 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider
2367 * @param string $layoutKey
2368 * @param array $configuration
2369 * @param string $xhtmlDoctype
2370 * @param string $expectedHtml
2371 */
2372 public function getImageSourceCollectionRendersDefinedLayoutKeyData($layoutKey , $configuration, $xhtmlDoctype, $expectedHtml) {
2373 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2374 $cObj = $this->getMock(
2375 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2376 array('stdWrap','getImgResource')
2377 );
2378 $cObj->start(array(), 'tt_content');
2379
2380 $file = 'testImageName';
2381
2382 $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
2383
2384 // Avoid calling of stdWrap
2385 $cObj
2386 ->expects($this->any())
2387 ->method('stdWrap')
2388 ->will($this->returnArgument(0));
2389
2390 // Avoid calling of imgResource
2391 $cObj
2392 ->expects($this->exactly(2))
2393 ->method('getImgResource')
2394 ->with($this->equalTo('testImageName'))
2395 ->will($this->returnValue(array(100, 100, NULL, 'bar-file.jpg')));
2396
2397 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2398
2399 $this->assertEquals($expectedHtml, $result);
2400 }
2401
2402 /**
2403 * Make sure the hook in get sourceCollection is called
2404 *
2405 * @test
2406 */
2407 public function getImageSourceCollectionHookCalled() {
2408 // Avoid calling stdwrap and getIMgResouce
2409 $this->cObj->expects($this->any())
2410 ->method('stdWrap')
2411 ->will($this->returnArgument(0));
2412
2413 $this->cObj->expects($this->any())
2414 ->method('getImgResource')
2415 ->will($this->returnValue(array(100, 100, NULL, 'bar-file.jpg')));
2416
2417 $resourceFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', array(), array(), '', FALSE);
2418 $this->cObj->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
2419
2420 $className = uniqid('tx_coretest_getImageSourceCollectionHookCalled');
2421 $getImageSourceCollectionHookMock = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectOneSourceCollectionHookInterface', array('getOneSourceCollection'), array(), $className);
2422 $GLOBALS['T3_VAR']['getUserObj'][$className] = $getImageSourceCollectionHookMock;
2423 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'][] = $className;
2424
2425 $getImageSourceCollectionHookMock
2426 ->expects($this->exactly(1))
2427 ->method('getOneSourceCollection')
2428 ->will($this->returnCallback(array($this, 'isGetOneSourceCollectionCalledCallback')));
2429
2430 $configuration = array(
2431 'layoutKey' => 'data',
2432 'layout.' => array (
2433 'data.' => array(
2434 'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2435 'source' => 'data-###DATAKEY###="###SRC###"'
2436 )
2437 ),
2438 'sourceCollection.' => array(
2439 'small.' => array(
2440 'width' => '200',
2441 'srcsetCandidate' => '600w',
2442 'mediaQuery' => '(max-device-width: 600px)',
2443 'dataKey' => 'small',
2444 ),
2445 ),
2446 );
2447
2448 $result = $this->cObj->getImageSourceCollection('data', $configuration, uniqid('testImage-'));
2449
2450 $this->assertSame($result, 'isGetOneSourceCollectionCalledCallback');
2451 }
2452
2453 /**
2454 * Handles the arguments that have been sent to the getImgResource hook.
2455 *
2456 * @return string
2457 * @see getImageSourceCollectionHookCalled
2458 */
2459 public function isGetOneSourceCollectionCalledCallback() {
2460 list($sourceRenderConfiguration, $sourceConfiguration, $oneSourceCollection, $parent) = func_get_args();
2461 $this->assertTrue(is_array($sourceRenderConfiguration));
2462 $this->assertTrue(is_array($sourceConfiguration));
2463 return 'isGetOneSourceCollectionCalledCallback';
2464 }
2465 }