‪TYPO3CMS  ‪main
RequestHandlerTest.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\Test;
24 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
25 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
26 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
27 
29 {
31  'typo3/sysext/frontend/Tests/Functional/Fixtures/Assets/app.css' => 'fileadmin/app.css',
32  'typo3/sysext/frontend/Tests/Functional/Fixtures/Assets/app.js' => 'fileadmin/app.js',
33  ];
34 
35  protected function ‪setUp(): void
36  {
37  $this->configurationToUseInTestInstance['SYS']['features']['security.frontend.enforceContentSecurityPolicy'] = true;
38  $this->configurationToUseInTestInstance['FE']['debug'] = true;
39  parent::setUp();
40 
41  $this->withDatabaseSnapshot(function () {
42  $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
43  $backendUser = $this->setUpBackendUser(1);
44  ‪$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser);
45  $scenarioFile = __DIR__ . '/Fixtures/SlugScenario.yaml';
46  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
47  $writer = DataHandlerWriter::withBackendUser($backendUser);
48  $writer->invokeFactory($factory);
49  static::failIfArrayIsNotEmpty($writer->getErrors());
50  $this->setUpFrontendRootPage(
51  1000,
52  [
53  'EXT:frontend/Tests/Functional/SiteHandling/Fixtures/RequestHandler.typoscript',
54  ],
55  [
56  'title' => 'ACME Root',
57  ]
58  );
59  });
61  'website-local',
62  $this->‪buildSiteConfiguration(1000, 'https://website.local/')
63  );
64  }
65 
66  protected function ‪tearDown(): void
67  {
68  GeneralUtility::purgeInstances();
69  parent::tearDown();
70  }
71 
72  #[Test]
73  public function ‪nonceAttributesForAssetsAreUpdated(): void
74  {
75  $firstResponse = $this->executeFrontendSubRequest(new InternalRequest('https://website.local/welcome'));
76  $firstCspHeader = $firstResponse->getHeaderLine('Content-Security-Policy');
77  $dom = new \DOMDocument();
78  $dom->loadHTML((string)$firstResponse->getBody());
79  $xpath = new \DOMXPath($dom);
80  $firstScriptNonce = $xpath->query('//script')->item(0)?->attributes->getNamedItem('nonce')?->nodeValue;
81  $firstLinkNonce = $xpath->query('//link')->item(0)?->attributes->getNamedItem('nonce')?->nodeValue;
82 
83  self::assertNotEmpty($firstScriptNonce);
84  self::assertSame($firstScriptNonce, $firstLinkNonce);
85  self::assertStringContainsString(sprintf("'nonce-%s'", $firstScriptNonce), $firstCspHeader);
86  self::assertEmpty($firstResponse->getHeaderLine('X-TYPO3-Debug-Cache'));
87 
88  $secondResponse = $this->executeFrontendSubRequest(new InternalRequest('https://website.local/welcome'));
89  $secondCspHeader = $secondResponse->getHeaderLine('Content-Security-Policy');
90  $dom = new \DOMDocument();
91  $dom->loadHTML((string)$secondResponse->getBody());
92  $xpath = new \DOMXPath($dom);
93  $secondScriptNonce = $xpath->query('//script')->item(0)?->attributes->getNamedItem('nonce')?->nodeValue;
94  $secondLinkNonce = $xpath->query('//link')->item(0)?->attributes->getNamedItem('nonce')?->nodeValue;
95 
96  self::assertNotEmpty($secondScriptNonce);
97  self::assertSame($secondScriptNonce, $secondLinkNonce);
98  self::assertNotSame($firstScriptNonce, $secondScriptNonce);
99  self::assertStringContainsString(sprintf("'nonce-%s'", $secondScriptNonce), $secondCspHeader);
100  // @todo `FunctionalTestCase` sets caches to `NullBackend`, thus caching cannot be asserted
101  // self::assertStringStartsWith('Cached page generated', $secondResponse->getHeaderLine('X-TYPO3-Debug-Cache'));
102  }
103 
104  #[Test]
105  public function ‪nonceValueSubstitutionIsInvoked(): void
106  {
107  $nonceValueSubstitutionMock = $this->createMock(NonceValueSubstitution::class);
108  $nonceValueSubstitutionMock->expects(self::once())
109  ->method('substituteNonce')
110  ->with(self::isType('array'))
111  ->willReturnCallback(static fn(array $context) => $context['content'] ?? null);
112  GeneralUtility::addInstance(NonceValueSubstitution::class, $nonceValueSubstitutionMock);
113  $this->executeFrontendSubRequest(new InternalRequest('https://website.local/welcome'));
114  }
115 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\RequestHandlerTest\tearDown
‪tearDown()
Definition: RequestHandlerTest.php:66
‪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\RequestHandlerTest\$pathsToProvideInTestInstance
‪array $pathsToProvideInTestInstance
Definition: RequestHandlerTest.php:30
‪TYPO3\CMS\Frontend\Cache\NonceValueSubstitution
Definition: NonceValueSubstitution.php:24
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\RequestHandlerTest\nonceAttributesForAssetsAreUpdated
‪nonceAttributesForAssetsAreUpdated()
Definition: RequestHandlerTest.php:73
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:18
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\RequestHandlerTest
Definition: RequestHandlerTest.php:29
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\RequestHandlerTest\setUp
‪setUp()
Definition: RequestHandlerTest.php:35
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\RequestHandlerTest\nonceValueSubstitutionIsInvoked
‪nonceValueSubstitutionIsInvoked()
Definition: RequestHandlerTest.php:105