2 declare(strict_types = 1);
21 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
22 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
23 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
24 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
25 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
35 private $siteTitle =
'A Company that Manufactures Everything Inc';
44 parent::setUpBeforeClass();
45 static::initializeDatabaseSnapshot();
50 static::destroyDatabaseSnapshot();
51 parent::tearDownAfterClass();
54 protected function setUp()
59 $this->internalRequestContext = (
new InternalRequestContext())
60 ->withGlobalSettings([
'TYPO3_CONF_VARS' => static::TYPO3_CONF_VARS]);
62 $this->withDatabaseSnapshot(
function () {
69 $backendUser = $this->setUpBackendUserFromFixture(1);
72 $scenarioFile = __DIR__ .
'/Fixtures/SlugScenario.yaml';
73 $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
74 $writer = DataHandlerWriter::withBackendUser($backendUser);
75 $writer->invokeFactory($factory);
76 static::failIfArrayIsNotEmpty(
80 $this->setUpFrontendRootPage(
83 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
84 'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
87 'title' =>
'ACME Root',
88 'sitetitle' => $this->siteTitle,
95 unset($this->internalRequestContext);
105 'https://website.local/',
106 'https://website.local/?',
107 'https://website.local//',
110 return $this->wrapInArray(
111 $this->keysFromValues($domainPaths)
128 $expectedStatusCode = 307;
129 $expectedHeaders = [
'location' => [
'https://website.local/welcome']];
131 $response = $this->executeFrontendRequest(
132 new InternalRequest($uri),
133 $this->internalRequestContext
135 static::assertSame($expectedStatusCode, $response->getStatusCode());
136 static::assertSame($expectedHeaders, $response->getHeaders());
145 'https://website.local/',
146 'https://website.local/?',
147 'https://website.local//',
150 return $this->wrapInArray(
151 $this->keysFromValues($domainPaths)
171 $expectedStatusCode = 307;
173 'location' => [
'https://website.local/en-en/'],
176 $response = $this->executeFrontendRequest(
177 new InternalRequest($uri),
178 $this->internalRequestContext
180 static::assertSame($expectedStatusCode, $response->getStatusCode());
181 static::assertSame($expectedHeaders, $response->getHeaders());
200 $expectedStatusCode = 200;
201 $expectedPageTitle =
'EN: Welcome';
203 $response = $this->executeFrontendRequest(
204 new InternalRequest($uri),
205 $this->internalRequestContext,
208 $responseStructure = ResponseContent::fromString(
209 (
string)$response->getBody()
214 $response->getStatusCode()
218 $responseStructure->getScopePath(
'template/sitetitle')
222 $responseStructure->getScopePath(
'page/title')
240 $expectedStatusCode = 307;
241 $expectedHeaders = [
'location' => [
'https://website.local/en-en/welcome']];
243 $uri =
'https://website.other/any/invalid/slug';
244 $response = $this->executeFrontendRequest(
245 new InternalRequest($uri),
246 $this->internalRequestContext
251 $response->getStatusCode()
255 $response->getHeaders()
278 $uri =
'https://website.local/any/invalid/slug';
279 $response = $this->executeFrontendRequest(
280 new InternalRequest($uri),
281 $this->internalRequestContext
286 $response->getStatusCode()
288 static::assertStringContainsString(
289 'message: The requested page does not exist',
290 (
string)$response->getBody()
308 $uri =
'https://website.local/en-en/any/invalid/slug';
309 $response = $this->executeFrontendRequest(
310 new InternalRequest($uri),
311 $this->internalRequestContext
316 $response->getStatusCode()
318 static::assertContains(
319 'message: The requested page does not exist',
320 (
string)$response->getBody()
338 $uri =
'https://website.local/en-en/?type=13';
339 $response = $this->executeFrontendRequest(
340 new InternalRequest($uri),
341 $this->internalRequestContext
346 $response->getStatusCode()
348 self::assertStringContainsString(
349 'message: The page is not configured',
350 (
string)$response->getBody()
360 'https://website.local/en-en/welcome',
361 'https://website.local/fr-fr/bienvenue',
362 'https://website.local/fr-ca/bienvenue',
366 function (
string $uri) {
367 if (strpos($uri,
'/fr-fr/') !==
false) {
368 $expectedPageTitle =
'FR: Welcome';
369 } elseif (strpos($uri,
'/fr-ca/') !==
false) {
370 $expectedPageTitle =
'FR-CA: Welcome';
372 $expectedPageTitle =
'EN: Welcome';
374 return [$uri, $expectedPageTitle];
376 $this->keysFromValues($domainPaths)
399 $response = $this->executeFrontendRequest(
400 new InternalRequest($uri),
401 $this->internalRequestContext
403 $responseStructure = ResponseContent::fromString(
404 (
string)$response->getBody()
409 $response->getStatusCode()
413 $responseStructure->getScopePath(
'template/sitetitle')
417 $responseStructure->getScopePath(
'page/title')
427 'https://website.us/welcome',
428 'https://website.fr/bienvenue',
429 'https://website.ca/bienvenue',
433 function (
string $uri) {
434 if (strpos($uri,
'.fr/') !==
false) {
435 $expectedPageTitle =
'FR: Welcome';
436 } elseif (strpos($uri,
'.ca/') !==
false) {
437 $expectedPageTitle =
'FR-CA: Welcome';
439 $expectedPageTitle =
'EN: Welcome';
441 return [$uri, $expectedPageTitle];
443 $this->keysFromValues($domainPaths)
466 $response = $this->executeFrontendRequest(
467 new InternalRequest($uri),
468 $this->internalRequestContext
470 $responseStructure = ResponseContent::fromString(
471 (
string)$response->getBody()
476 $response->getStatusCode()
480 $responseStructure->getScopePath(
'template/sitetitle')
484 $responseStructure->getScopePath(
'page/title')
495 [
'https://website.local/my-acme/whitepapers', 1,
'Whitepapers'],
496 [
'https://website.local/my-acme/whitepapers/products', 1,
'Products'],
497 [
'https://website.local/my-acme/whitepapers/solutions', 1,
'Solutions'],
499 [
'https://website.local/my-acme/whitepapers', 2,
'Whitepapers'],
500 [
'https://website.local/my-acme/whitepapers/products', 2,
'Products'],
501 [
'https://website.local/my-acme/whitepapers/research', 2,
'Research'],
502 [
'https://website.local/my-acme/forecasts', 2,
'Forecasts'],
503 [
'https://website.local/my-acme/forecasts/current-year', 2,
'Current Year'],
505 [
'https://website.local/my-acme/whitepapers', 3,
'Whitepapers'],
506 [
'https://website.local/my-acme/whitepapers/products', 3,
'Products'],
507 [
'https://website.local/my-acme/whitepapers/solutions', 3,
'Solutions'],
508 [
'https://website.local/my-acme/whitepapers/research', 3,
'Research'],
509 [
'https://website.local/my-acme/forecasts', 3,
'Forecasts'],
510 [
'https://website.local/my-acme/forecasts/current-year', 3,
'Current Year'],
513 return $this->keysFromTemplate($instructions,
'%1$s (user:%2$s)');
531 $response = $this->executeFrontendRequest(
532 new InternalRequest($uri),
533 $this->internalRequestContext
534 ->withFrontendUserId($frontendUserId)
536 $responseStructure = ResponseContent::fromString(
537 (
string)$response->getBody()
542 $response->getStatusCode()
546 $responseStructure->getScopePath(
'template/sitetitle')
550 $responseStructure->getScopePath(
'page/title')
561 [
'https://website.local/my-acme/whitepapers', 0],
563 [
'https://website.local/my-acme/whitepapers/solutions', 0],
564 [
'https://website.local/my-acme/whitepapers/research', 0],
565 [
'https://website.local/my-acme/forecasts', 0],
568 [
'https://website.local/my-acme/whitepapers/research', 1],
569 [
'https://website.local/my-acme/forecasts', 1],
572 [
'https://website.local/my-acme/whitepapers/solutions', 2],
575 return $this->keysFromTemplate($instructions,
'%1$s (user:%2$s)');
592 $response = $this->executeFrontendRequest(
593 new InternalRequest($uri),
594 $this->internalRequestContext
595 ->withFrontendUserId($frontendUserId)
600 $response->getStatusCode()
603 (
string)$response->getBody(),
605 static::stringContains(
'Reason: ID was not an accessible page'),
606 static::stringContains(
'Reason: Subsection was found and not accessible')
627 $response = $this->executeFrontendRequest(
628 new InternalRequest($uri),
629 $this->internalRequestContext
630 ->withFrontendUserId($frontendUserId)
635 $response->getStatusCode()
637 static::assertContains(
638 'reasons: code,fe_group',
639 (
string)$response->getBody()
642 (
string)$response->getBody(),
644 static::stringContains(
'message: ID was not an accessible page'),
645 static::stringContains(
'message: Subsection was found and not accessible')
660 $this->markTestSkipped(
'Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
669 $response = $this->executeFrontendRequest(
670 new InternalRequest($uri),
671 $this->internalRequestContext
672 ->withFrontendUserId($frontendUserId)
677 $response->getStatusCode()
697 $response = $this->executeFrontendRequest(
698 new InternalRequest($uri),
699 $this->internalRequestContext
700 ->withFrontendUserId($frontendUserId)
702 $json = json_decode((
string)$response->getBody(),
true);
706 $response->getStatusCode()
709 $json[
'message'] ??
null,
711 static::identicalTo(
'ID was not an accessible page'),
712 static::identicalTo(
'Subsection was found and not accessible')
723 'https://website.local/',
733 '?testing[value]=1&cHash=',
734 '?testing[value]=1&cHash=WRONG',
737 return $this->wrapInArray(
738 $this->keysFromValues(
757 $this->expectExceptionCode(1518472189);
758 $this->expectException(PageNotFoundException::class);
760 $this->executeFrontendRequest(
761 new InternalRequest($uri),
762 $this->internalRequestContext
774 $response = $this->executeFrontendRequest(
775 new InternalRequest($uri),
776 $this->internalRequestContext->withMergedGlobalSettings([
777 'TYPO3_CONF_VARS' => [
779 'pageNotFound_handling' =>
'READFILE:typo3/sysext/core/Tests/Functional/Fixtures/Frontend/PageError.txt',
787 $response->getStatusCode()
790 (
string)$response->getBody(),
792 static::stringContains(
'reason: Request parameters could not be validated (&cHash empty)'),
793 static::stringContains(
'reason: Request parameters could not be validated (&cHash comparison failed)')
813 $response = $this->executeFrontendRequest(
814 new InternalRequest($uri),
815 $this->internalRequestContext
820 $response->getStatusCode()
823 (
string)$response->getBody(),
825 static::stringContains(
'message: Request parameters could not be validated (&cHash empty)'),
826 static::stringContains(
'message: Request parameters could not be validated (&cHash comparison failed)')
840 $this->markTestSkipped(
'Skipped until PageContentErrorHandler::handlePageError does not use HTTP anymore');
849 $response = $this->executeFrontendRequest(
850 new InternalRequest($uri),
851 $this->internalRequestContext
856 $response->getStatusCode()
875 $response = $this->executeFrontendRequest(
876 new InternalRequest($uri),
877 $this->internalRequestContext
879 $json = json_decode((
string)$response->getBody(),
true);
883 $response->getStatusCode()
886 $json[
'message'] ??
null,
888 static::identicalTo(
'Request parameters could not be validated (&cHash empty)'),
889 static::identicalTo(
'Request parameters could not be validated (&cHash comparison failed)')
900 'https://website.local/',
909 'welcome?cHash=f42b850e435f0cedd366f5db749fc1af',
916 $dataSet = $this->wrapInArray(
917 $this->keysFromValues(
938 $response = $this->executeFrontendRequest(
939 new InternalRequest($uri),
940 $this->internalRequestContext
942 $responseStructure = ResponseContent::fromString(
943 (
string)$response->getBody()
947 $responseStructure->getScopePath(
'getpost/testing.value')