‪TYPO3CMS  ‪main
RequestHandlingTest.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\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
22 use Symfony\Component\Mailer\SentMessage;
30 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
31 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
32 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
33 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
34 
35 final class ‪RequestHandlingTest extends FunctionalTestCase
36 {
38 
39  protected array ‪$coreExtensionsToLoad = ['form', 'fluid_styled_content'];
40  protected array ‪$testExtensionsToLoad = [
41  'typo3/sysext/form/Tests/Functional/RequestHandling/Fixtures/Extensions/form_caching_tests',
42  ];
43  protected array ‪$configurationToUseInTestInstance = [
44  'MAIL' => [
45  'defaultMailFromAddress' => 'hello@typo3.org',
46  'defaultMailFromName' => 'TYPO3',
47  'transport' => 'mbox',
48  'transport_spool_type' => 'file',
49  'transport_spool_filepath' => ‪self::MAIL_SPOOL_FOLDER,
50  ],
51  'SYS' => [
52  'caching' => [
53  'cacheConfigurations' => [
54  'hash' => [
55  'backend' => Typo3DatabaseBackend::class,
56  'frontend' => VariableFrontend::class,
57  ],
58  'pages' => [
59  'backend' => Typo3DatabaseBackend::class,
60  'frontend' => VariableFrontend::class,
61  ],
62  'rootline' => [
63  'backend' => Typo3DatabaseBackend::class,
64  'frontend' => VariableFrontend::class,
65  ],
66  ],
67  ],
68  'encryptionKey' => '4408d27a916d51e624b69af3554f516dbab61037a9f7b9fd6f81b4d3bedeccb6',
69  ],
70  ];
71 
72  private string ‪$databaseScenarioFile = __DIR__ . '/Fixtures/OnePageWithMultipleFormIntegrationsScenario.yaml';
73  private const ‪ROOT_PAGE_BASE_URI = 'http://localhost';
74  private const ‪LANGUAGE_PRESETS = [
75  'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_GB.UTF8'],
76  ];
77  private const ‪MAIL_SPOOL_FOLDER = 'typo3temp/var/transient/spool/';
78 
79  protected function ‪setUp(): void
80  {
81  parent::setUp();
83  'site1',
84  $this->‪buildSiteConfiguration(1000, self::ROOT_PAGE_BASE_URI . '/'),
85  [
86  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
87  ]
88  );
89  $this->withDatabaseSnapshot(function () {
90  $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv');
91  $backendUser = $this->setUpBackendUser(1);
92  ‪$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser);
93  $factory = DataHandlerFactory::fromYamlFile($this->databaseScenarioFile);
94  $writer = DataHandlerWriter::withBackendUser($backendUser);
95  $writer->invokeFactory($factory);
96  ‪self::failIfArrayIsNotEmpty($writer->getErrors());
97  });
98  }
99 
100  protected function ‪tearDown(): void
101  {
102  $this->purgeMailSpool();
103  parent::tearDown();
104  }
105 
106  private function ‪getMailSpoolMessages(): array
107  {
108  $messages = [];
109  foreach (array_filter(glob($this->instancePath . '/' . self::MAIL_SPOOL_FOLDER . '*'), 'is_file') as $path) {
110  $serializedMessage = file_get_contents($path);
111  $sentMessage = unserialize($serializedMessage);
112  if (!$sentMessage instanceof SentMessage) {
113  continue;
114  }
115  $fluidEmail = $sentMessage->getOriginalMessage();
116  if (!$fluidEmail instanceof ‪FluidEmail) {
117  continue;
118  }
119  $parsedHeaders = $this->parseRawHeaders($sentMessage->toString());
120  $item = [
121  'plaintext' => $fluidEmail->getTextBody(),
122  'html' => $fluidEmail->getHtmlBody(),
123  'subject' => $fluidEmail->getSubject(),
124  'date' => $fluidEmail->getDate() ?? $parsedHeaders['Date'] ?? null,
125  'to' => $fluidEmail->getTo(),
126  ];
127  if (is_string($item['date'])) {
128  // @todo `@timezone` is not handled here - probably tests don't need date at all
129  $item['date'] = new \DateTimeImmutable($item['date']);
130  }
131  $messages[] = $item;
132  }
133  return $messages;
134  }
135 
139  private function parseRawHeaders(string $rawMessage): array
140  {
141  $rawParts = explode("\r\n\r\n", $rawMessage, 2);
142  $rawLines = explode("\r\n", $rawParts[0]);
143  $rawHeaders = array_map(
144  fn(string $rawLine) => array_map(
145  'trim',
146  explode(':', $rawLine, 2)
147  ),
148  $rawLines
149  );
150  return array_combine(
151  array_column($rawHeaders, 0),
152  array_column($rawHeaders, 1)
153  );
154  }
155 
156  private function purgeMailSpool(): void
157  {
158  foreach (glob($this->instancePath . '/' . self::MAIL_SPOOL_FOLDER . '*') as $path) {
159  unlink($path);
160  }
161  }
162 
163  public static function theCachingBehavesTheSameForAllFormIntegrationVariantsDataProvider(): \Generator
164  {
165  ‪yield 'Multistep form / ext:form content element' => [
166  'formIdentifier' => 'multistep-test-form-1001',
167  'formNamePrefix' => 'tx_form_formframework',
168  ];
169 
170  ‪yield 'Multistep form / custom extbase controller => RenderActionIsCached' => [
171  'formIdentifier' => 'RenderActionIsCached-1002',
172  'formNamePrefix' => 'tx_formcachingtests_renderactioniscached',
173  ];
174 
175  ‪yield 'Multistep form / custom extbase controller => AllActionsUncached' => [
176  'formIdentifier' => 'AllActionsUncached-1003',
177  'formNamePrefix' => 'tx_formcachingtests_allactionsuncached',
178  ];
179 
180  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
181  // yield 'Multistep form / custom extbase controller => AllActionsCached' => [
182  // 'formIdentifier' => 'AllActionsCached-1004',
183  // 'formNamePrefix' => 'tx_formcachingtests_allactionscached',
184  // ];
185 
186  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
187  // yield 'Multistep form / simple FLUIDTEMPLATE' => [
188  // 'formIdentifier' => 'FormFromSimpleFluidtemplate',
189  // 'formNamePrefix' => 'tx_form_formframework',
190  // ];
191 
192  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
193  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
194  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
195  // 'formNamePrefix' => 'tx_formcachingtests_allactionscached',
196  // ];
197 
198  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
199  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
200  'formNamePrefix' => 'tx_formcachingtests_allactionscached',
201  ];
202 
203  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
204  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
205  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
206  // 'formNamePrefix' => 'tx_formcachingtests_renderactioniscached',
207  // ];
208 
209  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
210  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
211  'formNamePrefix' => 'tx_formcachingtests_renderactioniscached',
212  ];
213 
214  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
215  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
216  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
217  // 'formNamePrefix' => 'tx_formcachingtests_allactionsuncached',
218  // ];
219 
220  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
221  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
222  'formNamePrefix' => 'tx_formcachingtests_allactionsuncached',
223  ];
224 
225  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
226  // yield 'Multistep form / COA FLUIDTEMPLATE through ext:form controller' => [
227  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughExtFormController',
228  // 'formNamePrefix' => 'tx_form_formframework',
229  // ];
230 
231  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through ext:form controller' => [
232  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughExtFormController',
233  'formNamePrefix' => 'tx_form_formframework',
234  ];
235  }
236 
237  #[DataProvider('theCachingBehavesTheSameForAllFormIntegrationVariantsDataProvider')]
238  #[Test]
239  public function ‪theCachingBehavesTheSameForAllFormIntegrationVariants(string $formIdentifier, string $formNamePrefix): void
240  {
241  $uri = static::ROOT_PAGE_BASE_URI . '/form';
242 
243  $subject = new ‪FormDataFactory();
244 
245  // goto form page
246  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
247  $pageMarkup = (string)$this->executeFrontendSubRequest($internalRequest, null, true)->getBody();
248  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
249 
250  $honeypotIdFromStep1 = $formData->getHoneypotId();
251  $sessionIdFromStep1 = $formData->getSessionId();
252 
253  self::assertEmpty($sessionIdFromStep1, 'session element is not rendered');
254  self::assertEmpty($formData->toArray()['elementData'][$formNamePrefix . '[' . $formIdentifier . '][text-1]']['value'] ?? '_notempty_', 'form element "text-1" is empty');
255  self::assertNotEmpty($honeypotIdFromStep1, 'honeypot element exists');
256 
257  // post data and go to summary page
258  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
259  $formPostRequest = $formData->with('text-1', 'FOObarBAZ')->toPostRequest($internalRequest);
260  $pageMarkup = (string)$this->executeFrontendSubRequest($formPostRequest, null, true)->getBody();
261  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
262 
263  $honeypotIdFromStep2 = $formData->getHoneypotId();
264  $sessionIdFromStep2 = $formData->getSessionId();
265  $formMarkup = $formData->getFormMarkup();
266 
267  self::assertStringContainsString('Summary step', $formMarkup, 'the summary form step is shown');
268  self::assertStringContainsString('FOObarBAZ', $formMarkup, 'data from "text-1" is shown');
269  self::assertNotEmpty($sessionIdFromStep2, 'session element is rendered');
270  self::assertEmpty($honeypotIdFromStep2, 'honeypot element does not exists on summary form step');
271 
272  // go back to first page
273  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
274  $formPostRequest = $formData->with('__currentPage', '0')->toPostRequest($internalRequest);
275  $pageMarkup = (string)$this->executeFrontendSubRequest($formPostRequest, null, true)->getBody();
276  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
277 
278  $honeypotIdFromStep3 = $formData->getHoneypotId();
279  $sessionIdFromStep3 = $formData->getSessionId();
280 
281  self::assertEquals('FOObarBAZ', $formData->toArray()['elementData'][$formNamePrefix . '[' . $formIdentifier . '][text-1]']['value'] ?? null, 'form element "text-1" contains submitted data');
282  self::assertNotEquals($honeypotIdFromStep3, $honeypotIdFromStep1, 'honeypot differs from historical honeypot');
283  self::assertEquals($sessionIdFromStep3, $sessionIdFromStep2, 'session is still available');
284 
285  // post data and go to summary page
286  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
287  $formPostRequest = $formData->with('text-1', 'BAZbarFOO')->toPostRequest($internalRequest);
288  $pageMarkup = (string)$this->executeFrontendSubRequest($formPostRequest, null, true)->getBody();
289  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
290 
291  $honeypotIdFromStep4 = $formData->getHoneypotId();
292  $sessionIdFromStep4 = $formData->getSessionId();
293  $formMarkup = $formData->getFormMarkup();
294 
295  self::assertStringContainsString('Summary step', $formMarkup, 'the summary form step is shown');
296  self::assertStringContainsString('BAZbarFOO', $formMarkup, 'data from "text-1" is shown');
297  self::assertEmpty($honeypotIdFromStep4, 'honeypot element does not exists on summary form step');
298  self::assertEquals($sessionIdFromStep4, $sessionIdFromStep3, 'session is still available');
299 
300  // submit and trigger finishers
301  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
302  $formPostRequest = $formData->toPostRequest($internalRequest);
303  $pageMarkup = (string)$this->executeFrontendSubRequest($formPostRequest, null, true)->getBody();
304  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//*[@id="' . $formIdentifier . '"]');
305 
306  $formMarkup = $formData->getFormMarkup();
307  $mails = $this->‪getMailSpoolMessages();
308 
309  self::assertStringContainsString('Form is submitted', $formMarkup, 'the finisher text is shown');
310  self::assertCount(1, $this->‪getMailSpoolMessages(), 'a mail is sent');
311  self::assertStringContainsString('Text: BAZbarFOO', $mails[0]['plaintext'] ?? '', 'Mail contains form data');
312  }
313 
315  {
316  ‪yield 'Multistep form / ext:form content element' => [
317  'formIdentifier' => 'multistep-test-form-1001',
318  ];
319 
320  ‪yield 'Multistep form / custom extbase controller => RenderActionIsCached' => [
321  'formIdentifier' => 'RenderActionIsCached-1002',
322  ];
323 
324  ‪yield 'Multistep form / custom extbase controller => AllActionsUncached' => [
325  'formIdentifier' => 'AllActionsUncached-1003',
326  ];
327 
328  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
329  // yield 'Multistep form / custom extbase controller => AllActionsCached' => [
330  // 'formIdentifier' => 'AllActionsCached-1004',
331  // ];
332 
333  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
334  // yield 'Multistep form / simple FLUIDTEMPLATE' => [
335  // 'formIdentifier' => 'FormFromSimpleFluidtemplate',
336  // ];
337 
338  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
339  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
340  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
341  // ];
342 
343  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
344  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
345  ];
346 
347  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
348  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
349  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
350  // ];
351 
352  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
353  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
354  ];
355 
356  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
357  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
358  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
359  // ];
360 
361  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
362  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
363  ];
364 
365  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/70460 is fixed
366  // yield 'Multistep form / COA FLUIDTEMPLATE through ext:form controller' => [
367  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughExtFormController',
368  // ];
369 
370  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through ext:form controller' => [
371  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughExtFormController',
372  ];
373  }
374 
375  #[DataProvider('formRendersUncachedIfTheActionTargetIsCalledViaHttpGetDataProvider')]
376  #[Test]
377  public function ‪formRendersUncachedIfTheActionTargetIsCalledViaHttpGet(string $formIdentifier): void
378  {
379  $uri = static::ROOT_PAGE_BASE_URI . '/form';
380 
381  $subject = new ‪FormDataFactory();
382 
383  // goto form page
384  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
385  $pageMarkup = (string)$this->executeFrontendSubRequest($internalRequest, null, true)->getBody();
386  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
387 
388  // goto form target with HTTP GET
389  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
390  (string)$this->executeFrontendSubRequest($formData->toGetRequest($internalRequest, false), null, true)->getBody();
391 
392  // goto form page
393  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
394  $pageMarkup = (string)$this->executeFrontendSubRequest($internalRequest, null, true)->getBody();
395  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
396 
397  // post data and go to summary page
398  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
399  $formPostRequest = $formData->with('text-1', 'FOObarBAZ')->toPostRequest($internalRequest);
400  $pageMarkup = (string)$this->executeFrontendSubRequest($formPostRequest, null, true)->getBody();
401  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
402 
403  $formMarkup = $formData->getFormMarkup();
404 
405  self::assertStringContainsString('Summary step', $formMarkup, 'the summary form step is shown');
406  self::assertStringContainsString('FOObarBAZ', $formMarkup, 'data from "text-1" is shown');
407  }
408 
410  {
411  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
412  // yield 'Multistep form / ext:form content element' => [
413  // 'formIdentifier' => 'multistep-test-form-1001',
414  // ];
415 
416  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
417  // yield 'Multistep form / custom extbase controller => RenderActionIsCached' => [
418  // 'formIdentifier' => 'RenderActionIsCached-1002',
419  // ];
420 
421  ‪yield 'Multistep form / custom extbase controller => AllActionsUncached' => [
422  'formIdentifier' => 'AllActionsUncached-1003',
423  ];
424 
425  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
426  // yield 'Multistep form / custom extbase controller => AllActionsCached' => [
427  // 'formIdentifier' => 'AllActionsCached-1004',
428  // ];
429 
430  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
431  // yield 'Multistep form / simple FLUIDTEMPLATE' => [
432  // 'formIdentifier' => 'FormFromSimpleFluidtemplate',
433  // ];
434 
435  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
436  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
437  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
438  // ];
439 
440  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsCached' => [
441  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsCached',
442  ];
443 
444  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
445  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
446  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
447  // ];
448 
449  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => RenderActionIsCached' => [
450  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerRenderActionIsCached',
451  ];
452 
453  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
454  // yield 'Multistep form / COA FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
455  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
456  // ];
457 
458  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through custom extbase controller => AllActionsUncached' => [
459  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughCustomExtbaseControllerAllActionsUncached',
460  ];
461 
462  // disabled until https://review.typo3.org/c/Packages/TYPO3.CMS/+/67642/ is fixed
463  // yield 'Multistep form / COA FLUIDTEMPLATE through ext:form controller' => [
464  // 'formIdentifier' => 'FormFromCoaFluidtemplateThroughExtFormController',
465  // ];
466 
467  ‪yield 'Multistep form / COA_INT FLUIDTEMPLATE through ext:form controller' => [
468  'formIdentifier' => 'FormFromCoaIntFluidtemplateThroughExtFormController',
469  ];
470  }
471 
472  #[DataProvider('theHoneypotElementChangesWithEveryCallOfTheFirstFormStepDataProvider')]
473  #[Test]
474  public function ‪theHoneypotElementChangesWithEveryCallOfTheFirstFormStep(string $formIdentifier): void
475  {
476  $uri = static::ROOT_PAGE_BASE_URI . '/form';
477 
478  $subject = new ‪FormDataFactory();
479 
480  // goto form page
481  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
482  $pageMarkup = (string)$this->executeFrontendSubRequest($internalRequest, null, true)->getBody();
483  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
484  $honeypotId = $formData->getHoneypotId();
485 
486  self::assertNotEmpty($honeypotId, 'honeypot element exists');
487 
488  // revisit form page
489  $internalRequest = (new InternalRequest($uri))->withAttribute('currentContentObject', $this->get(ContentObjectRenderer::class));
490  $pageMarkup = (string)$this->executeFrontendSubRequest($internalRequest, null, true)->getBody();
491  $formData = $subject->fromHtmlMarkupAndXpath($pageMarkup, '//form[@id="' . $formIdentifier . '"]');
492 
493  $honeypotIdFromRevisit = $formData->getHoneypotId();
494 
495  self::assertNotEquals($honeypotIdFromRevisit, $honeypotId, 'honeypot differs from historical honeypot');
496  }
497 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\failIfArrayIsNotEmpty
‪static failIfArrayIsNotEmpty(array $items)
Definition: SiteBasedTestTrait.php:38
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\getMailSpoolMessages
‪getMailSpoolMessages()
Definition: RequestHandlingTest.php:105
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling
Definition: RequestHandlingTest.php:18
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\formRendersUncachedIfTheActionTargetIsCalledViaHttpGet
‪formRendersUncachedIfTheActionTargetIsCalledViaHttpGet(string $formIdentifier)
Definition: RequestHandlingTest.php:376
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait
Definition: SiteBasedTestTrait.php:37
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest
Definition: RequestHandlingTest.php:36
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\theHoneypotElementChangesWithEveryCallOfTheFirstFormStepDataProvider
‪static theHoneypotElementChangesWithEveryCallOfTheFirstFormStepDataProvider()
Definition: RequestHandlingTest.php:408
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:50
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:88
‪TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
Definition: Typo3DatabaseBackend.php:30
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\LANGUAGE_PRESETS
‪const LANGUAGE_PRESETS
Definition: RequestHandlingTest.php:73
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\ROOT_PAGE_BASE_URI
‪const ROOT_PAGE_BASE_URI
Definition: RequestHandlingTest.php:72
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\formRendersUncachedIfTheActionTargetIsCalledViaHttpGetDataProvider
‪static formRendersUncachedIfTheActionTargetIsCalledViaHttpGetDataProvider()
Definition: RequestHandlingTest.php:313
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\setUp
‪setUp()
Definition: RequestHandlingTest.php:78
‪TYPO3\CMS\Core\Mail\FluidEmail
Definition: FluidEmail.php:35
‪TYPO3\CMS\Core\Cache\Frontend\VariableFrontend
Definition: VariableFrontend.php:25
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\yield
‪yield
Definition: RequestHandlingTest.php:169
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\$databaseScenarioFile
‪string $databaseScenarioFile
Definition: RequestHandlingTest.php:71
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\$configurationToUseInTestInstance
‪array $configurationToUseInTestInstance
Definition: RequestHandlingTest.php:42
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\MAIL_SPOOL_FOLDER
‪const MAIL_SPOOL_FOLDER
Definition: RequestHandlingTest.php:76
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\theCachingBehavesTheSameForAllFormIntegrationVariants
‪theCachingBehavesTheSameForAllFormIntegrationVariants(string $formIdentifier, string $formNamePrefix)
Definition: RequestHandlingTest.php:238
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:98
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\theHoneypotElementChangesWithEveryCallOfTheFirstFormStep
‪theHoneypotElementChangesWithEveryCallOfTheFirstFormStep(string $formIdentifier)
Definition: RequestHandlingTest.php:473
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\tearDown
‪tearDown()
Definition: RequestHandlingTest.php:99
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\$testExtensionsToLoad
‪array $testExtensionsToLoad
Definition: RequestHandlingTest.php:39
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:102
‪TYPO3\CMS\Form\Tests\Functional\RequestHandling\RequestHandlingTest\$coreExtensionsToLoad
‪array $coreExtensionsToLoad
Definition: RequestHandlingTest.php:38
‪TYPO3\CMS\Form\Tests\Functional\Framework\FormHandling\FormDataFactory
Definition: FormDataFactory.php:25