[TASK] Correctly initialize environment for DataHandler in tests
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Functional / SiteHandling / PlainRequestTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Tests\Functional\SiteHandling;
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
18 use TYPO3\CMS\Core\Core\Bootstrap;
19 use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
20 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService;
21 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataMapFactory;
22 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
23 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
24 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\ResponseContent;
25
26 /**
27 * Test case for frontend requests without having site handling configured
28 */
29 class PlainRequestTest extends AbstractRequestTest
30 {
31 /**
32 * @var string
33 */
34 private $siteTitle = 'A Company that Manufactures Everything Inc';
35
36 /**
37 * @var InternalRequestContext
38 */
39 private $internalRequestContext;
40
41 /**
42 * @var ActionService
43 */
44 private $actionService;
45
46 protected function setUp()
47 {
48 parent::setUp();
49
50 // these settings are forwarded to the frontend sub-request as well
51 $this->internalRequestContext = (new InternalRequestContext())
52 ->withGlobalSettings(['TYPO3_CONF_VARS' => static::TYPO3_CONF_VARS]);
53
54 $this->setUpBackendUserFromFixture(1);
55 $this->actionService = new ActionService();
56 Bootstrap::initializeLanguageObject();
57
58 $scenarioFile = __DIR__ . '/Fixtures/scenario.yaml';
59 $factory = DataMapFactory::fromYamlFile($scenarioFile);
60 $this->actionService->invoke(
61 $factory->getDataMap(),
62 [],
63 $factory->getSuggestedIds()
64 );
65 static::failIfArrayIsNotEmpty(
66 $this->actionService->getDataHandler()->errorLog
67 );
68
69 $this->setUpFrontendRootPage(
70 101,
71 [
72 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript',
73 'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/JsonRenderer.typoscript',
74 ],
75 [
76 'title' => 'ACME Root',
77 'sitetitle' => $this->siteTitle,
78 ]
79 );
80 }
81
82 protected function tearDown()
83 {
84 unset(
85 $this->actionService,
86 $this->internalRequestContext
87 );
88 parent::tearDown();
89 }
90
91 /**
92 * @return array
93 */
94 public function requestsAreRedirectedDataProvider(): array
95 {
96 $domainPaths = [
97 '/',
98 'http://localhost/',
99 'https://localhost/',
100 'http://website.local/',
101 'https://website.local/',
102 ];
103
104 $queries = [
105 '?',
106 '?id=101',
107 '?id=acme-root'
108 ];
109
110 return $this->wrapInArray(
111 $this->keysFromValues(
112 $this->meltStrings([$domainPaths, $queries])
113 )
114 );
115 }
116
117 /**
118 * @param string $uri
119 *
120 * @test
121 * @dataProvider requestsAreRedirectedDataProvider
122 */
123 public function requestsAreRedirected(string $uri)
124 {
125 $expectedStatusCode = 307;
126 $expectedHeaders = ['location' => ['index.php?id=acme-first']];
127
128 $response = $this->executeFrontendRequest(
129 new InternalRequest($uri),
130 $this->internalRequestContext
131 );
132 static::assertSame($expectedStatusCode, $response->getStatusCode());
133 static::assertSame($expectedHeaders, $response->getHeaders());
134 }
135
136 /**
137 * @return array
138 */
139 public function pageIsRenderedDataProvider(): array
140 {
141 $domainPaths = [
142 '/',
143 'http://localhost/',
144 'https://localhost/',
145 'http://website.local/',
146 'https://website.local/',
147 ];
148
149 $queries = [
150 '?id=102',
151 '?id=acme-first',
152 ];
153
154 $languageQueries = [
155 '',
156 '&L=0',
157 '&L=1',
158 '&L=2',
159 ];
160
161 return array_map(
162 function (string $uri) {
163 if (strpos($uri, '&L=1') !== false) {
164 $expectedPageTitle = 'FR: Welcome';
165 } elseif (strpos($uri, '&L=2') !== false) {
166 $expectedPageTitle = 'FR-CA: Welcome';
167 } else {
168 $expectedPageTitle = 'EN: Welcome';
169 }
170 return [$uri, $expectedPageTitle];
171 },
172 $this->keysFromValues(
173 $this->meltStrings([$domainPaths, $queries, $languageQueries])
174 )
175 );
176 }
177
178 /**
179 * @param string $uri
180 * @param string $expectedPageTitle
181 *
182 * @test
183 * @dataProvider pageIsRenderedDataProvider
184 */
185 public function pageIsRendered(string $uri, string $expectedPageTitle)
186 {
187 $response = $this->executeFrontendRequest(
188 new InternalRequest($uri),
189 $this->internalRequestContext
190 );
191 $responseStructure = ResponseContent::fromString(
192 (string)$response->getBody()
193 );
194
195 static::assertSame(
196 200,
197 $response->getStatusCode()
198 );
199 static::assertSame(
200 $this->siteTitle,
201 $responseStructure->getScopePath('template/sitetitle')
202 );
203 static::assertSame(
204 $expectedPageTitle,
205 $responseStructure->getScopePath('page/title')
206 );
207 }
208
209 /**
210 * @return array
211 */
212 public function pageRenderingStopsWithInvalidCacheHashDataProvider(): array
213 {
214 $domainPaths = [
215 '/',
216 'http://localhost/',
217 'https://localhost/',
218 'http://website.local/',
219 'https://website.local/',
220 ];
221
222 $queries = [
223 '?',
224 '?id=101',
225 '?id=acme-root',
226 '?id=102',
227 '?id=acme-first',
228 ];
229
230 $customQueries = [
231 '&testing[value]=1',
232 '&testing[value]=1&cHash=',
233 '&testing[value]=1&cHash=WRONG',
234 ];
235
236 return $this->wrapInArray(
237 $this->keysFromValues(
238 $this->meltStrings([$domainPaths, $queries, $customQueries])
239 )
240 );
241 }
242
243 /**
244 * @param string $uri
245 *
246 * @test
247 * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
248 * @todo In TYPO3 v8 this seemed to be rendered, without throwing that exception
249 */
250 public function pageRequestThrowsExceptionWithInvalidCacheHash(string $uri)
251 {
252 $this->expectExceptionCode(1518472189);
253 $this->expectException(PageNotFoundException::class);
254
255 $this->executeFrontendRequest(
256 new InternalRequest($uri),
257 $this->internalRequestContext
258 );
259 }
260
261 /**
262 * @param string $uri
263 *
264 * @test
265 * @dataProvider pageRenderingStopsWithInvalidCacheHashDataProvider
266 */
267 public function pageRequestSendsNotFoundResponseWithInvalidCacheHash(string $uri)
268 {
269 $response = $this->executeFrontendRequest(
270 new InternalRequest($uri),
271 $this->internalRequestContext->withMergedGlobalSettings([
272 'TYPO3_CONF_VARS' => [
273 'FE' => [
274 'pageNotFound_handling' => 'READFILE:typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/PageError.txt',
275 ]
276 ]
277 ])
278 );
279
280 static::assertSame(
281 404,
282 $response->getStatusCode()
283 );
284 static::assertThat(
285 (string)$response->getBody(),
286 static::logicalOr(
287 static::stringContains('reason: Request parameters could not be validated (&amp;cHash empty)'),
288 static::stringContains('reason: Request parameters could not be validated (&amp;cHash comparison failed)')
289 )
290 );
291 }
292
293 /**
294 * @return array
295 */
296 public function pageIsRenderedWithValidCacheHashDataProvider(): array
297 {
298 $domainPaths = [
299 '/',
300 'http://localhost/',
301 'https://localhost/',
302 'http://website.local/',
303 'https://website.local/',
304 ];
305
306 // cHash has been calculated with encryption key set to
307 // '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6'
308 $queries = [
309 // @todo Currently fails since cHash is verified after(!) redirect to page 102
310 // '?&cHash=814ea11ad629c7e24cfd031cea2779f4&id=101',
311 // '?&cHash=814ea11ad629c7e24cfd031cea2779f4id=acme-root',
312 '?&cHash=126d2980c12f4759fed1bb7429db2dff&id=102',
313 '?&cHash=126d2980c12f4759fed1bb7429db2dff&id=acme-first',
314 ];
315
316 $customQueries = [
317 '&testing[value]=1',
318 ];
319
320 $dataSet = $this->wrapInArray(
321 $this->keysFromValues(
322 $this->meltStrings([$domainPaths, $queries, $customQueries])
323 )
324 );
325
326 return $dataSet;
327 }
328
329 /**
330 * @param string $uri
331 *
332 * @test
333 * @dataProvider pageIsRenderedWithValidCacheHashDataProvider
334 */
335 public function pageIsRenderedWithValidCacheHash($uri)
336 {
337 $response = $this->executeFrontendRequest(
338 new InternalRequest($uri),
339 $this->internalRequestContext
340 );
341 $responseStructure = ResponseContent::fromString(
342 (string)$response->getBody()
343 );
344 static::assertSame(
345 '1',
346 $responseStructure->getScopePath('getpost/testing.value')
347 );
348 }
349 }