.../Drupal/Tests/Core/Form/FormBuilderTest.php | 45 ++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index e5f2963..f37a4c7 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -820,7 +820,7 @@ public function providerTestInvalidToken() { * * @dataProvider providerTestFormTokenCacheability */ - public function testFormTokenCacheability($token, $is_authenticated, $expected_form_cacheability, $expected_token_cacheability, $method) { + public function testFormTokenCacheability($token, $is_authenticated, $method) { $user = $this->prophesize(AccountProxyInterface::class); $user->isAuthenticated() ->willReturn($is_authenticated); @@ -845,19 +845,32 @@ public function testFormTokenCacheability($token, $is_authenticated, $expected_f $form_state = new FormState(); $built_form = $this->formBuilder->buildForm($form_arg, $form_state); - if (!isset($expected_form_cacheability) || ($method == 'get' && !is_string($token))) { + + // FormBuilder does not even consider to set a form token when: + // - #token = FALSE (opting out explicitly) + // - #method = GET and #token is not set to a string (GET forms don't get a + // form token by default, and this form did not explicitly opt in) + if ($token === FALSE || ($method == 'get' && !is_string($token))) { $this->assertFalse(isset($built_form['#cache'])); - } - else { - $this->assertTrue(isset($built_form['#cache'])); - $this->assertEquals($expected_form_cacheability, $built_form['#cache']); - } - if (!isset($expected_token_cacheability)) { $this->assertFalse(isset($built_form['form_token'])); } + // Otherwise, a form token is set, but only if the user is logged in. It is + // impossible (and unnecessary) to set a form token if the user is not + // logged in, because there is no session, and hence no CSRF token. else { - $this->assertTrue(isset($built_form['form_token'])); - $this->assertEquals($expected_token_cacheability, $built_form['form_token']['#cache']); + // For forms that are eligible for form tokens, a cache context must be + // set that indicates the form token only exists for logged in users. + $this->assertTrue(isset($built_form['#cache'])); + $this->assertEquals(['contexts' => ['user.roles:authenticated']], $built_form['#cache']); + // Finally, verify that a form token is generated when appropriate, with + // the expected cacheability metadata (or lack thereof). + if (!$is_authenticated) { + $this->assertFalse(isset($built_form['form_token'])); + } + else { + $this->assertTrue(isset($built_form['form_token'])); + $this->assertFalse(isset($built_form['form_token']['#cache'])); + } } } @@ -868,12 +881,12 @@ public function testFormTokenCacheability($token, $is_authenticated, $expected_f */ function providerTestFormTokenCacheability() { return [ - 'token:none,authenticated:true' => [NULL, TRUE, ['contexts' => ['user.roles:authenticated']], ['max-age' => 0], 'post'], - 'token:none,authenticated:false' => [NULL, FALSE, ['contexts' => ['user.roles:authenticated']], NULL, 'post'], - 'token:false,authenticated:false' => [FALSE, FALSE, NULL, NULL, 'post'], - 'token:false,authenticated:true' => [FALSE, TRUE, NULL, NULL, 'post'], - 'token:none,authenticated:false,method:get' => [NULL, FALSE, ['contexts' => ['user.roles:authenticated']], NULL, 'get'], - 'token:test_form_id,authenticated:false,method:get' => ['test_form_id', TRUE, ['contexts' => ['user.roles:authenticated']], ['max-age' => 0], 'get'], + 'token:none,authenticated:true' => [NULL, TRUE, 'post'], + 'token:none,authenticated:false' => [NULL, FALSE, 'post'], + 'token:false,authenticated:false' => [FALSE, FALSE, 'post'], + 'token:false,authenticated:true' => [FALSE, TRUE, 'post'], + 'token:none,authenticated:false,method:get' => [NULL, FALSE, 'get'], + 'token:test_form_id,authenticated:true,method:get' => ['test_form_id', TRUE, 'get'], ]; }