[TASK] Add unit test to cover stdWrap_append
[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 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Log\LoggerInterface;
18 use TYPO3\CMS\Core\Cache\CacheManager;
19 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface as CacheFrontendInterface;
20 use TYPO3\CMS\Core\Charset\CharsetConverter;
21 use TYPO3\CMS\Core\Core\ApplicationContext;
22 use TYPO3\CMS\Core\Database\DatabaseConnection;
23 use TYPO3\CMS\Core\Log\LogManager;
24 use TYPO3\CMS\Core\Resource\File;
25 use TYPO3\CMS\Core\Resource\ResourceFactory;
26 use TYPO3\CMS\Core\Tests\UnitTestCase;
27 use TYPO3\CMS\Core\TypoScript\TemplateService;
28 use TYPO3\CMS\Core\Utility\DebugUtility;
29 use TYPO3\CMS\Core\Utility\GeneralUtility;
30 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
31 use TYPO3\CMS\Frontend\ContentObject\CaseContentObject;
32 use TYPO3\CMS\Frontend\ContentObject\ContentContentObject;
33 use TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject;
34 use TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayInternalContentObject;
35 use TYPO3\CMS\Frontend\ContentObject\ContentObjectOneSourceCollectionHookInterface;
36 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
37 use TYPO3\CMS\Frontend\ContentObject\ContentObjectStdWrapHookInterface;
38 use TYPO3\CMS\Frontend\ContentObject\EditPanelContentObject;
39 use TYPO3\CMS\Frontend\ContentObject\FileContentObject;
40 use TYPO3\CMS\Frontend\ContentObject\FilesContentObject;
41 use TYPO3\CMS\Frontend\ContentObject\FluidTemplateContentObject;
42 use TYPO3\CMS\Frontend\ContentObject\HierarchicalMenuContentObject;
43 use TYPO3\CMS\Frontend\ContentObject\ImageContentObject;
44 use TYPO3\CMS\Frontend\ContentObject\ImageResourceContentObject;
45 use TYPO3\CMS\Frontend\ContentObject\LoadRegisterContentObject;
46 use TYPO3\CMS\Frontend\ContentObject\RecordsContentObject;
47 use TYPO3\CMS\Frontend\ContentObject\RestoreRegisterContentObject;
48 use TYPO3\CMS\Frontend\ContentObject\ScalableVectorGraphicsContentObject;
49 use TYPO3\CMS\Frontend\ContentObject\TemplateContentObject;
50 use TYPO3\CMS\Frontend\ContentObject\TextContentObject;
51 use TYPO3\CMS\Frontend\ContentObject\UserContentObject;
52 use TYPO3\CMS\Frontend\ContentObject\UserInternalContentObject;
53 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
54 use TYPO3\CMS\Frontend\Page\PageRepository;
55 use TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Fixtures\PageRepositoryFixture;
56
57 /**
58 * Testcase for TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
59 */
60 class ContentObjectRendererTest extends UnitTestCase
61 {
62 /**
63 * @var string
64 */
65 protected $currentLocale;
66
67 /**
68 * @var array A backup of registered singleton instances
69 */
70 protected $singletonInstances = array();
71
72 /**
73 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
74 */
75 protected $subject = null;
76
77 /**
78 * @var \PHPUnit_Framework_MockObject_MockObject|TypoScriptFrontendController|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
79 */
80 protected $frontendControllerMock = null;
81
82 /**
83 * @var \PHPUnit_Framework_MockObject_MockObject|TemplateService
84 */
85 protected $templateServiceMock = null;
86
87 /**
88 * Default content object name -> class name map, shipped with TYPO3 CMS
89 *
90 * @var array
91 */
92 protected $contentObjectMap = [
93 'TEXT' => TextContentObject::class,
94 'CASE' => CaseContentObject::class,
95 'COBJ_ARRAY' => ContentObjectArrayContentObject::class,
96 'COA' => ContentObjectArrayContentObject::class,
97 'COA_INT' => ContentObjectArrayInternalContentObject::class,
98 'USER' => UserContentObject::class,
99 'USER_INT' => UserInternalContentObject::class,
100 'FILE' => FileContentObject::class,
101 'FILES' => FilesContentObject::class,
102 'IMAGE' => ImageContentObject::class,
103 'IMG_RESOURCE' => ImageResourceContentObject::class,
104 'CONTENT' => ContentContentObject::class,
105 'RECORDS' => RecordsContentObject::class,
106 'HMENU' => HierarchicalMenuContentObject::class,
107 'CASEFUNC' => CaseContentObject::class,
108 'LOAD_REGISTER' => LoadRegisterContentObject::class,
109 'RESTORE_REGISTER' => RestoreRegisterContentObject::class,
110 'TEMPLATE' => TemplateContentObject::class,
111 'FLUIDTEMPLATE' => FluidTemplateContentObject::class,
112 'SVG' => ScalableVectorGraphicsContentObject::class,
113 'EDITPANEL' => EditPanelContentObject::class
114 ];
115
116 /**
117 * Set up
118 */
119 protected function setUp()
120 {
121 $this->currentLocale = setlocale(LC_NUMERIC, 0);
122 $this->singletonInstances = GeneralUtility::getSingletonInstances();
123 $this->createMockedLoggerAndLogManager();
124
125 $this->templateServiceMock =
126 $this->getMockBuilder(TemplateService::class)
127 ->setMethods(['getFileName', 'linkData'])->getMock();
128 $pageRepositoryMock =
129 $this->getMockBuilder(PageRepositoryFixture::class)
130 ->setMethods(['getRawRecord', 'getMountPointInfo'])->getMock();
131 $this->frontendControllerMock =
132 $this->getAccessibleMock(TypoScriptFrontendController::class,
133 ['dummy'], [], '', false);
134 $this->frontendControllerMock->tmpl = $this->templateServiceMock;
135 $this->frontendControllerMock->config = [];
136 $this->frontendControllerMock->page = [];
137 $this->frontendControllerMock->sys_page = $pageRepositoryMock;
138 $GLOBALS['TSFE'] = $this->frontendControllerMock;
139 $GLOBALS['TYPO3_DB'] =
140 $this->getMockBuilder(DatabaseConnection::class)->getMock();
141
142 $this->subject = $this->getAccessibleMock(
143 ContentObjectRenderer::class,
144 ['getResourceFactory', 'getEnvironmentVariable'],
145 [$this->frontendControllerMock]
146 );
147 $this->subject->setContentObjectClassMap($this->contentObjectMap);
148 $this->subject->start([], 'tt_content');
149 }
150
151 protected function tearDown()
152 {
153 setlocale(LC_NUMERIC, $this->currentLocale);
154 GeneralUtility::resetSingletonInstances($this->singletonInstances);
155 parent::tearDown();
156 }
157
158 //////////////////////
159 // Utility functions
160 //////////////////////
161
162 /**
163 * Avoid logging to the file system (file writer is currently the only configured writer)
164 */
165 protected function createMockedLoggerAndLogManager()
166 {
167 $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock();
168 $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock();
169 $logManagerMock->expects($this->any())
170 ->method('getLogger')
171 ->willReturn($loggerMock);
172 GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
173 }
174
175 /**
176 * Converts the subject and the expected result into utf-8.
177 *
178 * @param string $subject the subject, will be modified
179 * @param string $expected the expected result, will be modified
180 */
181 protected function handleCharset(&$subject, &$expected)
182 {
183 $charsetConverter = new CharsetConverter();
184 $subject = $charsetConverter->conv($subject, 'iso-8859-1', 'utf-8');
185 $expected = $charsetConverter->conv($expected, 'iso-8859-1', 'utf-8');
186 }
187
188 /////////////////////////////////////////////
189 // Tests concerning the getImgResource hook
190 /////////////////////////////////////////////
191 /**
192 * @test
193 */
194 public function getImgResourceCallsGetImgResourcePostProcessHook()
195 {
196 $this->templateServiceMock
197 ->expects($this->atLeastOnce())
198 ->method('getFileName')
199 ->with('typo3/clear.gif')
200 ->will($this->returnValue('typo3/clear.gif'));
201
202 $resourceFactory = $this->createMock(ResourceFactory::class);
203 $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
204
205 $className = $this->getUniqueId('tx_coretest');
206 $getImgResourceHookMock = $this->getMockBuilder(\TYPO3\CMS\Frontend\ContentObject\ContentObjectGetImageResourceHookInterface::class)
207 ->setMethods(array('getImgResourcePostProcess'))
208 ->setMockClassName($className)
209 ->getMock();
210 $getImgResourceHookMock
211 ->expects($this->once())
212 ->method('getImgResourcePostProcess')
213 ->will($this->returnCallback(array($this, 'isGetImgResourceHookCalledCallback')));
214 $getImgResourceHookObjects = array($getImgResourceHookMock);
215 $this->subject->_setRef('getImgResourceHookObjects', $getImgResourceHookObjects);
216 $this->subject->getImgResource('typo3/clear.gif', array());
217 }
218
219 /**
220 * Handles the arguments that have been sent to the getImgResource hook.
221 *
222 * @param string $file
223 * @param array $fileArray
224 * @param $imageResource
225 * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parent
226 * @return array
227 * @see getImgResourceHookGetsCalled
228 */
229 public function isGetImgResourceHookCalledCallback($file, $fileArray, $imageResource, $parent)
230 {
231 $this->assertEquals('typo3/clear.gif', $file);
232 $this->assertEquals('typo3/clear.gif', $imageResource['origFile']);
233 $this->assertTrue(is_array($fileArray));
234 $this->assertTrue($parent instanceof ContentObjectRenderer);
235 return $imageResource;
236 }
237
238 //////////////////////////////////////
239 // Tests concerning getContentObject
240 //////////////////////////////////////
241
242 public function getContentObjectValidContentObjectsDataProvider()
243 {
244 $dataProvider = array();
245 foreach ($this->contentObjectMap as $name => $className) {
246 $dataProvider[] = array($name, $className);
247 }
248 return $dataProvider;
249 }
250
251 /**
252 * @test
253 * @dataProvider getContentObjectValidContentObjectsDataProvider
254 * @param string $name TypoScript name of content object
255 * @param string $fullClassName Expected class name
256 */
257 public function getContentObjectCallsMakeInstanceForNewContentObjectInstance($name, $fullClassName)
258 {
259 $contentObjectInstance = $this->createMock($fullClassName);
260 GeneralUtility::addInstance($fullClassName, $contentObjectInstance);
261 $this->assertSame($contentObjectInstance, $this->subject->getContentObject($name));
262 }
263
264 /////////////////////////////////////////
265 // Tests concerning getQueryArguments()
266 /////////////////////////////////////////
267 /**
268 * @test
269 */
270 public function getQueryArgumentsExcludesParameters()
271 {
272 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
273 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
274 );
275 $getQueryArgumentsConfiguration = array();
276 $getQueryArgumentsConfiguration['exclude'] = array();
277 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
278 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
279 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
280 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
281 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
282 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
283 $this->assertEquals($expectedResult, $actualResult);
284 }
285
286 /**
287 * @test
288 */
289 public function getQueryArgumentsExcludesGetParameters()
290 {
291 $_GET = array(
292 'key1' => 'value1',
293 'key2' => 'value2',
294 'key3' => array(
295 'key31' => 'value31',
296 'key32' => array(
297 'key321' => 'value321',
298 'key322' => 'value322'
299 )
300 )
301 );
302 $getQueryArgumentsConfiguration = array();
303 $getQueryArgumentsConfiguration['method'] = 'GET';
304 $getQueryArgumentsConfiguration['exclude'] = array();
305 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
306 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
307 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
308 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
309 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
310 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
311 $this->assertEquals($expectedResult, $actualResult);
312 }
313
314 /**
315 * @test
316 */
317 public function getQueryArgumentsOverrulesSingleParameter()
318 {
319 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
320 $this->returnValue('key1=value1')
321 );
322 $getQueryArgumentsConfiguration = array();
323 $overruleArguments = array(
324 // Should be overridden
325 'key1' => 'value1Overruled',
326 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
327 'key2' => 'value2Overruled'
328 );
329 $expectedResult = '&key1=value1Overruled';
330 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
331 $this->assertEquals($expectedResult, $actualResult);
332 }
333
334 /**
335 * @test
336 */
337 public function getQueryArgumentsOverrulesMultiDimensionalParameters()
338 {
339 $_POST = array(
340 'key1' => 'value1',
341 'key2' => 'value2',
342 'key3' => array(
343 'key31' => 'value31',
344 'key32' => array(
345 'key321' => 'value321',
346 'key322' => 'value322'
347 )
348 )
349 );
350 $getQueryArgumentsConfiguration = array();
351 $getQueryArgumentsConfiguration['method'] = 'POST';
352 $getQueryArgumentsConfiguration['exclude'] = array();
353 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
354 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
355 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
356 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
357 $overruleArguments = array(
358 // Should be overriden
359 'key2' => 'value2Overruled',
360 'key3' => array(
361 'key32' => array(
362 // Shouldn't be set: Parameter is excluded and not forced
363 'key321' => 'value321Overruled',
364 // Should be overriden: Parameter is not excluded
365 'key322' => 'value322Overruled',
366 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
367 'key323' => 'value323Overruled'
368 )
369 )
370 );
371 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key322]=value322Overruled');
372 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
373 $this->assertEquals($expectedResult, $actualResult);
374 }
375
376 /**
377 * @test
378 */
379 public function getQueryArgumentsOverrulesMultiDimensionalForcedParameters()
380 {
381 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
382 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
383 );
384 $_POST = array(
385 'key1' => 'value1',
386 'key2' => 'value2',
387 'key3' => array(
388 'key31' => 'value31',
389 'key32' => array(
390 'key321' => 'value321',
391 'key322' => 'value322'
392 )
393 )
394 );
395 $getQueryArgumentsConfiguration = array();
396 $getQueryArgumentsConfiguration['exclude'] = array();
397 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
398 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
399 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
400 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key322]';
401 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
402 $overruleArguments = array(
403 // Should be overriden
404 'key2' => 'value2Overruled',
405 'key3' => array(
406 'key32' => array(
407 // Should be set: Parameter is excluded but forced
408 'key321' => 'value321Overruled',
409 // Should be set: Parameter doesn't exist in source array but is forced
410 'key323' => 'value323Overruled'
411 )
412 )
413 );
414 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key321]=value321Overruled&key3[key32][key323]=value323Overruled');
415 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
416 $this->assertEquals($expectedResult, $actualResult);
417 $getQueryArgumentsConfiguration['method'] = 'POST';
418 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
419 $this->assertEquals($expectedResult, $actualResult);
420 }
421
422 /**
423 * @test
424 */
425 public function getQueryArgumentsWithMethodPostGetMergesParameters()
426 {
427 $_POST = array(
428 'key1' => 'POST1',
429 'key2' => 'POST2',
430 'key3' => array(
431 'key31' => 'POST31',
432 'key32' => 'POST32',
433 'key33' => array(
434 'key331' => 'POST331',
435 'key332' => 'POST332',
436 )
437 )
438 );
439 $_GET = array(
440 'key2' => 'GET2',
441 'key3' => array(
442 'key32' => 'GET32',
443 'key33' => array(
444 'key331' => 'GET331',
445 )
446 )
447 );
448 $getQueryArgumentsConfiguration = array();
449 $getQueryArgumentsConfiguration['method'] = 'POST,GET';
450 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
451 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
452 $this->assertEquals($expectedResult, $actualResult);
453 }
454
455 /**
456 * @test
457 */
458 public function getQueryArgumentsWithMethodGetPostMergesParameters()
459 {
460 $_GET = array(
461 'key1' => 'GET1',
462 'key2' => 'GET2',
463 'key3' => array(
464 'key31' => 'GET31',
465 'key32' => 'GET32',
466 'key33' => array(
467 'key331' => 'GET331',
468 'key332' => 'GET332',
469 )
470 )
471 );
472 $_POST = array(
473 'key2' => 'POST2',
474 'key3' => array(
475 'key32' => 'POST32',
476 'key33' => array(
477 'key331' => 'POST331',
478 )
479 )
480 );
481 $getQueryArgumentsConfiguration = array();
482 $getQueryArgumentsConfiguration['method'] = 'GET,POST';
483 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
484 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
485 $this->assertEquals($expectedResult, $actualResult);
486 }
487
488 /**
489 * Encodes square brackets in URL.
490 *
491 * @param string $string
492 * @return string
493 */
494 private function rawUrlEncodeSquareBracketsInUrl($string)
495 {
496 return str_replace(array('[', ']'), array('%5B', '%5D'), $string);
497 }
498
499 //////////////////////////
500 // Tests concerning crop
501 //////////////////////////
502 /**
503 * @test
504 */
505 public function cropIsMultibyteSafe()
506 {
507 $this->assertEquals('бла', $this->subject->crop('бла', '3|...'));
508 }
509
510 //////////////////////////////
511 // Tests concerning cropHTML
512 //////////////////////////////
513
514 /**
515 * Check if stdWrap_cropHTML works properly.
516 *
517 * Show:
518 *
519 * - Delegates to method cropHTML.
520 * - Parameter 1 is $content.
521 * - Parameter 2 is $conf['cropHTML'].
522 * - Returns the return value.
523 *
524 * @test
525 * @return void
526 */
527 public function stdWrap_cropHTML()
528 {
529 $content = $this->getUniqueId('content');
530 $conf = [
531 'cropHTML' => $this->getUniqueId('cropHTML'),
532 'cropHTML.' => $this->getUniqueId('not used'),
533 ];
534 $return = $this->getUniqueId('return');
535 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
536 ->setMethods(['cropHTML'])->getMock();
537 $subject
538 ->expects($this->once())
539 ->method('cropHTML')
540 ->with( $content, $conf['cropHTML'])
541 ->willReturn($return);
542 $this->assertSame($return,
543 $subject->stdWrap_cropHTML($content, $conf));
544 }
545
546 /**
547 * Data provider for cropHTML.
548 *
549 * Provides combinations of text type and configuration.
550 *
551 * @return array [$expect, $conf, $content]
552 */
553 public function cropHTMLDataProvider()
554 {
555 $plainText = 'Kasper Sk' . chr(229) . 'rh' . chr(248)
556 . 'j implemented the original version of the crop function.';
557 $textWithMarkup = '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
558 . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> the '
559 . 'original version of the crop function.';
560 $textWithEntities = 'Kasper Sk&aring;rh&oslash;j implemented the; '
561 . 'original ' . 'version of the crop function.';
562 $textWithLinebreaks = "Lorem ipsum dolor sit amet,\n"
563 . "consetetur sadipscing elitr,\n"
564 . "sed diam nonumy eirmod tempor invidunt ut labore e"
565 . "t dolore magna aliquyam";
566
567 return [
568 'plain text; 11|...' => [
569 'Kasper Sk' . chr(229) . 'r...',
570 $plainText, '11|...',
571 ],
572 'plain text; -58|...' => [
573 '...h' . chr(248) . 'j implemented the original version of '
574 . 'the crop function.',
575 $plainText, '-58|...',
576 ],
577 'plain text; 4|...|1' => [
578 'Kasp...',
579 $plainText, '4|...|1',
580 ],
581 'plain text; 20|...|1' => [
582 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j...',
583 $plainText, '20|...|1',
584 ],
585 'plain text; -5|...|1' => [
586 '...tion.',
587 $plainText, '-5|...|1',
588 ],
589 'plain text; -49|...|1' => [
590 '...the original version of the crop function.',
591 $plainText, '-49|...|1',
592 ],
593 'text with markup; 11|...' => [
594 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
595 . chr(229) . 'r...</a></strong>',
596 $textWithMarkup, '11|...',
597 ],
598 'text with markup; 13|...' => [
599 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
600 . chr(229) . 'rh' . chr(248) . '...</a></strong>',
601 $textWithMarkup, '13|...',
602 ],
603 'text with markup; 14|...' => [
604 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
605 . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
606 $textWithMarkup, '14|...',
607 ],
608 'text with markup; 15|...' => [
609 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
610 . chr(229) . 'rh' . chr(248) . 'j</a> ...</strong>',
611 $textWithMarkup, '15|...',
612 ],
613 'text with markup; 29|...' => [
614 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
615 . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> '
616 . 'th...',
617 $textWithMarkup, '29|...',
618 ],
619 'text with markup; -58|...' => [
620 '<strong><a href="mailto:kasper@typo3.org">...h' . chr(248)
621 . 'j</a> implemented</strong> the original version of the crop '
622 . 'function.',
623 $textWithMarkup, '-58|...',
624 ],
625 'text with markup 4|...|1' => [
626 '<strong><a href="mailto:kasper@typo3.org">Kasp...</a>'
627 . '</strong>',
628 $textWithMarkup, '4|...|1',
629 ],
630 'text with markup; 11|...|1' => [
631 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a>'
632 . '</strong>',
633 $textWithMarkup, '11|...|1',
634 ],
635 'text with markup; 13|...|1' => [
636 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a>'
637 . '</strong>',
638 $textWithMarkup, '13|...|1',
639 ],
640 'text with markup; 14|...|1' => [
641 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
642 . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
643 $textWithMarkup, '14|...|1',
644 ],
645 'text with markup; 15|...|1' => [
646 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
647 . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>',
648 $textWithMarkup, '15|...|1',
649 ],
650 'text with markup; 29|...|1' => [
651 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk'
652 . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong>...',
653 $textWithMarkup, '29|...|1',
654 ],
655 'text with markup; -66|...|1' => [
656 '<strong><a href="mailto:kasper@typo3.org">...Sk' . chr(229)
657 . 'rh' . chr(248) . 'j</a> implemented</strong> the original v'
658 . 'ersion of the crop function.',
659 $textWithMarkup, '-66|...|1',
660 ],
661 'text with entities 9|...' => [
662 'Kasper Sk...',
663 $textWithEntities, '9|...',
664 ],
665 'text with entities 10|...' => [
666 'Kasper Sk&aring;...',
667 $textWithEntities, '10|...',
668 ],
669 'text with entities 11|...' => [
670 'Kasper Sk&aring;r...',
671 $textWithEntities, '11|...',
672 ],
673 'text with entities 13|...' => [
674 'Kasper Sk&aring;rh&oslash;...',
675 $textWithEntities, '13|...',
676 ],
677 'text with entities 14|...' => [
678 'Kasper Sk&aring;rh&oslash;j...',
679 $textWithEntities, '14|...',
680 ],
681 'text with entities 15|...' => [
682 'Kasper Sk&aring;rh&oslash;j ...',
683 $textWithEntities, '15|...',
684 ],
685 'text with entities 16|...' => [
686 'Kasper Sk&aring;rh&oslash;j i...',
687 $textWithEntities, '16|...',
688 ],
689 'text with entities -57|...' => [
690 '...j implemented the; original version of the crop function.',
691 $textWithEntities, '-57|...',
692 ],
693 'text with entities -58|...' => [
694 '...&oslash;j implemented the; original version of the crop '
695 . 'function.',
696 $textWithEntities, '-58|...',
697 ],
698 'text with entities -59|...' => [
699 '...h&oslash;j implemented the; original version of the crop '
700 . 'function.',
701 $textWithEntities, '-59|...',
702 ],
703 'text with entities 4|...|1' => [
704 'Kasp...',
705 $textWithEntities, '4|...|1',
706 ],
707 'text with entities 9|...|1' => [
708 'Kasper...',
709 $textWithEntities, '9|...|1',
710 ],
711 'text with entities 10|...|1' => [
712 'Kasper...',
713 $textWithEntities, '10|...|1',
714 ],
715 'text with entities 11|...|1' => [
716 'Kasper...',
717 $textWithEntities, '11|...|1',
718 ],
719 'text with entities 13|...|1' => [
720 'Kasper...',
721 $textWithEntities, '13|...|1',
722 ],
723 'text with entities 14|...|1' => [
724 'Kasper Sk&aring;rh&oslash;j...',
725 $textWithEntities, '14|...|1',
726 ],
727 'text with entities 15|...|1' => [
728 'Kasper Sk&aring;rh&oslash;j...',
729 $textWithEntities, '15|...|1',
730 ],
731 'text with entities 16|...|1' => [
732 'Kasper Sk&aring;rh&oslash;j...',
733 $textWithEntities, '16|...|1',
734 ],
735 'text with entities -57|...|1' => [
736 '...implemented the; original version of the crop function.',
737 $textWithEntities, '-57|...|1',
738 ],
739 'text with entities -58|...|1' => [
740 '...implemented the; original version of the crop function.',
741 $textWithEntities, '-58|...|1',
742 ],
743 'text with entities -59|...|1' => [
744 '...implemented the; original version of the crop function.',
745 $textWithEntities, '-59|...|1',
746 ],
747 'text with dash in html-element 28|...|1' => [
748 'Some text with a link to <link email.address@example.org - '
749 . 'mail "Open email window">my...</link>',
750 'Some text with a link to <link email.address@example.org - m'
751 . 'ail "Open email window">my email.address@example.org<'
752 . '/link> and text after it',
753 '28|...|1',
754 ],
755 'html elements with dashes in attributes' => [
756 '<em data-foo="x">foobar</em>foo',
757 '<em data-foo="x">foobar</em>foobaz',
758 '9',
759 ],
760 'html elements with iframe embedded 24|...|1' => [
761 'Text with iframe <iframe src="//what.ever/"></iframe> and...',
762 'Text with iframe <iframe src="//what.ever/">'
763 . '</iframe> and text after it',
764 '24|...|1',
765 ],
766 'html elements with script tag embedded 24|...|1' => [
767 'Text with script <script>alert(\'foo\');</script> and...',
768 'Text with script <script>alert(\'foo\');</script> '
769 . 'and text after it',
770 '24|...|1',
771 ],
772 'text with linebreaks' => [
773 "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\ns"
774 . "ed diam nonumy eirmod tempor invidunt ut labore e"
775 . "t dolore magna",
776 $textWithLinebreaks, '121',
777 ],
778 ];
779 }
780
781 /**
782 * Check if cropHTML works properly.
783 *
784 * @test
785 * @dataProvider cropHTMLDataProvider
786 * @param string $expect The expected cropped output.
787 * @param string $content The given input.
788 * @param string $conf The given configuration.
789 * @return void
790 */
791 public function cropHTML($expect, $content, $conf)
792 {
793 $this->handleCharset($content, $expect);
794 $this->assertSame($expect,
795 $this->subject->cropHTML($content, $conf));
796 }
797
798 /**
799 * Data provider for stdWrap_cacheRead
800 *
801 * @return array Order: expect, input, conf, times, with, will
802 */
803 public function stdWrap_cacheReadDataProvider()
804 {
805 $cacheConf = [$this->getUniqueId('cache.')];
806 $conf = ['cache.' => $cacheConf];
807 return [
808 'no conf' => [
809 'content', 'content', [],
810 0, null, null,
811 ],
812 'no cache. conf' => [
813 'content', 'content', ['otherConf' => 1],
814 0, null, null,
815 ],
816 'non-cached simulation' => [
817 'content', 'content', $conf,
818 1, $cacheConf, false,
819 ],
820 'cached simulation' => [
821 'cachedContent', 'content', $conf,
822 1, $cacheConf, 'cachedContent',
823 ],
824 ];
825 }
826
827 /**
828 * Check if stdWrap_cacheRead works properly.
829 *
830 * - the method branches correctly
831 * - getFromCache is called to fetch from cache
832 * - $conf['cache.'] is passed on as parameter
833 *
834 * @test
835 * @dataProvider stdWrap_cacheReadDataProvider
836 * @param string $expect Expected result.
837 * @param string $input Given input string.
838 * @param array $conf Property 'cache.'
839 * @param integer $times Times called mocked method.
840 * @param array $with Parameter passed to mocked method.
841 * @param string|false $will Return value of mocked method.
842 * @return void
843 */
844 public function stdWrap_cacheRead(
845 $expect, $input, $conf, $times, $with, $will)
846 {
847 $subject = $this->getAccessibleMock(
848 ContentObjectRenderer::class, ['getFromCache']);
849 $subject
850 ->expects($this->exactly($times))
851 ->method('getFromCache')
852 ->with($with)
853 ->willReturn($will);
854 $this->assertSame($expect,
855 $subject->stdWrap_cacheRead($input, $conf));
856 }
857
858 /**
859 * Data provider for fourTypesOfStdWrapHookObjectProcessors
860 *
861 * @return array Order: stdWrap, hookObjectCall
862 */
863 public function fourTypesOfStdWrapHookObjectProcessorsDataProvider()
864 {
865 return [
866 'preProcess' => [
867 'stdWrap_stdWrapPreProcess', 'stdWrapPreProcess'
868 ],
869 'override' => [
870 'stdWrap_stdWrapOverride', 'stdWrapOverride'
871 ],
872 'process' => [
873 'stdWrap_stdWrapProcess', 'stdWrapProcess'
874 ],
875 'postProcess' => [
876 'stdWrap_stdWrapPostProcess', 'stdWrapPostProcess'
877 ],
878 ];
879 }
880
881 /**
882 * Check if stdWrapHookObject processors work properly.
883 *
884 * Checks:
885 *
886 * - stdWrap_stdWrapPreProcess
887 * - stdWrap_stdWrapOverride
888 * - stdWrap_stdWrapProcess
889 * - stdWrap_stdWrapPostProcess
890 *
891 * @test
892 * @dataProvider fourTypesOfStdWrapHookObjectProcessorsDataProvider
893 * @param string $stdWrapMethod: The method to cover.
894 * @param string $hookObjectCall: The expected hook object call.
895 * @return void
896 */
897 public function fourTypesOfStdWrapHookObjectProcessors(
898 $stdWrapMethod, $hookObjectCall)
899 {
900 $conf = [$this->getUniqueId('conf')];
901 $content = $this->getUniqueId('content');
902 $processed1 = $this->getUniqueId('processed1');
903 $processed2 = $this->getUniqueId('processed2');
904 $hookObject1 = $this->createMock(
905 ContentObjectStdWrapHookInterface::class);
906 $hookObject1->expects($this->once())
907 ->method($hookObjectCall)
908 ->with($content, $conf)
909 ->willReturn($processed1);
910 $hookObject2 = $this->createMock(
911 ContentObjectStdWrapHookInterface::class);
912 $hookObject2->expects($this->once())
913 ->method($hookObjectCall)
914 ->with($processed1, $conf)
915 ->willReturn($processed2);
916 $this->subject->_set('stdWrapHookObjects',
917 [$hookObject1, $hookObject2]);
918 $result = $this->subject->$stdWrapMethod($content, $conf);
919 $this->assertSame($processed2, $result);
920 }
921
922 /**
923 * Check if stdWrap_setContentToCurrent works properly.
924 *
925 * @test
926 * @return void
927 */
928 public function stdWrap_setContentToCurrent()
929 {
930 $content = $this->getUniqueId('content');
931 $this->assertNotSame($content, $this->subject->getData('current'));
932 $this->assertSame($content,
933 $this->subject->stdWrap_setContentToCurrent($content));
934 $this->assertSame($content, $this->subject->getData('current'));
935 }
936
937 /**
938 * Data provider for stdWrap_setCurrent
939 *
940 * @return array Order input, conf
941 */
942 public function stdWrap_setCurrentDataProvider()
943 {
944 return [
945 'no conf' => [
946 'content',
947 [],
948 ],
949 'empty string' => [
950 'content',
951 ['setCurrent' => ''],
952 ],
953 'non-empty string' => [
954 'content',
955 ['setCurrent' => 'xxx'],
956 ],
957 'integer null' => [
958 'content',
959 ['setCurrent' => 0],
960 ],
961 'integer not null' => [
962 'content',
963 ['setCurrent' => 1],
964 ],
965 'boolean true' => [
966 'content',
967 ['setCurrent' => true],
968 ],
969 'boolean false' => [
970 'content',
971 ['setCurrent' => false],
972 ],
973 ];
974 }
975
976 /**
977 * Check if stdWrap_setCurrent works properly.
978 *
979 * @test
980 * @dataProvider stdWrap_setCurrentDataProvider
981 * @param string $input The input value.
982 * @param array $conf Property: setCurrent
983 * @return void
984 */
985 public function stdWrap_setCurrent($input, $conf)
986 {
987 if (isset($conf['setCurrent'])) {
988 $this->assertNotSame($conf['setCurrent'], $this->subject->getData('current'));
989 }
990 $this->assertSame($input, $this->subject->stdWrap_setCurrent($input, $conf));
991 if (isset($conf['setCurrent'])) {
992 $this->assertSame($conf['setCurrent'], $this->subject->getData('current'));
993 }
994 }
995
996 /**
997 * Data provider for stdWrap_data.
998 *
999 * @return array [$expect, $data, $alt]
1000 */
1001 public function stdWrap_dataDataProvider()
1002 {
1003 $data = [$this->getUniqueId('data')];
1004 $alt = [$this->getUniqueId('alternativeData')];
1005 return [
1006 'default' => [$data, $data, ''],
1007 'alt is array' => [$alt, $data, $alt],
1008 'alt is empty array' => [[], $data, []],
1009 'alt null' => [$data, $data, null],
1010 'alt string' => [$data, $data, 'xxx'],
1011 'alt int' => [$data, $data, 1],
1012 'alt bool' => [$data, $data, true],
1013 ];
1014 }
1015
1016 /**
1017 * Checks that stdWrap_data works properly.
1018 *
1019 * Show:
1020 *
1021 * - Delegates to method getData.
1022 * - Parameter 1 is $conf['data'].
1023 * - Parameter 2 is property data by default.
1024 * - Parameter 2 is property alternativeData, if set as array.
1025 * - Property alternativeData is always unset to ''.
1026 * - Returns the return value.
1027 *
1028 * @test
1029 * @dataProvider stdWrap_dataDataProvider
1030 * @param mixed $expect Expect either $data or $alternativeData.
1031 * @param array $data The data.
1032 * @param mixed $alt The alternativeData.
1033 * @return void
1034 */
1035 public function stdWrap_data($expect, $data, $alt)
1036 {
1037 $conf = ['data' => $this->getUniqueId('conf.data')];
1038 $return = $this->getUniqueId('return');
1039 $subject = $this->getAccessibleMock(
1040 ContentObjectRenderer::class, ['getData']);
1041 $subject->_set('data', $data);
1042 $subject->_set('alternativeData', $alt);
1043 $subject
1044 ->expects($this->once())
1045 ->method('getData')
1046 ->with($conf['data'], $expect)
1047 ->willReturn($return);
1048 $this->assertSame($return, $subject->stdWrap_data('discard', $conf));
1049 $this->assertSame('', $subject->_get('alternativeData'));
1050 }
1051
1052 /**
1053 * Check if stdWrap_insertData works properly.
1054 *
1055 * Show:
1056 *
1057 * - Delegates to method insertData.
1058 * - Parameter 1 is $content.
1059 * - Returns the return value.
1060 *
1061 * @test
1062 * @return void
1063 */
1064 public function stdWrap_insertData()
1065 {
1066 $content = $this->getUniqueId('content');
1067 $conf = [$this->getUniqueId('conf not used')];
1068 $return = $this->getUniqueId('return');
1069 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1070 ->setMethods(['insertData'])->getMock();
1071 $subject->expects($this->once())->method('insertData')
1072 ->with($content)->willReturn($return);
1073 $this->assertSame($return,
1074 $subject->stdWrap_insertData($content, $conf));
1075 }
1076
1077 /**
1078 * Check if stdWrap_preIfEmptyListNum works properly.
1079 *
1080 * Show:
1081 *
1082 * - Delegates to method listNum.
1083 * - Parameter 1 is $content.
1084 * - Parameter 2 is $conf['preIfEmptyListNum'].
1085 * - Parameter 3 is $conf['preIfEmptyListNum.']['splitChar'].
1086 * - Returns the return value.
1087 *
1088 * @test
1089 * @return void
1090 */
1091 public function stdWrap_preIfEmptyListNum()
1092 {
1093 $content = $this->getUniqueId('content');
1094 $conf = [
1095 'preIfEmptyListNum' => $this->getUniqueId('preIfEmptyListNum'),
1096 'preIfEmptyListNum.' => [
1097 'splitChar' => $this->getUniqueId('splitChar')
1098 ],
1099 ];
1100 $return = $this->getUniqueId('return');
1101 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1102 ->setMethods(['listNum'])->getMock();
1103 $subject
1104 ->expects($this->once())
1105 ->method('listNum')
1106 ->with(
1107 $content,
1108 $conf['preIfEmptyListNum'],
1109 $conf['preIfEmptyListNum.']['splitChar']
1110 )
1111 ->willReturn($return);
1112 $this->assertSame($return,
1113 $subject->stdWrap_preIfEmptyListNum($content, $conf));
1114 }
1115
1116 /**
1117 * Check if stdWrap_current works properly.
1118 *
1119 * Show:
1120 *
1121 * - current is returned from $this->data
1122 * - the key is stored in $this->currentValKey
1123 * - the key defaults to 'currentValue_kidjls9dksoje'
1124 *
1125 * @test
1126 * @return void
1127 */
1128 public function stdWrap_current()
1129 {
1130 $data = [
1131 'currentValue_kidjls9dksoje' => 'default',
1132 'currentValue_new' => 'new',
1133 ];
1134 $this->subject->_set('data', $data);
1135 $this->assertSame('currentValue_kidjls9dksoje',
1136 $this->subject->_get('currentValKey'));
1137 $this->assertSame('default',
1138 $this->subject->stdWrap_current('discarded', ['discarded']));
1139 $this->subject->_set('currentValKey', 'currentValue_new');
1140 $this->assertSame('new',
1141 $this->subject->stdWrap_current('discarded', ['discarded']));
1142 }
1143
1144 /**
1145 * Check if stdWrap_preUserFunc works properly.
1146 *
1147 * Show:
1148 *
1149 * - Delegates to method callUserFunction.
1150 * - Parameter 1 is $conf['preUserFunc'].
1151 * - Parameter 2 is $conf['preUserFunc.'].
1152 * - Parameter 3 is $content.
1153 * - Returns the return value.
1154 *
1155 * @test
1156 * @return void
1157 */
1158 public function stdWrap_preUserFunc()
1159 {
1160 $content = $this->getUniqueId('content');
1161 $conf = [
1162 'preUserFunc' => $this->getUniqueId('preUserFunc'),
1163 'preUserFunc.' => [$this->getUniqueId('preUserFunc.')],
1164 ];
1165 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1166 ->setMethods(['callUserFunction'])->getMock();
1167 $subject->expects($this->once())->method('callUserFunction')
1168 ->with($conf['preUserFunc'], $conf['preUserFunc.'], $content)
1169 ->willReturn('return');
1170 $this->assertSame('return',
1171 $subject->stdWrap_preUserFunc($content, $conf));
1172 }
1173
1174 /**
1175 * Data provider for stdWrap_csConv
1176 *
1177 * @return array Order expected, input, conf
1178 */
1179 public function stdWrap_overrideDataProvider()
1180 {
1181 return [
1182 'standard case' => [
1183 'override', 'content', ['override' => 'override']
1184 ],
1185 'empty conf does not override' => [
1186 'content', 'content', []
1187 ],
1188 'empty string does not override' => [
1189 'content', 'content', ['override' => '']
1190 ],
1191 'whitespace does not override' => [
1192 'content', 'content', ['override' => ' ' . TAB]
1193 ],
1194 'zero does not override' => [
1195 'content', 'content', ['override' => 0]
1196 ],
1197 'false does not override' => [
1198 'content', 'content', ['override' => false]
1199 ],
1200 'null does not override' => [
1201 'content', 'content', ['override' => null]
1202 ],
1203 'one does override' => [
1204 1, 'content', ['override' => 1]
1205 ],
1206 'minus one does override' => [
1207 -1, 'content', ['override' => -1]
1208 ],
1209 'float does override' => [
1210 -0.1, 'content', ['override' => -0.1]
1211 ],
1212 'true does override' => [
1213 true, 'content', ['override' => true]
1214 ],
1215 'the value is not trimmed' => [
1216 TAB . 'override', 'content', ['override' => TAB . 'override']
1217 ],
1218 ];
1219 }
1220
1221 /**
1222 * Check if stdWrap_override works properly.
1223 *
1224 * @test
1225 * @dataProvider stdWrap_overrideDataProvider
1226 * @param string $input The input value.
1227 * @param array $conf Property: setCurrent
1228 * @return void
1229 */
1230 public function stdWrap_override($expect, $content, $conf)
1231 {
1232 $this->assertSame($expect,
1233 $this->subject->stdWrap_override($content, $conf));
1234 }
1235
1236 /**
1237 * Check if stdWrap_listNum works properly.
1238 *
1239 * Show:
1240 *
1241 * - Delegates to method listNum.
1242 * - Parameter 1 is $content.
1243 * - Parameter 2 is $conf['listNum'].
1244 * - Parameter 3 is $conf['listNum.']['splitChar'].
1245 * - Returns the return value.
1246 *
1247 * @test
1248 * @return void
1249 */
1250 public function stdWrap_listNum()
1251 {
1252 $content = $this->getUniqueId('content');
1253 $conf = [
1254 'listNum' => $this->getUniqueId('listNum'),
1255 'listNum.' => [
1256 'splitChar' => $this->getUniqueId('splitChar')
1257 ],
1258 ];
1259 $return = $this->getUniqueId('return');
1260 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1261 ->setMethods(['listNum'])->getMock();
1262 $subject
1263 ->expects($this->once())
1264 ->method('listNum')
1265 ->with(
1266 $content,
1267 $conf['listNum'],
1268 $conf['listNum.']['splitChar']
1269 )
1270 ->willReturn($return);
1271 $this->assertSame($return,
1272 $subject->stdWrap_listNum($content, $conf));
1273 }
1274
1275 /**
1276 * Check if stdWrap_field works properly.
1277 *
1278 * Show:
1279 *
1280 * - calls getFieldVal
1281 * - passes conf['field'] as parameter
1282 *
1283 * @test
1284 * @return void
1285 */
1286 public function stdWrap_field()
1287 {
1288 $expect = $this->getUniqueId('expect');
1289 $conf = ['field' => $this->getUniqueId('field')];
1290 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1291 ->setMethods(['getFieldVal'])->getMock();
1292 $subject
1293 ->expects($this->once())
1294 ->method('getFieldVal')
1295 ->with($conf['field'])
1296 ->willReturn($expect);
1297 $this->assertSame($expect,
1298 $subject->stdWrap_field('discarded', $conf));
1299 }
1300
1301 /**
1302 * Check if stdWrap_cObject works properly.
1303 *
1304 * Show:
1305 *
1306 * - Delegates to the method cObjGetSingle().
1307 * - First parameter is $conf['cObject'].
1308 * - Second parameter is $conf['cObject.'].
1309 * - Third parameter is '/stdWrap/.cObject'.
1310 * - Returns the return.
1311 *
1312 * @test
1313 * @return void
1314 */
1315 public function stdWrap_cObject()
1316 {
1317 $debugKey = '/stdWrap/.cObject';
1318 $conf = [
1319 'cObject' => $this->getUniqueId('cObject'),
1320 'cObject.' => [$this->getUniqueId('cObject.')],
1321 ];
1322 $return = $this->getUniqueId('return');
1323 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1324 ->setMethods(['cObjGetSingle'])->getMock();
1325 $subject
1326 ->expects($this->once())
1327 ->method('cObjGetSingle')
1328 ->with($conf['cObject'], $conf['cObject.'], $debugKey)
1329 ->willReturn($return);
1330 $this->assertSame($return,
1331 $subject->stdWrap_cObject('discard', $conf));
1332 }
1333
1334 /**
1335 * Check if stdWrap_append works properly.
1336 *
1337 * Show:
1338 *
1339 * - Delegates to the method cObjGetSingle().
1340 * - First parameter is $conf['append'].
1341 * - Second parameter is $conf['append.'].
1342 * - Third parameter is '/stdWrap/.append'.
1343 * - Returns the return value appended to $content.
1344 *
1345 * @test
1346 * @return void
1347 */
1348 public function stdWrap_append()
1349 {
1350 $debugKey = '/stdWrap/.append';
1351 $content = $this->getUniqueId('content');
1352 $conf = [
1353 'append' => $this->getUniqueId('append'),
1354 'append.' => [$this->getUniqueId('append.')],
1355 ];
1356 $return = $this->getUniqueId('return');
1357 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1358 ->setMethods(['cObjGetSingle'])->getMock();
1359 $subject
1360 ->expects($this->once())
1361 ->method('cObjGetSingle')
1362 ->with($conf['append'], $conf['append.'], $debugKey)
1363 ->willReturn($return);
1364 $this->assertSame($content . $return,
1365 $subject->stdWrap_append($content, $conf));
1366 }
1367
1368 /**
1369 * Check if stdWrap_numRows works properly.
1370 *
1371 * Show:
1372 *
1373 * - Delegates to method numRows.
1374 * - Parameter is $conf['numRows.'].
1375 * - Returns the return value.
1376 *
1377 * @test
1378 * @return void
1379 */
1380 public function stdWrap_numRows()
1381 {
1382 $conf = [
1383 'numRows' => $this->getUniqueId('numRows'),
1384 'numRows.' => [$this->getUniqueId('numRows')],
1385 ];
1386 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1387 ->setMethods(['numRows'])->getMock();
1388 $subject->expects($this->once())->method('numRows')
1389 ->with($conf['numRows.'])->willReturn('return');
1390 $this->assertSame('return',
1391 $subject->stdWrap_numRows('discard', $conf));
1392 }
1393
1394 /**
1395 * Check if stdWrap_filelist works properly.
1396 *
1397 * Show:
1398 *
1399 * - Delegates to method filelist.
1400 * - Parameter is $conf['filelist'].
1401 * - Returns the return value.
1402 *
1403 * @test
1404 * @return void
1405 */
1406 public function stdWrap_filelist()
1407 {
1408 $conf = [
1409 'filelist' => $this->getUniqueId('filelist'),
1410 'filelist.' => [$this->getUniqueId('not used')],
1411 ];
1412 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1413 ->setMethods(['filelist'])->getMock();
1414 $subject->expects($this->once())->method('filelist')
1415 ->with($conf['filelist'])->willReturn('return');
1416 $this->assertSame('return',
1417 $subject->stdWrap_filelist('discard', $conf));
1418 }
1419
1420 /**
1421 * Check if stdWrap_filelink works properly.
1422 *
1423 * Show:
1424 *
1425 * - Delegates to method filelink.
1426 * - Parameter 1 is $content.
1427 * - Parameter 2 is $conf['filelink.'].
1428 * - Returns the return value.
1429 *
1430 * @test
1431 * @return void
1432 */
1433 public function stdWrap_filelink()
1434 {
1435 $content = $this->getUniqueId('content');
1436 $conf = [
1437 'filelink' => $this->getUniqueId('not used'),
1438 'filelink.' => [$this->getUniqueId('filelink.')],
1439 ];
1440 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1441 ->setMethods(['filelink'])->getMock();
1442 $subject->expects($this->once())->method('filelink')
1443 ->with($content, $conf['filelink.'])->willReturn('return');
1444 $this->assertSame('return',
1445 $subject->stdWrap_filelink($content, $conf));
1446 }
1447
1448 /**
1449 * Data provider for stdWrap_fieldRequired.
1450 *
1451 * @return array [$expect, $stop, $content, $conf]
1452 */
1453 public function stdWrap_fieldRequiredDataProvider()
1454 {
1455 $content = $this->getUniqueId('content');
1456 return [
1457 // resulting in boolean false
1458 'false is false' => [
1459 '', true, $content, ['fieldRequired' => 'false']
1460 ],
1461 'null is false' => [
1462 '', true, $content, ['fieldRequired' => 'null']
1463 ],
1464 'empty string is false' => [
1465 '', true, $content, ['fieldRequired' => 'empty']
1466 ],
1467 'whitespace is false' => [
1468 '', true, $content, ['fieldRequired' => 'whitespace']
1469 ],
1470 'string zero is false' => [
1471 '', true, $content, ['fieldRequired' => 'stringZero']
1472 ],
1473 'string zero with whitespace is false' => [
1474 '', true, $content,
1475 ['fieldRequired' => 'stringZeroWithWhiteSpace']
1476 ],
1477 'zero is false' => [
1478 '', true, $content, ['fieldRequired' => 'zero']
1479 ],
1480 // resulting in boolean true
1481 'true is true' => [
1482 $content, false, $content, ['fieldRequired' => 'true']
1483 ],
1484 'string is true' => [
1485 $content, false, $content, ['fieldRequired' => 'string']
1486 ],
1487 'one is true' => [
1488 $content, false, $content, ['fieldRequired' => 'one']
1489 ]
1490 ];
1491 }
1492
1493 /**
1494 * Check if stdWrap_fieldRequired works properly.
1495 *
1496 * Show:
1497 *
1498 * - The value is taken from property array data.
1499 * - The key is taken from $conf['fieldRequired'].
1500 * - The value is casted to string by trim() and trimmed.
1501 * - It is further casted to boolean by if().
1502 * - False triggers a stop of further rendering.
1503 * - False returns '', true the given content as is.
1504 *
1505 * @test
1506 * @dataProvider stdWrap_fieldRequiredDataProvider
1507 * @param mixed $expect The expected output.
1508 * @param bool $stop Expect stop further rendering.
1509 * @param mixed $content The given input.
1510 * @param array $conf The given configuration.
1511 * @return void
1512 */
1513 public function stdWrap_fieldRequired($expect, $stop, $content, $conf)
1514 {
1515 $data = [
1516 'null' => null,
1517 'false' => false,
1518 'empty' => '',
1519 'whitespace' => TAB . ' ',
1520 'stringZero' => '0',
1521 'stringZeroWithWhiteSpace' => TAB . ' 0 ' . TAB,
1522 'zero' => 0,
1523 'string' => 'string',
1524 'true' => true,
1525 'one' => 1
1526 ];
1527 $subject = $this->subject;
1528 $subject->_set('data', $data);
1529 $subject->_set('stdWrapRecursionLevel', 1);
1530 $subject->_set('stopRendering', [1 => false]);
1531 $this->assertSame($expect,
1532 $subject->stdWrap_fieldRequired($content, $conf));
1533 $this->assertSame($stop, $subject->_get('stopRendering')[1]);
1534 }
1535
1536 /**
1537 * Data provider for stdWrap_csConv
1538 *
1539 * @return array Order expected, input, conf
1540 */
1541 public function stdWrap_csConvDataProvider()
1542 {
1543 return [
1544 'empty string from ISO-8859-15' => [
1545 '',
1546 iconv('UTF-8', 'ISO-8859-15', ''),
1547 ['csConv' => 'ISO-8859-15']
1548 ],
1549 'empty string from BIG-5' => [
1550 '',
1551 mb_convert_encoding('', 'BIG-5'),
1552 ['csConv' => 'BIG-5']
1553 ],
1554 '"0" from ISO-8859-15' => [
1555 '0',
1556 iconv('UTF-8', 'ISO-8859-15', '0'),
1557 ['csConv' => 'ISO-8859-15']
1558 ],
1559 '"0" from BIG-5' => [
1560 '0',
1561 mb_convert_encoding('0', 'BIG-5'),
1562 ['csConv' => 'BIG-5']
1563 ],
1564 'euro symbol from ISO-88859-15' => [
1565 '€',
1566 iconv('UTF-8', 'ISO-8859-15', '€'),
1567 ['csConv' => 'ISO-8859-15']
1568 ],
1569 'good morning from BIG-5' => [
1570 '早安',
1571 mb_convert_encoding('早安', 'BIG-5'),
1572 ['csConv' => 'BIG-5']
1573 ],
1574 ];
1575 }
1576
1577 /**
1578 * Check if stdWrap_csConv works properly.
1579 *
1580 * @test
1581 * @dataProvider stdWrap_csConvDataProvider
1582 * @param string $expected The expected value.
1583 * @param string $value The input value.
1584 * @param array $conf Property: csConv
1585 * @return void
1586 */
1587 public function stdWrap_csConv($expected, $input, $conf)
1588 {
1589 $this->assertSame($expected,
1590 $this->subject->stdWrap_csConv($input, $conf));
1591 }
1592
1593 /**
1594 * Check if stdWrap_split works properly.
1595 *
1596 * Show:
1597 *
1598 * - Delegates to method splitObj.
1599 * - Parameter 1 is $content.
1600 * - Prameter 2 is $conf['split.'].
1601 * - Returns the return value.
1602 *
1603 * @test
1604 * @return void
1605 */
1606 public function stdWrap_split()
1607 {
1608 $content = $this->getUniqueId('content');
1609 $conf = [
1610 'split' => $this->getUniqueId('not used'),
1611 'split.' => [$this->getUniqueId('split.')],
1612 ];
1613 $return = $this->getUniqueId('return');
1614 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1615 ->setMethods(['splitObj'])->getMock();
1616 $subject
1617 ->expects($this->once())
1618 ->method('splitObj')
1619 ->with($content, $conf['split.'])
1620 ->willReturn($return);
1621 $this->assertSame($return,
1622 $subject->stdWrap_split($content, $conf));
1623 }
1624
1625 /**
1626 * Data provider for stdWrap_prioriCalc
1627 *
1628 * @return array [$expect, $content, $conf]
1629 */
1630 public function stdWrap_prioriCalcDataProvider()
1631 {
1632 return [
1633 'priority of *' => ['7', '1 + 2 * 3', []],
1634 'priority of parentheses' => ['9', '(1 + 2) * 3', []],
1635 'float' => ['1.5', '3/2', []],
1636 'intval casts to int' => [1, '3/2', ['prioriCalc' => 'intval']],
1637 'intval does not round' => [2, '2.7', ['prioriCalc' => 'intval']],
1638 ];
1639 }
1640
1641 /**
1642 * Data provider for stdWrap_HTMLparser
1643 *
1644 * @return array [$expect, $content, $conf, $times, $will].
1645 */
1646 public function stdWrap_HTMLparserDataProvider()
1647 {
1648 $content = $this->getUniqueId('content');
1649 $parsed = $this->getUniqueId('parsed');
1650 return [
1651 'no config' => [
1652 $content, $content, [], 0, $parsed
1653 ],
1654 'no array' => [
1655 $content, $content, ['HTMLparser.' => 1], 0, $parsed
1656 ],
1657 'empty array' => [
1658 $parsed, $content, ['HTMLparser.' => []], 1, $parsed
1659 ],
1660 'non-empty array' => [
1661 $parsed, $content, ['HTMLparser.' => [true]], 1, $parsed
1662 ],
1663 ];
1664 }
1665
1666 /**
1667 * Check if stdWrap_HTMLparser works properly
1668 *
1669 * Show:
1670 *
1671 * - Checks if $conf['HTMLparser.'] is an array.
1672 * - No:
1673 * - Returns $content as is.
1674 * - Yes:
1675 * - Delegates to method HTMLparser_TSbridge.
1676 * - Parameter 1 is $content.
1677 * - Parameter 2 is $conf['HTMLparser'].
1678 * - Returns the return value.
1679 *
1680 * @test
1681 * @dataProvider stdWrap_HTMLparserDataProvider
1682 * @param string $expect The expected output.
1683 * @param string $content The given content.
1684 * @param array $conf The given configuration.
1685 * @param int $times Times HTMLparser_TSbridge is called (0 or 1).
1686 * @param string $will Return of HTMLparser_TSbridge.
1687 * @return void.
1688 */
1689 public function stdWrap_HTMLparser(
1690 $expect, $content, $conf, $times, $will)
1691 {
1692 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1693 ->setMethods(['HTMLparser_TSbridge'])->getMock();
1694 $subject
1695 ->expects($this->exactly($times))
1696 ->method('HTMLparser_TSbridge')
1697 ->with($content, $conf['HTMLparser.'])
1698 ->willReturn($will);
1699 $this->assertSame($expect,
1700 $subject->stdWrap_HTMLparser($content, $conf));
1701 }
1702
1703 /**
1704 * Check if stdWrap_prioriCalc works properly.
1705 *
1706 * Show:
1707 *
1708 * - If $conf['prioriCalc'] is 'intval' the return is casted to int.
1709 * - Delegates to MathUtility::calculateWithParentheses.
1710 *
1711 * Note: As PHPUnit can't mock static methods, the call to
1712 * MathUtility::calculateWithParentheses can't be easily intercepted.
1713 * The test is done by testing input/output pairs instead. To not
1714 * duplicate the testing of calculateWithParentheses just a few
1715 * smoke tests are done here.
1716 *
1717 * @test
1718 * @dataProvider stdWrap_prioriCalcDataProvider
1719 * @param mixed $expect The expected output.
1720 * @param string $content The given content.
1721 * @param array $conf The given configuration.
1722 * @return void
1723 */
1724 public function stdWrap_prioriCalc($expect, $content, $conf)
1725 {
1726 $result = $this->subject->stdWrap_prioriCalc($content, $conf);
1727 $this->assertSame($expect, $result);
1728 }
1729
1730 /**
1731 * Test for the stdWrap_stripHtml
1732 *
1733 * @test
1734 */
1735 public function stdWrap_stripHtml()
1736 {
1737 $content = '<html><p>Hello <span class="inline">inline tag<span>!</p><p>Hello!</p></html>';
1738 $expected = 'Hello inline tag!Hello!';
1739 $this->assertSame($expected, $this->subject->stdWrap_stripHtml($content));
1740 }
1741
1742
1743 /**
1744 * Check if stdWrap_crop works properly.
1745 *
1746 * Show:
1747 *
1748 * - Delegates to method listNum.
1749 * - Parameter 1 is $content.
1750 * - Parameter 2 is $conf['crop'].
1751 * - Returns the return value.
1752 *
1753 * @test
1754 * @return void
1755 */
1756 public function stdWrap_crop()
1757 {
1758 $content = $this->getUniqueId('content');
1759 $conf = [
1760 'crop' => $this->getUniqueId('crop'),
1761 'crop.' => $this->getUniqueId('not used'),
1762 ];
1763 $return = $this->getUniqueId('return');
1764 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1765 ->setMethods(['crop'])->getMock();
1766 $subject
1767 ->expects($this->once())
1768 ->method('crop')
1769 ->with( $content, $conf['crop'])
1770 ->willReturn($return);
1771 $this->assertSame($return,
1772 $subject->stdWrap_crop($content, $conf));
1773 }
1774
1775
1776 /**
1777 * Data provider for round
1778 *
1779 * @return array [$expect, $contet, $conf]
1780 */
1781 public function roundDataProvider()
1782 {
1783 return [
1784 // floats
1785 'down' => [1.0, 1.11, []],
1786 'up' => [2.0, 1.51, []],
1787 'rounds up from x.50' => [2.0, 1.50, []],
1788 'down with decimals' => [0.12, 0.1231, ['decimals' => 2]],
1789 'up with decimals' => [0.13, 0.1251, ['decimals' => 2]],
1790 'ceil' => [1.0, 0.11, ['roundType' => 'ceil']],
1791 'ceil does not accept decimals' => [
1792 1.0, 0.111, [
1793 'roundType' => 'ceil',
1794 'decimals' => 2,
1795 ],
1796 ],
1797 'floor' => [2.0, 2.99, ['roundType' => 'floor']],
1798 'floor does not accept decimals' => [
1799 2.0, 2.999, [
1800 'roundType' => 'floor',
1801 'decimals' => 2,
1802 ],
1803 ],
1804 'round, down' => [1.0, 1.11, ['roundType' => 'round']],
1805 'round, up' => [2.0, 1.55, ['roundType' => 'round']],
1806 'round does accept decimals' => [
1807 5.56, 5.5555, [
1808 'roundType' => 'round',
1809 'decimals' => 2,
1810 ],
1811 ],
1812 // strings
1813 'emtpy string' => [0.0, '', []],
1814 'word string' => [0.0, 'word', []],
1815 'float string' => [1.0, '1.123456789', []],
1816 // other types
1817 'null' => [0.0, null, []],
1818 'false' => [0.0, false, []],
1819 'true' => [1.0, true, []]
1820 ];
1821 }
1822
1823 /**
1824 * Check if round works properly
1825 *
1826 * Show:
1827 *
1828 * - Different types of input are casted to float.
1829 * - Configuration ceil rounds like ceil().
1830 * - Configuration floor rounds like floor().
1831 * - Otherwise rounds like round() and decimals can be applied.
1832 * - Always returns float.
1833 *
1834 * @param float $expected The expected output.
1835 * @param mixed $content The given content.
1836 * @param array $conf The given configuration of 'round.'.
1837 * @return void
1838 * @dataProvider roundDataProvider
1839 * @test
1840 */
1841 public function round($expect, $content, $conf)
1842 {
1843 $this->assertSame($expect,
1844 $this->subject->_call('round', $content, $conf));
1845 }
1846
1847 /**
1848 * Check if stdWrap_round works properly
1849 *
1850 * Show:
1851 *
1852 * - Delegates to method round.
1853 * - Parameter 1 is $content.
1854 * - Parameter 2 is $conf['round.'].
1855 * - Returns the return value.
1856 *
1857 * @test
1858 * @return void
1859 */
1860 public function stdWrap_round()
1861 {
1862 $content = $this->getUniqueId('content');
1863 $conf = [
1864 'round' => $this->getUniqueId('not used'),
1865 'round.' => [$this->getUniqueId('round.')],
1866 ];
1867 $return = $this->getUniqueId('return');
1868 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1869 ->setMethods(['round'])->getMock();
1870 $subject
1871 ->expects($this->once())
1872 ->method('round')
1873 ->with($content, $conf['round.'])
1874 ->willReturn($return);
1875 $this->assertSame($return, $subject->stdWrap_round($content, $conf));
1876 }
1877
1878 /**
1879 * Check if stdWrap_numberFormat works properly.
1880 *
1881 * Show:
1882 *
1883 * - Delegates to the method numberFormat.
1884 * - Parameter 1 is $content.
1885 * - Parameter 2 is $conf['numberFormat.'].
1886 * - Returns the return value.
1887 *
1888 * @test
1889 * @return void
1890 */
1891 public function stdWrap_numberFormat()
1892 {
1893 $content = $this->getUniqueId('content');
1894 $conf = [
1895 'numberFormat' => $this->getUniqueId('not used'),
1896 'numberFormat.' => [$this->getUniqueId('numberFormat.')],
1897 ];
1898 $return = $this->getUniqueId('return');
1899 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1900 ->setMethods(['numberFormat'])->getMock();
1901 $subject
1902 ->expects($this->once())
1903 ->method('numberFormat')
1904 ->with($content, $conf['numberFormat.'])
1905 ->willReturn($return);
1906 $this->assertSame($return,
1907 $subject->stdWrap_numberFormat($content, $conf));
1908 }
1909
1910 /**
1911 * Data provider for expandList
1912 *
1913 * @return array [$expect, $content]
1914 */
1915 public function stdWrap_expandListDataProvider()
1916 {
1917 return [
1918 'numbers' => ['1,2,3', '1,2,3'],
1919 'range' => ['3,4,5', '3-5'],
1920 'numbers and range' => ['1,3,4,5,7', '1,3-5,7']
1921 ];
1922 }
1923
1924 /**
1925 * Test for the stdWrap function "expandList"
1926 *
1927 * The method simply delegates to GeneralUtility::expandList. There is no
1928 * need to repeat the full set of tests of this method here. As PHPUnit
1929 * can't mock static methods, to prove they are called, all we do here
1930 * is to provide a few smoke tests.
1931 *
1932 * @test
1933 * @dataProvider stdWrap_expandListDataProvider
1934 * @param string $expected The expeced output.
1935 * @param string $content The given content.
1936 * @return void
1937 */
1938 public function stdWrap_expandList($expected, $content)
1939 {
1940 $this->assertEquals($expected,
1941 $this->subject->stdWrap_expandList($content));
1942 }
1943
1944 /**
1945 * Data provider for stdWrap_trim.
1946 *
1947 * @return array [$expect, $content]
1948 */
1949 public function stdWrap_trimDataProvider()
1950 {
1951 return [
1952 // string not trimmed
1953 'empty string' => ['', ''],
1954 'string without whitespace' => ['xxx', 'xxx'],
1955 'string with whitespace inside' => [
1956 'xx ' . TAB . ' xx',
1957 'xx ' . TAB . ' xx',
1958 ],
1959 'string with newlines inside' => [
1960 'xx ' . PHP_EOL . ' xx',
1961 'xx ' . PHP_EOL . ' xx',
1962 ],
1963 // string trimmed
1964 'blanks around' => ['xxx', ' xxx '],
1965 'tabs around' => ['xxx', TAB . 'xxx' . TAB],
1966 'newlines around' => ['xxx', PHP_EOL . 'xxx' . PHP_EOL],
1967 'mixed case' => ['xxx', TAB . ' xxx ' . PHP_EOL],
1968 // non strings
1969 'null' => ['', null],
1970 'false' => ['', false],
1971 'true' => ['1', true],
1972 'zero' => ['0', 0],
1973 'one' => ['1', 1],
1974 '-1' => ['-1', -1],
1975 '0.0' => ['0', 0.0],
1976 '1.0' => ['1', 1.0],
1977 '-1.0' => ['-1', -1.0],
1978 '1.1' => ['1.1', 1.1],
1979 ];
1980 }
1981
1982 /**
1983 * Check that stdWrap_trim works properly.
1984 *
1985 * Show:
1986 *
1987 * - the given string is trimmed like PHP trim
1988 * - non-strings are casted to strings:
1989 * - null => 'null'
1990 * - false => ''
1991 * - true => '1'
1992 * - 0 => '0'
1993 * - -1 => '-1'
1994 * - 1.0 => '1'
1995 * - 1.1 => '1.1'
1996 *
1997 * @test
1998 * @dataProvider stdWrap_trimDataProvider
1999 * @param string $expected The expected output.
2000 * @param mixed $content The given content.
2001 * @return void
2002 */
2003 public function stdWrap_trim($expect, $content)
2004 {
2005 $result = $this->subject->stdWrap_trim($content);
2006 $this->assertSame($expect, $result);
2007 }
2008
2009 /**
2010 * Data provider for stdWrap_if.
2011 *
2012 * @return array [$expect, $stop, $content, $conf, $times, $will]
2013 */
2014 public function stdWrap_ifDataProvider()
2015 {
2016 $content = $this->getUniqueId('content');
2017 $conf = ['if.' => [$this->getUniqueId('if.')]];
2018 return [
2019 // evals to true
2020 'empty config' => [
2021 $content, false, $content, [], 0, null
2022 ],
2023 'if. is empty array' => [
2024 $content, false, $content, ['if.' => []], 0, null
2025 ],
2026 'if. is null' => [
2027 $content, false, $content, ['if.' => null], 0, null
2028 ],
2029 'if. is false' => [
2030 $content, false, $content, ['if.' => false], 0, null
2031 ],
2032 'if. is 0' => [
2033 $content, false, $content, ['if.' => false], 0, null
2034 ],
2035 'if. is "0"' => [
2036 $content, false, $content, ['if.' => '0'], 0, null
2037 ],
2038 'checkIf returning true' => [
2039 $content, false, $content, $conf, 1, true
2040 ],
2041 // evals to false
2042 'checkIf returning false' => [
2043 '', true, $content, $conf, 1, false
2044 ],
2045 ];
2046 }
2047
2048 /**
2049 * Check if stdWrap_if works properly.
2050 *
2051 * Show:
2052 *
2053 * - Delegates to the method checkIf to check for 'true'.
2054 * - The parameter to checkIf is $conf['if.'].
2055 * - Is also 'true' if $conf['if.'] is empty (PHP method empty).
2056 * - 'False' triggers a stop of further rendering.
2057 * - Returns the content as is or '' if false.
2058 *
2059 * @test
2060 * @dataProvider stdWrap_ifDataProvider
2061 * @param mixed $expect The expected output.
2062 * @param bool $stop Expect stop further rendering.
2063 * @param mixed $content The given content.
2064 * @param mixed $config The given configuration.
2065 * @param int $times Times checkIf is called (0 or 1).
2066 * @param bool|null $will Return of checkIf (null if not called).
2067 * @return void
2068 */
2069 public function stdWrap_if($expect, $stop, $content, $conf, $times, $will)
2070 {
2071 $subject = $this->getAccessibleMock(
2072 ContentObjectRenderer::class, ['checkIf']);
2073 $subject->_set('stdWrapRecursionLevel', 1);
2074 $subject->_set('stopRendering', [1 => false]);
2075 $subject
2076 ->expects($this->exactly($times))
2077 ->method('checkIf')
2078 ->with($conf['if.'])
2079 ->willReturn($will);
2080 $this->assertSame($expect, $subject->stdWrap_if($content, $conf));
2081 $this->assertSame($stop, $subject->_get('stopRendering')[1]);
2082 }
2083
2084 /**
2085 * Data provider for stdWrap_required.
2086 *
2087 * @return array [$expect, $stop, $content]
2088 */
2089 public function stdWrap_requiredDataProvider()
2090 {
2091 return [
2092 // empty content
2093 'empty string is empty' => ['', true, ''],
2094 'null is empty' => ['', true, null],
2095 'false is empty' => ['', true, false],
2096
2097 // non-empty content
2098 'blank is not empty' => [' ', false, ' '],
2099 'tab is not empty' => [TAB, false, TAB],
2100 'linebreak is not empty' => [PHP_EOL, false, PHP_EOL],
2101 '"0" is not empty' => ['0', false, '0'],
2102 '0 is not empty' => [0, false, 0],
2103 '1 is not empty' => [1, false, 1],
2104 'true is not empty' => [true, false, true],
2105 ];
2106 }
2107
2108 /**
2109 * Check if stdWrap_required works properly.
2110 *
2111 * Show:
2112 *
2113 * - Content is empty if it equals '' after cast to string.
2114 * - Empty content triggers a stop of further rendering.
2115 * - Returns the content as is or '' for empty content.
2116 *
2117 * @test
2118 * @dataProvider stdWrap_requiredDataProvider
2119 * @param mixed $expect The expected output.
2120 * @param bool $stop Expect stop further rendering.
2121 * @param mixed $content The given input.
2122 * @return void
2123 */
2124 public function stdWrap_required($expect, $stop, $content)
2125 {
2126 $subject = $this->subject;
2127 $subject->_set('stdWrapRecursionLevel', 1);
2128 $subject->_set('stopRendering', [1 => false]);
2129 $this->assertSame($expect, $subject->stdWrap_required($content));
2130 $this->assertSame($stop, $subject->_get('stopRendering')[1]);
2131 }
2132
2133 /**
2134 * Data provider for stdWrap_intval
2135 *
2136 * @return array [$expect, $content]
2137 */
2138 public function stdWrap_intvalDataProvider()
2139 {
2140 return [
2141 // numbers
2142 'int' => [123, 123],
2143 'float' => [123, 123.45],
2144 'float does not round up' => [123, 123.55],
2145 // negative numbers
2146 'negative int' => [-123, -123],
2147 'negative float' => [-123, -123.45],
2148 'negative float does not round down' => [ -123, -123.55],
2149 // strings
2150 'word string' => [0, 'string'],
2151 'empty string' => [0, ''],
2152 'zero string' => [0, '0'],
2153 'int string' => [123, '123'],
2154 'float string' => [123, '123.55'],
2155 'negative float string' => [-123, '-123.55'],
2156 // other types
2157 'null' => [0, null],
2158 'true' => [1, true],
2159 'false' => [0, false]
2160 ];
2161 }
2162
2163 /**
2164 * Check that stdWrap_intval works properly.
2165 *
2166 * Show:
2167 *
2168 * - It does not round up.
2169 * - All types of input is casted to int:
2170 * - null: 0
2171 * - false: 0
2172 * - true: 1
2173 * -
2174 *
2175 *
2176 *
2177 * @test
2178 * @dataProvider stdWrap_intvalDataProvider
2179 * @param int $expect The expected output.
2180 * @param string $content The given input.
2181 * @return void
2182 */
2183 public function stdWrap_intval($expect, $content)
2184 {
2185 $this->assertSame($expect, $this->subject->stdWrap_intval($content));
2186 }
2187
2188 /**
2189 * Data provider for stdWrap_strPad.
2190 *
2191 * @return array [$expect, $content, $conf]
2192 */
2193 public function stdWrap_strPadDataProvider()
2194 {
2195 return [
2196 'pad string with default settings and length 10' => [
2197 'Alien ',
2198 'Alien',
2199 [
2200 'length' => '10',
2201 ],
2202 ],
2203 'pad string with padWith -= and type left and length 10' => [
2204 '-=-=-Alien',
2205 'Alien',
2206 [
2207 'length' => '10',
2208 'padWith' => '-=',
2209 'type' => 'left',
2210 ],
2211 ],
2212 'pad string with padWith _ and type both and length 10' => [
2213 '__Alien___',
2214 'Alien',
2215 [
2216 'length' => '10',
2217 'padWith' => '_',
2218 'type' => 'both',
2219 ],
2220 ],
2221 'pad string with padWith 0 and type both and length 10' => [
2222 '00Alien000',
2223 'Alien',
2224 [
2225 'length' => '10',
2226 'padWith' => '0',
2227 'type' => 'both',
2228 ],
2229 ],
2230 'pad string with padWith ___ and type both and length 6' => [
2231 'Alien_',
2232 'Alien',
2233 [
2234 'length' => '6',
2235 'padWith' => '___',
2236 'type' => 'both',
2237 ],
2238 ],
2239 'pad string with padWith _ and type both and length 12, using stdWrap for length' => [
2240 '___Alien____',
2241 'Alien',
2242 [
2243 'length' => '1',
2244 'length.' => [
2245 'wrap' => '|2',
2246 ],
2247 'padWith' => '_',
2248 'type' => 'both',
2249 ],
2250 ],
2251 'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => [
2252 '-_=Alien-_=-',
2253 'Alien',
2254 [
2255 'length' => '12',
2256 'padWith' => '_',
2257 'padWith.' => [
2258 'wrap' => '-|=',
2259 ],
2260 'type' => 'both',
2261 ],
2262 ],
2263 'pad string with padWith _ and type both and length 12, using stdWrap for type' => [
2264 '_______Alien',
2265 'Alien',
2266 [
2267 'length' => '12',
2268 'padWith' => '_',
2269 'type' => 'both',
2270 // make type become "left"
2271 'type.' => [
2272 'substring' => '2,1',
2273 'wrap' => 'lef|',
2274 ],
2275 ],
2276 ],
2277 ];
2278 }
2279
2280 /**
2281 * Check if stdWrap_strPad works properly.
2282 *
2283 * @test
2284 * @dataProvider stdWrap_strPadDataProvider
2285 * @param string $expect The expected output.
2286 * @param string $content The given input.
2287 * @param array $conf The configuration of 'strPad.'.
2288 * @return void
2289 */
2290 public function stdWrap_strPad($expect, $content, $conf)
2291 {
2292 $conf = ['strPad.' => $conf];
2293 $result = $this->subject->stdWrap_strPad($content, $conf);
2294 $this->assertSame($expect, $result);
2295 }
2296
2297 /**
2298 * Check that stdWrap_stdWrap works properly.
2299 *
2300 * Show:
2301 * - Delegates to method stdWrap.
2302 * - Parameter 1 is $content.
2303 * - Parameter 2 is $conf['stdWrap.'].
2304 * - Returns the return value.
2305 *
2306 * @test
2307 * @return void.
2308 */
2309 public function stdWrap_stdWrap()
2310 {
2311 $content = $this->getUniqueId('content');
2312 $conf = [
2313 'stdWrap' => $this->getUniqueId('not used'),
2314 'stdWrap.' => [$this->getUniqueId('stdWrap.')],
2315 ];
2316 $return = $this->getUniqueId('return');
2317 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
2318 ->setMethods(['stdWrap'])->getMock();
2319 $subject
2320 ->expects($this->once())
2321 ->method('stdWrap')
2322 ->with($content, $conf['stdWrap.'])
2323 ->willReturn($return);
2324 $this->assertSame($return, $subject->stdWrap_stdWrap($content, $conf));
2325 }
2326
2327 /**
2328 * Check that stdWrap_dataWrap works properly.
2329 *
2330 * Show:
2331 *
2332 * - Delegates to method dataWrap.
2333 * - Parameter 1 is $content.
2334 * - Parameter 2 is $conf['dataWrap'].
2335 * - Returns the return value.
2336 *
2337 * @test
2338 * @return void.
2339 */
2340 public function stdWrap_dataWrap()
2341 {
2342 $content = $this->getUniqueId('content');
2343 $conf = [
2344 'dataWrap' => $this->getUniqueId('dataWrap'),
2345 'dataWrap.' => [$this->getUniqueId('not used')],
2346 ];
2347 $return = $this->getUniqueId('return');
2348 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
2349 ->setMethods(['dataWrap'])->getMock();
2350 $subject
2351 ->expects($this->once())
2352 ->method('dataWrap')
2353 ->with($content, $conf['dataWrap'])
2354 ->willReturn($return);
2355 $this->assertSame($return,
2356 $subject->stdWrap_dataWrap($content, $conf));
2357 }
2358
2359 /**
2360 * Data provider for the hash test
2361 *
2362 * @return array [$expect, $content, $conf]
2363 */
2364 public function hashDataProvider()
2365 {
2366 return [
2367 'md5' => [
2368 'bacb98acf97e0b6112b1d1b650b84971',
2369 'joh316',
2370 ['hash' => 'md5']
2371 ],
2372 'sha1' => [
2373 '063b3d108bed9f88fa618c6046de0dccadcf3158',
2374 'joh316',
2375 ['hash' => 'sha1']
2376 ],
2377 'stdWrap capability' => [
2378 'bacb98acf97e0b6112b1d1b650b84971',
2379 'joh316',
2380 [
2381 'hash' => '5',
2382 'hash.' => ['wrap' => 'md|']
2383 ]
2384 ],
2385 'non-existing hashing algorithm' => [
2386 '',
2387 'joh316',
2388 ['hash' => 'non-existing']
2389 ]
2390 ];
2391 }
2392
2393 /**
2394 * Check if stdWrap_hash works properly.
2395 *
2396 * Show:
2397 *
2398 * - Algorithms: sha1, md5
2399 * - Returns '' for invalid algorithm.
2400 * - Value can be processed by stdWrap.
2401 *
2402 * @test
2403 * @dataProvider hashDataProvider
2404 * @param string $expect The expected output.
2405 * @param string $content The given content.
2406 * @param array $conf The given configuration.
2407 * @return void
2408 */
2409 public function stdWrap_hash($expect, $content, $conf)
2410 {
2411 $this->assertSame($expect,
2412 $this->subject->stdWrap_hash($content, $conf));
2413 }
2414
2415 /**
2416 * @test
2417 */
2418 public function recursiveStdWrapProperlyRendersBasicString()
2419 {
2420 $stdWrapConfiguration = array(
2421 'noTrimWrap' => '|| 123|',
2422 'stdWrap.' => array(
2423 'wrap' => '<b>|</b>'
2424 )
2425 );
2426 $this->assertSame(
2427 '<b>Test</b> 123',
2428 $this->subject->stdWrap('Test', $stdWrapConfiguration)
2429 );
2430 }
2431
2432 /**
2433 * @test
2434 */
2435 public function recursiveStdWrapIsOnlyCalledOnce()
2436 {
2437 $stdWrapConfiguration = array(
2438 'append' => 'TEXT',
2439 'append.' => array(
2440 'data' => 'register:Counter'
2441 ),
2442 'stdWrap.' => array(
2443 'append' => 'LOAD_REGISTER',
2444 'append.' => array(
2445 'Counter.' => array(
2446 'prioriCalc' => 'intval',
2447 'cObject' => 'TEXT',
2448 'cObject.' => array(
2449 'data' => 'register:Counter',
2450 'wrap' => '|+1',
2451 )
2452 )
2453 )
2454 )
2455 );
2456 $this->assertSame(
2457 'Counter:1',
2458 $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
2459 );
2460 }
2461
2462 /**
2463 * Data provider for numberFormat.
2464 *
2465 * @return array [$expect, $content, $conf]
2466 */
2467 public function numberFormatDataProvider()
2468 {
2469 return [
2470 'testing decimals' => [
2471 '0.80', 0.8,
2472 ['decimals' => 2]
2473 ],
2474 'testing decimals with input as string' => [
2475 '0.80', '0.8',
2476 ['decimals' => 2]
2477 ],
2478 'testing dec_point' => [
2479 '0,8', 0.8,
2480 ['decimals' => 1, 'dec_point' => ',']
2481 ],
2482 'testing thousands_sep' => [
2483 '1.000', 999.99,
2484 [
2485 'decimals' => 0,
2486 'thousands_sep.' => ['char' => 46]
2487 ]
2488 ],
2489 'testing mixture' => [
2490 '1.281.731,5', 1281731.45,
2491 [
2492 'decimals' => 1,
2493 'dec_point.' => ['char' => 44],
2494 'thousands_sep.' => ['char' => 46]
2495 ]
2496 ]
2497 ];
2498 }
2499
2500 /**
2501 * Check if numberFormat works properly.
2502 *
2503 * @dataProvider numberFormatDataProvider
2504 * @test
2505 */
2506 public function numberFormat($expects, $content, $conf)
2507 {
2508 $this->assertSame($expects,
2509 $this->subject->numberFormat($content, $conf));
2510 }
2511
2512 /**
2513 * Check if stdWrap_replacement works properly.
2514 *
2515 * Show:
2516 *
2517 * - Delegates to method replacement.
2518 * - Parameter 1 is $content.
2519 * - Parameter 2 is $conf['replacement.'].
2520 * - Returns the return value.
2521 *
2522 * @test
2523 * @return void
2524 */
2525 public function stdWrap_replacement()
2526 {
2527 $content = $this->getUniqueId('content');
2528 $conf = [
2529 'replacement' => $this->getUniqueId('not used'),
2530 'replacement.' => [$this->getUniqueId('replacement.')],
2531 ];
2532 $return = $this->getUniqueId('return');
2533 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
2534 ->setMethods(['replacement'])->getMock();
2535 $subject
2536 ->expects($this->once())
2537 ->method('replacement')
2538 ->with( $content, $conf['replacement.'])
2539 ->willReturn($return);
2540 $this->assertSame($return,
2541 $subject->stdWrap_replacement($content, $conf));
2542 }
2543
2544 /**
2545 * Data provider replacement
2546 *
2547 * @return array [$expect, $content, $conf]
2548 */
2549 public function replacementDataProvider()
2550 {
2551 return [
2552 'multiple replacements, including regex' => [
2553 'There is an animal, an animal and an animal around the block! Yeah!',
2554 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2555 [
2556 '20.' => [
2557 'search' => '_',
2558 'replace.' => ['char' => '32']
2559 ],
2560 '120.' => [
2561 'search' => 'in da hood',
2562 'replace' => 'around the block'
2563 ],
2564 '130.' => [
2565 'search' => '#a (Cat|Dog|Tiger)#i',
2566 'replace' => 'an animal',
2567 'useRegExp' => '1'
2568 ]
2569 ]
2570 ],
2571 'replacement with optionSplit, normal pattern' => [
2572 'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!',
2573 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2574 [
2575 '10.' => [
2576 'search' => '_',
2577 'replace' => '1 || 2 || 3',
2578 'useOptionSplitReplace' => '1'
2579 ]
2580 ]
2581 ],
2582 'replacement with optionSplit, using regex' => [
2583 'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!',
2584 'There is a cat, a dog and a tiger in da hood! Yeah!',
2585 [
2586 '10.' => [
2587 'search' => '#(a) (Cat|Dog|Tiger)#i',
2588 'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
2589 'useOptionSplitReplace' => '1',
2590 'useRegExp' => '1'
2591 ]
2592 ]
2593 ]
2594 ];
2595 }
2596
2597 /**
2598 * Check if stdWrap.replacement and all of its properties work properly
2599 *
2600 * @test
2601 * @dataProvider replacementDataProvider
2602 * @param string $content The given input.
2603 * @param string $expects The expected result.
2604 * @param array $conf The given configuration.
2605 * @return void
2606 */
2607 public function replacement($expects, $content, $conf)
2608 {
2609 $this->assertSame($expects,
2610 $this->subject->_call('replacement', $content, $conf));
2611 }
2612
2613 /**
2614 * Data provider for stdWrap_rawUrlEncode
2615 *
2616 * @return array [$expect, $content].
2617 */
2618 public function stdWrap_rawUrlEncodeDataProvider()
2619 {
2620 return [
2621 'https://typo3.org?id=10' => [
2622 'https%3A%2F%2Ftypo3.org%3Fid%3D10',
2623 'https://typo3.org?id=10',
2624 ],
2625 'https://typo3.org?id=10&foo=bar' => [
2626 'https%3A%2F%2Ftypo3.org%3Fid%3D10%26foo%3Dbar',
2627 'https://typo3.org?id=10&foo=bar',
2628 ],
2629 ];
2630 }
2631
2632 /**
2633 * Check if rawUrlEncode works properly.
2634 *
2635 * @test
2636 * @dataProvider stdWrap_rawUrlEncodeDataProvider
2637 * @param string $expect The expected output.
2638 * @param string $content The given input.
2639 * @return void
2640 */
2641 public function stdWrap_rawUrlEncode($expect, $content)
2642 {
2643 $this->assertSame($expect,
2644 $this->subject->stdWrap_rawUrlEncode($content));
2645 }
2646
2647 /**
2648 * Data provider for the getQuery test
2649 *
2650 * @return array multi-dimensional array with the second level like this:
2651 * @see getQuery
2652 */
2653 public function getQueryDataProvider()
2654 {
2655 $data = array(
2656 'testing empty conf' => array(
2657 'tt_content',
2658 array(),
2659 array(
2660 'SELECT' => '*'
2661 )
2662 ),
2663 'testing #17284: adding uid/pid for workspaces' => array(
2664 'tt_content',
2665 array(
2666 'selectFields' => 'header,bodytext'
2667 ),
2668 array(
2669 'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2670 )
2671 ),
2672 'testing #17284: no need to add' => array(
2673 'tt_content',
2674 array(
2675 'selectFields' => 'tt_content.*'
2676 ),
2677 array(
2678 'SELECT' => 'tt_content.*'
2679 )
2680 ),
2681 'testing #17284: no need to add #2' => array(
2682 'tt_content',
2683 array(
2684 'selectFields' => '*'
2685 ),
2686 array(
2687 'SELECT' => '*'
2688 )
2689 ),
2690 'testing #29783: joined tables, prefix tablename' => array(
2691 'tt_content',
2692 array(
2693 'selectFields' => 'tt_content.header,be_users.username',
2694 'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
2695 ),
2696 array(
2697 'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2698 )
2699 ),
2700 'testing #34152: single count(*), add nothing' => array(
2701 'tt_content',
2702 array(
2703 'selectFields' => 'count(*)'
2704 ),
2705 array(
2706 'SELECT' => 'count(*)'
2707 )
2708 ),
2709 'testing #34152: single max(crdate), add nothing' => array(
2710 'tt_content',
2711 array(
2712 'selectFields' => 'max(crdate)'
2713 ),
2714 array(
2715 'SELECT' => 'max(crdate)'
2716 )
2717 ),
2718 'testing #34152: single min(crdate), add nothing' => array(
2719 'tt_content',
2720 array(
2721 'selectFields' => 'min(crdate)'
2722 ),
2723 array(
2724 'SELECT' => 'min(crdate)'
2725 )
2726 ),
2727 'testing #34152: single sum(is_siteroot), add nothing' => array(
2728 'tt_content',
2729 array(
2730 'selectFields' => 'sum(is_siteroot)'
2731 ),
2732 array(
2733 'SELECT' => 'sum(is_siteroot)'
2734 )
2735 ),
2736 'testing #34152: single avg(crdate), add nothing' => array(
2737 'tt_content',
2738 array(
2739 'selectFields' => 'avg(crdate)'
2740 ),
2741 array(
2742 'SELECT' => 'avg(crdate)'
2743 )
2744 )
2745 );
2746 return $data;
2747 }
2748
2749 /**
2750 * Check if sanitizeSelectPart works as expected
2751 *
2752 * @dataProvider getQueryDataProvider
2753 * @test
2754 */
2755 public function getQuery($table, $conf, $expected)
2756 {
2757 $GLOBALS['TCA'] = array(
2758 'pages' => array(
2759 'ctrl' => array(
2760 'enablecolumns' => array(
2761 'disabled' => 'hidden'
2762 )
2763 )
2764 ),
2765 'tt_content' => array(
2766 'ctrl' => array(
2767 'enablecolumns' => array(
2768 'disabled' => 'hidden'
2769 ),
2770 'versioningWS' => true
2771 )
2772 ),
2773 );
2774 $result = $this->subject->getQuery($table, $conf, true);
2775 foreach ($expected as $field => $value) {
2776 $this->assertEquals($value, $result[$field]);
2777 }
2778 }
2779
2780 /**
2781 * @test
2782 */
2783 public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet()
2784 {
2785 $GLOBALS['TCA'] = array(
2786 'pages' => array(
2787 'ctrl' => array(
2788 'enablecolumns' => array(
2789 'disabled' => 'hidden'
2790 )
2791 )
2792 ),
2793 'tt_content' => array(
2794 'ctrl' => array(
2795 'enablecolumns' => array(
2796 'disabled' => 'hidden'
2797 )
2798 )
2799 ),
2800 );
2801 $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
2802 $this->subject->start(array(), 'tt_content');
2803 $conf = array(
2804 'recursive' => '15',
2805 'pidInList' => '16, -35'
2806 );
2807 $this->subject->expects($this->at(0))
2808 ->method('getTreeList')
2809 ->with(-16, 15)
2810 ->will($this->returnValue('15,16'));
2811 $this->subject->expects($this->at(1))
2812 ->method('getTreeList')
2813 ->with(-35, 15)
2814 ->will($this->returnValue('15,35'));
2815 $this->subject->getQuery('tt_content', $conf, true);
2816 }
2817
2818 /**
2819 * @test
2820 */
2821 public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet()
2822 {
2823 $GLOBALS['TCA'] = array(
2824 'pages' => array(
2825 'ctrl' => array(
2826 'enablecolumns' => array(
2827 'disabled' => 'hidden'
2828 )
2829 )
2830 ),
2831 'tt_content' => array(
2832 'ctrl' => array(
2833 'enablecolumns' => array(
2834 'disabled' => 'hidden'
2835 )
2836 )
2837 ),
2838 );
2839 $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
2840 $GLOBALS['TSFE']->id = 27;
2841 $this->subject->start(array(), 'tt_content');
2842 $conf = array(
2843 'pidInList' => 'this',
2844 'recursive' => '4'
2845 );
2846 $this->subject->expects($this->once())
2847 ->method('getTreeList')
2848 ->with(-27)
2849 ->will($this->returnValue('27'));
2850 $this->subject->getQuery('tt_content', $conf, true);
2851 }
2852
2853 /**
2854 * Data provider for the stdWrap_date test
2855 *
2856 * @return array [$expect, $content, $conf, $now]
2857 */
2858 public function stdWrap_dateDataProvider()
2859 {
2860 // Fictive execution time: 2015-10-02 12:00
2861 $now = 1443780000;
2862 return [
2863 'given timestamp' => [
2864 '02.10.2015',
2865 $now,
2866 ['date' => 'd.m.Y'],
2867 $now
2868 ],
2869 'empty string' => [
2870 '02.10.2015',
2871 '',
2872 ['date' => 'd.m.Y'],
2873 $now
2874 ],
2875 'testing null' => [
2876 '02.10.2015',
2877 null,
2878 ['date' => 'd.m.Y'],
2879 $now
2880 ],
2881 'given timestamp return GMT' => [
2882 '02.10.2015 10:00:00',
2883 $now,
2884 [
2885 'date' => 'd.m.Y H:i:s',
2886 'date.' => ['GMT' => true],
2887 ],
2888 $now
2889 ]
2890 ];
2891 }
2892
2893 /**
2894 * Check if stdWrap_date works properly.
2895 *
2896 * @test
2897 * @dataProvider stdWrap_dateDataProvider
2898 * @param string $expected The expected output.
2899 * @param mixed $content The given input.
2900 * @param array $conf The given configuration.
2901 * @param int $now Fictive execution time.
2902 * @return void
2903 */
2904 public function stdWrap_date($expected, $content, $conf, $now)
2905 {
2906 $GLOBALS['EXEC_TIME'] = $now;
2907 $this->assertEquals($expected,
2908 $this->subject->stdWrap_date($content, $conf));
2909 }
2910
2911 /**
2912 * Data provider for stdWrap_strftime
2913 *
2914 * @return array [$expect, $content, $conf, $now]
2915 */
2916 public function stdWrap_strftimeDataProvider()
2917 {
2918 // Fictive execution time is 2012-09-01 12:00 in UTC/GMT.
2919 $now = 1346500800;
2920 return [
2921 'given timestamp' => [
2922 '01-09-2012',
2923 $now,
2924 ['strftime' => '%d-%m-%Y'],
2925 $now
2926 ],
2927 'empty string' => [
2928 '01-09-2012',
2929 '',
2930 ['strftime' => '%d-%m-%Y'],
2931 $now
2932 ],
2933 'testing null' => [
2934 '01-09-2012',
2935 null,
2936 ['strftime' => '%d-%m-%Y'],
2937 $now
2938 ]
2939 ];
2940 }
2941
2942 /**
2943 * Check if stdWrap_strftime works properly.
2944 *
2945 * @test
2946 * @dataProvider stdWrap_strftimeDataProvider
2947 * @param string $expect The expected output.
2948 * @param mixed $content The given input.
2949 * @param array $conf The given configuration.
2950 * @param int $now Fictive execution time.
2951 * @return void
2952 */
2953 public function stdWrap_strftime($expect, $content, $conf, $now)
2954 {
2955 // Save current timezone and set to UTC to make the system under test
2956 // behave the same in all server timezone settings
2957 $timezoneBackup = date_default_timezone_get();
2958 date_default_timezone_set('UTC');
2959
2960 $GLOBALS['EXEC_TIME'] = $now;
2961 $result = $this->subject->stdWrap_strftime($content, $conf);
2962
2963 // Reset timezone
2964 date_default_timezone_set($timezoneBackup);
2965
2966 $this->assertSame($expect, $result);
2967 }
2968
2969 /**
2970 * Data provider for the stdWrap_strtotime test
2971 *
2972 * @return array [$expect, $content, $conf]
2973 */
2974 public function stdWrap_strtotimeDataProvider()
2975 {
2976 return [
2977 'date from content' => [
2978 1417651200, '2014-12-04',
2979 ['strtotime' => '1']
2980 ],
2981 'manipulation of date from content' => [
2982 1417996800, '2014-12-04',
2983 ['strtotime' => '+ 2 weekdays']
2984 ],
2985 'date from configuration' => [
2986 1417651200, '',
2987 ['strtotime' => '2014-12-04']
2988 ],
2989 'manipulation of date from configuration' => [
2990 1417996800, '',
2991 ['strtotime' => '2014-12-04 + 2 weekdays']
2992 ],
2993 'empty input' => [
2994 false, '',
2995 ['strtotime' => '1']
2996 ],
2997 'date from content and configuration' => [
2998 false, '2014-12-04',
2999 ['strtotime' => '2014-12-05']
3000 ]
3001 ];
3002 }
3003
3004 /**
3005 * Check if stdWrap_strtotime works properly.
3006 *
3007 * @test
3008 * @dataProvider stdWrap_strtotimeDataProvider
3009 * @param int $expect The expected output.
3010 * @param mixed $content The given input.
3011 * @param array $conf The given configuration.
3012 * @return void