‪TYPO3CMS  ‪main
UriPrefixRenderingTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
25 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
26 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
27 
28 final class ‪UriPrefixRenderingTest extends FunctionalTestCase
29 {
31 
32  protected array ‪$configurationToUseInTestInstance = [
33  'FE' => [
34  'cacheHash' => [
35  'excludedParameters' => ['testAbsRefPrefix', 'testCompressor'],
36  ],
37  ],
38  ];
39 
43  private array ‪$definedResources = [
44  'absoluteCSS' => '/typo3/sysext/backend/Resources/Public/Css/backend.css',
45  'relativeCSS' => 'typo3/sysext/backend/Resources/Public/Css/backend.css',
46  'extensionCSS' => 'EXT:rte_ckeditor/Resources/Public/Css/contents.css',
47  'externalCSS' => 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
48  'absoluteJS' => '/typo3/sysext/backend/Resources/Public/JavaScript/backend.js',
49  'relativeJS' => 'typo3/sysext/core/Resources/Public/JavaScript/Contrib/autosize.js',
50  'extensionJS' => 'EXT:core/Resources/Public/JavaScript/Contrib/jquery.js',
51  'externalJS' => 'https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js',
52  'localImage' => 'typo3/sysext/frontend/Resources/Public/Icons/Extension.svg',
53  ];
54 
58  private array ‪$resolvedResources = [
59  'relativeCSS' => 'typo3/sysext/backend/Resources/Public/Css/backend.css',
60  'extensionCSS' => 'typo3/sysext/rte_ckeditor/Resources/Public/Css/contents.css',
61  'externalCSS' => 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css',
62  'relativeJS' => 'typo3/sysext/core/Resources/Public/JavaScript/Contrib/autosize.js',
63  'extensionJS' => 'typo3/sysext/core/Resources/Public/JavaScript/Contrib/jquery.js',
64  'externalJS' => 'https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js',
65  'localImage' => 'typo3/sysext/frontend/Resources/Public/Icons/Extension.svg',
66  ];
67 
68  protected array ‪$coreExtensionsToLoad = ['rte_ckeditor'];
69 
70  protected const ‪LANGUAGE_PRESETS = [
71  'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8', 'iso' => 'en'],
72  ];
73 
74  protected function ‪setUp(): void
75  {
76  parent::setUp();
77  $this->importCsvDataSet(__DIR__ . '/../../../../core/Tests/Functional/Fixtures/pages.csv');
79  'test',
80  $this->‪buildSiteConfiguration(1, '/'),
81  [
82  $this->‪buildDefaultLanguageConfiguration('EN', '/en/'),
83  ],
84  $this->‪buildErrorHandlingConfiguration('Fluid', [404]),
85  );
86  $this->setUpFrontendRootPage(
87  1,
88  ['EXT:frontend/Tests/Functional/Rendering/Fixtures/UriPrefixRenderingTest.typoscript']
89  );
91  1,
92  $this->‪compileTypoScriptConstants($this->definedResources)
93  );
94  }
95 
96  public static function ‪urisAreRenderedUsingAbsRefPrefixDataProvider(): array
97  {
98  return [
99  // no compression settings
100  'none - none' => [
101  'none', 'none',
102  [
103  'absolute' => '"{{CANDIDATE}}"',
104  'local' => '"{{CANDIDATE}}"',
105  'relative' => '"{{CANDIDATE}}\?\d+"',
106  'extension' => '"{{CANDIDATE}}\?\d+"',
107  'external' => '"{{CANDIDATE}}"',
108  ],
109  ],
110  'auto - none' => [
111  'auto', 'none',
112  [
113  'absolute' => '"{{CANDIDATE}}"',
114  'local' => '"/{{CANDIDATE}}"',
115  'relative' => '"/{{CANDIDATE}}\?\d+"',
116  'extension' => '"/{{CANDIDATE}}\?\d+"',
117  'external' => '"{{CANDIDATE}}"',
118  ],
119  ],
120  'absolute-with-host - none' => [
121  'absolute-with-host', 'none',
122  [
123  'absolute' => '"{{CANDIDATE}}"',
124  'local' => '"http://localhost/{{CANDIDATE}}"',
125  'relative' => '"http://localhost/{{CANDIDATE}}\?\d+"',
126  'extension' => '"http://localhost/{{CANDIDATE}}\?\d+"',
127  'external' => '"{{CANDIDATE}}"',
128  ],
129  ],
130  'absolute-without-host - none' => [
131  'absolute-without-host', 'none',
132  [
133  'absolute' => '"{{CANDIDATE}}"',
134  'local' => '"/{{CANDIDATE}}"',
135  'relative' => '"/{{CANDIDATE}}\?\d+"',
136  'extension' => '"/{{CANDIDATE}}\?\d+"',
137  'external' => '"{{CANDIDATE}}"',
138  ],
139  ],
140  // concatenation
141  'none - concatenate' => [
142  'none', 'concatenate',
143  [
144  '!absolute' => '{{CANDIDATE}}',
145  '!relative' => '{{CANDIDATE}}',
146  '!extension' => '{{CANDIDATE}}',
147  'absolute' => '"typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
148  'local' => '"{{CANDIDATE}}"',
149  'relative' => '"typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
150  'extension' => '"typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
151  'external' => '"{{CANDIDATE}}"',
152  ],
153  ],
154  'auto - concatenate' => [
155  'auto', 'concatenate',
156  [
157  '!absolute' => '{{CANDIDATE}}',
158  '!relative' => '{{CANDIDATE}}',
159  '!extension' => '{{CANDIDATE}}',
160  'absolute' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
161  'local' => '"/{{CANDIDATE}}"',
162  'relative' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
163  'extension' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
164  'external' => '"{{CANDIDATE}}"',
165  ],
166  ],
167  'absolute-with-host - concatenate' => [
168  'absolute-with-host', 'concatenate',
169  [
170  '!absolute' => '{{CANDIDATE}}',
171  '!relative' => '{{CANDIDATE}}',
172  '!extension' => '{{CANDIDATE}}',
173  'absolute' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
174  'local' => '"http://localhost/{{CANDIDATE}}"',
175  'relative' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
176  'extension' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
177  'external' => '"{{CANDIDATE}}"',
178  ],
179  ],
180  'absolute-without-host - concatenate' => [
181  'absolute-without-host', 'concatenate',
182  [
183  '!absolute' => '{{CANDIDATE}}',
184  '!relative' => '{{CANDIDATE}}',
185  '!extension' => '{{CANDIDATE}}',
186  'absolute' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
187  'local' => '"/{{CANDIDATE}}"',
188  'relative' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
189  'extension' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
190  'external' => '"{{CANDIDATE}}"',
191  ],
192  ],
193  // compression
194  'none - compress' => [
195  'none', 'compress',
196  [
197  '!absolute' => '{{CANDIDATE}}',
198  '!relative' => '{{CANDIDATE}}',
199  '!extension' => '{{CANDIDATE}}',
200  'absolute' => '"typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
201  'local' => '"{{CANDIDATE}}"',
202  'relative' => '"typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
203  'extension' => '"typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
204  'external' => '"{{CANDIDATE}}"',
205  ],
206  ],
207  'auto - compress' => [
208  'auto', 'compress',
209  [
210  '!absolute' => '{{CANDIDATE}}',
211  '!relative' => '{{CANDIDATE}}',
212  '!extension' => '{{CANDIDATE}}',
213  'absolute' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
214  'local' => '"/{{CANDIDATE}}"',
215  'relative' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
216  'extension' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
217  'external' => '"{{CANDIDATE}}"',
218  ],
219  ],
220  'absolute-with-host - compress' => [
221  'absolute-with-host', 'compress',
222  [
223  '!absolute' => '{{CANDIDATE}}',
224  '!relative' => '{{CANDIDATE}}',
225  '!extension' => '{{CANDIDATE}}',
226  'absolute' => '"http://localhost/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
227  'local' => '"http://localhost/{{CANDIDATE}}"',
228  'relative' => '"http://localhost/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
229  'extension' => '"http://localhost/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
230  'external' => '"{{CANDIDATE}}"',
231  ],
232  ],
233  'absolute-without-host - compress' => [
234  'absolute-without-host', 'compress',
235  [
236  '!absolute' => '{{CANDIDATE}}',
237  '!relative' => '{{CANDIDATE}}',
238  '!extension' => '{{CANDIDATE}}',
239  'absolute' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
240  'local' => '"/{{CANDIDATE}}"',
241  'relative' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
242  'extension' => '"/typo3temp/assets/compressed/{{CANDIDATE-FILENAME}}-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
243  'external' => '"{{CANDIDATE}}"',
244  ],
245  ],
246  // concatenation & compression
247  'none - concatenate-and-compress' => [
248  'none', 'concatenate-and-compress',
249  [
250  '!absolute' => '{{CANDIDATE}}',
251  '!relative' => '{{CANDIDATE}}',
252  '!extension' => '{{CANDIDATE}}',
253  'absolute' => '"typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
254  'local' => '"{{CANDIDATE}}"',
255  'relative' => '"typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
256  'extension' => '"typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
257  'external' => '"{{CANDIDATE}}"',
258  ],
259  ],
260  'auto - concatenate-and-compress' => [
261  'auto', 'concatenate-and-compress',
262  [
263  '!absolute' => '{{CANDIDATE}}',
264  '!relative' => '{{CANDIDATE}}',
265  '!extension' => '{{CANDIDATE}}',
266  'absolute' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
267  'local' => '"/{{CANDIDATE}}"',
268  'relative' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
269  'extension' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
270  'external' => '"{{CANDIDATE}}"',
271  ],
272  ],
273  'absolute-with-host - concatenate-and-compress' => [
274  'absolute-with-host', 'concatenate-and-compress',
275  [
276  '!absolute' => '{{CANDIDATE}}',
277  '!relative' => '{{CANDIDATE}}',
278  '!extension' => '{{CANDIDATE}}',
279  'absolute' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
280  'local' => '"http://localhost/{{CANDIDATE}}"',
281  'relative' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
282  'extension' => '"http://localhost/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
283  'external' => '"{{CANDIDATE}}"',
284  ],
285  ],
286  'absolute-without-host - concatenate-and-compress' => [
287  'absolute-without-host', 'concatenate-and-compress',
288  [
289  '!absolute' => '{{CANDIDATE}}',
290  '!relative' => '{{CANDIDATE}}',
291  '!extension' => '{{CANDIDATE}}',
292  'absolute' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
293  'local' => '"/{{CANDIDATE}}"',
294  'relative' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
295  'extension' => '"/typo3temp/assets/compressed/merged-[a-z0-9]+-[a-z0-9]+\.{{CANDIDATE-EXTENSION}}\?\d+"',
296  'external' => '"{{CANDIDATE}}"',
297  ],
298  ],
299  ];
300  }
301 
302  #[DataProvider('urisAreRenderedUsingAbsRefPrefixDataProvider')]
303  #[Test]
304  public function ‪urisAreRenderedUsingAbsRefPrefix(string $absRefPrefixAspect, string $compressorAspect, array $expectations): void
305  {
306  $response = $this->executeFrontendSubRequest(
307  (new InternalRequest())->withQueryParameters([
308  'id' => 1,
309  'testAbsRefPrefix' => $absRefPrefixAspect,
310  'testCompressor' => $compressorAspect,
311  ])
312  );
313  $content = (string)$response->getBody();
314 
315  foreach ($expectations as $type => $expectation) {
316  $shallExist = true;
317  if (str_starts_with($type, '!')) {
318  $shallExist = false;
319  $type = substr($type, 1);
320  }
321  $candidates = array_map(
322  function (string $candidateKey) {
323  return $this->resolvedResources[$candidateKey];
324  },
325  array_filter(
326  array_keys($this->resolvedResources),
327  static function (string $candidateKey) use ($type) {
328  return str_starts_with($candidateKey, $type);
329  }
330  )
331  );
332  foreach ($candidates as $candidate) {
333  $pathInfo = pathinfo($candidate);
334  $pattern = str_replace(
335  [
336  '{{CANDIDATE}}',
337  '{{CANDIDATE-FILENAME}}',
338  '{{CANDIDATE-EXTENSION}}',
339  ],
340  [
341  preg_quote($candidate, '#'),
342  preg_quote($pathInfo['filename'], '#'),
343  preg_quote($pathInfo['extension'] ?? '', '#'),
344  ],
345  $expectation
346  );
347 
348  if ($shallExist) {
349  self::assertMatchesRegularExpression(
350  '#' . $pattern . '#',
351  $content
352  );
353  } else {
354  self::assertDoesNotMatchRegularExpression(
355  '#' . $pattern . '#',
356  $content
357  );
358  }
359  }
360  }
361  }
362 
366  protected function ‪setTypoScriptConstantsToTemplateRecord(int $pageId, string $constants, bool $append = false): void
367  {
368  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_template');
369 
370  $template = $connection->select(['uid', 'constants'], 'sys_template', ['pid' => $pageId, 'root' => 1])->fetchAssociative();
371  if (empty($template)) {
372  self::fail('Cannot find root template on page with id: "' . $pageId . '"');
373  }
374  $updateFields = [];
375  $updateFields['constants'] = ($append ? $template['constants'] . LF : '') . $constants;
376  $connection->update(
377  'sys_template',
378  $updateFields,
379  ['uid' => $template['uid']]
380  );
381  }
382 
383  protected function ‪compileTypoScriptConstants(array $constants): string
384  {
385  $lines = [];
386  foreach ($constants as $constantName => $constantValue) {
387  $lines[] = $constantName . ' = ' . $constantValue;
388  }
389  return implode(PHP_EOL, $lines);
390  }
391 }
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\$configurationToUseInTestInstance
‪array $configurationToUseInTestInstance
Definition: UriPrefixRenderingTest.php:31
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\$resolvedResources
‪array $resolvedResources
Definition: UriPrefixRenderingTest.php:57
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\$coreExtensionsToLoad
‪array $coreExtensionsToLoad
Definition: UriPrefixRenderingTest.php:67
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait
Definition: SiteBasedTestTrait.php:37
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:50
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:88
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildErrorHandlingConfiguration
‪buildErrorHandlingConfiguration(string $handler, array $codes)
Definition: SiteBasedTestTrait.php:142
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\setUp
‪setUp()
Definition: UriPrefixRenderingTest.php:73
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\$definedResources
‪array $definedResources
Definition: UriPrefixRenderingTest.php:42
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\LANGUAGE_PRESETS
‪const LANGUAGE_PRESETS
Definition: UriPrefixRenderingTest.php:69
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest
Definition: UriPrefixRenderingTest.php:29
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\setTypoScriptConstantsToTemplateRecord
‪setTypoScriptConstantsToTemplateRecord(int $pageId, string $constants, bool $append=false)
Definition: UriPrefixRenderingTest.php:365
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:98
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\compileTypoScriptConstants
‪compileTypoScriptConstants(array $constants)
Definition: UriPrefixRenderingTest.php:382
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\urisAreRenderedUsingAbsRefPrefix
‪urisAreRenderedUsingAbsRefPrefix(string $absRefPrefixAspect, string $compressorAspect, array $expectations)
Definition: UriPrefixRenderingTest.php:303
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering
Definition: AbsoluteUriPrefixRenderingTest.php:18
‪TYPO3\CMS\Frontend\Tests\Functional\Rendering\UriPrefixRenderingTest\urisAreRenderedUsingAbsRefPrefixDataProvider
‪static urisAreRenderedUsingAbsRefPrefixDataProvider()
Definition: UriPrefixRenderingTest.php:95