‪TYPO3CMS  9.5
PageRendererTest.php
Go to the documentation of this file.
1 <?php
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\NullLogger;
23 
27 class ‪PageRendererTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
28 {
33  {
34  $subject = new ‪PageRenderer();
35  $subject->setCharSet('utf-8');
36  $subject->setLanguage('default');
37 
38  $prologueString = $expectedPrologueString = '<?xml version="1.0" encoding="utf-8" ?>';
39  $subject->setXmlPrologAndDocType($prologueString);
40 
41  $title = $this->getUniqueId('aTitle-');
42  $subject->setTitle($title);
43  $expectedTitleString = '<title>' . $title . '</title>';
44 
45  $charset = 'utf-8';
46  $subject->setCharSet($charset);
47  $expectedCharsetString = '<meta http-equiv="Content-Type" content="text/html; charset=' . $charset . '" />';
48 
49  $favouriteIcon = 'http://google.com/favicon.ico';
50  $subject->setFavIcon($favouriteIcon);
51  $expectedFavouriteIconPartOne = '<link rel="shortcut icon" href="' . $favouriteIcon . '" />';
52 
53  $baseUrl = 'http://google.com/';
54  $subject->setBaseUrl($baseUrl);
55  $expectedBaseUrlString = '<base href="' . $baseUrl . '" />';
56 
57  $subject->setMetaTag('property', 'og:type', 'foobar');
58  $subject->setMetaTag('name', 'author', 'husel');
59  $subject->setMetaTag('name', 'author', 'foobar');
60  $subject->setMetaTag('http-equiv', 'refresh', '5');
61  $subject->setMetaTag('name', 'DC.Author', '<evil tag>');
62  $subject->setMetaTag('property', 'og:image', '/path/to/image1.jpg', [], false);
63  $subject->setMetaTag('property', 'og:image', '/path/to/image2.jpg', [], false);
64 
65  // Unset meta tag
66  $subject->setMetaTag('NaMe', 'randomTag', 'foobar');
67  $subject->removeMetaTag('name', 'RanDoMtAg');
68 
69  $inlineComment = $this->getUniqueId('comment');
70  $subject->addInlineComment($inlineComment);
71  $expectedInlineCommentString = '<!-- ' . LF . $inlineComment . '-->';
72 
73  $headerData = $expectedHeaderData = '<tag method="private" name="test" />';
74  $subject->addHeaderData($headerData);
75 
76  $subject->addJsLibrary('test', 'fileadmin/test.js', 'text/javascript', false, false, 'wrapBeforeXwrapAfter', false, 'X');
77  $expectedJsLibraryRegExp = '#wrapBefore<script src="fileadmin/test\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>wrapAfter#';
78 
79  $subject->addJsFile('fileadmin/test.js', 'text/javascript', false, false, 'wrapBeforeXwrapAfter', false, 'X');
80  $expectedJsFileRegExp = '#wrapBefore<script src="fileadmin/test\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>wrapAfter#';
81 
82  $jsInlineCode = $expectedJsInlineCodeString = 'var x = "' . $this->getUniqueId('jsInline-') . '"';
83  $subject->addJsInlineCode($this->getUniqueId(), $jsInlineCode);
84 
85  $cssFile = $this->getUniqueId('cssFile-');
86  $expectedCssFileString = 'wrapBefore<link rel="stylesheet" type="text/css" href="' . $cssFile . '" media="print" />wrapAfter';
87  $subject->addCssFile($cssFile, 'stylesheet', 'print', '', true, false, 'wrapBeforeXwrapAfter', false, 'X');
88 
89  $expectedCssInlineBlockOnTopString = '/*general3*/' . LF . 'h1 {margin:20px;}' . LF . '/*general2*/' . LF . 'body {margin:20px;}';
90  $subject->addCssInlineBlock('general2', 'body {margin:20px;}');
91  $subject->addCssInlineBlock('general3', 'h1 {margin:20px;}', null, true);
92 
93  $subject->loadJquery(null, null, ‪PageRenderer::JQUERY_NAMESPACE_NONE, true);
94  $expectedJqueryRegExp = '#<script src="typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery/jquery\\.min\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>#';
95 
96  $expectedBodyContent = $this->getUniqueId('ABCDE-');
97  $subject->setBodyContent($expectedBodyContent);
98 
99  $renderedString = $subject->render();
100 
101  $this->assertContains($expectedPrologueString, $renderedString);
102  $this->assertContains($expectedTitleString, $renderedString);
103  $this->assertContains($expectedCharsetString, $renderedString);
104  $this->assertContains($expectedFavouriteIconPartOne, $renderedString);
105  $this->assertContains($expectedBaseUrlString, $renderedString);
106  $this->assertContains($expectedInlineCommentString, $renderedString);
107  $this->assertContains($expectedHeaderData, $renderedString);
108  $this->assertRegExp($expectedJsLibraryRegExp, $renderedString);
109  $this->assertRegExp($expectedJsFileRegExp, $renderedString);
110  $this->assertContains($expectedJsInlineCodeString, $renderedString);
111  $this->assertContains($expectedCssFileString, $renderedString);
112  $this->assertContains($expectedCssInlineBlockOnTopString, $renderedString);
113  $this->assertRegExp($expectedJqueryRegExp, $renderedString);
114  $this->assertContains($expectedBodyContent, $renderedString);
115  $this->assertContains('<meta property="og:type" content="foobar" />', $renderedString);
116  $this->assertContains('<meta name="author" content="foobar" />', $renderedString);
117  $this->assertContains('<meta http-equiv="refresh" content="5" />', $renderedString);
118  $this->assertContains('<meta name="dc.author" content="&lt;evil tag&gt;" />', $renderedString);
119  $this->assertNotContains('<meta name="randomtag" content="foobar">', $renderedString);
120  $this->assertNotContains('<meta name="randomtag" content="foobar" />', $renderedString);
121  $this->assertContains('<meta name="generator" content="TYPO3 CMS" />', $renderedString);
122  $this->assertContains('<meta property="og:image" content="/path/to/image1.jpg" />', $renderedString);
123  $this->assertContains('<meta property="og:image" content="/path/to/image2.jpg" />', $renderedString);
124  }
125 
130  {
131  $subject = new ‪PageRenderer();
132  $subject->setCharSet('utf-8');
133  $subject->setLanguage('default');
134 
135  $subject->enableMoveJsFromHeaderToFooter();
136 
137  $footerData = $expectedFooterData = '<tag method="private" name="test" />';
138  $subject->addFooterData($footerData);
139 
140  $expectedJsFooterLibraryRegExp = '#wrapBefore<script src="fileadmin/test\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>wrapAfter#';
141  $subject->addJsFooterLibrary('test', 'fileadmin/test.js', 'text/javascript', false, false, 'wrapBeforeXwrapAfter', false, 'X');
142 
143  $expectedJsFooterRegExp = '#wrapBefore<script src="fileadmin/test\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>wrapAfter#';
144  $subject->addJsFooterFile('fileadmin/test.js', 'text/javascript', false, false, 'wrapBeforeXwrapAfter', false, 'X');
145 
146  $jsFooterInlineCode = $expectedJsFooterInlineCodeString = 'var x = "' . $this->getUniqueId('jsFooterInline-') . '"';
147  $subject->addJsFooterInlineCode($this->getUniqueId(), $jsFooterInlineCode);
148 
149  // Bunch of label tests
150  $subject->addInlineLanguageLabel('myKey', 'myValue');
151  $subject->addInlineLanguageLabelArray([
152  'myKeyArray1' => 'myValueArray1',
153  'myKeyArray2' => 'myValueArray2'
154  ]);
155  $subject->addInlineLanguageLabelArray([
156  'myKeyArray3' => 'myValueArray3'
157  ]);
158  $expectedInlineLabelReturnValue = 'TYPO3.lang = {"myKey":"myValue","myKeyArray1":"myValueArray1","myKeyArray2":"myValueArray2","myKeyArray3":"myValueArray3"';
159 
160  $subject->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf');
161  $expectedLanguageLabel1 = 'labels.beUser';
162  $expectedLanguageLabel2 = 'labels.feUser';
163 
164  // Bunch of inline settings test
165  $subject->addInlineSetting('myApp', 'myKey', 'myValue');
166  $subject->addInlineSettingArray('myApp', [
167  'myKey1' => 'myValue1',
168  'myKey2' => 'myValue2'
169  ]);
170  $subject->addInlineSettingArray('myApp', [
171  'myKey3' => 'myValue3'
172  ]);
173  $expectedInlineSettingsReturnValue = 'TYPO3.settings = {"myApp":{"myKey":"myValue","myKey1":"myValue1","myKey2":"myValue2","myKey3":"myValue3"}';
174 
175  $renderedString = $subject->render(‪PageRenderer::PART_FOOTER);
176 
177  $this->assertContains($expectedFooterData, $renderedString);
178  $this->assertRegExp($expectedJsFooterLibraryRegExp, $renderedString);
179  $this->assertRegExp($expectedJsFooterRegExp, $renderedString);
180  $this->assertContains($expectedJsFooterInlineCodeString, $renderedString);
181  $this->assertContains($expectedInlineLabelReturnValue, $renderedString);
182  $this->assertContains($expectedLanguageLabel1, $renderedString);
183  $this->assertContains($expectedLanguageLabel2, $renderedString);
184  $this->assertContains($expectedInlineSettingsReturnValue, $renderedString);
185  }
186 
191  {
192  return [
193  'Custom namespace falls back to "no conflict"' => [
194  'namespace' => 'MyNameSpace',
195  'matchNoConflict' => true,
196  ],
197  '"None" namespace is respected' => [
199  'matchNoConflict' => false,
200  ],
201  ];
202  }
203 
210  public function ‪loadJqueryRespectsNamespace($namespace, $matchNoConflict)
211  {
212  $subject = new ‪PageRenderer();
213 
214  $expectedRegExp = '#<script src="typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery/jquery\\.min\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>#';
215  $noConflictStatement = 'jQuery.noConflict();';
216  $subject->loadJquery(null, null, $namespace, true);
217 
218  //jQuery.noConflict();
219  $out = $subject->render();
220  $this->assertRegExp($expectedRegExp, $out);
221 
222  if ($matchNoConflict) {
223  $this->assertContains($noConflictStatement, $out);
224  } else {
225  $this->assertNotContains($noConflictStatement, $out);
226  }
227  }
228 
233  {
234  $subject = new ‪PageRenderer();
235 
236  $expectedRegExp = '#<script src="typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery/jquery\\.min\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>#';
237  $expectedStatement = 'jQuery.noConflict();';
238  $subject->loadJquery(null, null, 'MyNameSpace', true);
239  $out = $subject->render();
240  $this->assertRegExp($expectedRegExp, $out);
241  $this->assertContains($expectedStatement, $out);
242  $this->assertNotContains('var TYPO3 = TYPO3 || {}; TYPO3.', $out);
243  }
244 
249  {
250  $subject = new ‪PageRenderer();
251 
252  $expectedRegExp = '#<script src="typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery/jquery\\.min\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>#';
253  $subject->loadJquery(null, null, ‪PageRenderer::JQUERY_NAMESPACE_NONE, true);
254  $out = $subject->render();
255  $this->assertRegExp($expectedRegExp, $out);
256  $this->assertNotContains('jQuery.noConflict', $out);
257  }
258 
263  {
264  $subject = new ‪PageRenderer();
265 
266  $expectedRegExp = '#<script src="typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery/jquery\\.(js|\\d+\\.js|js\\?\\d+)" type="text/javascript"></script>#';
267  $expectedStatement = 'jQuery.noConflict();';
268  $subject->loadJquery(null, null, 'MyNameSpace', true);
269  $subject->enableDebugMode();
270  $out = $subject->render();
271  $this->assertRegExp($expectedRegExp, $out);
272  $this->assertContains($expectedStatement, $out);
273  }
274 
279  {
280  return [
281  'google with version number' => [
282  '1.6.3',
283  'google',
284  '#<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.js" type="text/javascript"></script>#'
285  ],
286  'msn with version number' => [
287  '1.6.3',
288  'msn',
289  '#<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.3.js" type="text/javascript"></script>#'
290  ],
291  'jquery with version number' => [
292  '1.6.3',
293  'jquery',
294  '#<script src="https://code.jquery.com/jquery-1.6.3.js" type="text/javascript"></script>#'
295  ],
296  'jquery with custom URL' => [
297  '1.6.3',
298  'https://my.cool.cdn/foo/jquery.js',
299  '#<script src="https://my.cool.cdn/foo/jquery.js" type="text/javascript"></script>#'
300  ],
301  ];
302  }
303 
311  public function ‪isJqueryLoadedFromSourceUncompressedIfDebugModeIsEnabled($version, $source, $regex)
312  {
313  $subject = new ‪PageRenderer();
314 
315  $subject->loadJquery($version, $source, ‪PageRenderer::JQUERY_NAMESPACE_NONE, true);
316  $subject->enableDebugMode();
317  $out = $subject->render();
318  $this->assertRegExp($regex, $out);
319  }
320 
325  {
326  $subject = new ‪PageRenderer();
327 
328  $expectedRegex = '#<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>#';
329  $subject->loadJquery('1.6.3', 'google', ‪PageRenderer::JQUERY_NAMESPACE_NONE, true);
330  $out = $subject->render();
331  $this->assertRegExp($expectedRegex, $out);
332  }
333 
338  {
339  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['session']['BE'] = [
340  'backend' => DatabaseSessionBackend::class,
341  'options' => [
342  'table' => 'be_sessions',
343  ],
344  ];
345  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
346  ‪$GLOBALS['BE_USER']->id = md5('abc');
347  ‪$GLOBALS['BE_USER']->user = ['uid' => 1];
348  ‪$GLOBALS['BE_USER']->setLogger(new NullLogger());
349 
350  ‪$GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class);
351 
352  $subject = new ‪PageRenderer();
353  $subject->setCharSet('utf-8');
354  $subject->setLanguage('default');
355 
356  $packages = [
357  [
358  'name' => 'foo',
359  'location' => '/typo3conf/ext/foo/Resources/Public/JavaScript/Contrib/foo',
360  'main' => 'lib/foo'
361  ],
362  [
363  'name' => 'bar',
364  'location' => '/typo3conf/ext/bar/Resources/Public/JavaScript/Contrib/bar',
365  'main' => 'lib/bar'
366  ]
367  ];
368 
369  foreach ($packages as $package) {
370  $subject->addRequireJsConfiguration([
371  'packages' => [$package]
372  ]);
373  }
374 
375  $expectedConfiguration = json_encode(['packages' => $packages]);
376  // Remove surrounding brackets as the expectation is a substring of a larger JSON string
377  $expectedConfiguration = trim($expectedConfiguration, '{}');
378 
379  $renderedString = $subject->render();
380  self::assertStringContainsString($expectedConfiguration, $renderedString);
381  }
382 }
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\isJqueryLoadedFromSourceUncompressedIfDebugModeIsEnabled
‪isJqueryLoadedFromSourceUncompressedIfDebugModeIsEnabled($version, $source, $regex)
Definition: PageRendererTest.php:311
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\loadJqueryWithDefaultNoConflictModeDoesNotSetNamespace
‪loadJqueryWithDefaultNoConflictModeDoesNotSetNamespace()
Definition: PageRendererTest.php:232
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest
Definition: PageRendererTest.php:28
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\loadJqueryFromSourceDataProvider
‪array loadJqueryFromSourceDataProvider()
Definition: PageRendererTest.php:278
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:35
‪TYPO3\CMS\Core\Page\PageRenderer\PART_FOOTER
‪const PART_FOOTER
Definition: PageRenderer.php:39
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:45
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\pageRendererMergesRequireJsPackagesOnConsecutiveCalls
‪pageRendererMergesRequireJsPackagesOnConsecutiveCalls()
Definition: PageRendererTest.php:337
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\loadJqueryLoadsTheLatestJqueryVersionInNoConflictModeUncompressedInDebugMode
‪loadJqueryLoadsTheLatestJqueryVersionInNoConflictModeUncompressedInDebugMode()
Definition: PageRendererTest.php:262
‪TYPO3\CMS\Core\Page\PageRenderer\JQUERY_NAMESPACE_NONE
‪const JQUERY_NAMESPACE_NONE
Definition: PageRenderer.php:45
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\loadJqueryWithNamespaceNoneDoesNotIncludeNoConflictHandling
‪loadJqueryWithNamespaceNoneDoesNotIncludeNoConflictHandling()
Definition: PageRendererTest.php:248
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\pageRendererRendersFooterValues
‪pageRendererRendersFooterValues()
Definition: PageRendererTest.php:129
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\loadJqueryRespectsNamespace
‪loadJqueryRespectsNamespace($namespace, $matchNoConflict)
Definition: PageRendererTest.php:210
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\isJqueryLoadedMinifiedFromGoogleByDefault
‪isJqueryLoadedMinifiedFromGoogleByDefault()
Definition: PageRendererTest.php:324
‪TYPO3\CMS\Core\Session\Backend\DatabaseSessionBackend
Definition: DatabaseSessionBackend.php:34
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Functional\Page
Definition: PageRendererTest.php:2
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\pageRendererRendersInsertsMainContentStringsInOutput
‪pageRendererRendersInsertsMainContentStringsInOutput()
Definition: PageRendererTest.php:32
‪TYPO3\CMS\Core\Tests\Functional\Page\PageRendererTest\jqueryNamespaceDataProvider
‪array jqueryNamespaceDataProvider()
Definition: PageRendererTest.php:190