TYPO3  7.6
TemplateViewTest.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Fluid\Tests\Unit\View;
3 
4 /* *
5  * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6  * *
7  * It is free software; you can redistribute it and/or modify it under *
8  * the terms of the GNU Lesser General Public License, either version 3 *
9  * of the License, or (at your option) any later version. *
10  * *
11  * The TYPO3 project - inspiring people to share! *
12  * */
13 
14 include_once(__DIR__ . '/Fixtures/TransparentSyntaxTreeNode.php');
15 include_once(__DIR__ . '/Fixtures/TemplateViewFixture.php');
16 
17 use org\bovigo\vfs\vfsStreamWrapper;
20 use TYPO3\CMS\Core\Tests\AccessibleObjectInterface;
21 use TYPO3\CMS\Core\Tests\UnitTestCase;
24 use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
34 
38 class TemplateViewTest extends UnitTestCase
39 {
46  {
47  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'ViewHelpers_Widget', 'Paginate', 'html');
48  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
49  $templateView->_set('controllerContext', $mockControllerContext);
50  $expected = array(ExtensionManagementUtility::extPath('frontend') . 'Resources/Private/Templates/ViewHelpers/Widget/Paginate/@action.html');
51  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/@subpackage/@controller/@action.@format', false, false);
52  $this->assertEquals($expected, $actual);
53  }
54 
61  {
62  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'ViewHelpers\\Widget', 'Paginate', 'html');
63  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
64  $templateView->_set('controllerContext', $mockControllerContext);
65  $expected = array(ExtensionManagementUtility::extPath('frontend') . 'Resources/Private/Templates/ViewHelpers/Widget/Paginate/@action.html');
66  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/@subpackage/@controller/@action.@format', false, false);
67  $this->assertEquals($expected, $actual);
68  }
69 
79  protected function setupMockControllerContextForPathResolving($packageKey, $subPackageKey, $controllerName, $format)
80  {
81  $controllerObjectName = "TYPO3\\$packageKey\\" . ($subPackageKey != $subPackageKey . '\\' ? : '') . 'Controller\\' . $controllerName . 'Controller';
82  $mockRequest = $this->getMock(WebRequest::class);
83  $mockRequest->expects($this->any())->method('getControllerExtensionKey')->will($this->returnValue('frontend'));
84  $mockRequest->expects($this->any())->method('getControllerPackageKey')->will($this->returnValue($packageKey));
85  $mockRequest->expects($this->any())->method('getControllerSubPackageKey')->will($this->returnValue($subPackageKey));
86  $mockRequest->expects($this->any())->method('getControllerName')->will($this->returnValue($controllerName));
87  $mockRequest->expects($this->any())->method('getControllerObjectName')->will($this->returnValue($controllerObjectName));
88  $mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue($format));
89 
90  $mockControllerContext = $this->getMock(ControllerContext::class, array('getRequest'), array(), '', false);
91  $mockControllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($mockRequest));
92 
93  return $mockControllerContext;
94  }
95 
100  {
101  return array(
102  // bubbling controller & subpackage parts and optional format
103  array(
104  'package' => 'Some.Package',
105  'subPackage' => 'Some\\Sub\\Package',
106  'controller' => 'SomeController',
107  'format' => 'html',
108  'templateRootPath' => 'Resources/Private/Templates',
109  'templateRootPaths' => null,
110  'partialRootPath' => 'Resources/Private/Partials',
111  'partialRootPaths' => null,
112  'layoutRootPath' => 'Resources/Private/Layouts',
113  'layoutRootPaths' => null,
114  'bubbleControllerAndSubpackage' => true,
115  'formatIsOptional' => true,
116  'pattern' => '@templateRoot/@subpackage/@controller/@action.@format',
117  'expectedResult' => array(
118  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action.html',
119  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action',
120  'Resources/Private/Templates/Some/Sub/Package/@action.html',
121  'Resources/Private/Templates/Some/Sub/Package/@action',
122  'Resources/Private/Templates/Sub/Package/@action.html',
123  'Resources/Private/Templates/Sub/Package/@action',
124  'Resources/Private/Templates/Package/@action.html',
125  'Resources/Private/Templates/Package/@action',
126  'Resources/Private/Templates/@action.html',
127  'Resources/Private/Templates/@action',
128  )
129  ),
130  // just optional format
131  array(
132  'package' => 'Some.Package',
133  'subPackage' => 'Some\\Sub\\Package',
134  'controller' => 'SomeController',
135  'format' => 'html',
136  'templateRootPath' => 'Resources/Private/Templates/',
137  'templateRootPaths' => null,
138  'partialRootPath' => 'Resources/Private/Partials',
139  'partialRootPaths' => null,
140  'layoutRootPath' => 'Resources/Private/Layouts',
141  'layoutRootPaths' => null,
142  'bubbleControllerAndSubpackage' => false,
143  'formatIsOptional' => true,
144  'pattern' => '@templateRoot/@subpackage/@controller/@action.@format',
145  'expectedResult' => array(
146  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action.html',
147  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action',
148  )
149  ),
150  // just bubbling controller & subpackage parts
151  array(
152  'package' => 'Some.Package',
153  'subPackage' => 'Some\\Sub\\Package',
154  'controller' => 'SomeController',
155  'format' => 'json',
156  'templateRootPath' => 'Resources/Private/Templates',
157  'templateRootPaths' => null,
158  'partialRootPath' => 'Resources/Private/Partials',
159  'partialRootPaths' => null,
160  'layoutRootPath' => 'Resources/Private/Layouts',
161  'layoutRootPaths' => null,
162  'bubbleControllerAndSubpackage' => true,
163  'formatIsOptional' => false,
164  'pattern' => '@partialRoot/@subpackage/@controller/@action.@format',
165  'expectedResult' => array(
166  'Resources/Private/Partials/Some/Sub/Package/SomeController/@action.json',
167  'Resources/Private/Partials/Some/Sub/Package/@action.json',
168  'Resources/Private/Partials/Sub/Package/@action.json',
169  'Resources/Private/Partials/Package/@action.json',
170  'Resources/Private/Partials/@action.json',
171  )
172  ),
173  // layoutRootPath
174  array(
175  'package' => 'Some.Package',
176  'subPackage' => null,
177  'controller' => null,
178  'format' => 'xml',
179  'templateRootPath' => 'Resources/Private/Templates',
180  'templateRootPaths' => null,
181  'partialRootPath' => 'Resources/Private/Partials',
182  'partialRootPaths' => null,
183  'layoutRootPath' => 'Resources/Private/Layouts',
184  'layoutRootPaths' => null,
185  'bubbleControllerAndSubpackage' => true,
186  'formatIsOptional' => true,
187  'pattern' => '@layoutRoot/@subpackage/@controller/@action.@format',
188  'expectedResult' => array(
189  'Resources/Private/Layouts/@action.xml',
190  'Resources/Private/Layouts/@action',
191  )
192  ),
193  // partialRootPath
194  array(
195  'package' => 'Some.Package',
196  'subPackage' => 'Some\\Sub\\Package',
197  'controller' => null,
198  'format' => 'html',
199  'templateRootPath' => 'Resources/Private/Templates',
200  'templateRootPaths' => null,
201  'partialRootPath' => 'Resources/Private/Partials',
202  'partialRootPaths' => null,
203  'layoutRootPath' => 'Resources/Private/Layouts',
204  'layoutRootPaths' => null,
205  'bubbleControllerAndSubpackage' => true,
206  'formatIsOptional' => true,
207  'pattern' => '@templateRoot/@subpackage/@controller/@action.@format',
208  'expectedResult' => array(
209  'Resources/Private/Templates/Some/Sub/Package/@action.html',
210  'Resources/Private/Templates/Some/Sub/Package/@action',
211  'Resources/Private/Templates/Sub/Package/@action.html',
212  'Resources/Private/Templates/Sub/Package/@action',
213  'Resources/Private/Templates/Package/@action.html',
214  'Resources/Private/Templates/Package/@action',
215  'Resources/Private/Templates/@action.html',
216  'Resources/Private/Templates/@action',
217  )
218  ),
219  // optional format as directory name
220  array(
221  'package' => 'Some.Package',
222  'subPackage' => 'Some\\Sub\\Package',
223  'controller' => 'SomeController',
224  'format' => 'xml',
225  'templateRootPath' => 'Resources/Private/Templates_@format',
226  'templateRootPaths' => null,
227  'partialRootPath' => 'Resources/Private/Partials',
228  'partialRootPaths' => null,
229  'layoutRootPath' => 'Resources/Private/Layouts',
230  'layoutRootPaths' => null,
231  'bubbleControllerAndSubpackage' => false,
232  'formatIsOptional' => true,
233  'pattern' => '@templateRoot/@subpackage/@controller/@action',
234  'expectedResult' => array(
235  'Resources/Private/Templates_xml/Some/Sub/Package/SomeController/@action',
236  'Resources/Private/Templates_/Some/Sub/Package/SomeController/@action',
237  )
238  ),
239  // mandatory format as directory name
240  array(
241  'package' => 'Some.Package',
242  'subPackage' => 'Some\\Sub\\Package',
243  'controller' => 'SomeController',
244  'format' => 'json',
245  'templateRootPath' => 'Resources/Private/Templates_@format',
246  'templateRootPaths' => null,
247  'partialRootPath' => 'Resources/Private/Partials',
248  'partialRootPaths' => null,
249  'layoutRootPath' => 'Resources/Private/Layouts',
250  'layoutRootPaths' => null,
251  'bubbleControllerAndSubpackage' => false,
252  'formatIsOptional' => false,
253  'pattern' => '@templateRoot/@subpackage/@controller/@action',
254  'expectedResult' => array(
255  'Resources/Private/Templates_json/Some/Sub/Package/SomeController/@action',
256  )
257  ),
258  // paths must not contain double slashes
259  array(
260  'package' => 'Some.Package',
261  'subPackage' => null,
262  'controller' => 'SomeController',
263  'format' => 'html',
264  'templateRootPath' => 'Resources/Private/Templates',
265  'templateRootPaths' => null,
266  'partialRootPath' => 'Resources/Private/Partials',
267  'partialRootPaths' => null,
268  'layoutRootPath' => 'Some/Root/Path/',
269  'layoutRootPaths' => null,
270  'bubbleControllerAndSubpackage' => true,
271  'formatIsOptional' => true,
272  'pattern' => '@layoutRoot/@subpackage/@controller/@action.@format',
273  'expectedResult' => array(
274  'Some/Root/Path/SomeController/@action.html',
275  'Some/Root/Path/SomeController/@action',
276  'Some/Root/Path/@action.html',
277  'Some/Root/Path/@action',
278  )
279  ),
280  // paths must be unique
281  array(
282  'package' => 'Some.Package',
283  'subPackage' => 'Some\\Sub\\Package',
284  'controller' => 'SomeController',
285  'format' => 'json',
286  'templateRootPath' => 'Resources/Private/Templates',
287  'templateRootPaths' => null,
288  'partialRootPath' => 'Resources/Private/Partials',
289  'partialRootPaths' => null,
290  'layoutRootPath' => 'Resources/Private/Layouts',
291  'layoutRootPaths' => null,
292  'bubbleControllerAndSubpackage' => true,
293  'formatIsOptional' => false,
294  'pattern' => 'foo',
295  'expectedResult' => array(
296  'foo',
297  )
298  ),
299  // template fallback paths
300  array(
301  'package' => 'Some.Package',
302  'subPackage' => 'Some\\Sub\\Package',
303  'controller' => 'SomeController',
304  'format' => 'html',
305  'templateRootPath' => 'Resources/Private/Templates',
306  'templateRootPaths' => array('Resources/Private/Templates', 'Some/Fallback/Path'),
307  'partialRootPath' => 'Resources/Private/Partials',
308  'partialRootPaths' => null,
309  'layoutRootPath' => 'Resources/Private/Layouts',
310  'layoutRootPaths' => null,
311  'bubbleControllerAndSubpackage' => false,
312  'formatIsOptional' => true,
313  'pattern' => '@templateRoot/@subpackage/@controller/@action.@format',
314  'expectedResult' => array(
315  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action.html',
316  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action',
317  'Some/Fallback/Path/Some/Sub/Package/SomeController/@action.html',
318  'Some/Fallback/Path/Some/Sub/Package/SomeController/@action',
319  )
320  ),
321  // template fallback paths with bubbleControllerAndSubpackage
322  array(
323  'package' => 'Some.Package',
324  'subPackage' => 'Some\\Sub\\Package',
325  'controller' => 'SomeController',
326  'format' => 'html',
327  'templateRootPath' => 'Resources/Private/Templates',
328  'templateRootPaths' => array('Resources/Private/Templates', 'Some/Fallback/Path'),
329  'partialRootPath' => 'Resources/Private/Partials',
330  'partialRootPaths' => null,
331  'layoutRootPath' => 'Resources/Private/Layouts',
332  'layoutRootPaths' => null,
333  'bubbleControllerAndSubpackage' => true,
334  'formatIsOptional' => false,
335  'pattern' => '@templateRoot/@subpackage/@controller/@action.@format',
336  'expectedResult' => array(
337  'Resources/Private/Templates/Some/Sub/Package/SomeController/@action.html',
338  'Resources/Private/Templates/Some/Sub/Package/@action.html',
339  'Resources/Private/Templates/Sub/Package/@action.html',
340  'Resources/Private/Templates/Package/@action.html',
341  'Resources/Private/Templates/@action.html',
342  'Some/Fallback/Path/Some/Sub/Package/SomeController/@action.html',
343  'Some/Fallback/Path/Some/Sub/Package/@action.html',
344  'Some/Fallback/Path/Sub/Package/@action.html',
345  'Some/Fallback/Path/Package/@action.html',
346  'Some/Fallback/Path/@action.html',
347  )
348  ),
349  // partial fallback paths
350  array(
351  'package' => 'Some.Package',
352  'subPackage' => 'Some\\Sub\\Package',
353  'controller' => 'SomeController',
354  'format' => 'html',
355  'templateRootPath' => 'Resources/Private/Templates',
356  'templateRootPaths' => null,
357  'partialRootPath' => 'Resources/Private/Partials',
358  'partialRootPaths' => array('Default/Resources/Path', 'Fallback/'),
359  'layoutRootPath' => 'Resources/Private/Layouts',
360  'layoutRootPaths' => null,
361  'bubbleControllerAndSubpackage' => false,
362  'formatIsOptional' => true,
363  'pattern' => '@partialRoot/@subpackage/@controller/@partial.@format',
364  'expectedResult' => array(
365  'Default/Resources/Path/Some/Sub/Package/SomeController/@partial.html',
366  'Default/Resources/Path/Some/Sub/Package/SomeController/@partial',
367  'Fallback/Some/Sub/Package/SomeController/@partial.html',
368  'Fallback/Some/Sub/Package/SomeController/@partial',
369  )
370  ),
371  // partial fallback paths with bubbleControllerAndSubpackage
372  array(
373  'package' => 'Some.Package',
374  'subPackage' => 'Some\\Sub\\Package',
375  'controller' => 'SomeController',
376  'format' => 'html',
377  'templateRootPath' => 'Resources/Private/Templates',
378  'templateRootPaths' => array('Resources/Private/Templates', 'Some/Fallback/Path'),
379  'partialRootPath' => 'Resources/Private/Partials',
380  'partialRootPaths' => array('Default/Resources/Path', 'Fallback1/', 'Fallback2'),
381  'layoutRootPath' => 'Resources/Private/Layouts',
382  'layoutRootPaths' => null,
383  'bubbleControllerAndSubpackage' => true,
384  'formatIsOptional' => true,
385  'pattern' => '@partialRoot/@controller/@subpackage/@partial',
386  'expectedResult' => array(
387  'Default/Resources/Path/SomeController/Some/Sub/Package/@partial',
388  'Default/Resources/Path/Some/Sub/Package/@partial',
389  'Default/Resources/Path/Sub/Package/@partial',
390  'Default/Resources/Path/Package/@partial',
391  'Default/Resources/Path/@partial',
392  'Fallback1/SomeController/Some/Sub/Package/@partial',
393  'Fallback1/Some/Sub/Package/@partial',
394  'Fallback1/Sub/Package/@partial',
395  'Fallback1/Package/@partial',
396  'Fallback1/@partial',
397  'Fallback2/SomeController/Some/Sub/Package/@partial',
398  'Fallback2/Some/Sub/Package/@partial',
399  'Fallback2/Sub/Package/@partial',
400  'Fallback2/Package/@partial',
401  'Fallback2/@partial',
402  )
403  ),
404  // layout fallback paths
405  array(
406  'package' => 'Some.Package',
407  'subPackage' => 'Some\\Sub\\Package',
408  'controller' => 'SomeController',
409  'format' => 'html',
410  'templateRootPath' => 'Resources/Private/Templates',
411  'templateRootPaths' => array('Resources/Private/Templates', 'Some/Fallback/Path'),
412  'partialRootPath' => 'Resources/Private/Partials',
413  'partialRootPaths' => array('foo', 'bar'),
414  'layoutRootPath' => 'Resources/Private/Layouts',
415  'layoutRootPaths' => array('Default/Layout/Path', 'Fallback/Path'),
416  'bubbleControllerAndSubpackage' => false,
417  'formatIsOptional' => false,
418  'pattern' => '@layoutRoot/@subpackage/@controller/@layout.@format',
419  'expectedResult' => array(
420  'Default/Layout/Path/Some/Sub/Package/SomeController/@layout.html',
421  'Fallback/Path/Some/Sub/Package/SomeController/@layout.html',
422  )
423  ),
424  // layout fallback paths with bubbleControllerAndSubpackage
425  array(
426  'package' => 'Some.Package',
427  'subPackage' => 'Some\\Sub\\Package',
428  'controller' => 'SomeController',
429  'format' => 'html',
430  'templateRootPath' => 'Resources/Private/Templates',
431  'templateRootPaths' => null,
432  'partialRootPath' => 'Resources/Private/Partials',
433  'partialRootPaths' => null,
434  'layoutRootPath' => 'Resources/Private/Layouts',
435  'layoutRootPaths' => array('Resources/Layouts', 'Some/Fallback/Path'),
436  'bubbleControllerAndSubpackage' => true,
437  'formatIsOptional' => true,
438  'pattern' => 'Static/@layoutRoot/@subpackage/@controller/@layout.@format',
439  'expectedResult' => array(
440  'Static/Resources/Layouts/Some/Sub/Package/SomeController/@layout.html',
441  'Static/Resources/Layouts/Some/Sub/Package/SomeController/@layout',
442  'Static/Resources/Layouts/Some/Sub/Package/@layout.html',
443  'Static/Resources/Layouts/Some/Sub/Package/@layout',
444  'Static/Resources/Layouts/Sub/Package/@layout.html',
445  'Static/Resources/Layouts/Sub/Package/@layout',
446  'Static/Resources/Layouts/Package/@layout.html',
447  'Static/Resources/Layouts/Package/@layout',
448  'Static/Resources/Layouts/@layout.html',
449  'Static/Resources/Layouts/@layout',
450  'Static/Some/Fallback/Path/Some/Sub/Package/SomeController/@layout.html',
451  'Static/Some/Fallback/Path/Some/Sub/Package/SomeController/@layout',
452  'Static/Some/Fallback/Path/Some/Sub/Package/@layout.html',
453  'Static/Some/Fallback/Path/Some/Sub/Package/@layout',
454  'Static/Some/Fallback/Path/Sub/Package/@layout.html',
455  'Static/Some/Fallback/Path/Sub/Package/@layout',
456  'Static/Some/Fallback/Path/Package/@layout.html',
457  'Static/Some/Fallback/Path/Package/@layout',
458  'Static/Some/Fallback/Path/@layout.html',
459  'Static/Some/Fallback/Path/@layout',
460  )
461  ),
462  // combined fallback paths
463  array(
464  'package' => 'Some.Package',
465  'subPackage' => 'Some\\Sub\\Package',
466  'controller' => 'SomeController',
467  'format' => 'html',
468  'templateRootPath' => 'Resources/Private/Templates',
469  'templateRootPaths' => array('Resources/Templates', 'Templates/Fallback1', 'Templates/Fallback2'),
470  'partialRootPath' => 'Resources/Private/Partials',
471  'partialRootPaths' => array('Resources/Partials'),
472  'layoutRootPath' => 'Resources/Private/Layouts',
473  'layoutRootPaths' => array('Resources/Layouts', 'Layouts/Fallback1'),
474  'bubbleControllerAndSubpackage' => false,
475  'formatIsOptional' => true,
476  'pattern' => '@layoutRoot/@templateRoot/@partialRoot/@subpackage/@controller/foo',
477  'expectedResult' => array(
478  'Resources/Layouts/Resources/Templates/Resources/Partials/Some/Sub/Package/SomeController/foo',
479  'Layouts/Fallback1/Resources/Templates/Resources/Partials/Some/Sub/Package/SomeController/foo',
480  'Resources/Layouts/Templates/Fallback1/Resources/Partials/Some/Sub/Package/SomeController/foo',
481  'Layouts/Fallback1/Templates/Fallback1/Resources/Partials/Some/Sub/Package/SomeController/foo',
482  'Resources/Layouts/Templates/Fallback2/Resources/Partials/Some/Sub/Package/SomeController/foo',
483  'Layouts/Fallback1/Templates/Fallback2/Resources/Partials/Some/Sub/Package/SomeController/foo',
484  )
485  ),
486  );
487  }
488 
508  public function expandGenericPathPatternTests($package, $subPackage, $controller, $format, $templateRootPath, array $templateRootPaths = null, $partialRootPath, array $partialRootPaths = null, $layoutRootPath, array $layoutRootPaths = null, $bubbleControllerAndSubpackage, $formatIsOptional, $pattern, $expectedResult)
509  {
510  $mockControllerContext = $this->setupMockControllerContextForPathResolving($package, $subPackage, $controller, $format);
511 
513  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
514  $templateView->setControllerContext($mockControllerContext);
515  if ($templateRootPath !== null) {
516  $templateView->setTemplateRootPath($templateRootPath);
517  }
518  if ($templateRootPaths !== null) {
519  $templateView->setTemplateRootPaths($templateRootPaths);
520  }
521 
522  if ($partialRootPath !== null) {
523  $templateView->setPartialRootPath($partialRootPath);
524  }
525  if ($partialRootPaths !== null) {
526  $templateView->setPartialRootPaths($partialRootPaths);
527  }
528 
529  if ($layoutRootPath !== null) {
530  $templateView->setLayoutRootPath($layoutRootPath);
531  }
532  if ($layoutRootPaths !== null) {
533  $templateView->setLayoutRootPaths($layoutRootPaths);
534  }
535 
536  $actualResult = $templateView->_call('expandGenericPathPattern', $pattern, $bubbleControllerAndSubpackage, $formatIsOptional);
537  $this->assertEquals($expectedResult, $actualResult);
538  }
539 
544  {
545  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', null, 'My', 'html');
546 
547  $templateView = $this->getAccessibleMock(TemplateView::class, array('getTemplateRootPaths'), array(), '', false);
548  $templateView->_set('controllerContext', $mockControllerContext);
549  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(array('Resources/Private/')));
550 
551  $expected = array('Resources/Private/Templates/My/@action.html');
552  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', false, false);
553  $this->assertEquals($expected, $actual);
554  }
555 
556 
561  {
562  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
563 
564  $templateView = $this->getAccessibleMock(TemplateView::class, array('getTemplateRootPaths'), array(), '', false);
565  $templateView->_set('controllerContext', $mockControllerContext);
566  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(array('Resources/Private/')));
567  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', false, false);
568 
569  $expected = array(
570  'Resources/Private/Templates/MySubPackage/My/@action.html'
571  );
572  $this->assertEquals($expected, $actual);
573  }
574 
579  {
580  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
581 
582  $templateView = $this->getAccessibleMock(TemplateView::class, array('getTemplateRootPaths'), array(), '', false);
583  $templateView->_set('controllerContext', $mockControllerContext);
584  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(array('Resources/Private/')));
585  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', false, true);
586 
587  $expected = array(
588  'Resources/Private/Templates/MySubPackage/My/@action.html',
589  'Resources/Private/Templates/MySubPackage/My/@action'
590  );
591  $this->assertEquals($expected, $actual);
592  }
593 
598  {
599  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
600 
601  $templateView = $this->getAccessibleMock(TemplateView::class, array('getTemplateRootPaths'), array(), '', false);
602  $templateView->_set('controllerContext', $mockControllerContext);
603  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(array('Resources/Private/')));
604  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', true, true);
605 
606  $expected = array(
607  'Resources/Private/Templates/MySubPackage/My/@action.html',
608  'Resources/Private/Templates/MySubPackage/My/@action',
609  'Resources/Private/Templates/MySubPackage/@action.html',
610  'Resources/Private/Templates/MySubPackage/@action',
611  'Resources/Private/Templates/@action.html',
612  'Resources/Private/Templates/@action'
613  );
614  $this->assertEquals($expected, $actual);
615  }
616 
620  public function getTemplateRootPathsReturnsUserSpecifiedTemplatePaths()
621  {
623  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
624  $templateView->setTemplateRootPath('/foo/bar');
625  $expected = array('/foo/bar');
626  $actual = $templateView->_call('getTemplateRootPaths');
627  $this->assertEquals($expected, $actual, 'A set template root path was not returned correctly.');
628  }
629 
633  public function setTemplateRootPathOverrulesSetTemplateRootPaths()
634  {
636  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
637  $templateView->setTemplateRootPath('/foo/bar');
638  $templateView->setTemplateRootPaths(array('/overruled/path'));
639  $expected = array('/overruled/path');
640  $actual = $templateView->_call('getTemplateRootPaths');
641  $this->assertEquals($expected, $actual, 'A set template root path was not returned correctly.');
642  }
643 
647  public function getPartialRootPathsReturnsUserSpecifiedPartialPath()
648  {
650  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
651  $templateView->setPartialRootPath('/foo/bar');
652  $expected = array('/foo/bar');
653  $actual = $templateView->_call('getPartialRootPaths');
654  $this->assertEquals($expected, $actual, 'A set partial root path was not returned correctly.');
655  }
656 
660  public function getLayoutRootPathsReturnsUserSpecifiedPartialPath()
661  {
663  $templateView = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', false);
664  $templateView->setLayoutRootPath('/foo/bar');
665  $expected = array('/foo/bar');
666  $actual = $templateView->_call('getLayoutRootPaths');
667  $this->assertEquals($expected, $actual, 'A set partial root path was not returned correctly.');
668  }
669 
673  public function pathToPartialIsResolvedCorrectly()
674  {
675  vfsStreamWrapper::register();
676  mkdir('vfs://MyPartials');
677  \file_put_contents('vfs://MyPartials/SomePartial', 'contentsOfSomePartial');
678 
679  $paths = array(
680  'vfs://NonExistentDir/UnknowFile.html',
681  'vfs://MyPartials/SomePartial.html',
682  'vfs://MyPartials/SomePartial'
683  );
684 
686  $templateView = $this->getAccessibleMock(TemplateView::class, array('expandGenericPathPattern', 'resolveFileNamePath'), array(), '', false);
687  $templateView->expects($this->once())->method('expandGenericPathPattern')->with('@partialRoot/@subpackage/@partial.@format', true, true)->will($this->returnValue($paths));
688  $templateView->expects($this->any())->method('resolveFileNamePath')->will($this->onConsecutiveCalls(
689  $paths[0],
690  $paths[1],
691  $paths[2]
692  ));
693 
694  $templateView->setTemplateRootPath('MyTemplates');
695  $templateView->setPartialRootPath('MyPartials');
696  $templateView->setLayoutRootPath('MyLayouts');
697 
698  $this->assertSame('contentsOfSomePartial', $templateView->_call('getPartialSource', 'SomePartial'));
699  }
700 
704  public function resolveTemplatePathAndFilenameChecksDifferentPathPatternsAndReturnsTheFirstPathWhichExists()
705  {
706  vfsStreamWrapper::register();
707  mkdir('vfs://MyTemplates');
708  \file_put_contents('vfs://MyTemplates/MyCoolAction.html', 'contentsOfMyCoolAction');
709 
710  $paths = array(
711  'vfs://NonExistentDir/UnknownFile.html',
712  'vfs://MyTemplates/@action.html'
713  );
714 
716  $templateView = $this->getAccessibleMock(TemplateView::class, array('expandGenericPathPattern', 'resolveFileNamePath'), array(), '', false);
717  $templateView->expects($this->once())->method('expandGenericPathPattern')->with('@templateRoot/@subpackage/@controller/@action.@format', false, false)->will($this->returnValue($paths));
718  $templateView->expects($this->any())->method('resolveFileNamePath')->will($this->onConsecutiveCalls(
719  $paths[0],
720  'vfs://MyTemplates/MyCoolAction.html'
721  ));
722 
723  $templateView->setTemplateRootPath('MyTemplates');
724  $templateView->setPartialRootPath('MyPartials');
725  $templateView->setLayoutRootPath('MyLayouts');
726 
727  $this->assertSame('contentsOfMyCoolAction', $templateView->_call('getTemplateSource', 'myCoolAction'));
728  }
729 
734  {
735  vfsStreamWrapper::register();
736  mkdir('vfs://MyTemplates');
737  \file_put_contents('vfs://MyTemplates/MyCoolAction.html', 'contentsOfMyCoolAction');
738 
739  $templateView = $this->getAccessibleMock(TemplateView::class, array('resolveFileNamePath'), array(), '', false);
740  $templateView->expects($this->any())->method('resolveFileNamePath')->willReturnArgument(0);
741  $templateView->_set('templatePathAndFilename', 'vfs://MyTemplates/MyCoolAction.html');
742 
743  $this->assertSame('contentsOfMyCoolAction', $templateView->_call('getTemplateSource'));
744  }
745 
749  public function getLayoutPathAndFilenameRespectsCasingOfLayoutName()
750  {
751  $singletonInstances = GeneralUtility::getSingletonInstances();
752 
753  $mockParsedTemplate = $this->getMock(ParsedTemplateInterface::class);
754  $mockTemplateParser = $this->getMock(TemplateParser::class);
755  $mockTemplateParser->expects($this->any())->method('parse')->will($this->returnValue($mockParsedTemplate));
756 
758  $mockObjectManager = $this->getMock(ObjectManager::class);
759  $mockObjectManager->expects($this->any())->method('get')->will($this->returnCallback(array($this, 'objectManagerCallback')));
760 
761  $mockRequest = $this->getMock(WebRequest::class);
762  $mockControllerContext = $this->getMock(ControllerContext::class);
763  $mockControllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($mockRequest));
764 
765  $mockViewHelperVariableContainer = $this->getMock(ViewHelperVariableContainer::class);
767  $mockRenderingContext = $this->getMock(RenderingContext::class);
768  $mockRenderingContext->expects($this->any())->method('getControllerContext')->will($this->returnValue($mockControllerContext));
769  $mockRenderingContext->expects($this->any())->method('getViewHelperVariableContainer')->will($this->returnValue($mockViewHelperVariableContainer));
770 
772  $view = $this->getAccessibleMock(TemplateView::class, array('testFileExistence', 'buildParserConfiguration'), array(), '', false);
773  $view->_set('templateParser', $mockTemplateParser);
774  $view->_set('objectManager', $mockObjectManager);
775  $view->setRenderingContext($mockRenderingContext);
776 
777  $mockTemplateCompiler = $this->getMock(TemplateCompiler::class);
778  $view->_set('templateCompiler', $mockTemplateCompiler);
779  GeneralUtility::setSingletonInstance(ObjectManager::class, $mockObjectManager);
780  $mockContentObject = $this->getMock(ContentObjectRenderer::class);
781  GeneralUtility::addInstance(ContentObjectRenderer::class, $mockContentObject);
782 
784  $mockCacheManager = $this->getMock(CacheManager::class, array(), array(), '', false);
785  $mockCache = $this->getMock(PhpFrontend::class, array(), array(), '', false);
786  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
787  GeneralUtility::setSingletonInstance(CacheManager::class, $mockCacheManager);
788 
789  $mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
790  $view->setLayoutRootPaths(array('some/Default/Directory'));
791  $view->setTemplateRootPaths(array('some/Default/Directory'));
792  $view->setPartialRootPaths(array('some/Default/Directory'));
793  $view->expects($this->at(0))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/LayoutName.html')->willReturn(false);
794  $view->expects($this->at(1))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/layoutName.html')->willReturn(true);
795  $this->assertSame(PATH_site . 'some/Default/Directory/layoutName.html', $view->_call('getLayoutPathAndFilename', 'layoutName'));
796 
798  GeneralUtility::resetSingletonInstances($singletonInstances);
799  }
800 }