TYPO3 CMS  TYPO3_7-6
TemplateViewTest.php
Go to the documentation of this file.
1 <?php
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 
34 
39 {
46  {
47  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'ViewHelpers_Widget', 'Paginate', 'html');
48  $templateView = $this->getAccessibleMock(TemplateView::class, ['dummy'], [], '', false);
49  $templateView->_set('controllerContext', $mockControllerContext);
50  $expected = [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, ['dummy'], [], '', false);
64  $templateView->_set('controllerContext', $mockControllerContext);
65  $expected = [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, ['getRequest'], [], '', false);
91  $mockControllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($mockRequest));
92 
93  return $mockControllerContext;
94  }
95 
100  {
101  return [
102  // bubbling controller & subpackage parts and optional format
103  [
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' => [
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  [
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' => [
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  [
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' => [
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  [
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' => [
189  'Resources/Private/Layouts/@action.xml',
190  'Resources/Private/Layouts/@action',
191  ]
192  ],
193  // partialRootPath
194  [
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' => [
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  [
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' => [
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  [
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' => [
255  'Resources/Private/Templates_json/Some/Sub/Package/SomeController/@action',
256  ]
257  ],
258  // paths must not contain double slashes
259  [
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' => [
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  [
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' => [
296  'foo',
297  ]
298  ],
299  // template fallback paths
300  [
301  'package' => 'Some.Package',
302  'subPackage' => 'Some\\Sub\\Package',
303  'controller' => 'SomeController',
304  'format' => 'html',
305  'templateRootPath' => 'Resources/Private/Templates',
306  'templateRootPaths' => ['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' => [
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  [
323  'package' => 'Some.Package',
324  'subPackage' => 'Some\\Sub\\Package',
325  'controller' => 'SomeController',
326  'format' => 'html',
327  'templateRootPath' => 'Resources/Private/Templates',
328  'templateRootPaths' => ['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' => [
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  [
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' => ['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' => [
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  [
373  'package' => 'Some.Package',
374  'subPackage' => 'Some\\Sub\\Package',
375  'controller' => 'SomeController',
376  'format' => 'html',
377  'templateRootPath' => 'Resources/Private/Templates',
378  'templateRootPaths' => ['Resources/Private/Templates', 'Some/Fallback/Path'],
379  'partialRootPath' => 'Resources/Private/Partials',
380  'partialRootPaths' => ['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' => [
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  [
406  'package' => 'Some.Package',
407  'subPackage' => 'Some\\Sub\\Package',
408  'controller' => 'SomeController',
409  'format' => 'html',
410  'templateRootPath' => 'Resources/Private/Templates',
411  'templateRootPaths' => ['Resources/Private/Templates', 'Some/Fallback/Path'],
412  'partialRootPath' => 'Resources/Private/Partials',
413  'partialRootPaths' => ['foo', 'bar'],
414  'layoutRootPath' => 'Resources/Private/Layouts',
415  'layoutRootPaths' => ['Default/Layout/Path', 'Fallback/Path'],
416  'bubbleControllerAndSubpackage' => false,
417  'formatIsOptional' => false,
418  'pattern' => '@layoutRoot/@subpackage/@controller/@layout.@format',
419  'expectedResult' => [
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  [
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' => ['Resources/Layouts', 'Some/Fallback/Path'],
436  'bubbleControllerAndSubpackage' => true,
437  'formatIsOptional' => true,
438  'pattern' => 'Static/@layoutRoot/@subpackage/@controller/@layout.@format',
439  'expectedResult' => [
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  [
464  'package' => 'Some.Package',
465  'subPackage' => 'Some\\Sub\\Package',
466  'controller' => 'SomeController',
467  'format' => 'html',
468  'templateRootPath' => 'Resources/Private/Templates',
469  'templateRootPaths' => ['Resources/Templates', 'Templates/Fallback1', 'Templates/Fallback2'],
470  'partialRootPath' => 'Resources/Private/Partials',
471  'partialRootPaths' => ['Resources/Partials'],
472  'layoutRootPath' => 'Resources/Private/Layouts',
473  'layoutRootPaths' => ['Resources/Layouts', 'Layouts/Fallback1'],
474  'bubbleControllerAndSubpackage' => false,
475  'formatIsOptional' => true,
476  'pattern' => '@layoutRoot/@templateRoot/@partialRoot/@subpackage/@controller/foo',
477  'expectedResult' => [
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, ['dummy'], [], '', 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, ['getTemplateRootPaths'], [], '', false);
548  $templateView->_set('controllerContext', $mockControllerContext);
549  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(['Resources/Private/']));
550 
551  $expected = ['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 
560  {
561  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
562 
563  $templateView = $this->getAccessibleMock(TemplateView::class, ['getTemplateRootPaths'], [], '', false);
564  $templateView->_set('controllerContext', $mockControllerContext);
565  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(['Resources/Private/']));
566  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', false, false);
567 
568  $expected = [
569  'Resources/Private/Templates/MySubPackage/My/@action.html'
570  ];
571  $this->assertEquals($expected, $actual);
572  }
573 
578  {
579  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
580 
581  $templateView = $this->getAccessibleMock(TemplateView::class, ['getTemplateRootPaths'], [], '', false);
582  $templateView->_set('controllerContext', $mockControllerContext);
583  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(['Resources/Private/']));
584  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', false, true);
585 
586  $expected = [
587  'Resources/Private/Templates/MySubPackage/My/@action.html',
588  'Resources/Private/Templates/MySubPackage/My/@action'
589  ];
590  $this->assertEquals($expected, $actual);
591  }
592 
597  {
598  $mockControllerContext = $this->setupMockControllerContextForPathResolving('MyPackage', 'MySubPackage', 'My', 'html');
599 
600  $templateView = $this->getAccessibleMock(TemplateView::class, ['getTemplateRootPaths'], [], '', false);
601  $templateView->_set('controllerContext', $mockControllerContext);
602  $templateView->expects($this->any())->method('getTemplateRootPaths')->will($this->returnValue(['Resources/Private/']));
603  $actual = $templateView->_call('expandGenericPathPattern', '@templateRoot/Templates/@subpackage/@controller/@action.@format', true, true);
604 
605  $expected = [
606  'Resources/Private/Templates/MySubPackage/My/@action.html',
607  'Resources/Private/Templates/MySubPackage/My/@action',
608  'Resources/Private/Templates/MySubPackage/@action.html',
609  'Resources/Private/Templates/MySubPackage/@action',
610  'Resources/Private/Templates/@action.html',
611  'Resources/Private/Templates/@action'
612  ];
613  $this->assertEquals($expected, $actual);
614  }
615 
619  public function getTemplateRootPathsReturnsUserSpecifiedTemplatePaths()
620  {
622  $templateView = $this->getAccessibleMock(TemplateView::class, ['dummy'], [], '', false);
623  $templateView->setTemplateRootPath('/foo/bar');
624  $expected = ['/foo/bar'];
625  $actual = $templateView->_call('getTemplateRootPaths');
626  $this->assertEquals($expected, $actual, 'A set template root path was not returned correctly.');
627  }
628 
632  public function setTemplateRootPathOverrulesSetTemplateRootPaths()
633  {
635  $templateView = $this->getAccessibleMock(TemplateView::class, ['dummy'], [], '', false);
636  $templateView->setTemplateRootPath('/foo/bar');
637  $templateView->setTemplateRootPaths(['/overruled/path']);
638  $expected = ['/overruled/path'];
639  $actual = $templateView->_call('getTemplateRootPaths');
640  $this->assertEquals($expected, $actual, 'A set template root path was not returned correctly.');
641  }
642 
646  public function getPartialRootPathsReturnsUserSpecifiedPartialPath()
647  {
649  $templateView = $this->getAccessibleMock(TemplateView::class, ['dummy'], [], '', false);
650  $templateView->setPartialRootPath('/foo/bar');
651  $expected = ['/foo/bar'];
652  $actual = $templateView->_call('getPartialRootPaths');
653  $this->assertEquals($expected, $actual, 'A set partial root path was not returned correctly.');
654  }
655 
659  public function getLayoutRootPathsReturnsUserSpecifiedPartialPath()
660  {
662  $templateView = $this->getAccessibleMock(TemplateView::class, ['dummy'], [], '', false);
663  $templateView->setLayoutRootPath('/foo/bar');
664  $expected = ['/foo/bar'];
665  $actual = $templateView->_call('getLayoutRootPaths');
666  $this->assertEquals($expected, $actual, 'A set partial root path was not returned correctly.');
667  }
668 
672  public function pathToPartialIsResolvedCorrectly()
673  {
674  vfsStreamWrapper::register();
675  mkdir('vfs://MyPartials');
676  \file_put_contents('vfs://MyPartials/SomePartial', 'contentsOfSomePartial');
677 
678  $paths = [
679  'vfs://NonExistentDir/UnknowFile.html',
680  'vfs://MyPartials/SomePartial.html',
681  'vfs://MyPartials/SomePartial'
682  ];
683 
685  $templateView = $this->getAccessibleMock(TemplateView::class, ['expandGenericPathPattern', 'resolveFileNamePath'], [], '', false);
686  $templateView->expects($this->once())->method('expandGenericPathPattern')->with('@partialRoot/@subpackage/@partial.@format', true, true)->will($this->returnValue($paths));
687  $templateView->expects($this->any())->method('resolveFileNamePath')->will($this->onConsecutiveCalls(
688  $paths[0],
689  $paths[1],
690  $paths[2]
691  ));
692 
693  $templateView->setTemplateRootPath('MyTemplates');
694  $templateView->setPartialRootPath('MyPartials');
695  $templateView->setLayoutRootPath('MyLayouts');
696 
697  $this->assertSame('contentsOfSomePartial', $templateView->_call('getPartialSource', 'SomePartial'));
698  }
699 
703  public function resolveTemplatePathAndFilenameChecksDifferentPathPatternsAndReturnsTheFirstPathWhichExists()
704  {
705  vfsStreamWrapper::register();
706  mkdir('vfs://MyTemplates');
707  \file_put_contents('vfs://MyTemplates/MyCoolAction.html', 'contentsOfMyCoolAction');
708 
709  $paths = [
710  'vfs://NonExistentDir/UnknownFile.html',
711  'vfs://MyTemplates/@action.html'
712  ];
713 
715  $templateView = $this->getAccessibleMock(TemplateView::class, ['expandGenericPathPattern', 'resolveFileNamePath'], [], '', false);
716  $templateView->expects($this->once())->method('expandGenericPathPattern')->with('@templateRoot/@subpackage/@controller/@action.@format', false, false)->will($this->returnValue($paths));
717  $templateView->expects($this->any())->method('resolveFileNamePath')->will($this->onConsecutiveCalls(
718  $paths[0],
719  'vfs://MyTemplates/MyCoolAction.html'
720  ));
721 
722  $templateView->setTemplateRootPath('MyTemplates');
723  $templateView->setPartialRootPath('MyPartials');
724  $templateView->setLayoutRootPath('MyLayouts');
725 
726  $this->assertSame('contentsOfMyCoolAction', $templateView->_call('getTemplateSource', 'myCoolAction'));
727  }
728 
733  {
734  vfsStreamWrapper::register();
735  mkdir('vfs://MyTemplates');
736  \file_put_contents('vfs://MyTemplates/MyCoolAction.html', 'contentsOfMyCoolAction');
737 
738  $templateView = $this->getAccessibleMock(TemplateView::class, ['resolveFileNamePath'], [], '', false);
739  $templateView->expects($this->any())->method('resolveFileNamePath')->willReturnArgument(0);
740  $templateView->_set('templatePathAndFilename', 'vfs://MyTemplates/MyCoolAction.html');
741 
742  $this->assertSame('contentsOfMyCoolAction', $templateView->_call('getTemplateSource'));
743  }
744 
748  public function getLayoutPathAndFilenameRespectsCasingOfLayoutName()
749  {
750  $singletonInstances = GeneralUtility::getSingletonInstances();
751 
752  $mockParsedTemplate = $this->getMock(ParsedTemplateInterface::class);
753  $mockTemplateParser = $this->getMock(TemplateParser::class);
754  $mockTemplateParser->expects($this->any())->method('parse')->will($this->returnValue($mockParsedTemplate));
755 
757  $mockObjectManager = $this->getMock(ObjectManager::class);
758  $mockObjectManager->expects($this->any())->method('get')->will($this->returnCallback([$this, 'objectManagerCallback']));
759 
760  $mockRequest = $this->getMock(WebRequest::class);
761  $mockControllerContext = $this->getMock(ControllerContext::class);
762  $mockControllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($mockRequest));
763 
764  $mockViewHelperVariableContainer = $this->getMock(ViewHelperVariableContainer::class);
766  $mockRenderingContext = $this->getMock(RenderingContext::class);
767  $mockRenderingContext->expects($this->any())->method('getControllerContext')->will($this->returnValue($mockControllerContext));
768  $mockRenderingContext->expects($this->any())->method('getViewHelperVariableContainer')->will($this->returnValue($mockViewHelperVariableContainer));
769 
771  $view = $this->getAccessibleMock(TemplateView::class, ['testFileExistence', 'buildParserConfiguration'], [], '', false);
772  $view->_set('templateParser', $mockTemplateParser);
773  $view->_set('objectManager', $mockObjectManager);
774  $view->setRenderingContext($mockRenderingContext);
775 
776  $mockTemplateCompiler = $this->getMock(TemplateCompiler::class);
777  $view->_set('templateCompiler', $mockTemplateCompiler);
778  GeneralUtility::setSingletonInstance(ObjectManager::class, $mockObjectManager);
779  $mockContentObject = $this->getMock(ContentObjectRenderer::class);
780  GeneralUtility::addInstance(ContentObjectRenderer::class, $mockContentObject);
781 
783  $mockCacheManager = $this->getMock(CacheManager::class, [], [], '', false);
784  $mockCache = $this->getMock(PhpFrontend::class, [], [], '', false);
785  $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
786  GeneralUtility::setSingletonInstance(CacheManager::class, $mockCacheManager);
787 
788  $mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html'));
789  $view->setLayoutRootPaths(['some/Default/Directory']);
790  $view->setTemplateRootPaths(['some/Default/Directory']);
791  $view->setPartialRootPaths(['some/Default/Directory']);
792  $view->expects($this->at(0))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/LayoutName.html')->willReturn(false);
793  $view->expects($this->at(1))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/layoutName.html')->willReturn(true);
794  $this->assertSame(PATH_site . 'some/Default/Directory/layoutName.html', $view->_call('getLayoutPathAndFilename', 'layoutName'));
795 
797  GeneralUtility::resetSingletonInstances($singletonInstances);
798  }
799 }
setupMockControllerContextForPathResolving($packageKey, $subPackageKey, $controllerName, $format)
static addInstance($className, $instance)
static setSingletonInstance($className, SingletonInterface $instance)
static resetSingletonInstances(array $newSingletonInstances)
getAccessibleMock( $originalClassName, $methods=[], array $arguments=[], $mockClassName='', $callOriginalConstructor=true, $callOriginalClone=true, $callAutoload=true)