[FOLLOWUP][BUGFIX] Allow frontend requests from different document root
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / ContentObject / FluidTemplateContentObjectTest.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 TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Extbase\Mvc\Request;
19 use TYPO3\CMS\Extbase\Service\TypoScriptService;
20 use TYPO3\CMS\Fluid\View\StandaloneView;
21 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
22 use TYPO3\CMS\Frontend\ContentObject\FluidTemplateContentObject;
23
24 /**
25 * Testcase
26 *
27 * @author Christian Kuhn <lolli@schwarzbu.ch>
28 */
29 class FluidTemplateContentObjectTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
30
31 /**
32 * @var array A backup of registered singleton instances
33 */
34 protected $singletonInstances = array();
35
36 /**
37 * @var FluidTemplateContentObject|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
38 */
39 protected $subject = NULL;
40
41 /**
42 * @var ContentObjectRenderer|\PHPUnit_Framework_MockObject_MockObject
43 */
44 protected $contentObjectRenderer = NULL;
45
46 /**
47 * @var StandaloneView|\PHPUnit_Framework_MockObject_MockObject
48 */
49 protected $standaloneView = NULL;
50
51 /**
52 * @var Request|\PHPUnit_Framework_MockObject_MockObject
53 */
54 protected $request = NULL;
55
56 /**
57 * Set up
58 */
59 public function setUp() {
60 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
61 $this->contentObjectRenderer = $this->getMock(
62 'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer'
63 );
64 $this->subject = $this->getAccessibleMock(
65 'TYPO3\\CMS\\Frontend\\ContentObject\\FluidTemplateContentObject',
66 array('dummy', 'initializeStandaloneViewInstance'),
67 array($this->contentObjectRenderer)
68 );
69 /** @var $tsfe \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */
70 $tsfe = $this->getMock('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', array(), array(), '', FALSE);
71 $tsfe->tmpl = $this->getMock('TYPO3\\CMS\\Core\\TypoScript\\TemplateService');
72 $GLOBALS['TSFE'] = $tsfe;
73 }
74
75 /**
76 * Tear down
77 */
78 public function tearDown() {
79 \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
80 parent::tearDown();
81 }
82
83 /**
84 * Add a mock standalone view to subject
85 */
86 protected function addMockViewToSubject() {
87 $this->standaloneView = $this->getMock('TYPO3\\CMS\\Fluid\\View\\StandaloneView', array(), array(), '', FALSE);
88 $this->request = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request');
89 $this->standaloneView
90 ->expects($this->any())
91 ->method('getRequest')
92 ->will($this->returnValue($this->request));
93 $this->subject->_set('view', $this->standaloneView);
94 }
95
96 /**
97 * @test
98 */
99 public function constructSetsContentObjectRenderer() {
100 $this->assertSame($this->contentObjectRenderer, $this->subject->getContentObject());
101 }
102
103 /**
104 * @test
105 */
106 public function renderCallsInitializeStandaloneViewInstance() {
107 $this->addMockViewToSubject();
108 $this->subject
109 ->expects($this->once())
110 ->method('initializeStandaloneViewInstance');
111 $this->subject->render(array());
112 }
113
114 /**
115 * @test
116 */
117 public function renderCallsTemplateServiceGetFileNameForGivenTemplateFile() {
118 $this->addMockViewToSubject();
119 /** @var $templateService \PHPUnit_Framework_MockObject_MockObject */
120 $templateService = $GLOBALS['TSFE']->tmpl;
121 $templateService
122 ->expects($this->any())
123 ->method('getFileName')
124 ->with('foo');
125 $this->subject->render(array('file' => 'foo'));
126 }
127
128 /**
129 * @test
130 */
131 public function renderCallsStandardWrapForGivenTemplateFileWithStandardWrap() {
132 $this->addMockViewToSubject();
133 $this->contentObjectRenderer
134 ->expects($this->any())
135 ->method('stdWrap')
136 ->with('foo', array('bar' => 'baz'));
137 $this->subject->render(array('file' => 'foo', 'file.' => array('bar' => 'baz')));
138 }
139
140 /**
141 * @test
142 */
143 public function renderSetsTemplateFileInView() {
144 $this->addMockViewToSubject();
145 /** @var $templateService \PHPUnit_Framework_MockObject_MockObject */
146 $templateService = $GLOBALS['TSFE']->tmpl;
147 $templateService
148 ->expects($this->any())
149 ->method('getFileName')
150 ->with('foo')
151 ->will($this->returnValue('bar'));
152 $this->standaloneView
153 ->expects($this->any())
154 ->method('setTemplatePathAndFilename')
155 ->with(PATH_site . 'bar');
156 $this->subject->render(array('file' => 'foo'));
157 }
158
159 /**
160 * @test
161 */
162 public function renderSetsTemplateFileByTemplateInView() {
163 $this->addMockViewToSubject();
164
165 $this->contentObjectRenderer
166 ->expects($this->any())
167 ->method('cObjGetSingle')
168 ->with('FILE', array('file' => PATH_site . 'foo/bar.html'))
169 ->will($this->returnValue('baz'));
170
171 $this->standaloneView
172 ->expects($this->any())
173 ->method('setTemplateSource')
174 ->with('baz');
175
176 $this->subject->render(array(
177 'template' => 'FILE',
178 'template.' => array(
179 'file' => PATH_site . 'foo/bar.html'
180 )
181 ));
182 }
183
184 /**
185 * @test
186 */
187 public function renderSetsLayoutRootPathInView() {
188 $this->addMockViewToSubject();
189 $this->standaloneView
190 ->expects($this->once())
191 ->method('setLayoutRootPaths')
192 ->with(array(PATH_site . 'foo/bar.html'));
193 $this->subject->render(array('layoutRootPath' => 'foo/bar.html'));
194 }
195
196 /**
197 * @test
198 */
199 public function renderCallsStandardWrapForLayoutRootPath() {
200 $this->addMockViewToSubject();
201 $this->contentObjectRenderer
202 ->expects($this->once())
203 ->method('stdWrap')
204 ->with('foo', array('bar' => 'baz'));
205 $this->subject->render(array('layoutRootPath' => 'foo', 'layoutRootPath.' => array('bar' => 'baz')));
206 }
207
208 /**
209 * @test
210 */
211 public function fallbacksForLayoutRootPathAreSet() {
212 $this->addMockViewToSubject();
213 $this->standaloneView
214 ->expects($this->once())
215 ->method('setLayoutRootPaths')
216 ->with(array(10 => PATH_site . 'foo/bar.html', 20 => PATH_site . 'foo/bar2.html'));
217 $this->subject->render(array('layoutRootPaths.' => array(10 => 'foo/bar.html', 20 => 'foo/bar2.html')));
218 }
219
220 /**
221 * @test
222 */
223 public function fallbacksForLayoutRootPathAreAppendedToLayoutRootPath() {
224 $this->addMockViewToSubject();
225 $this->standaloneView
226 ->expects($this->once())
227 ->method('setLayoutRootPaths')
228 ->with(array(0 => PATH_site . 'foo/main.html', 10 => PATH_site . 'foo/bar.html', 20 => PATH_site . 'foo/bar2.html'));
229 $this->subject->render(array('layoutRootPath' => 'foo/main.html', 'layoutRootPaths.' => array(10 => 'foo/bar.html', 20 => 'foo/bar2.html')));
230 }
231
232 /**
233 * @test
234 */
235 public function renderSetsPartialRootPathInView() {
236 $this->addMockViewToSubject();
237 $this->standaloneView
238 ->expects($this->once())
239 ->method('setPartialRootPaths')
240 ->with(array(PATH_site . 'foo/bar.html'));
241 $this->subject->render(array('partialRootPath' => 'foo/bar.html'));
242 }
243
244 /**
245 * @test
246 */
247 public function renderCallsStandardWrapForPartialRootPath() {
248 $this->addMockViewToSubject();
249 $this->contentObjectRenderer
250 ->expects($this->once())
251 ->method('stdWrap')
252 ->with('foo', array('bar' => 'baz'));
253 $this->subject->render(array('partialRootPath' => 'foo', 'partialRootPath.' => array('bar' => 'baz')));
254 }
255
256
257 /**
258 * @test
259 */
260 public function fallbacksForPartialRootPathAreSet() {
261 $this->addMockViewToSubject();
262 $this->standaloneView
263 ->expects($this->once())
264 ->method('setPartialRootPaths')
265 ->with(array(10 => PATH_site . 'foo', 20 => PATH_site . 'bar'));
266 $this->subject->render(array('partialRootPaths.' => array(10 => 'foo', 20 => 'bar')));
267 }
268
269 /**
270 * @test
271 */
272 public function fallbacksForPartialRootPathAreAppendedToPartialRootPath() {
273 $this->addMockViewToSubject();
274 $this->standaloneView
275 ->expects($this->once())
276 ->method('setPartialRootPaths')
277 ->with(array(0 => PATH_site . 'main', 10 => PATH_site . 'foo', 20 => PATH_site . 'bar'));
278 $this->subject->render(array('partialRootPath' => 'main', 'partialRootPaths.' => array(10 => 'foo', 20 => 'bar')));
279 }
280
281 /**
282 * @test
283 */
284 public function renderSetsFormatInView() {
285 $this->addMockViewToSubject();
286 $this->standaloneView
287 ->expects($this->once())
288 ->method('setFormat')
289 ->with('xml');
290 $this->subject->render(array('format' => 'xml'));
291 }
292
293 /**
294 * @test
295 */
296 public function renderCallsStandardWrapForFormat() {
297 $this->addMockViewToSubject();
298 $this->contentObjectRenderer
299 ->expects($this->once())
300 ->method('stdWrap')
301 ->with('foo', array('bar' => 'baz'));
302 $this->subject->render(array('format' => 'foo', 'format.' => array('bar' => 'baz')));
303 }
304
305 /**
306 * @test
307 */
308 public function renderSetsExtbasePluginNameInRequest() {
309 $this->addMockViewToSubject();
310 $this->request
311 ->expects($this->once())
312 ->method('setPluginName')
313 ->with('foo');
314 $configuration = array(
315 'extbase.' => array(
316 'pluginName' => 'foo',
317 ),
318 );
319 $this->subject->render($configuration);
320 }
321
322 /**
323 * @test
324 */
325 public function renderCallsStandardWrapForExtbasePluginName() {
326 $this->addMockViewToSubject();
327 $this->contentObjectRenderer
328 ->expects($this->once())
329 ->method('stdWrap')
330 ->with('foo', array('bar' => 'baz'));
331 $configuration = array(
332 'extbase.' => array(
333 'pluginName' => 'foo',
334 'pluginName.' => array(
335 'bar' => 'baz',
336 ),
337 ),
338 );
339 $this->subject->render($configuration);
340 }
341
342 /**
343 * @test
344 */
345 public function renderSetsExtbaseControllerExtensionNameInRequest() {
346 $this->addMockViewToSubject();
347 $this->request
348 ->expects($this->once())
349 ->method('setControllerExtensionName')
350 ->with('foo');
351 $configuration = array(
352 'extbase.' => array(
353 'controllerExtensionName' => 'foo',
354 ),
355 );
356 $this->subject->render($configuration);
357 }
358
359 /**
360 * @test
361 */
362 public function renderCallsStandardWrapForExtbaseControllerExtensionName() {
363 $this->addMockViewToSubject();
364 $this->contentObjectRenderer
365 ->expects($this->once())
366 ->method('stdWrap')
367 ->with('foo', array('bar' => 'baz'));
368 $configuration = array(
369 'extbase.' => array(
370 'controllerExtensionName' => 'foo',
371 'controllerExtensionName.' => array(
372 'bar' => 'baz',
373 ),
374 ),
375 );
376 $this->subject->render($configuration);
377 }
378
379 /**
380 * @test
381 */
382 public function renderSetsExtbaseControllerNameInRequest() {
383 $this->addMockViewToSubject();
384 $this->request
385 ->expects($this->once())
386 ->method('setControllerName')
387 ->with('foo');
388 $configuration = array(
389 'extbase.' => array(
390 'controllerName' => 'foo',
391 ),
392 );
393 $this->subject->render($configuration);
394 }
395
396 /**
397 * @test
398 */
399 public function renderCallsStandardWrapForExtbaseControllerName() {
400 $this->addMockViewToSubject();
401 $this->contentObjectRenderer
402 ->expects($this->once())
403 ->method('stdWrap')
404 ->with('foo', array('bar' => 'baz'));
405 $configuration = array(
406 'extbase.' => array(
407 'controllerName' => 'foo',
408 'controllerName.' => array(
409 'bar' => 'baz',
410 ),
411 ),
412 );
413 $this->subject->render($configuration);
414 }
415
416 /**
417 * @test
418 */
419 public function renderSetsExtbaseControllerActionNameInRequest() {
420 $this->addMockViewToSubject();
421 $this->request
422 ->expects($this->once())
423 ->method('setControllerActionName')
424 ->with('foo');
425 $configuration = array(
426 'extbase.' => array(
427 'controllerActionName' => 'foo',
428 ),
429 );
430 $this->subject->render($configuration);
431 }
432
433 /**
434 * @test
435 */
436 public function renderCallsStandardWrapForExtbaseControllerActionName() {
437 $this->addMockViewToSubject();
438 $this->contentObjectRenderer
439 ->expects($this->once())
440 ->method('stdWrap')
441 ->with('foo', array('bar' => 'baz'));
442 $configuration = array(
443 'extbase.' => array(
444 'controllerActionName' => 'foo',
445 'controllerActionName.' => array(
446 'bar' => 'baz',
447 ),
448 ),
449 );
450 $this->subject->render($configuration);
451 }
452
453 /**
454 * @test
455 */
456 public function renderAssignsSettingsArrayToView() {
457 $this->addMockViewToSubject();
458
459 $configuration = array(
460 'settings.' => array(
461 'foo' => 'value',
462 'bar.' => array(
463 'baz' => 'value2',
464 ),
465 ),
466 );
467
468 $expectedSettingsToBeSet = array(
469 'foo' => 'value',
470 'bar' => array(
471 'baz' => 'value2',
472 ),
473 );
474
475 $typoScriptServiceMock = $this->getMock('TYPO3\\CMS\\Extbase\\Service\\TypoScriptService');
476 $typoScriptServiceMock
477 ->expects($this->once())
478 ->method('convertTypoScriptArrayToPlainArray')
479 ->with($configuration['settings.'])
480 ->will($this->returnValue($expectedSettingsToBeSet));
481 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Extbase\\Service\\TypoScriptService', $typoScriptServiceMock);
482
483 $this->standaloneView
484 ->expects($this->at(1))
485 ->method('assign')
486 ->with('settings', $expectedSettingsToBeSet);
487
488 $this->subject->render($configuration);
489 }
490
491 /**
492 * @test
493 * @expectedException \InvalidArgumentException
494 */
495 public function renderThrowsExceptionForNotAllowedVariableData() {
496 $this->addMockViewToSubject();
497 $configuration = array(
498 'variables.' => array(
499 'data' => 'foo',
500 'data.' => array(
501 'bar' => 'baz',
502 ),
503 ),
504 );
505 $this->subject->render($configuration);
506 }
507
508 /**
509 * @test
510 * @expectedException \InvalidArgumentException
511 */
512 public function renderThrowsExceptionForNotAllowedVariableCurrent() {
513 $this->addMockViewToSubject();
514 $configuration = array(
515 'variables.' => array(
516 'current' => 'foo',
517 'current.' => array(
518 'bar' => 'baz',
519 ),
520 ),
521 );
522 $this->subject->render($configuration);
523 }
524
525 /**
526 * @test
527 */
528 public function renderCallsCObjGetSingleForAllowedVariable() {
529 $this->addMockViewToSubject();
530 $configuration = array(
531 'variables.' => array(
532 'aVar' => 'TEXT',
533 'aVar.' => array(
534 'value' => 'foo',
535 ),
536 ),
537 );
538 $this->contentObjectRenderer
539 ->expects($this->once())
540 ->method('cObjGetSingle')
541 ->with('TEXT', array('value' => 'foo'));
542 $this->subject->render($configuration);
543 }
544
545 /**
546 * @test
547 */
548 public function renderAssignsRenderedContentObjectVariableToView() {
549 $this->addMockViewToSubject();
550 $configuration = array(
551 'variables.' => array(
552 'aVar' => 'TEXT',
553 'aVar.' => array(
554 'value' => 'foo',
555 ),
556 ),
557 );
558 $this->contentObjectRenderer
559 ->expects($this->once())
560 ->method('cObjGetSingle')
561 ->will($this->returnValue('foo'));
562 $this->standaloneView
563 ->expects($this->at(1))
564 ->method('assign')
565 ->with('aVar', 'foo');
566 $this->subject->render($configuration);
567 }
568
569 /**
570 * @test
571 */
572 public function renderAssignsContentObjectRendererDataToView() {
573 $this->addMockViewToSubject();
574 $this->contentObjectRenderer->data = array('foo');
575 $this->standaloneView
576 ->expects($this->at(1))
577 ->method('assign')
578 ->with('data', array('foo'));
579 $this->subject->render(array());
580 }
581
582 /**
583 * @test
584 */
585 public function renderAssignsContentObjectRendererCurrentValueToView() {
586 $this->addMockViewToSubject();
587 $this->contentObjectRenderer->data = array('currentKey' => 'currentValue');
588 $this->contentObjectRenderer->currentValKey= 'currentKey';
589 $this->standaloneView
590 ->expects($this->at(2))
591 ->method('assign')
592 ->with('current', 'currentValue');
593 $this->subject->render(array());
594 }
595
596 /**
597 * @test
598 */
599 public function renderCallsRenderOnStandaloneViewie() {
600 $this->addMockViewToSubject();
601 $this->standaloneView
602 ->expects($this->once())
603 ->method('render');
604 $this->subject->render(array());
605 }
606
607 /**
608 * @test
609 */
610 public function renderCallsStandardWrapOnResultStringIfGivenInConfiguration() {
611 $this->addMockViewToSubject();
612 $configuration = array(
613 'stdWrap.' => array(
614 'foo' => 'bar',
615 ),
616 );
617 $this->standaloneView
618 ->expects($this->any())
619 ->method('render')
620 ->will($this->returnValue('baz'));
621 $this->contentObjectRenderer
622 ->expects($this->once())
623 ->method('stdWrap')
624 ->with('baz', array('foo' => 'bar'));
625 $this->subject->render($configuration);
626 }
627 }