[FEATURE] Enable queries using "root" and "-1" for pidInList
[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 $GLOBALS['TCA'] = array(
1233 'pages' => array(
1234 'ctrl' => array(
1235 'enablecolumns' => array(
1236 'disabled' => 'hidden'
1237 )
1238 )
1239 ),
1240 'tt_content' => array(
1241 'ctrl' => array(
1242 'enablecolumns' => array(
1243 'disabled' => 'hidden'
1244 ),
1245 'versioningWS' => 2
1246 )
1247 ),
1248 );
1249 $result = $this->cObj->getQuery($table, $conf, TRUE);
1250 foreach ($expected as $field => $value) {
1251 $this->assertEquals($value, $result[$field]);
1252 }
1253 }
1254
1255 /**
1256 * @test
1257 */
1258 public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet() {
1259 $GLOBALS['TCA'] = array(
1260 'pages' => array(
1261 'ctrl' => array(
1262 'enablecolumns' => array(
1263 'disabled' => 'hidden'
1264 )
1265 )
1266 ),
1267 'tt_content' => array(
1268 'ctrl' => array(
1269 'enablecolumns' => array(
1270 'disabled' => 'hidden'
1271 )
1272 )
1273 ),
1274 );
1275 $this->cObj = $this->getAccessibleMock('\\TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer', array('getTreeList'));
1276 $this->cObj->start(array(), 'tt_content');
1277 $conf = array(
1278 'recursive' => '15',
1279 'pidInList' => '16, -35'
1280 );
1281 $this->cObj->expects($this->at(0))
1282 ->method('getTreeList')
1283 ->with(-16, 15)
1284 ->will($this->returnValue('15,16'));
1285 $this->cObj->expects($this->at(1))
1286 ->method('getTreeList')
1287 ->with(-35, 15)
1288 ->will($this->returnValue('15,35'));
1289 $this->cObj->getQuery('tt_content', $conf, TRUE);
1290 }
1291
1292 /**
1293 * @test
1294 */
1295 public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet() {
1296 $GLOBALS['TCA'] = array(
1297 'pages' => array(
1298 'ctrl' => array(
1299 'enablecolumns' => array(
1300 'disabled' => 'hidden'
1301 )
1302 )
1303 ),
1304 'tt_content' => array(
1305 'ctrl' => array(
1306 'enablecolumns' => array(
1307 'disabled' => 'hidden'
1308 )
1309 )
1310 ),
1311 );
1312 $this->cObj = $this->getAccessibleMock('\\TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer', array('getTreeList'));
1313 $GLOBALS['TSFE']->id = 27;
1314 $this->cObj->start(array(), 'tt_content');
1315 $conf = array(
1316 'pidInList' => 'this',
1317 'recursive' => '4'
1318 );
1319 $this->cObj->expects($this->once())
1320 ->method('getTreeList')
1321 ->with(-27)
1322 ->will($this->returnValue('27'));
1323 $this->cObj->getQuery('tt_content', $conf, TRUE);
1324 }
1325
1326 /**
1327 * Data provider for the stdWrap_strftime test
1328 *
1329 * @return array multi-dimensional array with the second level like this:
1330 * @see stdWrap_strftime
1331 */
1332 public function stdWrap_strftimeReturnsFormattedStringDataProvider() {
1333 $data = array(
1334 'given timestamp' => array(
1335 1346500800, // This is 2012-09-01 12:00 in UTC/GMT
1336 array(
1337 'strftime' => '%d-%m-%Y',
1338 ),
1339 ),
1340 'empty string' => array(
1341 '',
1342 array(
1343 'strftime' => '%d-%m-%Y',
1344 ),
1345 ),
1346 'testing null' => array(
1347 NULL,
1348 array(
1349 'strftime' => '%d-%m-%Y',
1350 ),
1351 ),
1352 );
1353 return $data;
1354 }
1355
1356 /**
1357 * @test
1358 * @dataProvider stdWrap_strftimeReturnsFormattedStringDataProvider
1359 */
1360 public function stdWrap_strftimeReturnsFormattedString($content, $conf) {
1361 // Set exec_time to a hard timestamp
1362 $GLOBALS['EXEC_TIME'] = 1346500800;
1363 // Save current timezone and set to UTC to make the system under test behave
1364 // the same in all server timezone settings
1365 $timezoneBackup = date_default_timezone_get();
1366 date_default_timezone_set('UTC');
1367
1368 $result = $this->cObj->stdWrap_strftime($content, $conf);
1369
1370 // Reset timezone
1371 date_default_timezone_set($timezoneBackup);
1372
1373 $this->assertEquals('01-09-2012', $result);
1374 }
1375
1376 /**
1377 * @param string|NULL $content
1378 * @param array $configuration
1379 * @param string $expected
1380 * @dataProvider stdWrap_ifNullDeterminesNullValuesDataProvider
1381 * @test
1382 */
1383 public function stdWrap_ifNullDeterminesNullValues($content, array $configuration, $expected) {
1384 $result = $this->cObj->stdWrap_ifNull($content, $configuration);
1385 $this->assertEquals($expected, $result);
1386 }
1387
1388 /**
1389 * Data provider for stdWrap_ifNullDeterminesNullValues test
1390 *
1391 * @return array
1392 */
1393 public function stdWrap_ifNullDeterminesNullValuesDataProvider() {
1394 return array(
1395 'null value' => array(
1396 NULL,
1397 array(
1398 'ifNull' => '1',
1399 ),
1400 '1',
1401 ),
1402 'zero value' => array(
1403 '0',
1404 array(
1405 'ifNull' => '1',
1406 ),
1407 '0',
1408 ),
1409 );
1410 }
1411
1412 /**
1413 * @param $content
1414 * @param array $configuration
1415 * @param $expected
1416 * @dataProvider stdWrap_noTrimWrapAcceptsSplitCharDataProvider
1417 * @test
1418 */
1419 public function stdWrap_noTrimWrapAcceptsSplitChar($content, array $configuration, $expected) {
1420 $result = $this->cObj->stdWrap_noTrimWrap($content, $configuration);
1421 $this->assertEquals($expected, $result);
1422 }
1423
1424 /**
1425 * Data provider for stdWrap_noTrimWrapAcceptsSplitChar test
1426 *
1427 * @return array
1428 */
1429 public function stdWrap_noTrimWrapAcceptsSplitCharDataProvider() {
1430 return array(
1431 'No char given' => array(
1432 'middle',
1433 array(
1434 'noTrimWrap' => '| left | right |',
1435 ),
1436 ' left middle right '
1437 ),
1438 'Zero char given' => array(
1439 'middle',
1440 array(
1441 'noTrimWrap' => '0 left 0 right 0',
1442 'noTrimWrap.' => array('splitChar' => '0'),
1443
1444 ),
1445 ' left middle right '
1446 ),
1447 'Default char given' => array(
1448 'middle',
1449 array(
1450 'noTrimWrap' => '| left | right |',
1451 'noTrimWrap.' => array('splitChar' => '|'),
1452 ),
1453 ' left middle right '
1454 ),
1455 'Split char is a' => array(
1456 'middle',
1457 array(
1458 'noTrimWrap' => 'a left a right a',
1459 'noTrimWrap.' => array('splitChar' => 'a'),
1460 ),
1461 ' left middle right '
1462 ),
1463 'Split char is multi-char (ab)' => array(
1464 'middle',
1465 array(
1466 'noTrimWrap' => 'ab left ab right ab',
1467 'noTrimWrap.' => array('splitChar' => 'ab'),
1468 ),
1469 ' left middle right '
1470 ),
1471 'Split char accepts stdWrap' => array(
1472 'middle',
1473 array(
1474 'noTrimWrap' => 'abc left abc right abc',
1475 'noTrimWrap.' => array(
1476 'splitChar' => 'b',
1477 'splitChar.' => array('wrap' => 'a|c'),
1478 ),
1479 ),
1480 ' left middle right '
1481 ),
1482 );
1483 }
1484
1485 /**
1486 * @param array $expectedTags
1487 * @param array $configuration
1488 * @test
1489 * @dataProvider stdWrap_addPageCacheTagsAddsPageTagsDataProvider
1490 */
1491 public function stdWrap_addPageCacheTagsAddsPageTags(array $expectedTags, array $configuration) {
1492 $this->cObj->stdWrap_addPageCacheTags('', $configuration);
1493 $this->assertEquals($expectedTags, $this->tsfe->_get('pageCacheTags'));
1494 }
1495
1496 /**
1497 * @return array
1498 */
1499 public function stdWrap_addPageCacheTagsAddsPageTagsDataProvider() {
1500 return array(
1501 'No Tag' => array(
1502 array(),
1503 array('addPageCacheTags' => ''),
1504 ),
1505 'Two expectedTags' => array(
1506 array('tag1', 'tag2'),
1507 array('addPageCacheTags' => 'tag1,tag2'),
1508 ),
1509 'Two expectedTags plus one with stdWrap' => array(
1510 array('tag1', 'tag2', 'tag3'),
1511 array(
1512 'addPageCacheTags' => 'tag1,tag2',
1513 'addPageCacheTags.' => array('wrap' => '|,tag3')
1514 ),
1515 ),
1516 );
1517 }
1518
1519 /**
1520 * Data provider for stdWrap_encodeForJavaScriptValue test
1521 *
1522 * @return array multi-dimensional array with the second level like this:
1523 * @see encodeForJavaScriptValue
1524 */
1525 public function stdWrap_encodeForJavaScriptValueDataProvider() {
1526 return array(
1527 'double quote in string' => array(
1528 'double quote"',
1529 array(),
1530 '\'double\u0020quote\u0022\''
1531 ),
1532 'backslash in string' => array(
1533 'backslash \\',
1534 array(),
1535 '\'backslash\u0020\u005C\''
1536 ),
1537 'exclamation mark' => array(
1538 'exclamation!',
1539 array(),
1540 '\'exclamation\u0021\''
1541 ),
1542 'whitespace tab, newline and carriage return' => array(
1543 "white\tspace\ns\r",
1544 array(),
1545 '\'white\u0009space\u000As\u000D\''
1546 ),
1547 'single quote in string' => array(
1548 'single quote \'',
1549 array(),
1550 '\'single\u0020quote\u0020\u0027\''
1551 ),
1552 'tag' => array(
1553 '<tag>',
1554 array(),
1555 '\'\u003Ctag\u003E\''
1556 ),
1557 'ampersand in string' => array(
1558 'amper&sand',
1559 array(),
1560 '\'amper\u0026sand\''
1561 ),
1562 );
1563 }
1564
1565 /**
1566 * Check if encodeForJavaScriptValue works properly
1567 *
1568 * @dataProvider stdWrap_encodeForJavaScriptValueDataProvider
1569 * @test
1570 */
1571 public function stdWrap_encodeForJavaScriptValue($input, $conf, $expected) {
1572 $result = $this->cObj->stdWrap_encodeForJavaScriptValue($input, $conf);
1573 $this->assertEquals($expected, $result);
1574 }
1575
1576
1577 /////////////////////////////
1578 // Tests concerning getData()
1579 /////////////////////////////
1580
1581 /**
1582 * @return array
1583 */
1584 public function getDataWithTypeGpDataProvider() {
1585 return array(
1586 'Value in get-data' => array('onlyInGet', 'GetValue'),
1587 'Value in post-data' => array('onlyInPost', 'PostValue'),
1588 'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
1589 );
1590 }
1591
1592 /**
1593 * Checks if getData() works with type "gp"
1594 *
1595 * @test
1596 * @dataProvider getDataWithTypeGpDataProvider
1597 */
1598 public function getDataWithTypeGp($key, $expectedValue) {
1599 $_GET = array(
1600 'onlyInGet' => 'GetValue',
1601 'inGetAndPost' => 'ValueInGet',
1602 );
1603 $_POST = array(
1604 'onlyInPost' => 'PostValue',
1605 'inGetAndPost' => 'ValueInPost',
1606 );
1607 $this->assertEquals($expectedValue, $this->cObj->getData('gp:' . $key));
1608 }
1609
1610 /**
1611 * Checks if getData() works with type "tsfe"
1612 *
1613 * @test
1614 */
1615 public function getDataWithTypeTsfe() {
1616 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->cObj->getData('tsfe:renderCharset'));
1617 }
1618
1619 /**
1620 * Checks if getData() works with type "getenv"
1621 *
1622 * @test
1623 */
1624 public function getDataWithTypeGetenv() {
1625 $envName = uniqid('frontendtest');
1626 $value = uniqid('someValue');
1627 putenv($envName . '=' . $value);
1628 $this->assertEquals($value, $this->cObj->getData('getenv:' . $envName));
1629 }
1630
1631 /**
1632 * Checks if getData() works with type "getindpenv"
1633 *
1634 * @test
1635 */
1636 public function getDataWithTypeGetindpenv() {
1637 $this->assertEquals(PATH_thisScript, $this->cObj->getData('getindpenv:SCRIPT_FILENAME'));
1638 }
1639
1640 /**
1641 * Checks if getData() works with type "getindpenv"
1642 *
1643 * @test
1644 */
1645 public function getDataWithTypeField() {
1646 $key = 'someKey';
1647 $value = 'someValue';
1648 $field = array($key => $value);
1649
1650 $this->assertEquals($value, $this->cObj->getData('field:' . $key, $field));
1651 }
1652
1653 /**
1654 * Basic check if getData gets the uid of a file object
1655 *
1656 * @test
1657 */
1658 public function getDataWithTypeFileReturnsUidOfFileObject() {
1659 $uid = uniqid();
1660 $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\File', array(), array(), '', FALSE);
1661 $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
1662 $this->cObj->setCurrentFile($file);
1663 $this->assertEquals($uid, $this->cObj->getData('file:current:uid'));
1664 }
1665
1666 /**
1667 * Checks if getData() works with type "parameters"
1668 *
1669 * @test
1670 */
1671 public function getDataWithTypeParameters() {
1672 $key = uniqid('someKey');
1673 $value = uniqid('someValue');
1674 $this->cObj->parameters[$key] = $value;
1675
1676 $this->assertEquals($value, $this->cObj->getData('parameters:' . $key));
1677 }
1678
1679 /**
1680 * Checks if getData() works with type "register"
1681 *
1682 * @test
1683 */
1684 public function getDataWithTypeRegister() {
1685 $key = uniqid('someKey');
1686 $value = uniqid('someValue');
1687 $GLOBALS['TSFE']->register[$key] = $value;
1688
1689 $this->assertEquals($value, $this->cObj->getData('register:' . $key));
1690 }
1691
1692 /**
1693 * Checks if getData() works with type "level"
1694 *
1695 * @test
1696 */
1697 public function getDataWithTypeLevel() {
1698 $rootline = array(
1699 0 => array('uid' => 1, 'title' => 'title1'),
1700 1 => array('uid' => 2, 'title' => 'title2'),
1701 2 => array('uid' => 3, 'title' => 'title3'),
1702 );
1703
1704 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1705 $this->assertEquals(2, $this->cObj->getData('level'));
1706 }
1707
1708 /**
1709 * Checks if getData() works with type "global"
1710 *
1711 * @test
1712 */
1713 public function getDataWithTypeGlobal() {
1714 $this->assertEquals($GLOBALS['TSFE']->renderCharset, $this->cObj->getData('global:TSFE|renderCharset'));
1715 }
1716
1717 /**
1718 * Checks if getData() works with type "leveltitle"
1719 *
1720 * @test
1721 */
1722 public function getDataWithTypeLeveltitle() {
1723 $rootline = array(
1724 0 => array('uid' => 1, 'title' => 'title1'),
1725 1 => array('uid' => 2, 'title' => 'title2'),
1726 2 => array('uid' => 3, 'title' => ''),
1727 );
1728
1729 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1730 $this->assertEquals('', $this->cObj->getData('leveltitle:-1'));
1731 // since "title3" is not set, it will slide to "title2"
1732 $this->assertEquals('title2', $this->cObj->getData('leveltitle:-1,slide'));
1733 }
1734
1735 /**
1736 * Checks if getData() works with type "levelmedia"
1737 *
1738 * @test
1739 */
1740 public function getDataWithTypeLevelmedia() {
1741 $rootline = array(
1742 0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
1743 1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
1744 2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
1745 );
1746
1747 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1748 $this->assertEquals('', $this->cObj->getData('levelmedia:-1'));
1749 // since "title3" is not set, it will slide to "title2"
1750 $this->assertEquals('media2', $this->cObj->getData('levelmedia:-1,slide'));
1751 }
1752
1753 /**
1754 * Checks if getData() works with type "leveluid"
1755 *
1756 * @test
1757 */
1758 public function getDataWithTypeLeveluid() {
1759 $rootline = array(
1760 0 => array('uid' => 1, 'title' => 'title1'),
1761 1 => array('uid' => 2, 'title' => 'title2'),
1762 2 => array('uid' => 3, 'title' => 'title3'),
1763 );
1764
1765 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1766 $this->assertEquals(3, $this->cObj->getData('leveluid:-1'));
1767 // every element will have a uid - so adding slide doesn't really make sense, just for completeness
1768 $this->assertEquals(3, $this->cObj->getData('leveluid:-1,slide'));
1769 }
1770
1771 /**
1772 * Checks if getData() works with type "levelfield"
1773 *
1774 * @test
1775 */
1776 public function getDataWithTypeLevelfield() {
1777 $rootline = array(
1778 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1779 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
1780 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
1781 );
1782
1783 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1784 $this->assertEquals('', $this->cObj->getData('levelfield:-1,testfield'));
1785 $this->assertEquals('field2', $this->cObj->getData('levelfield:-1,testfield,slide'));
1786 }
1787
1788 /**
1789 * Checks if getData() works with type "fullrootline"
1790 *
1791 * @test
1792 */
1793 public function getDataWithTypeFullrootline() {
1794 $rootline1 = array(
1795 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1796 );
1797 $rootline2 = array(
1798 0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
1799 1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
1800 2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
1801 );
1802
1803 $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
1804 $GLOBALS['TSFE']->rootLine = $rootline2;
1805 $this->assertEquals('field2', $this->cObj->getData('fullrootline:-1,testfield'));
1806 }
1807
1808 /**
1809 * Checks if getData() works with type "date"
1810 *
1811 * @test
1812 */
1813 public function getDataWithTypeDate() {
1814 $format = 'Y-M-D';
1815 $defaultFormat = 'd/m Y';
1816
1817 $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->cObj->getData('date:' . $format));
1818 $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->cObj->getData('date'));
1819 }
1820
1821 /**
1822 * Checks if getData() works with type "page"
1823 *
1824 * @test
1825 */
1826 public function getDataWithTypePage() {
1827 $uid = rand();
1828 $GLOBALS['TSFE']->page['uid'] = $uid;
1829 $this->assertEquals($uid, $this->cObj->getData('page:uid'));
1830 }
1831
1832 /**
1833 * Checks if getData() works with type "current"
1834 *
1835 * @test
1836 */
1837 public function getDataWithTypeCurrent() {
1838 $key = uniqid('someKey');
1839 $value = uniqid('someValue');
1840 $this->cObj->data[$key] = $value;
1841 $this->cObj->currentValKey = $key;
1842 $this->assertEquals($value, $this->cObj->getData('current'));
1843 }
1844
1845 /**
1846 * Checks if getData() works with type "db"
1847 *
1848 * @test
1849 */
1850 public function getDataWithTypeDb() {
1851 $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
1852
1853 $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
1854 $this->assertEquals($dummyRecord['title'], $this->cObj->getData('db:tt_content:106:title'));
1855 }
1856
1857 /**
1858 * Checks if getData() works with type "lll"
1859 *
1860 * @test
1861 */
1862 public function getDataWithTypeLll() {
1863 $key = uniqid('someKey');
1864 $value = uniqid('someValue');
1865 $language = uniqid('someLanguage');
1866 $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
1867 $GLOBALS['TSFE']->lang = $language;
1868
1869 $this->assertEquals($value, $this->cObj->getData('lll:' . $key));
1870 }
1871
1872 /**
1873 * Checks if getData() works with type "path"
1874 *
1875 * @test
1876 */
1877 public function getDataWithTypePath() {
1878 $filenameIn = uniqid('someValue');
1879 $filenameOut = uniqid('someValue');
1880 $this->template->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
1881 $this->assertEquals($filenameOut, $this->cObj->getData('path:' . $filenameIn));
1882 }
1883
1884 /**
1885 * Checks if getData() works with type "parentRecordNumber"
1886 *
1887 * @test
1888 */
1889 public function getDataWithTypeParentRecordNumber() {
1890 $recordNumber = rand();
1891 $this->cObj->parentRecordNumber = $recordNumber;
1892 $this->assertEquals($recordNumber, $this->cObj->getData('cobj:parentRecordNumber'));
1893 }
1894
1895 /**
1896 * Checks if getData() works with type "debug:rootLine"
1897 *
1898 * @test
1899 */
1900 public function getDataWithTypeDebugRootline() {
1901 $rootline = array(
1902 0 => array('uid' => 1, 'title' => 'title1'),
1903 1 => array('uid' => 2, 'title' => 'title2'),
1904 2 => array('uid' => 3, 'title' => ''),
1905 );
1906 $expectedResult = '0uid1titletitle11uid2titletitle22uid3title';
1907 $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
1908
1909 $result = $this->cObj->getData('debug:rootLine');
1910 $cleanedResult = strip_tags($result);
1911 $cleanedResult = str_replace("\r", '', $cleanedResult);
1912 $cleanedResult = str_replace("\n", '', $cleanedResult);
1913 $cleanedResult = str_replace("\t", '', $cleanedResult);
1914 $cleanedResult = str_replace(' ', '', $cleanedResult);
1915
1916 $this->assertEquals($expectedResult, $cleanedResult);
1917 }
1918
1919 /**
1920 * Checks if getData() works with type "debug:fullRootLine"
1921 *
1922 * @test
1923 */
1924 public function getDataWithTypeDebugFullRootline() {
1925 $rootline = array(
1926 0 => array('uid' => 1, 'title' => 'title1'),
1927 1 => array('uid' => 2, 'title' => 'title2'),
1928 2 => array('uid' => 3, 'title' => ''),
1929 );
1930 $expectedResult = '0uid1titletitle11uid2titletitle22uid3title';
1931 $GLOBALS['TSFE']->rootLine = $rootline;
1932
1933 $result = $this->cObj->getData('debug:fullRootLine');
1934 $cleanedResult = strip_tags($result);
1935 $cleanedResult = str_replace("\r", '', $cleanedResult);
1936 $cleanedResult = str_replace("\n", '', $cleanedResult);
1937 $cleanedResult = str_replace("\t", '', $cleanedResult);
1938 $cleanedResult = str_replace(' ', '', $cleanedResult);
1939
1940 $this->assertEquals($expectedResult, $cleanedResult);
1941 }
1942
1943 /**
1944 * Checks if getData() works with type "debug:data"
1945 *
1946 * @test
1947 */
1948 public function getDataWithTypeDebugData() {
1949 $key = uniqid('someKey');
1950 $value = uniqid('someValue');
1951 $this->cObj->data = array($key => $value);
1952
1953 $expectedResult = $key . $value;
1954
1955 $result = $this->cObj->getData('debug:data');
1956 $cleanedResult = strip_tags($result);
1957 $cleanedResult = str_replace("\r", '', $cleanedResult);
1958 $cleanedResult = str_replace("\n", '', $cleanedResult);
1959 $cleanedResult = str_replace("\t", '', $cleanedResult);
1960 $cleanedResult = str_replace(' ', '', $cleanedResult);
1961
1962 $this->assertEquals($expectedResult, $cleanedResult);
1963 }
1964
1965 /**
1966 * Checks if getData() works with type "debug:register"
1967 *
1968 * @test
1969 */
1970 public function getDataWithTypeDebugRegister() {
1971 $key = uniqid('someKey');
1972 $value = uniqid('someValue');
1973 $GLOBALS['TSFE']->register = array($key => $value);
1974
1975 $expectedResult = $key . $value;
1976
1977 $result = $this->cObj->getData('debug:register');
1978 $cleanedResult = strip_tags($result);
1979 $cleanedResult = str_replace("\r", '', $cleanedResult);
1980 $cleanedResult = str_replace("\n", '', $cleanedResult);
1981 $cleanedResult = str_replace("\t", '', $cleanedResult);
1982 $cleanedResult = str_replace(' ', '', $cleanedResult);
1983
1984 $this->assertEquals($expectedResult, $cleanedResult);
1985 }
1986
1987 /**
1988 * Checks if getData() works with type "data:page"
1989 *
1990 * @test
1991 */
1992 public function getDataWithTypeDebugPage() {
1993 $uid = rand();
1994 $GLOBALS['TSFE']->page = array('uid' => $uid);
1995
1996 $expectedResult = 'uid' . $uid;
1997
1998 $result = $this->cObj->getData('debug:page');
1999 $cleanedResult = strip_tags($result);
2000 $cleanedResult = str_replace("\r", '', $cleanedResult);
2001 $cleanedResult = str_replace("\n", '', $cleanedResult);
2002 $cleanedResult = str_replace("\t", '', $cleanedResult);
2003 $cleanedResult = str_replace(' ', '', $cleanedResult);
2004
2005 $this->assertEquals($expectedResult, $cleanedResult);
2006 }
2007
2008 /**
2009 * @test
2010 */
2011 public function getTreeListReturnsChildPageUids() {
2012 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
2013 $GLOBALS['TSFE']->sys_page
2014 ->expects($this->any())
2015 ->method('getRawRecord')
2016 ->will(
2017 $this->onConsecutiveCalls(
2018 array('uid' => 17),
2019 array('uid' => 321),
2020 array('uid' => 719),
2021 array('uid' => 42)
2022 )
2023 );
2024
2025 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
2026 $GLOBALS['TYPO3_DB']
2027 ->expects($this->any())
2028 ->method('exec_SELECTgetRows')
2029 ->will(
2030 $this->onConsecutiveCalls(
2031 array(
2032 array('uid' => 321)
2033 ),
2034 array(
2035 array('uid' => 719)
2036 ),
2037 array(
2038 array('uid' => 42)
2039 )
2040 )
2041 );
2042 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2043 // 17 is positive, we expect 17 NOT to be included in result
2044 $result = $this->cObj->getTreeList(17, 5, 0, TRUE);
2045 $expectedResult = '42,719,321';
2046 $this->assertEquals($expectedResult, $result);
2047 }
2048
2049 /**
2050 * @test
2051 */
2052 public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue() {
2053 $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(NULL));
2054 $GLOBALS['TSFE']->sys_page
2055 ->expects($this->any())
2056 ->method('getRawRecord')
2057 ->will(
2058 $this->onConsecutiveCalls(
2059 array('uid' => 17),
2060 array('uid' => 321),
2061 array('uid' => 719),
2062 array('uid' => 42)
2063 )
2064 );
2065
2066 $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(NULL));
2067 $GLOBALS['TYPO3_DB']
2068 ->expects($this->any())
2069 ->method('exec_SELECTgetRows')
2070 ->will(
2071 $this->onConsecutiveCalls(
2072 array(
2073 array('uid' => 321)
2074 ),
2075 array(
2076 array('uid' => 719)
2077 ),
2078 array(
2079 array('uid' => 42)
2080 )
2081 )
2082 );
2083 // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
2084 // 17 is negative, we expect 17 to be included in result
2085 $result = $this->cObj->getTreeList(-17, 5, 0, TRUE);
2086 $expectedResult = '42,719,321,17';
2087 $this->assertEquals($expectedResult, $result);
2088 }
2089
2090 /**
2091 * @test
2092 */
2093 public function aTagParamsHasLeadingSpaceIfNotEmpty() {
2094 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2095 $this->assertEquals(' data-test="testdata"', $aTagParams );
2096 }
2097
2098 /**
2099 * @test
2100 */
2101 public function aTagParamsHaveSpaceBetweenLocalAndGlobalParams() {
2102 $GLOBALS['TSFE']->ATagParams = 'data-global="dataglobal"';
2103 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => 'data-test="testdata"'));
2104 $this->assertEquals(' data-global="dataglobal" data-test="testdata"', $aTagParams );
2105 }
2106
2107 /**
2108 * @test
2109 */
2110 public function aTagParamsHasNoLeadingSpaceIfEmpty() {
2111 // make sure global ATagParams are empty
2112 $GLOBALS['TSFE']->ATagParams = '';
2113 $aTagParams = $this->cObj->getATagParams(array('ATagParams' => ''));
2114 $this->assertEquals('', $aTagParams);
2115 }
2116
2117 /**
2118 * @return array
2119 */
2120 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider() {
2121 return array(
2122 array(NULL, NULL),
2123 array('', NULL),
2124 array('', array()),
2125 array('fooo', array('foo' => 'bar'))
2126 );
2127 }
2128
2129 /**
2130 * Make sure that the rendering falls back to the classic <img style if nothing else is found
2131 *
2132 * @test
2133 * @dataProvider getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider
2134 * @param string $key
2135 * @param array $configuration
2136 */
2137 public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFound($key, $configuration) {
2138 $defaultImgTagTemplate = '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
2139 $result = $this->cObj->getImageTagTemplate($key, $configuration);
2140 $this->assertEquals($result, $defaultImgTagTemplate);
2141 }
2142
2143 /**
2144 * @return array
2145 */
2146 public function getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider() {
2147 return array(
2148 array(
2149 'foo',
2150 array(
2151 'layout.' => array(
2152 'foo.' => array(
2153 'element' => '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2154 )
2155 )
2156 ),
2157 '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
2158 )
2159
2160 );
2161 }
2162
2163 /**
2164 * Assure if a layoutKey and layout is given the selected layout is returned
2165 *
2166 * @test
2167 * @dataProvider getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider
2168 * @param string $key
2169 * @param array $configuration
2170 * @param string $expectation
2171 */
2172 public function getImageTagTemplateReturnTemplateElementIdentifiedByKey($key, $configuration, $expectation) {
2173 $result = $this->cObj->getImageTagTemplate($key, $configuration);
2174 $this->assertEquals($result, $expectation);
2175 }
2176
2177 /**
2178 * @return array
2179 */
2180 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider() {
2181 return array(
2182 array(NULL, NULL, NULL),
2183 array('foo', NULL, NULL),
2184 array('foo', array('sourceCollection.' => 1), 'bar')
2185 );
2186 }
2187
2188 /**
2189 * Make sure the source collection is empty if no valid configuration or source collection is defined
2190 *
2191 * @test
2192 * @dataProvider getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider
2193 * @param string $layoutKey
2194 * @param array $configuration
2195 * @param string $file
2196 */
2197 public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefined($layoutKey, $configuration, $file) {
2198 $result = $this->cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2199 $this->assertSame($result, '');
2200 }
2201
2202 /**
2203 * Make sure the generation of subimages calls the generation of the subimages and uses the layout -> source template
2204 *
2205 * @test
2206 */
2207 public function getImageSourceCollectionRendersDefinedSources() {
2208 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2209 $cObj = $this->getMock(
2210 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2211 array('stdWrap','getImgResource')
2212 );
2213 $cObj->start(array(), 'tt_content');
2214
2215 $layoutKey = 'test';
2216
2217 $configuration = array(
2218 'layoutKey' => 'test',
2219 'layout.' => array (
2220 'test.' => array(
2221 'element' => '<img ###SRC### ###SRCCOLLECTION### ###SELFCLOSINGTAGSLASH###>',
2222 'source' => '---###SRC###---'
2223 )
2224 ),
2225 'sourceCollection.' => array(
2226 '1.' => array(
2227 'width' => '200'
2228 )
2229 )
2230 );
2231
2232 $file = 'testImageName';
2233
2234 // Avoid calling of stdWrap
2235 $cObj
2236 ->expects($this->any())
2237 ->method('stdWrap')
2238 ->will($this->returnArgument(0));
2239
2240 // Avoid calling of imgResource
2241 $cObj
2242 ->expects($this->exactly(1))
2243 ->method('getImgResource')
2244 ->with($this->equalTo('testImageName'))
2245 ->will($this->returnValue(array(100, 100, NULL, 'bar')));
2246
2247 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2248
2249 $this->assertEquals('---bar---', $result);
2250 }
2251
2252 /**
2253 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyDefault test
2254 *
2255 * @return array multi-dimensional array with the second level like this:
2256 * @see getImageSourceCollectionRendersDefinedLayoutKeyDefault
2257 */
2258 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider() {
2259 /**
2260 * @see css_styled_content/static/setup.txt
2261 */
2262 $sourceCollectionArray = array(
2263 'small.' => array(
2264 'width' => '200',
2265 'srcsetCandidate' => '600w',
2266 'mediaQuery' => '(max-device-width: 600px)',
2267 'dataKey' => 'small',
2268 ),
2269 'smallRetina.' => array(
2270 'if.directReturn' => 0,
2271 'width' => '200',
2272 'pixelDensity' => '2',
2273 'srcsetCandidate' => '600w 2x',
2274 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2275 'dataKey' => 'smallRetina',
2276 )
2277 );
2278 return array(
2279 array(
2280 'default',
2281 array(
2282 'layoutKey' => 'default',
2283 'layout.' => array (
2284 'default.' => array(
2285 'element' => '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>',
2286 'source' => ''
2287 )
2288 ),
2289 'sourceCollection.' => $sourceCollectionArray
2290 )
2291 ),
2292 );
2293 }
2294
2295 /**
2296 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2297 *
2298 * @test
2299 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider
2300 * @param string $layoutKey
2301 * @param array $configuration
2302 */
2303 public function getImageSourceCollectionRendersDefinedLayoutKeyDefault($layoutKey , $configuration) {
2304 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2305 $cObj = $this->getMock(
2306 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2307 array('stdWrap','getImgResource')
2308 );
2309 $cObj->start(array(), 'tt_content');
2310
2311 $file = 'testImageName';
2312
2313 // Avoid calling of stdWrap
2314 $cObj
2315 ->expects($this->any())
2316 ->method('stdWrap')
2317 ->will($this->returnArgument(0));
2318
2319 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2320
2321 $this->assertEmpty($result);
2322 }
2323
2324 /**
2325 * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyData test
2326 *
2327 * @return array multi-dimensional array with the second level like this:
2328 * @see getImageSourceCollectionRendersDefinedLayoutKeyData
2329 */
2330 public function getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider() {
2331 /**
2332 * @see css_styled_content/static/setup.txt
2333 */
2334 $sourceCollectionArray = array(
2335 'small.' => array(
2336 'width' => '200',
2337 'srcsetCandidate' => '600w',
2338 'mediaQuery' => '(max-device-width: 600px)',
2339 'dataKey' => 'small',
2340 ),
2341 'smallRetina.' => array(
2342 'if.directReturn' => 1,
2343 'width' => '200',
2344 'pixelDensity' => '2',
2345 'srcsetCandidate' => '600w 2x',
2346 'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
2347 'dataKey' => 'smallRetina',
2348 )
2349 );
2350 return array(
2351 array(
2352 'srcset',
2353 array(
2354 'layoutKey' => 'srcset',
2355 'layout.' => array (
2356 'srcset.' => array(
2357 'element' => '<img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2358 'source' => '|*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###'
2359 )
2360 ),
2361 'sourceCollection.' => $sourceCollectionArray
2362 ),
2363 'xhtml_strict',
2364 'bar-file.jpg 600w,bar-file.jpg 600w 2x',
2365 ),
2366 array(
2367 'picture',
2368 array(
2369 'layoutKey' => 'picture',
2370 'layout.' => array (
2371 'picture.' => array(
2372 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2373 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2374 )
2375 ),
2376 'sourceCollection.' => $sourceCollectionArray,
2377 ),
2378 'xhtml_strict',
2379 '<source src="bar-file.jpg" media="(max-device-width: 600px)" /><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)" />',
2380 ),
2381 array(
2382 'picture',
2383 array(
2384 'layoutKey' => 'picture',
2385 'layout.' => array (
2386 'picture.' => array(
2387 'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
2388 'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
2389 )
2390 ),
2391 'sourceCollection.' => $sourceCollectionArray,
2392 ),
2393 '',
2394 '<source src="bar-file.jpg" media="(max-device-width: 600px)"><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)">',
2395 ),
2396 array(
2397 'data',
2398 array(
2399 'layoutKey' => 'data',
2400 'layout.' => array (
2401 'data.' => array(
2402 'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2403 'source' => 'data-###DATAKEY###="###SRC###"'
2404 )
2405 ),
2406 'sourceCollection.' => $sourceCollectionArray
2407 ),
2408 'xhtml_strict',
2409 'data-small="bar-file.jpg"data-smallRetina="bar-file.jpg"',
2410 ),
2411 );
2412 }
2413
2414 /**
2415 * Make sure the generation of subimages renders the expected HTML Code for the sourceset
2416 *
2417 * @test
2418 * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider
2419 * @param string $layoutKey
2420 * @param array $configuration
2421 * @param string $xhtmlDoctype
2422 * @param string $expectedHtml
2423 */
2424 public function getImageSourceCollectionRendersDefinedLayoutKeyData($layoutKey , $configuration, $xhtmlDoctype, $expectedHtml) {
2425 /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
2426 $cObj = $this->getMock(
2427 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer',
2428 array('stdWrap','getImgResource')
2429 );
2430 $cObj->start(array(), 'tt_content');
2431
2432 $file = 'testImageName';
2433
2434 $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
2435
2436 // Avoid calling of stdWrap
2437 $cObj
2438 ->expects($this->any())
2439 ->method('stdWrap')
2440 ->will($this->returnArgument(0));
2441
2442 // Avoid calling of imgResource
2443 $cObj
2444 ->expects($this->exactly(2))
2445 ->method('getImgResource')
2446 ->with($this->equalTo('testImageName'))
2447 ->will($this->returnValue(array(100, 100, NULL, 'bar-file.jpg')));
2448
2449 $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
2450
2451 $this->assertEquals($expectedHtml, $result);
2452 }
2453
2454 /**
2455 * Make sure the hook in get sourceCollection is called
2456 *
2457 * @test
2458 */
2459 public function getImageSourceCollectionHookCalled() {
2460 // Avoid calling stdwrap and getIMgResouce
2461 $this->cObj->expects($this->any())
2462 ->method('stdWrap')
2463 ->will($this->returnArgument(0));
2464
2465 $this->cObj->expects($this->any())
2466 ->method('getImgResource')
2467 ->will($this->returnValue(array(100, 100, NULL, 'bar-file.jpg')));
2468
2469 $resourceFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', array(), array(), '', FALSE);
2470 $this->cObj->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
2471
2472 $className = uniqid('tx_coretest_getImageSourceCollectionHookCalled');
2473 $getImageSourceCollectionHookMock = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectOneSourceCollectionHookInterface', array('getOneSourceCollection'), array(), $className);
2474 $GLOBALS['T3_VAR']['getUserObj'][$className] = $getImageSourceCollectionHookMock;
2475 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'][] = $className;
2476
2477 $getImageSourceCollectionHookMock
2478 ->expects($this->exactly(1))
2479 ->method('getOneSourceCollection')
2480 ->will($this->returnCallback(array($this, 'isGetOneSourceCollectionCalledCallback')));
2481
2482 $configuration = array(
2483 'layoutKey' => 'data',
2484 'layout.' => array (
2485 'data.' => array(
2486 'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
2487 'source' => 'data-###DATAKEY###="###SRC###"'
2488 )
2489 ),
2490 'sourceCollection.' => array(
2491 'small.' => array(
2492 'width' => '200',
2493 'srcsetCandidate' => '600w',
2494 'mediaQuery' => '(max-device-width: 600px)',
2495 'dataKey' => 'small',
2496 ),
2497 ),
2498 );
2499
2500 $result = $this->cObj->getImageSourceCollection('data', $configuration, uniqid('testImage-'));
2501
2502 $this->assertSame($result, 'isGetOneSourceCollectionCalledCallback');
2503 }
2504
2505 /**
2506 * Handles the arguments that have been sent to the getImgResource hook.
2507 *
2508 * @return string
2509 * @see getImageSourceCollectionHookCalled
2510 */
2511 public function isGetOneSourceCollectionCalledCallback() {
2512 list($sourceRenderConfiguration, $sourceConfiguration, $oneSourceCollection, $parent) = func_get_args();
2513 $this->assertTrue(is_array($sourceRenderConfiguration));
2514 $this->assertTrue(is_array($sourceConfiguration));
2515 return 'isGetOneSourceCollectionCalledCallback';
2516 }
2517 }