‪TYPO3CMS  9.5
PlainRequestTest.php
Go to the documentation of this file.
1 <?php
2 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 
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;
26 
31 {
35  private ‪$siteTitle = 'A Company that Manufactures Everything Inc';
36 
41 
42  public static function ‪setUpBeforeClass()
43  {
44  parent::setUpBeforeClass();
45  static::initializeDatabaseSnapshot();
46  }
47 
48  public static function ‪tearDownAfterClass()
49  {
50  static::destroyDatabaseSnapshot();
51  parent::tearDownAfterClass();
52  }
53 
54  protected function ‪setUp()
55  {
56  parent::setUp();
57 
58  // these settings are forwarded to the frontend sub-request as well
59  $this->internalRequestContext = (new InternalRequestContext())
60  ->withGlobalSettings(['TYPO3_CONF_VARS' => static::TYPO3_CONF_VARS]);
61 
62  $this->withDatabaseSnapshot(function () {
63  $this->‪setUpDatabase();
64  });
65  }
66 
67  protected function ‪setUpDatabase()
68  {
69  $backendUser = $this->setUpBackendUserFromFixture(1);
71 
72  $scenarioFile = __DIR__ . '/Fixtures/PlainScenario.yaml';
73  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
74  $writer = DataHandlerWriter::withBackendUser($backendUser);
75  $writer->invokeFactory($factory);
76  static::failIfArrayIsNotEmpty(
77  $writer->getErrors()
78  );
79 
80  $this->setUpFrontendRootPage(
81  1000,
82  [
83  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
84  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
85  ],
86  [
87  'title' => 'ACME Root',
88  'sitetitle' => $this->siteTitle,
89  ]
90  );
91  $this->setUpFrontendRootPage(
92  3000,
93  [
94  'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
95  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
96  ],
97  [
98  'title' => 'ACME Archive',
99  'sitetitle' => $this->siteTitle,
100  ]
101  );
102  }
103 
104  protected function ‪tearDown()
105  {
106  unset($this->internalRequestContext);
107  parent::tearDown();
108  }
109 
113  public function ‪shortcutsAreRedirectedDataProvider(): array
114  {
115  $domainPaths = [
116  '/',
117  'https://localhost/',
118  'https://website.local/',
119  ];
120 
121  $queries = [
122  '?',
123  '?id=1000',
124  '?id=acme-root'
125  ];
126 
127  return $this->wrapInArray(
128  $this->keysFromValues(
129  ‪PermutationUtility::meltStringItems([$domainPaths, $queries])
130  )
131  );
132  }
133 
140  public function ‪shortcutsAreRedirectedToFirstSubPage(string $uri)
141  {
142  $expectedStatusCode = 307;
143  $expectedHeaders = ['location' => ['index.php?id=acme-first']];
144 
145  $response = $this->executeFrontendRequest(
146  new InternalRequest($uri),
147  $this->internalRequestContext
148  );
149  static::assertSame($expectedStatusCode, $response->getStatusCode());
150  static::assertSame($expectedHeaders, $response->getHeaders());
151  }
152 
159  public function ‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri)
160  {
161  $expectedStatusCode = 200;
162  $expectedPageTitle = 'EN: Welcome';
163 
164  $response = $this->executeFrontendRequest(
165  new InternalRequest($uri),
166  $this->internalRequestContext,
167  true
168  );
169  $responseStructure = ResponseContent::fromString(
170  (string)$response->getBody()
171  );
172 
173  static::assertSame(
174  $expectedStatusCode,
175  $response->getStatusCode()
176  );
177  static::assertSame(
178  $this->siteTitle,
179  $responseStructure->getScopePath('template/sitetitle')
180  );
181  static::assertSame(
182  $expectedPageTitle,
183  $responseStructure->getScopePath('page/title')
184  );
185  }
186 
190  public function ‪pageIsRenderedDataProvider(): array
191  {
192  $domainPaths = [
193  '/',
194  'https://localhost/',
195  'https://website.local/',
196  ];
197 
198  $queries = [
199  '?id=1100',
200  '?id=acme-first',
201  ];
202 
203  $languageQueries = [
204  '',
205  '&L=0',
206  '&L=1',
207  '&L=2',
208  ];
209 
210  return array_map(
211  function (string $uri) {
212  if (strpos($uri, '&L=1') !== false) {
213  $expectedPageTitle = 'FR: Welcome';
214  } elseif (strpos($uri, '&L=2') !== false) {
215  $expectedPageTitle = 'FR-CA: Welcome';
216  } else {
217  $expectedPageTitle = 'EN: Welcome';
218  }
219  return [$uri, $expectedPageTitle];
220  },
221  $this->keysFromValues(
222  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $languageQueries])
223  )
224  );
225  }
226 
234  public function ‪pageIsRendered(string $uri, string $expectedPageTitle)
235  {
236  $response = $this->executeFrontendRequest(
237  new InternalRequest($uri),
238  $this->internalRequestContext
239  );
240  $responseStructure = ResponseContent::fromString(
241  (string)$response->getBody()
242  );
243 
244  static::assertSame(
245  200,
246  $response->getStatusCode()
247  );
248  static::assertSame(
249  $this->siteTitle,
250  $responseStructure->getScopePath('template/sitetitle')
251  );
252  static::assertSame(
253  $expectedPageTitle,
254  $responseStructure->getScopePath('page/title')
255  );
256  }
257 
261  public function ‪pageIsRenderedWithDomainsDataProvider(): array
262  {
263  $instructions = [
264  ['https://archive.acme.com/?id=3100', 'EN: Statistics'],
265  ['https://archive.acme.com/?id=3110', 'EN: Markets'],
266  ['https://archive.acme.com/?id=3120', 'EN: Products'],
267  ['https://archive.acme.com/?id=3130', 'EN: Partners'],
268  ];
269 
270  return $this->keysFromTemplate($instructions, '%1$s');
271  }
272 
280  public function ‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle)
281  {
282  $response = $this->executeFrontendRequest(
283  new InternalRequest($uri),
284  $this->internalRequestContext
285  );
286  $responseStructure = ResponseContent::fromString(
287  (string)$response->getBody()
288  );
289 
290  static::assertSame(
291  200,
292  $response->getStatusCode()
293  );
294  static::assertSame(
295  $this->siteTitle,
296  $responseStructure->getScopePath('template/sitetitle')
297  );
298  static::assertSame(
299  $expectedPageTitle,
300  $responseStructure->getScopePath('page/title')
301  );
302  }
303 
307  public function ‪restrictedPageIsRenderedDataProvider(): array
308  {
309  $instructions = [
310  // frontend user 1
311  ['https://website.local/?id=1510', 1, 'Whitepapers'],
312  ['https://website.local/?id=1511', 1, 'Products'],
313  ['https://website.local/?id=1512', 1, 'Solutions'],
314  // frontend user 2
315  ['https://website.local/?id=1510', 2, 'Whitepapers'],
316  ['https://website.local/?id=1511', 2, 'Products'],
317  ['https://website.local/?id=1515', 2, 'Research'],
318  ['https://website.local/?id=1520', 2, 'Forecasts'],
319  ['https://website.local/?id=1521', 2, 'Current Year'],
320  // frontend user 3
321  ['https://website.local/?id=1510', 3, 'Whitepapers'],
322  ['https://website.local/?id=1511', 3, 'Products'],
323  ['https://website.local/?id=1512', 3, 'Solutions'],
324  ['https://website.local/?id=1515', 3, 'Research'],
325  ['https://website.local/?id=1520', 3, 'Forecasts'],
326  ['https://website.local/?id=1521', 3, 'Current Year'],
327  ];
328 
329  return $this->keysFromTemplate($instructions, '%1$s (user:%2$s)');
330  }
331 
340  public function ‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
341  {
342  $response = $this->executeFrontendRequest(
343  new InternalRequest($uri),
344  $this->internalRequestContext
345  ->withFrontendUserId($frontendUserId)
346  );
347  $responseStructure = ResponseContent::fromString(
348  (string)$response->getBody()
349  );
350 
351  static::assertSame(
352  200,
353  $response->getStatusCode()
354  );
355  static::assertSame(
356  $this->siteTitle,
357  $responseStructure->getScopePath('template/sitetitle')
358  );
359  static::assertSame(
360  $expectedPageTitle,
361  $responseStructure->getScopePath('page/title')
362  );
363  }
364 
369  {
370  $instructions = [
371  // no frontend user given
372  ['https://website.local/?id=1510', 0],
373  ['https://website.local/?id=1511', 0],
374  ['https://website.local/?id=1512', 0],
375  ['https://website.local/?id=1515', 0],
376  ['https://website.local/?id=1520', 0],
377  ['https://website.local/?id=1521', 0],
378  // frontend user 1
379  ['https://website.local/?id=1515', 1],
380  ['https://website.local/?id=1520', 1],
381  ['https://website.local/?id=1521', 1],
382  // frontend user 2
383  ['https://website.local/?id=1512', 2],
384  ];
385 
386  return $this->keysFromTemplate($instructions, '%1$s (user:%2$s)');
387  }
388 
397  {
398  $response = $this->executeFrontendRequest(
399  new InternalRequest($uri),
400  $this->internalRequestContext
401  ->withFrontendUserId($frontendUserId)
402  );
403 
404  static::assertSame(
405  403,
406  $response->getStatusCode()
407  );
408  static::assertThat(
409  (string)$response->getBody(),
410  static::logicalOr(
411  static::stringContains('Reason: ID was not an accessible page'),
412  static::stringContains('Reason: Subsection was found and not accessible')
413  )
414  );
415  }
416 
425  {
426  $response = $this->executeFrontendRequest(
427  new InternalRequest($uri),
428  $this->internalRequestContext
429  ->withFrontendUserId($frontendUserId)
430  ->withMergedGlobalSettings([
431  'TYPO3_CONF_VARS' => [
432  'FE' => [
433  'pageNotFound_handling' => 'READFILE:typo3/sysext/core/Tests/Functional/Fixtures/Frontend/PageError.txt',
434  ]
435  ]
436  ])
437  );
438 
439  static::assertSame(
440  403,
441  $response->getStatusCode()
442  );
443  static::assertThat(
444  (string)$response->getBody(),
445  static::logicalOr(
446  static::stringContains('reason: ID was not an accessible page'),
447  static::stringContains('reason: Subsection was found and not accessible')
448  )
449  );
450  }
451 
456  {
457  $domainPaths = [
458  '/',
459  'https://localhost/',
460  'https://website.local/',
461  ];
462 
463  $queries = [
464  '?',
465  '?id=1000',
466  '?id=acme-root',
467  '?id=1100',
468  '?id=acme-first',
469  ];
470 
471  $customQueries = [
472  '&testing[value]=1',
473  '&testing[value]=1&cHash=',
474  '&testing[value]=1&cHash=WRONG',
475  ];
476 
477  return $this->wrapInArray(
478  $this->keysFromValues(
479  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
480  )
481  );
482  }
483 
491  public function ‪pageRequestThrowsExceptionWithInvalidCacheHash(string $uri)
492  {
493  $this->expectExceptionCode(1518472189);
494  $this->expectException(PageNotFoundException::class);
495 
496  $this->executeFrontendRequest(
497  new InternalRequest($uri),
498  $this->internalRequestContext
499  );
500  }
501 
509  {
510  $response = $this->executeFrontendRequest(
511  new InternalRequest($uri),
512  $this->internalRequestContext->withMergedGlobalSettings([
513  'TYPO3_CONF_VARS' => [
514  'FE' => [
515  'pageNotFound_handling' => 'READFILE:typo3/sysext/core/Tests/Functional/Fixtures/Frontend/PageError.txt',
516  ]
517  ]
518  ])
519  );
520 
521  static::assertSame(
522  404,
523  $response->getStatusCode()
524  );
525  static::assertThat(
526  (string)$response->getBody(),
527  static::logicalOr(
528  static::stringContains('reason: Request parameters could not be validated (&amp;cHash empty)'),
529  static::stringContains('reason: Request parameters could not be validated (&amp;cHash comparison failed)')
530  )
531  );
532  }
533 
537  public function ‪pageIsRenderedWithValidCacheHashDataProvider(): array
538  {
539  $domainPaths = [
540  '/',
541  'https://localhost/',
542  'https://website.local/',
543  ];
544 
545  // cHash has been calculated with encryption key set to
546  // '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6'
547  $queries = [
548  // @todo Currently fails since cHash is verified after(!) redirect to page 1100
549  // '?&cHash=7d1f13fa91159dac7feb3c824936b39d&id=1000',
550  // '?&cHash=7d1f13fa91159dac7feb3c824936b39d=acme-root',
551  '?&cHash=f42b850e435f0cedd366f5db749fc1af&id=1100',
552  '?&cHash=f42b850e435f0cedd366f5db749fc1af&id=acme-first',
553  ];
554 
555  $customQueries = [
556  '&testing[value]=1',
557  ];
558 
559  $dataSet = $this->wrapInArray(
560  $this->keysFromValues(
561  ‪PermutationUtility::meltStringItems([$domainPaths, $queries, $customQueries])
562  )
563  );
564 
565  return $dataSet;
566  }
567 
574  public function ‪pageIsRenderedWithValidCacheHash($uri)
575  {
576  $response = $this->executeFrontendRequest(
577  new InternalRequest($uri),
578  $this->internalRequestContext
579  );
580  $responseStructure = ResponseContent::fromString(
581  (string)$response->getBody()
582  );
583  static::assertSame(
584  '1',
585  $responseStructure->getScopePath('getpost/testing.value')
586  );
587  }
588 }
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageRequestSendsNotFoundResponseWithInvalidCacheHash
‪pageRequestSendsNotFoundResponseWithInvalidCacheHash(string $uri)
Definition: PlainRequestTest.php:506
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\tearDown
‪tearDown()
Definition: PlainRequestTest.php:102
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\shortcutsAreRedirectedToFirstSubPage
‪shortcutsAreRedirectedToFirstSubPage(string $uri)
Definition: PlainRequestTest.php:138
‪TYPO3\CMS\Core\Utility\PermutationUtility\meltStringItems
‪static array meltStringItems(array $payload, string $previousResult='')
Definition: PermutationUtility.php:34
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRenderedDataProvider
‪array pageIsRenderedDataProvider()
Definition: PlainRequestTest.php:188
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\restrictedPageIsRenderedDataProvider
‪array restrictedPageIsRenderedDataProvider()
Definition: PlainRequestTest.php:305
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\$siteTitle
‪string $siteTitle
Definition: PlainRequestTest.php:34
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase
Definition: AbstractTestCase.php:29
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRenderedWithValidCacheHashDataProvider
‪array pageIsRenderedWithValidCacheHashDataProvider()
Definition: PlainRequestTest.php:535
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\setUpBeforeClass
‪static setUpBeforeClass()
Definition: PlainRequestTest.php:40
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\setUpDatabase
‪setUpDatabase()
Definition: PlainRequestTest.php:65
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\shortcutsAreRedirectedDataProvider
‪array shortcutsAreRedirectedDataProvider()
Definition: PlainRequestTest.php:111
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\tearDownAfterClass
‪static tearDownAfterClass()
Definition: PlainRequestTest.php:46
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRendered
‪pageIsRendered(string $uri, string $expectedPageTitle)
Definition: PlainRequestTest.php:232
‪TYPO3\CMS\Core\Error\Http\PageNotFoundException
Definition: PageNotFoundException.php:21
‪TYPO3\CMS\Core\Utility\PermutationUtility
Definition: PermutationUtility.php:22
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\shortcutsAreRedirectedAndRenderFirstSubPage
‪shortcutsAreRedirectedAndRenderFirstSubPage(string $uri)
Definition: PlainRequestTest.php:157
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorUsingCustomErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorUsingCustomErrorHandling(string $uri, int $frontendUserId)
Definition: PlainRequestTest.php:422
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageRenderingStopsWithInvalidCacheHashDataProvider
‪array pageRenderingStopsWithInvalidCacheHashDataProvider()
Definition: PlainRequestTest.php:453
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorUsingDefaultErrorHandling
‪restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorUsingDefaultErrorHandling(string $uri, int $frontendUserId)
Definition: PlainRequestTest.php:394
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider
‪array restrictedPageSendsForbiddenResponseWithUnauthorizedVisitorDataProvider()
Definition: PlainRequestTest.php:366
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\setUp
‪setUp()
Definition: PlainRequestTest.php:52
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:3
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRenderedWithDomains
‪pageIsRenderedWithDomains(string $uri, string $expectedPageTitle)
Definition: PlainRequestTest.php:278
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:50
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRenderedWithValidCacheHash
‪pageIsRenderedWithValidCacheHash($uri)
Definition: PlainRequestTest.php:572
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageIsRenderedWithDomainsDataProvider
‪array pageIsRenderedWithDomainsDataProvider()
Definition: PlainRequestTest.php:259
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\$internalRequestContext
‪InternalRequestContext $internalRequestContext
Definition: PlainRequestTest.php:38
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\pageRequestThrowsExceptionWithInvalidCacheHash
‪pageRequestThrowsExceptionWithInvalidCacheHash(string $uri)
Definition: PlainRequestTest.php:489
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest\restrictedPageIsRendered
‪restrictedPageIsRendered(string $uri, int $frontendUserId, string $expectedPageTitle)
Definition: PlainRequestTest.php:338
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\PlainRequestTest
Definition: PlainRequestTest.php:31
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static Bootstrap null initializeLanguageObject()
Definition: Bootstrap.php:986