‪TYPO3CMS  11.5
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 
22 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
23 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
24 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
25 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
26 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
27 
32 {
33  protected function ‪setUp(): void
34  {
35  parent::setUp();
36 
37  $this->withDatabaseSnapshot(function () {
38  $this->‪setUpDatabase();
39  });
40  }
41 
42  protected function ‪setUpDatabase(): void
43  {
44  $backendUser = $this->setUpBackendUserFromFixture(1);
46 
47  $scenarioFile = __DIR__ . '/Fixtures/PlainScenario.yaml';
48  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
49  $writer = DataHandlerWriter::withBackendUser($backendUser);
50  $writer->invokeFactory($factory);
51  static::failIfArrayIsNotEmpty(
52  $writer->getErrors()
53  );
54 
55  $this->setUpFrontendRootPage(
56  1000,
57  [
58  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
59  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
60  ],
61  [
62  'title' => 'ACME Root',
63  ]
64  );
65  }
66 
70  public function ‪shortcutsAreRedirectedDataProvider(): array
71  {
72  $domainPaths = [
73  // @todo Implicit strict mode handling when calling non-existent site
74  // '/',
75  // 'https://localhost/',
76  'https://website.local/',
77  ];
78 
79  $queries = [
80  '',
81  ];
82 
83  return $this->‪wrapInArray(
84  $this->‪keysFromValues(
85  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
86  )
87  );
88  }
89 
96  public function ‪shortcutsAreRedirectedToFirstSubPage(string $uri): void
97  {
99  'website-local',
100  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
101  [
102  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
103  ]
104  );
105 
106  $expectedStatusCode = 307;
107  $expectedHeaders = ['location' => ['https://website.local/en-en/']];
108 
109  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
110  self::assertSame($expectedStatusCode, $response->getStatusCode());
111  self::assertSame($expectedHeaders, $response->getHeaders());
112  }
113 
120  public function ‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri): void
121  {
123  'website-local',
124  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
125  [
126  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
127  ]
128  );
129 
130  $expectedStatusCode = 200;
131  $expectedPageTitle = 'EN: Welcome';
132 
133  $response = $this->executeFrontendSubRequest(
134  new InternalRequest($uri),
135  null,
136  true
137  );
138  $responseStructure = ResponseContent::fromString(
139  (string)$response->getBody()
140  );
141 
142  self::assertSame(
143  $expectedStatusCode,
144  $response->getStatusCode()
145  );
146  self::assertSame(
147  $expectedPageTitle,
148  $responseStructure->getScopePath('page/title')
149  );
150  }
151 
155  public function ‪pageIsRenderedWithPathsDataProvider(): array
156  {
157  $domainPaths = [
158  // @todo currently base needs to be defined with domain
159  // '/',
160  'https://website.local/',
161  ];
162 
163  $languagePaths = [
164  'en-en/',
165  'fr-fr/',
166  'fr-ca/',
167  '简/',
168  ];
169 
170  $queries = [
171  '?id=1100',
172  ];
173 
174  return array_map(
175  static function (string $uri) {
176  if (str_contains($uri, '/fr-fr/')) {
177  $expectedPageTitle = 'FR: Welcome';
178  } elseif (str_contains($uri, '/fr-ca/')) {
179  $expectedPageTitle = 'FR-CA: Welcome';
180  } elseif (strpos($uri, '/简/') !== false) {
181  $expectedPageTitle = 'ZH-CN: Welcome';
182  } else {
183  $expectedPageTitle = 'EN: Welcome';
184  }
185  return [$uri, $expectedPageTitle];
186  },
187  $this->‪keysFromValues(
188  ‪PermutationUtility::meltStringItems([$domainPaths, $languagePaths, $queries])
189  )
190  );
191  }
192 
200  public function ‪pageIsRenderedWithPaths(string $uri, string $expectedPageTitle): void
201  {
203  'website-local',
204  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
205  [
206  $this->‪buildDefaultLanguageConfiguration('EN', '/en-en/'),
207  $this->‪buildLanguageConfiguration('FR', '/fr-fr/', ['EN']),
208  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
209  $this->‪buildLanguageConfiguration('ZH', '/简/', ['EN']),
210  ]
211  );
212 
213  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
214  $responseStructure = ResponseContent::fromString(
215  (string)$response->getBody()
216  );
217 
218  self::assertSame(
219  200,
220  $response->getStatusCode()
221  );
222  self::assertSame(
223  $expectedPageTitle,
224  $responseStructure->getScopePath('page/title')
225  );
226  }
227 
229  {
230  $domainPaths = [
231  // @todo currently base needs to be defined with domain
232  // '/',
233  'https://website.local/',
234  ];
235 
236  $languagePaths = [
237  '简/',
238  'fr-fr/',
239  'fr-ca/',
240  ];
241 
242  $queries = [
243  '?id=1110',
244  ];
245 
246  return array_map(
247  static function (string $uri) {
248  if (strpos($uri, '/fr-fr/') !== false) {
249  $expectedPageTitle = 'FR: Welcome ZH Default';
250  } elseif (strpos($uri, '/fr-ca/') !== false) {
251  $expectedPageTitle = 'FR-CA: Welcome ZH Default';
252  } else {
253  $expectedPageTitle = 'ZH-CN: Welcome Default';
254  }
255  return [$uri, $expectedPageTitle];
256  },
257  $this->‪keysFromValues(
258  ‪PermutationUtility::meltStringItems([$domainPaths, $languagePaths, $queries])
259  )
260  );
261  }
262 
267  public function ‪pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle): void
268  {
270  'website-local',
271  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
272  [
273  $this->‪buildDefaultLanguageConfiguration('ZH-CN', '/简/'),
274  $this->‪buildLanguageConfiguration('FR', '/fr-fr/', ['EN']),
275  $this->‪buildLanguageConfiguration('FR-CA', '/fr-ca/', ['FR', 'EN']),
276  ]
277  );
278 
279  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
280  $responseStructure = ResponseContent::fromString(
281  (string)$response->getBody()
282  );
283 
284  self::assertSame(
285  200,
286  $response->getStatusCode()
287  );
288  self::assertSame(
289  $expectedPageTitle,
290  $responseStructure->getScopePath('page/title')
291  );
292  }
293 
295  {
296  return [
297  ['https://website.local/简/简/?id=1110', 'ZH-CN: Welcome Default'],
298  ];
299  }
300 
305  public function ‪pageIsRenderedWithPathsAndChineseBase(string $uri, string $expectedPageTitle): void
306  {
308  'website-local',
309  $this->‪buildSiteConfiguration(1000, 'https://website.local/简/'),
310  [
311  $this->‪buildDefaultLanguageConfiguration('ZH-CN', '/简/'),
312  ]
313  );
314 
315  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
316  $responseStructure = ResponseContent::fromString(
317  (string)$response->getBody()
318  );
319 
320  self::assertSame(
321  200,
322  $response->getStatusCode()
323  );
324  self::assertSame(
325  $expectedPageTitle,
326  $responseStructure->getScopePath('page/title')
327  );
328  }
329 
334  {
335  $domainPaths = [
336  // @todo: This turns into a redirect to the default language (".us") making this function obsolete
337  // 'https://website.local/',
338  'https://website.us/',
339  'https://website.fr/',
340  // Explicitly testing umlaut domains
341  'https://wäbsite.ca/',
342  // Explicitly testing chinese character domains
343  'https://website.简/',
344  // @todo Implicit strict mode handling when calling non-existent site
345  // 'https://website.other/',
346  ];
347 
348  $queries = [
349  '?id=1100',
350  ];
351 
352  return array_map(
353  static function (string $uri) {
354  if (str_contains($uri, '.fr/')) {
355  $expectedPageTitle = 'FR: Welcome';
356  } elseif (str_contains($uri, '.ca/')) {
357  $expectedPageTitle = 'FR-CA: Welcome';
358  } elseif (strpos($uri, '.简/') !== false) {
359  $expectedPageTitle = 'ZH-CN: Welcome';
360  } else {
361  $expectedPageTitle = 'EN: Welcome';
362  }
363  return [$uri, $expectedPageTitle];
364  },
365  $this->‪keysFromValues(
366  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
367  )
368  );
369  }
370 
378  public function ‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle): void
379  {
381  'website-local',
382  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
383  [
384  $this->‪buildDefaultLanguageConfiguration('EN', 'https://website.us/'),
385  $this->‪buildLanguageConfiguration('FR', 'https://website.fr/', ['EN']),
386  $this->‪buildLanguageConfiguration('FR-CA', 'https://wäbsite.ca/', ['FR', 'EN']),
387  $this->‪buildLanguageConfiguration('ZH', 'https://website.简/', ['EN']),
388  ]
389  );
390 
391  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
392  $responseStructure = ResponseContent::fromString(
393  (string)$response->getBody()
394  );
395 
396  self::assertSame(
397  200,
398  $response->getStatusCode()
399  );
400  self::assertSame(
401  $expectedPageTitle,
402  $responseStructure->getScopePath('page/title')
403  );
404  }
405 
410  {
411  $instructions = [
412  // frontend user 1
413  ['https://website.local/?id=1510', 1, 'Whitepapers'],
414  ['https://website.local/?id=1511', 1, 'Products'],
415  ['https://website.local/?id=1512', 1, 'Solutions'],
416  // frontend user 2
417  ['https://website.local/?id=1510', 2, 'Whitepapers'],
418  ['https://website.local/?id=1511', 2, 'Products'],
419  ['https://website.local/?id=1515', 2, 'Research'],
420  ['https://website.local/?id=1520', 2, 'Forecasts'],
421  ['https://website.local/?id=1521', 2, 'Current Year'],
422  // frontend user 3
423  ['https://website.local/?id=1510', 3, 'Whitepapers'],
424  ['https://website.local/?id=1511', 3, 'Products'],
425  ['https://website.local/?id=1512', 3, 'Solutions'],
426  ['https://website.local/?id=1515', 3, 'Research'],
427  ['https://website.local/?id=1520', 3, 'Forecasts'],
428  ['https://website.local/?id=1521', 3, 'Current Year'],
429  // frontend user 1 with index
430  ['https://website.local/index.php?id=1510', 1, 'Whitepapers'],
431  ['https://website.local/index.php?id=1511', 1, 'Products'],
432  ['https://website.local/index.php?id=1512', 1, 'Solutions'],
433  // frontend user 2
434  ['https://website.local/index.php?id=1510', 2, 'Whitepapers'],
435  ['https://website.local/index.php?id=1511', 2, 'Products'],
436  ['https://website.local/index.php?id=1515', 2, 'Research'],
437  ['https://website.local/index.php?id=1520', 2, 'Forecasts'],
438  ['https://website.local/index.php?id=1521', 2, 'Current Year'],
439  // frontend user 3
440  ['https://website.local/index.php?id=1510', 3, 'Whitepapers'],
441  ['https://website.local/index.php?id=1511', 3, 'Products'],
442  ['https://website.local/index.php?id=1512', 3, 'Solutions'],
443  ['https://website.local/index.php?id=1515', 3, 'Research'],
444  ['https://website.local/index.php?id=1520', 3, 'Forecasts'],
445  ['https://website.local/index.php?id=1521', 3, 'Current Year'],
446  ];
447 
448  return $this->‪keysFromTemplate($instructions, '%1$s (user:%2$s)');
449  }
450 
459  public function ‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
460  {
462  'website-local',
463  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
464  );
465 
466  $response = $this->executeFrontendSubRequest(
467  new InternalRequest($uri),
468  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
469  );
470  $responseStructure = ResponseContent::fromString(
471  (string)$response->getBody()
472  );
473 
474  self::assertSame(
475  200,
476  $response->getStatusCode()
477  );
478  self::assertSame(
479  $expectedPageTitle,
480  $responseStructure->getScopePath('page/title')
481  );
482  }
483 
488  {
489  $instructions = [
490  // no frontend user given
491  ['https://website.local/?id=1510', 0],
492  ['https://website.local/?id=1511', 0],
493  ['https://website.local/?id=1512', 0],
494  ['https://website.local/?id=1515', 0],
495  ['https://website.local/?id=1520', 0],
496  ['https://website.local/?id=1521', 0],
497  ['https://website.local/?id=2021', 0],
498  // frontend user 1
499  ['https://website.local/?id=1515', 1],
500  ['https://website.local/?id=1520', 1],
501  ['https://website.local/?id=1521', 1],
502  ['https://website.local/?id=2021', 1],
503  // frontend user 2
504  ['https://website.local/?id=1512', 2],
505  ['https://website.local/?id=2021', 2],
506  ];
507 
508  return $this->‪keysFromTemplate($instructions, '%1$s (user:%2$s)');
509  }
510 
519  {
521  'website-local',
522  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
523  );
524 
525  $response = $this->executeFrontendSubRequest(
526  new InternalRequest($uri),
527  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
528  );
529 
530  self::assertSame(
531  403,
532  $response->getStatusCode()
533  );
534  self::assertThat(
535  (string)$response->getBody(),
536  self::logicalOr(
537  self::stringContains('Reason: ID was not an accessible page'),
538  self::stringContains('Reason: Subsection was found and not accessible')
539  )
540  );
541  }
542 
552  {
553  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
554 
556  'website-local',
557  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
558  [],
559  $this->‪buildErrorHandlingConfiguration('Page', [403])
560  );
561 
562  $response = $this->executeFrontendSubRequest(
563  new InternalRequest($uri),
564  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
565  );
566 
567  self::assertSame(
568  403,
569  $response->getStatusCode()
570  );
571  }
572 
581  {
583  'website-local',
584  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
585  [],
586  $this->‪buildErrorHandlingConfiguration('PHP', [403])
587  );
588 
589  $response = $this->executeFrontendSubRequest(
590  new InternalRequest($uri),
591  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
592  );
593  $json = json_decode((string)$response->getBody(), true);
594 
595  self::assertSame(
596  403,
597  $response->getStatusCode()
598  );
599  self::assertThat(
600  $json['message'] ?? null,
601  self::logicalOr(
602  self::identicalTo('ID was not an accessible page'),
603  self::identicalTo('Subsection was found and not accessible')
604  )
605  );
606  }
607 
612  {
613  $instructions = [
614  // frontend user 4
615  ['https://website.local/?id=2021', 4, 'FEGroups Restricted'],
616  ];
617 
618  return $this->‪keysFromTemplate($instructions, '%1$s (user:%2$s)');
619  }
620 
629  public function ‪restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle): void
630  {
632  'website-local',
633  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
634  );
635 
636  $response = $this->executeFrontendSubRequest(
637  new InternalRequest($uri),
638  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
639  );
640  $responseStructure = ResponseContent::fromString(
641  (string)$response->getBody()
642  );
643 
644  self::assertSame(
645  200,
646  $response->getStatusCode()
647  );
648  self::assertSame(
649  $expectedPageTitle,
650  $responseStructure->getScopePath('page/title')
651  );
652  }
653 
658  {
659  $instructions = [
660  // no frontend user given
661  ['https://website.local/?id=2021', 0],
662  // frontend user 1
663  ['https://website.local/?id=2021', 1],
664  // frontend user 2
665  ['https://website.local/?id=2021', 2],
666  // frontend user 3
667  ['https://website.local/?id=2021', 3],
668  ];
669 
670  return $this->‪keysFromTemplate($instructions, '%1$s (user:%2$s)');
671  }
672 
681  {
683  'website-local',
684  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
685  [],
686  $this->‪buildErrorHandlingConfiguration('Fluid', [403])
687  );
688 
689  $response = $this->executeFrontendSubRequest(
690  new InternalRequest($uri),
691  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
692  );
693 
694  self::assertSame(
695  403,
696  $response->getStatusCode()
697  );
698  self::assertStringContainsString(
699  'reasons: code,fe_group',
700  (string)$response->getBody()
701  );
702  self::assertThat(
703  (string)$response->getBody(),
704  self::logicalOr(
705  self::stringContains('message: ID was not an accessible page'),
706  self::stringContains('message: Subsection was found and not accessible')
707  )
708  );
709  }
710 
720  {
721  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
722 
724  'website-local',
725  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
726  [],
727  $this->‪buildErrorHandlingConfiguration('Page', [403])
728  );
729 
730  $response = $this->executeFrontendSubRequest(
731  new InternalRequest($uri),
732  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
733  );
734 
735  self::assertSame(
736  403,
737  $response->getStatusCode()
738  );
739  }
740 
749  {
751  'website-local',
752  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
753  [],
754  $this->‪buildErrorHandlingConfiguration('PHP', [403])
755  );
756 
757  $response = $this->executeFrontendSubRequest(
758  new InternalRequest($uri),
759  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
760  );
761  $json = json_decode((string)$response->getBody(), true);
762 
763  self::assertSame(
764  403,
765  $response->getStatusCode()
766  );
767  self::assertThat(
768  $json['message'] ?? null,
769  self::logicalOr(
770  self::identicalTo('ID was not an accessible page'),
771  self::identicalTo('Subsection was found and not accessible')
772  )
773  );
774  }
775 
780  {
781  $instructions = [
782  // hidden page, always 404
783  ['https://website.local/?id=1800', 0],
784  ['https://website.local/?id=1800', 1],
785  // hidden fe group restricted and fegroup generally okay
786  ['https://website.local/?id=2022', 4],
787  ];
788 
789  return $this->‪keysFromTemplate($instructions, '%1$s (user:%2$s)');
790  }
791 
796  public function ‪hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId): void
797  {
799  'website-local',
800  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
801  [],
802  $this->‪buildErrorHandlingConfiguration('PHP', [404])
803  );
804 
805  $response = $this->executeFrontendSubRequest(
806  new InternalRequest($uri),
807  (new InternalRequestContext())->withFrontendUserId($frontendUserId)
808  );
809  $json = json_decode((string)$response->getBody(), true);
810 
811  self::assertSame(
812  404,
813  $response->getStatusCode()
814  );
815  self::assertThat(
816  $json['message'] ?? null,
817  self::identicalTo('The requested page does not exist!')
818  );
819  }
820 
825  {
826  $domainPaths = [
827  'https://website.local/',
828  ];
829 
830  $queries = [
831  '?',
832  '?id=1000',
833  '?id=1100',
834  ];
835 
836  $customQueries = [
837  '&testing[value]=1',
838  '&testing[value]=1&cHash=',
839  '&testing[value]=1&cHash=WRONG',
840  ];
841 
842  return $this->‪wrapInArray(
843  $this->‪keysFromValues(
844  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
845  )
846  );
847  }
848 
856  {
858  'website-local',
859  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
860  [],
861  $this->‪buildErrorHandlingConfiguration('Fluid', [404])
862  );
863 
864  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
865 
866  self::assertSame(
867  404,
868  $response->getStatusCode()
869  );
870  self::assertThat(
871  (string)$response->getBody(),
872  self::logicalOr(
873  self::stringContains('message: Request parameters could not be validated (&amp;cHash empty)'),
874  self::stringContains('message: Request parameters could not be validated (&amp;cHash comparison failed)')
875  )
876  );
877  }
878 
887  {
888  self::markTestSkipped('Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
889 
891  'website-local',
892  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
893  [],
894  $this->‪buildErrorHandlingConfiguration('Page', [404])
895  );
896 
897  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
898 
899  self::assertSame(
900  404,
901  $response->getStatusCode()
902  );
903  }
904 
912  {
914  'website-local',
915  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
916  [],
917  $this->‪buildErrorHandlingConfiguration('PHP', [404])
918  );
919 
920  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
921  $json = json_decode((string)$response->getBody(), true);
922 
923  self::assertSame(
924  404,
925  $response->getStatusCode()
926  );
927  self::assertThat(
928  $json['message'] ?? null,
929  self::logicalOr(
930  self::identicalTo('Request parameters could not be validated (&cHash empty)'),
931  self::identicalTo('Request parameters could not be validated (&cHash comparison failed)')
932  )
933  );
934  }
935 
940  {
941  $domainPaths = [
942  // @todo Implicit strict mode handling when calling non-existent site
943  // '/',
944  // 'https://localhost/',
945  'https://website.local/',
946  ];
947 
948  // cHash has been calculated with encryption key set to
949  // '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6'
950  $queries = [
951  // @todo Currently fails since cHash is verified after(!) redirect to page 1100
952  // '?&cHash=7d1f13fa91159dac7feb3c824936b39d&id=1000',
953  '?&cHash=f42b850e435f0cedd366f5db749fc1af&id=1100',
954  ];
955 
956  $customQueries = [
957  '&testing[value]=1',
958  ];
959 
960  return $this->‪wrapInArray(
961  $this->‪keysFromValues(
962  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
963  )
964  );
965  }
966 
973  public function ‪pageIsRenderedWithValidCacheHash($uri): void
974  {
976  'website-local',
977  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
978  );
979 
980  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
981  $responseStructure = ResponseContent::fromString(
982  (string)$response->getBody()
983  );
984  self::assertSame(
985  '1',
986  $responseStructure->getScopePath('getpost/testing.value')
987  );
988  }
989 
994  {
995  $domainPaths = [
996  'https://website.local/',
997  'https://website.local/index.php',
998  ];
999 
1000  $queries = [
1001  '',
1002  '?id=1000',
1003  '?type=0',
1004  '?id=1000&type=0',
1005  ];
1006 
1007  return $this->‪wrapInArray(
1008  $this->‪keysFromValues(
1009  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
1010  )
1011  );
1012  }
1013 
1021  {
1023  'website-local',
1024  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
1025  );
1026 
1027  $expectedStatusCode = 307;
1028  $expectedHeaders = ['X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'], 'location' => ['https://website.local/en-welcome']];
1029 
1030  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
1031  self::assertSame($expectedStatusCode, $response->getStatusCode());
1032  self::assertSame($expectedHeaders, $response->getHeaders());
1033  }
1034 
1036  {
1037  return [
1038  'shortcut is redirected #1' => [
1039  'https://website.local/index.php?id=2030',
1040  307,
1041  [
1042  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1043  'location' => ['https://blog.local/authors'],
1044  ],
1045  ],
1046  'shortcut is redirected #2' => [
1047  'https://website.local/?id=2030',
1048  307,
1049  [
1050  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1051  'location' => ['https://blog.local/authors'],
1052  ],
1053  ],
1054  'shortcut is redirected #3' => [
1055  'https://website.local/index.php?id=2030&type=0',
1056  307,
1057  [
1058  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1059  'location' => ['https://blog.local/authors'],
1060  ],
1061  ],
1062  'shortcut is redirected #4' => [
1063  'https://website.local/?id=2030&type=0',
1064  307,
1065  [
1066  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1067  'location' => ['https://blog.local/authors'],
1068  ],
1069  ],
1070  'shortcut is redirected #5' => [
1071  'https://website.local/?id=2030&type=1',
1072  307,
1073  [
1074  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1075  'location' => ['https://blog.local/authors?type=1'],
1076  ],
1077  ],
1078  'shortcut is redirected #6' => [
1079  'https://website.local/?id=2030&type=1&additional=value',
1080  307,
1081  [
1082  'X-Redirect-By' => ['TYPO3 Shortcut/Mountpoint'],
1083  'location' => ['https://blog.local/authors?additional=value&type=1&cHash=9a534a0ab3d092ac113a3d8b5ea577ba'],
1084  ],
1085  ],
1086  ];
1087  }
1088 
1093  public function ‪crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders): void
1094  {
1096  'website-local',
1097  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
1098  );
1100  'blog-local',
1101  $this->‪buildSiteConfiguration(2000, 'https://blog.local/')
1102  );
1103  $this->setUpFrontendRootPage(
1104  2000,
1105  [
1106  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
1107  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
1108  ],
1109  [
1110  'title' => 'ACME Blog',
1111  ]
1112  );
1113 
1114  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
1115  self::assertSame($expectedStatusCode, $response->getStatusCode());
1116  self::assertSame($expectedHeaders, $response->getHeaders());
1117  }
1118 
1120  {
1121  return [
1122  'shortcut requested by id on wrong site #1' => [
1123  'https://blog.local/index.php?id=2030',
1124  ],
1125  'shortcut requested by id on wrong site #2' => [
1126  'https://blog.local/?id=2030',
1127  ],
1128  'shortcut requested by id on wrong site #3' => [
1129  'https://blog.local/index.php?id=2030&type=0',
1130  ],
1131  'shortcut requested by id on wrong site #4' => [
1132  'https://blog.local/?id=2030&type=0',
1133  ],
1134  ];
1135  }
1136 
1142  {
1144  'website-local',
1145  $this->‪buildSiteConfiguration(1000, 'https://website.local/'),
1146  [],
1147  $this->‪buildErrorHandlingConfiguration('PHP', [404])
1148  );
1150  'blog-local',
1151  $this->‪buildSiteConfiguration(2000, 'https://blog.local/'),
1152  [],
1153  $this->‪buildErrorHandlingConfiguration('PHP', [404])
1154  );
1155 
1156  $this->setUpFrontendRootPage(
1157  2000,
1158  [
1159  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
1160  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
1161  ],
1162  [
1163  'title' => 'ACME Blog',
1164  ]
1165  );
1166  $response = $this->executeFrontendSubRequest(new InternalRequest($uri));
1167  $json = json_decode((string)$response->getBody(), true);
1168  self::assertSame(404, $response->getStatusCode());
1169  self::assertThat(
1170  $json['message'] ?? null,
1171  self::stringContains('ID was outside the domain')
1172  );
1173  }
1174 }
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingFluidErrorHandling(string $uri)
Definition: SiteRequestTest.php:855
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingFluidErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:680
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider
‪array hiddenPageSends404ResponseRegardlessOfVisitorGroupDataProvider()
Definition: SiteRequestTest.php:779
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithValidCacheHash
‪pageIsRenderedWithValidCacheHash($uri)
Definition: SiteRequestTest.php:973
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildErrorHandlingConfiguration
‪array buildErrorHandlingConfiguration(string $handler, array $codes)
Definition: SiteBasedTestTrait.php:186
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRenderingStopsWithInvalidCacheHashDataProvider
‪array pageRenderingStopsWithInvalidCacheHashDataProvider()
Definition: SiteRequestTest.php:824
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedAndRenderFirstSubPage
‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri)
Definition: SiteRequestTest.php:120
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:719
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
‪array restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorDataProvider()
Definition: SiteRequestTest.php:657
‪TYPO3\CMS\Core\Utility\PermutationUtility\meltStringItems
‪static array meltStringItems(array $payload, string $previousResult='')
Definition: PermutationUtility.php:36
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvided
‪checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvided(string $uri)
Definition: SiteRequestTest.php:1020
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
‪array restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider()
Definition: SiteRequestTest.php:487
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest
Definition: SiteRequestTest.php:32
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithValidCacheHashDataProvider
‪array pageIsRenderedWithValidCacheHashDataProvider()
Definition: SiteRequestTest.php:939
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseDefaultLanguage
‪pageIsRenderedWithPathsAndChineseDefaultLanguage(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:267
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪array buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:144
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithDomains
‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:378
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:58
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsAreRedirectedDataProvider
‪crossSiteShortcutsAreRedirectedDataProvider()
Definition: SiteRequestTest.php:1035
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\keysFromTemplate
‪array keysFromTemplate(array $array, string $template, callable $callback=null)
Definition: AbstractTestCase.php:102
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase
Definition: AbstractTestCase.php:29
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling
‪restrictedPageWithParentSysFolderSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:748
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\setUp
‪setUp()
Definition: SiteRequestTest.php:33
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseBaseDataProvider
‪pageIsRenderedWithPathsAndChineseBaseDataProvider()
Definition: SiteRequestTest.php:294
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageIsRendered
‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
Definition: SiteRequestTest.php:459
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandling
‪crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandling(string $uri)
Definition: SiteRequestTest.php:1141
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider
‪pageIsRenderedWithPathsAndChineseDefaultLanguageDataProvider()
Definition: SiteRequestTest.php:228
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPhpErrorHandling(string $uri)
Definition: SiteRequestTest.php:911
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsAreRedirected
‪crossSiteShortcutsAreRedirected(string $uri, int $expectedStatusCode, array $expectedHeaders)
Definition: SiteRequestTest.php:1093
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪array buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:126
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:598
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPaths
‪pageIsRenderedWithPaths(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:200
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\hiddenPageSends404ResponseRegardlessOfVisitorGroup
‪hiddenPageSends404ResponseRegardlessOfVisitorGroup(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:796
‪TYPO3\CMS\Core\Utility\PermutationUtility
Definition: PermutationUtility.php:24
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\wrapInArray
‪array wrapInArray(array $array)
Definition: AbstractTestCase.php:68
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\keysFromValues
‪array keysFromValues(array $array)
Definition: AbstractTestCase.php:82
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider
‪array checkIfIndexPhpReturnsShortcutRedirectWithPageIdAndTypeNumProvidedDataProvider()
Definition: SiteRequestTest.php:993
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsDataProvider
‪array pageIsRenderedWithPathsDataProvider()
Definition: SiteRequestTest.php:155
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:18
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\setUpDatabase
‪setUpDatabase()
Definition: SiteRequestTest.php:42
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithoutHavingErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:518
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:70
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageIsRenderedDataProvider
‪array restrictedPageIsRenderedDataProvider()
Definition: SiteRequestTest.php:409
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPageErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:551
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderIsRenderedDataProvider
‪array restrictedPageWithParentSysFolderIsRenderedDataProvider()
Definition: SiteRequestTest.php:611
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling
‪pageRequestSendsNotFoundResponseWithInvalidCacheHashWithHavingPageErrorHandling(string $uri)
Definition: SiteRequestTest.php:886
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪array buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:111
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider
‪crossSiteShortcutsWithWrongSiteHostSendsPageNotFoundWithoutHavingErrorHandlingDataProvider()
Definition: SiteRequestTest.php:1119
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedToFirstSubPage
‪shortcutsAreRedirectedToFirstSubPage(string $uri)
Definition: SiteRequestTest.php:96
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\shortcutsAreRedirectedDataProvider
‪array shortcutsAreRedirectedDataProvider()
Definition: SiteRequestTest.php:70
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageWithParentSysFolderIsRendered
‪restrictedPageWithParentSysFolderIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
Definition: SiteRequestTest.php:629
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorWithHavingPhpErrorHandling(string $uri, int $frontendUserId)
Definition: SiteRequestTest.php:580
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithPathsAndChineseBase
‪pageIsRenderedWithPathsAndChineseBase(string $uri, string $expectedPageTitle)
Definition: SiteRequestTest.php:305
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\SiteRequestTest\pageIsRenderedWithDomainsDataProvider
‪array pageIsRenderedWithDomainsDataProvider()
Definition: SiteRequestTest.php:333