‪TYPO3CMS  ‪main
SiteRequestTest.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;
22 use Psr\Http\Message\UriInterface;
27 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
28 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
29 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
30 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
31 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
32 
34 {
35  protected function ‪setUp(): void
36  {
37  parent::setUp();
38  $this->withDatabaseSnapshot(function () {
39  $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
40  $backendUser = $this->setUpBackendUser(1);
41  ‪$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser);
42  $scenarioFile = __DIR__ . '/Fixtures/PlainScenario.yaml';
43  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
44  $writer = DataHandlerWriter::withBackendUser($backendUser);
45  $writer->invokeFactory($factory);
46  static::failIfArrayIsNotEmpty($writer->getErrors());
47  $this->setUpFrontendRootPage(
48  1000,
49  [
50  'EXT:core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
51  'EXT:frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
52  ],
53  [
54  'title' => 'ACME Root',
55  ]
56  );
57  });
58  }
59 
60  public static function ‪shortcutsAreRedirectedDataProvider(): array
61  {
62  $domainPaths = [
63  // @todo Implicit strict mode handling when calling non-existent site
64  // '/',
65  // 'https://localhost/',
66  'https://website.local/',
67  ];
68  $queries = [
69  '',
70  ];
71  return self::wrapInArray(
72  self::keysFromValues(
73  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
74  )
75  );
76  }
77 
78  #[DataProvider('shortcutsAreRedirectedDataProvider')]
79  #[Test]
80  public function ‪shortcutsAreRedirectedToFirstSubPage(string $uri): void
81  {
83  'website-local',
84  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
85  [
86  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
87  ]
88  );
89 
90  $expectedStatusCode = 307;
91  $expectedHeaders = ['location' => ['https://website.local/en-en/']];
92 
93  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
94  self::assertSame($expectedStatusCode, $response->getStatusCode());
95  self::assertSame($expectedHeaders, $response->getHeaders());
96  }
97 
98  #[DataProvider('shortcutsAreRedirectedDataProvider')]
99  #[Test]
100  public function ‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri): void
101  {
103  'website-local',
104  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
105  [
106  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
107  ]
108  );
109 
110  $expectedStatusCode = 200;
111  $expectedPageTitle = 'EN: Welcome';
112 
113  $response = $this->executeFrontendSubRequest(
114  new InternalRequest($uri),
115  null,
116  true
117  );
118  $responseStructure = ResponseContent::fromString(
119  (string)$response->getBody()
120  );
121 
122  self::assertSame(
123  $expectedStatusCode,
124  $response->getStatusCode()
125  );
126  self::assertSame(
127  $expectedPageTitle,
128  $responseStructure->getScopePath('page/title')
129  );
130  }
131 
132  public static function ‪pageIsRenderedWithPathsDataProvider(): array
133  {
134  $domainPaths = [
135  // @todo currently base needs to be defined with domain
136  // '/',
137  'https://website.local/',
138  ];
139  $languagePaths = [
140  'en-en/',
141  'fr-fr/',
142  'fr-ca/',
143  '简/',
144  ];
145  $queries = [
146  '?id=1100',
147  ];
148  return array_map(
149  static function (string $uri) {
150  if (str_contains($uri, '/fr-fr/')) {
151  $expectedPageTitle = 'FR: Welcome';
152  } elseif (str_contains($uri, '/fr-ca/')) {
153  $expectedPageTitle = 'FR-CA: Welcome';
154  } elseif (str_contains($uri, '/简/')) {
155  $expectedPageTitle = 'ZH-CN: Welcome';
156  } else {
157  $expectedPageTitle = 'EN: Welcome';
158  }
159  return [$uri, $expectedPageTitle];
160  },
161  self::keysFromValues(
162  ‪PermutationUtility::meltStringItems([$domainPaths, $languagePaths, $queries])
163  )
164  );
165  }
166 
167  #[DataProvider('pageIsRenderedWithPathsDataProvider')]
168  #[Test]
169  public function ‪pageIsRenderedWithPaths(string $uri, string $expectedPageTitle): void
170  {
172  'website-local',
173  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
174  [
175  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
176  $this->‪buildLanguageConfiguration('FR', '/fr-fr/', ['EN']),
177  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
178  $this->‪buildLanguageConfiguration('ZH', '/简/', ['EN']),
179  ]
180  );
181 
182  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
183  $responseStructure = ResponseContent::fromString(
184  (string)$response->getBody()
185  );
186 
187  self::assertSame(
188  200,
189  $response->getStatusCode()
190  );
191  self::assertSame(
192  $expectedPageTitle,
193  $responseStructure->getScopePath('page/title')
194  );
195  }
196 
198  {
199  $domainPaths = [
200  // @todo currently base needs to be defined with domain
201  // '/',
202  'https://website.local/',
203  ];
204  $languagePaths = [
205  '简/',
206  'fr-fr/',
207  'fr-ca/',
208  ];
209  $queries = [
210  '?id=1110',
211  ];
212  return array_map(
213  static function (string $uri) {
214  if (str_contains($uri, '/fr-fr/')) {
215  $expectedPageTitle = 'FR: Welcome ZH Default';
216  } elseif (str_contains($uri, '/fr-ca/')) {
217  $expectedPageTitle = 'FR-CA: Welcome ZH Default';
218  } else {
219  $expectedPageTitle = 'ZH-CN: Welcome Default';
220  }
221  return [$uri, $expectedPageTitle];
222  },
223  self::keysFromValues(
224  ‪PermutationUtility::meltStringItems([$domainPaths, $languagePaths, $queries])
225  )
226  );
227  }
228 
229  #[DataProvider('pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider')]
230  #[Test]
231  public function ‪pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle): void
232  {
234  'website-local',
235  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
236  [
237  $this->‪buildDefaultLanguageConfiguration('ZH-CN', '/简/'),
238  $this->‪buildLanguageConfiguration('FR', '/fr-fr/', ['EN']),
239  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
240  ]
241  );
242 
243  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
244  $responseStructure = ResponseContent::fromString(
245  (string)$response->getBody()
246  );
247 
248  self::assertSame(
249  200,
250  $response->getStatusCode()
251  );
252  self::assertSame(
253  $expectedPageTitle,
254  $responseStructure->getScopePath('page/title')
255  );
256  }
257 
259  {
260  return [
261  ['https://website.local/简/简/?id=1110', 'ZH-CN: Welcome Default'],
262  ];
263  }
264 
265  #[DataProvider('pageIsRenderedWithPathsAndChineseBaseDataProvider')]
266  #[Test]
267  public function ‪pageIsRenderedWithPathsAndChineseBase(string $uri, string $expectedPageTitle): void
268  {
270  'website-local',
271  $this->‪buildSiteConfiguration(1000, 'https://website.local/简/'),
272  [
273  $this->‪buildDefaultLanguageConfiguration('ZH-CN', '/简/'),
274  ]
275  );
276 
277  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
278  $responseStructure = ResponseContent::fromString(
279  (string)$response->getBody()
280  );
281 
282  self::assertSame(
283  200,
284  $response->getStatusCode()
285  );
286  self::assertSame(
287  $expectedPageTitle,
288  $responseStructure->getScopePath('page/title')
289  );
290  }
291 
292  public static function ‪pageIsRenderedWithDomainsDataProvider(): array
293  {
294  $domainPaths = [
295  // @todo: This turns into a redirect to the default language (".us") making this function obsolete
296  // 'https://website.local/',
297  'https://website.us/',
298  'https://website.fr/',
299  // Explicitly testing umlaut domains
300  'https://wäbsite.ca/',
301  // Explicitly testing chinese character domains
302  'https://website.简/',
303  // @todo Implicit strict mode handling when calling non-existent site
304  // 'https://website.other/',
305  ];
306  $queries = [
307  '?id=1100',
308  ];
309  return array_map(
310  static function (string $uri) {
311  if (str_contains($uri, '.fr/')) {
312  $expectedPageTitle = 'FR: Welcome';
313  } elseif (str_contains($uri, '.ca/')) {
314  $expectedPageTitle = 'FR-CA: Welcome';
315  } elseif (str_contains($uri, '.简/')) {
316  $expectedPageTitle = 'ZH-CN: Welcome';
317  } else {
318  $expectedPageTitle = 'EN: Welcome';
319  }
320  return [$uri, $expectedPageTitle];
321  },
322  self::keysFromValues(
323  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
324  )
325  );
326  }
327 
328  #[DataProvider('pageIsRenderedWithDomainsDataProvider')]
329  #[Test]
330  public function ‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle): void
331  {
333  'website-local',
334  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
335  [
336  $this->‪buildDefaultLanguageConfiguration('EN', 'https://website.us/'),
337  $this->‪buildLanguageConfiguration('FR', 'https://website.fr/', ['EN']),
338  $this->‪buildLanguageConfiguration('FR-CA', 'https://wäbsite.ca/', ['FR', 'EN']),
339  $this->‪buildLanguageConfiguration('ZH', 'https://website.简/', ['EN']),
340  ]
341  );
342 
343  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
344  $responseStructure = ResponseContent::fromString(
345  (string)$response->getBody()
346  );
347 
348  self::assertSame(
349  200,
350  $response->getStatusCode()
351  );
352  self::assertSame(
353  $expectedPageTitle,
354  $responseStructure->getScopePath('page/title')
355  );
356  }
357 
358  public static function ‪restrictedPageIsRenderedDataProvider(): array
359  {
360  $instructions = [
361  // frontend user 1
362  ['https://website.local/?id=1510', 1, 'Whitepapers'],
363  ['https://website.local/?id=1511', 1, 'Products'],
364  ['https://website.local/?id=1512', 1, 'Solutions'],
365  // frontend user 2
366  ['https://website.local/?id=1510', 2, 'Whitepapers'],
367  ['https://website.local/?id=1511', 2, 'Products'],
368  ['https://website.local/?id=1515', 2, 'Research'],
369  ['https://website.local/?id=1520', 2, 'Forecasts'],
370  ['https://website.local/?id=1521', 2, 'Current Year'],
371  // frontend user 3
372  ['https://website.local/?id=1510', 3, 'Whitepapers'],
373  ['https://website.local/?id=1511', 3, 'Products'],
374  ['https://website.local/?id=1512', 3, 'Solutions'],
375  ['https://website.local/?id=1515', 3, 'Research'],
376  ['https://website.local/?id=1520', 3, 'Forecasts'],
377  ['https://website.local/?id=1521', 3, 'Current Year'],
378  // frontend user 1 with index
379  ['https://website.local/index.php?id=1510', 1, 'Whitepapers'],
380  ['https://website.local/index.php?id=1511', 1, 'Products'],
381  ['https://website.local/index.php?id=1512', 1, 'Solutions'],
382  // frontend user 2
383  ['https://website.local/index.php?id=1510', 2, 'Whitepapers'],
384  ['https://website.local/index.php?id=1511', 2, 'Products'],
385  ['https://website.local/index.php?id=1515', 2, 'Research'],
386  ['https://website.local/index.php?id=1520', 2, 'Forecasts'],
387  ['https://website.local/index.php?id=1521', 2, 'Current Year'],
388  // frontend user 3
389  ['https://website.local/index.php?id=1510', 3, 'Whitepapers'],
390  ['https://website.local/index.php?id=1511', 3, 'Products'],
391  ['https://website.local/index.php?id=1512', 3, 'Solutions'],
392  ['https://website.local/index.php?id=1515', 3, 'Research'],
393  ['https://website.local/index.php?id=1520', 3, 'Forecasts'],
394  ['https://website.local/index.php?id=1521', 3, 'Current Year'],
395  ];
396  return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
397  }
398 
399  #[DataProvider('restrictedPageIsRenderedDataProvider')]
400  #[Test]
401  public function ‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
402  {
404  'website-local',
405  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
406  );
407 
408  $response = $this->executeFrontendSubRequest(
409  new InternalRequest($uri),
410  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
411  );
412  $responseStructure = ResponseContent::fromString(
413  (string)$response->getBody()
414  );
415 
416  self::assertSame(
417  200,
418  $response->getStatusCode()
419  );
420  self::assertSame(
421  $expectedPageTitle,
422  $responseStructure->getScopePath('page/title')
423  );
424  }
425 
427  {
428  $instructions = [
429  // no frontend user given
430  ['https://website.local/?id=1510', 0],
431  ['https://website.local/?id=1511', 0],
432  ['https://website.local/?id=1512', 0],
433  ['https://website.local/?id=1515', 0],
434  ['https://website.local/?id=1520', 0],
435  ['https://website.local/?id=1521', 0],
436  ['https://website.local/?id=2021', 0],
437  // frontend user 1
438  ['https://website.local/?id=1515', 1],
439  ['https://website.local/?id=1520', 1],
440  ['https://website.local/?id=1521', 1],
441  ['https://website.local/?id=2021', 1],
442  // frontend user 2
443  ['https://website.local/?id=1512', 2],
444  ['https://website.local/?id=2021', 2],
445  ];
446  return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
447  }
448 
449  #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
450  #[Test]
452  {
454  'website-local',
455  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
456  );
457 
458  $response = $this->executeFrontendSubRequest(
459  new InternalRequest($uri),
460  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
461  );
462 
463  self::assertSame(
464  403,
465  $response->getStatusCode()
466  );
467  self::assertThat(
468  (string)$response->getBody(),
469  self::logicalOr(
470  self::stringContains('Reason: ID was not an accessible page'),
471  self::stringContains('Reason: Subsection was found and not accessible')
472  )
473  );
474  }
475 
479  #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
480  #[Test]
482  {
483  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
484 
486  'website-local',
487  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
488  [],
489  $this->‪buildErrorHandlingConfiguration('Page', [403])
490  );
491 
492  $response = $this->executeFrontendSubRequest(
493  new InternalRequest($uri),
494  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
495  );
496 
497  self::assertSame(
498  403,
499  $response->getStatusCode()
500  );
501  }
502 
503  #[DataProvider('restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
504  #[Test]
506  {
508  'website-local',
509  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
510  [],
511  $this->‪buildErrorHandlingConfiguration('PHP', [403])
512  );
513 
514  $response = $this->executeFrontendSubRequest(
515  new InternalRequest($uri),
516  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
517  );
518  $json = json_decode((string)$response->getBody(), true);
519 
520  self::assertSame(
521  403,
522  $response->getStatusCode()
523  );
524  self::assertThat(
525  $json['message'] ?? null,
526  self::logicalOr(
527  self::identicalTo('ID was not an accessible page'),
528  self::identicalTo('Subsection was found and not accessible')
529  )
530  );
531  }
532 
534  {
535  $instructions = [
536  // frontend user 4
537  ['https://website.local/?id=2021', 4, 'FEGroups Restricted'],
538  ];
539  return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
540  }
541 
542  #[DataProvider('restrictedPageWithParentSysFolderIsRenderedDataProvider')]
543  #[Test]
544  public function ‪restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
545  {
547  'website-local',
548  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
549  );
550 
551  $response = $this->executeFrontendSubRequest(
552  new InternalRequest($uri),
553  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
554  );
555  $responseStructure = ResponseContent::fromString(
556  (string)$response->getBody()
557  );
558 
559  self::assertSame(
560  200,
561  $response->getStatusCode()
562  );
563  self::assertSame(
564  $expectedPageTitle,
565  $responseStructure->getScopePath('page/title')
566  );
567  }
568 
570  {
571  $instructions = [
572  // no frontend user given
573  ['https://website.local/?id=2021', 0],
574  // frontend user 1
575  ['https://website.local/?id=2021', 1],
576  // frontend user 2
577  ['https://website.local/?id=2021', 2],
578  // frontend user 3
579  ['https://website.local/?id=2021', 3],
580  ];
581  return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
582  }
583 
584  #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
585  #[Test]
587  {
589  'website-local',
590  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
591  [],
592  $this->‪buildErrorHandlingConfiguration('Fluid', [403])
593  );
594 
595  $response = $this->executeFrontendSubRequest(
596  new InternalRequest($uri),
597  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
598  );
599 
600  self::assertSame(
601  403,
602  $response->getStatusCode()
603  );
604  self::assertStringContainsString(
605  'reasons: code',
606  (string)$response->getBody()
607  );
608  self::assertThat(
609  (string)$response->getBody(),
610  self::logicalOr(
611  self::stringContains('message: ID was not an accessible page'),
612  self::stringContains('message: Subsection was found and not accessible')
613  )
614  );
615  }
616 
620  #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
621  #[Test]
623  {
624  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
625 
627  'website-local',
628  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
629  [],
630  $this->‪buildErrorHandlingConfiguration('Page', [403])
631  );
632 
633  $response = $this->executeFrontendSubRequest(
634  new InternalRequest($uri),
635  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
636  );
637 
638  self::assertSame(
639  403,
640  $response->getStatusCode()
641  );
642  }
643 
644  #[DataProvider('restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider')]
645  #[Test]
647  {
649  'website-local',
650  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
651  [],
652  $this->‪buildErrorHandlingConfiguration('PHP', [403])
653  );
654 
655  $response = $this->executeFrontendSubRequest(
656  new InternalRequest($uri),
657  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
658  );
659  $json = json_decode((string)$response->getBody(), true);
660 
661  self::assertSame(
662  403,
663  $response->getStatusCode()
664  );
665  self::assertThat(
666  $json['message'] ?? null,
667  self::logicalOr(
668  self::identicalTo('ID was not an accessible page'),
669  self::identicalTo('Subsection was found and not accessible')
670  )
671  );
672  }
673 
675  {
676  $instructions = [
677  // hidden page, always 404
678  ['https://website.local/?id=1800', 0],
679  ['https://website.local/?id=1800', 1],
680  // hidden fe group restricted and fegroup generally okay
681  ['https://website.local/?id=2022', 4],
682  ];
683  return self::keysFromTemplate($instructions, '%1$s (user:%2$s)');
684  }
685 
686  #[DataProvider('hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider')]
687  #[Test]
688  public function ‪hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId): void
689  {
691  'website-local',
692  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
693  [],
694  $this->‪buildErrorHandlingConfiguration('PHP', [404])
695  );
696 
697  $response = $this->executeFrontendSubRequest(
698  new InternalRequest($uri),
699  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
700  );
701  $json = json_decode((string)$response->getBody(), true);
702 
703  self::assertSame(
704  404,
705  $response->getStatusCode()
706  );
707  self::assertThat(
708  $json['message'] ?? null,
709  self::identicalTo('The requested page does not exist!')
710  );
711  }
712 
714  {
715  $domainPaths = [
716  'https://website.local/',
717  ];
718  $queries = [
719  '?',
720  '?id=1000',
721  '?id=1100',
722  ];
723  $customQueries = [
724  '&testing[value]=1',
725  '&testing[value]=1&cHash=',
726  '&testing[value]=1&cHash=WRONG',
727  ];
728  return self::wrapInArray(
729  self::keysFromValues(
730  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
731  )
732  );
733  }
734 
735  #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
736  #[Test]
738  {
740  'website-local',
741  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
742  [],
743  $this->‪buildErrorHandlingConfiguration('Fluid', [404])
744  );
745 
746  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
747 
748  self::assertSame(
749  404,
750  $response->getStatusCode()
751  );
752  self::assertThat(
753  (string)$response->getBody(),
754  self::logicalOr(
755  self::stringContains('message: Request parameters could not be validated (&amp;cHash empty)'),
756  self::stringContains('message: Request parameters could not be validated (&amp;cHash comparison failed)')
757  )
758  );
759  }
760 
764  #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
765  #[Test]
767  {
768  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
769 
771  'website-local',
772  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
773  [],
774  $this->‪buildErrorHandlingConfiguration('Page', [404])
775  );
776 
777  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
778 
779  self::assertSame(
780  404,
781  $response->getStatusCode()
782  );
783  }
784 
785  #[DataProvider('pageRenderingStopsWithInvalidCacheHashDataProvider')]
786  #[Test]
788  {
790  'website-local',
791  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
792  [],
793  $this->‪buildErrorHandlingConfiguration('PHP', [404])
794  );
795 
796  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
797  $json = json_decode((string)$response->getBody(), true);
798 
799  self::assertSame(
800  404,
801  $response->getStatusCode()
802  );
803  self::assertThat(
804  $json['message'] ?? null,
805  self::logicalOr(
806  self::identicalTo('Request parameters could not be validated (&cHash empty)'),
807  self::identicalTo('Request parameters could not be validated (&cHash comparison failed)')
808  )
809  );
810  }
811 
812  public static function ‪pageIsRenderedWithValidCacheHashDataProvider(): array
813  {
814  $domainPaths = [
815  // @todo Implicit strict mode handling when calling non-existent site
816  // '/',
817  // 'https://localhost/',
818  'https://website.local/',
819  ];
820  // cHash has been calculated with encryption key set to
821  // '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6'
822  $queries = [
823  // @todo Currently fails since cHash is verified after(!) redirect to page 1100
824  // '?&cHash=7d1f13fa91159dac7feb3c824936b39d&id=1000',
825  '?&cHash=f42b850e435f0cedd366f5db749fc1af&id=1100',
826  ];
827  $customQueries = [
828  '&testing[value]=1',
829  ];
830  return self::wrapInArray(
831  self::keysFromValues(
832  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
833  )
834  );
835  }
836 
837  #[DataProvider('pageIsRenderedWithValidCacheHashDataProvider')]
838  #[Test]
839  public function ‪pageIsRenderedWithValidCacheHash($uri): void
840  {
842  'website-local',
843  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
844  );
845 
846  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
847  $responseStructure = ResponseContent::fromString(
848  (string)$response->getBody()
849  );
850  self::assertSame(
851  '1',
852  $responseStructure->getScopePath('getpost/testing.value')
853  );
854  }
855 
857  {
858  $domainPaths = [
859  'https://website.local/',
860  'https://website.local/index.php',
861  ];
862  $queries = [
863  '',
864  '?id=1000',
865  '?type=0',
866  '?id=1000&type=0',
867  ];
868  return self::wrapInArray(
869  self::keysFromValues(
870  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
871  )
872  );
873  }
874 
875  #[DataProvider('checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider')]
876  #[Test]
878  {
880  'website-local',
881  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
882  );
883 
884  $expectedStatusCode = 307;
885  $expectedHeaders = ['X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'], 'location' => ['https://website.local/en-welcome']];
886 
887  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
888  self::assertSame($expectedStatusCode, $response->getStatusCode());
889  self::assertSame($expectedHeaders, $response->getHeaders());
890  }
891 
892  public static function ‪crossSiteShortcutsAreRedirectedDataProvider(): array
893  {
894  return [
895  'shortcut is redirected #1' => [
896  'https://website.local/index.php?id=2030',
897  307,
898  [
899  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
900  'location' => ['https://blog.local/authors'],
901  ],
902  ],
903  'shortcut is redirected #2' => [
904  'https://website.local/?id=2030',
905  307,
906  [
907  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
908  'location' => ['https://blog.local/authors'],
909  ],
910  ],
911  'shortcut is redirected #3' => [
912  'https://website.local/index.php?id=2030&type=0',
913  307,
914  [
915  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
916  'location' => ['https://blog.local/authors'],
917  ],
918  ],
919  'shortcut is redirected #4' => [
920  'https://website.local/?id=2030&type=0',
921  307,
922  [
923  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
924  'location' => ['https://blog.local/authors'],
925  ],
926  ],
927  'shortcut is redirected #5' => [
928  'https://website.local/?id=2030&type=1',
929  307,
930  [
931  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
932  'location' => ['https://blog.local/authors?type=1'],
933  ],
934  ],
935  'shortcut is redirected #6' => [
936  'https://website.local/?id=2030&type=1&additional=value',
937  307,
938  [
939  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
940  'location' => ['https://blog.local/authors?additional=value&type=1&cHash=9a534a0ab3d092ac113a3d8b5ea577ba'],
941  ],
942  ],
943  ];
944  }
945 
946  #[DataProvider('crossSiteShortcutsAreRedirectedDataProvider')]
947  #[Test]
948  public function ‪crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders): void
949  {
951  'website-local',
952  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
953  );
955  'blog-local',
956  $this->‪buildSiteConfiguration(2000, 'https://blog.local/')
957  );
958  $this->setUpFrontendRootPage(
959  2000,
960  [
961  'EXT:core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
962  'EXT:frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
963  ],
964  [
965  'title' => 'ACME Blog',
966  ]
967  );
968 
969  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
970  self::assertSame($expectedStatusCode, $response->getStatusCode());
971  self::assertSame($expectedHeaders, $response->getHeaders());
972  }
973 
975  {
976  return [
977  'shortcut requested by id on wrong site #1' => [
978  'https://blog.local/index.php?id=2030',
979  ],
980  'shortcut requested by id on wrong site #2' => [
981  'https://blog.local/?id=2030',
982  ],
983  'shortcut requested by id on wrong site #3' => [
984  'https://blog.local/index.php?id=2030&type=0',
985  ],
986  'shortcut requested by id on wrong site #4' => [
987  'https://blog.local/?id=2030&type=0',
988  ],
989  ];
990  }
991 
992  #[DataProvider('crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider')]
993  #[Test]
995  {
997  'website-local',
998  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
999  [],
1000  $this->‪buildErrorHandlingConfiguration('PHP', [404])
1001  );
1003  'blog-local',
1004  $this->‪buildSiteConfiguration(2000, 'https://blog.local/'),
1005  [],
1006  $this->‪buildErrorHandlingConfiguration('PHP', [404])
1007  );
1008 
1009  $this->setUpFrontendRootPage(
1010  2000,
1011  [
1012  'EXT:core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
1013  'EXT:frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
1014  ],
1015  [
1016  'title' => 'ACME Blog',
1017  ]
1018  );
1019  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
1020  $json = json_decode((string)$response->getBody(), true);
1021  self::assertSame(404, $response->getStatusCode());
1022  self::assertThat(
1023  $json['message'] ?? null,
1024  self::stringContains('ID was outside the domain')
1025  );
1026  }
1027 
1028  public static function ‪getUrisWithInvalidLegacyQueryParameters(): \Generator
1029  {
1030  $uri = new ‪Uri('https://website.local/');
1031  yield '#0 id with float value having a zero decimal' => [
1032  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => '1110.0'])),
1033  ];
1034  yield '#1 id string value with tailing numbers' => [
1035  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => 'step1110'])),
1036  ];
1037  yield '#2 id string value with leading numbers' => [
1038  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => '1110step'])),
1039  ];
1040  yield '#3 id string value without numbers' => [
1041  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => 'foobar'])),
1042  ];
1043  yield '#4 id string value with a exponent' => [
1044  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => '11e10'])),
1045  ];
1046  yield '#5 id with a zero as value' => [
1047  'uri' => $uri->withQuery(‪HttpUtility::buildQueryString(['id' => 0])),
1048  ];
1049  }
1050 
1051  #[DataProvider('getUrisWithInvalidLegacyQueryParameters')]
1052  #[Test]
1054  {
1056  'website-local',
1057  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
1058  [],
1059  $this->‪buildErrorHandlingConfiguration('PHP', [404])
1060  );
1061  $response = $this->executeFrontendSubRequest(
1062  new InternalRequest((string)$uri),
1063  new InternalRequestContext()
1064  );
1065  $json = json_decode((string)$response->getBody(), true);
1066  self::assertSame(404, $response->getStatusCode());
1067  self::assertThat(
1068  $json['message'] ?? null,
1069  self::stringContains('The requested page does not exist')
1070  );
1071  }
1072 }
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling(string $uri)
Definition: SiteRequestTest.php:737
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:586
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider
‪static checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider()
Definition: SiteRequestTest.php:856
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:108
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithValidCacheHash
‪pageIsRenderedWithValidCacheHash($uri)
Definition: SiteRequestTest.php:839
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedAndRenderFirstSubPage
‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri)
Definition: SiteRequestTest.php:100
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
‪static restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider()
Definition: SiteRequestTest.php:426
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:622
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvided
‪checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvided(string $uri)
Definition: SiteRequestTest.php:877
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest
Definition: SiteRequestTest.php:34
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider
‪static crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider()
Definition: SiteRequestTest.php:974
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseDefaultLanguage
‪pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:231
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
‪static restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider()
Definition: SiteRequestTest.php:569
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsAreRedirectedDataProvider
‪static crossSiteShortcutsAreRedirectedDataProvider()
Definition: SiteRequestTest.php:892
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithDomains
‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:330
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:50
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase
Definition: AbstractTestCase.php:29
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:88
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:646
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsDataProvider
‪static pageIsRenderedWithPathsDataProvider()
Definition: SiteRequestTest.php:132
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\setUp
‪setUp()
Definition: SiteRequestTest.php:35
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithDomainsDataProvider
‪static pageIsRenderedWithDomainsDataProvider()
Definition: SiteRequestTest.php:292
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider
‪static pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider()
Definition: SiteRequestTest.php:197
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageIsRendered
‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
Definition: SiteRequestTest.php:401
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildErrorHandlingConfiguration
‪buildErrorHandlingConfiguration(string $handler, array $codes)
Definition: SiteBasedTestTrait.php:142
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandling
‪crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandling(string $uri)
Definition: SiteRequestTest.php:994
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:30
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling(string $uri)
Definition: SiteRequestTest.php:787
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsAreRedirected
‪crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders)
Definition: SiteRequestTest.php:948
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\requestWithInvalidLegacyQueryParametersDisplayPageNotFoundPage
‪requestWithInvalidLegacyQueryParametersDisplayPageNotFoundPage(UriInterface $uri)
Definition: SiteRequestTest.php:1053
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPaths
‪pageIsRenderedWithPaths(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:169
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithValidCacheHashDataProvider
‪static pageIsRenderedWithValidCacheHashDataProvider()
Definition: SiteRequestTest.php:812
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\hiddenPageSends404ResponseRegardlessOfVisitorGroup
‪hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:688
‪TYPO3\CMS\Core\Utility\PermutationUtility
Definition: PermutationUtility.php:24
‪TYPO3\CMS\Core\Utility\HttpUtility\buildQueryString
‪static string buildQueryString(array $parameters, string $prependCharacter='', bool $skipEmptyParameters=false)
Definition: HttpUtility.php:124
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRenderingStopsWithInvalidCacheHashDataProvider
‪static pageRenderingStopsWithInvalidCacheHashDataProvider()
Definition: SiteRequestTest.php:713
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderIsRenderedDataProvider
‪static restrictedPageWithParentSysFolderIsRenderedDataProvider()
Definition: SiteRequestTest.php:533
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:18
‪TYPO3\CMS\Core\Utility\PermutationUtility\meltStringItems
‪static string[] meltStringItems(array $payload, string $previousResult='')
Definition: PermutationUtility.php:36
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider
‪static hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider()
Definition: SiteRequestTest.php:674
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:98
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:451
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedDataProvider
‪static shortcutsAreRedirectedDataProvider()
Definition: SiteRequestTest.php:60
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:481
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling(string $uri)
Definition: SiteRequestTest.php:766
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseBaseDataProvider
‪static pageIsRenderedWithPathsAndChineseBaseDataProvider()
Definition: SiteRequestTest.php:258
‪TYPO3\CMS\Core\Utility\HttpUtility
Definition: HttpUtility.php:24
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedToFirstSubPage
‪shortcutsAreRedirectedToFirstSubPage(string $uri)
Definition: SiteRequestTest.php:80
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderIsRendered
‪restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
Definition: SiteRequestTest.php:544
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:505
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageIsRenderedDataProvider
‪static restrictedPageIsRenderedDataProvider()
Definition: SiteRequestTest.php:358
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseBase
‪pageIsRenderedWithPathsAndChineseBase(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:267
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\getUrisWithInvalidLegacyQueryParameters
‪static getUrisWithInvalidLegacyQueryParameters()
Definition: SiteRequestTest.php:1028