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