function FormStatePersistTest::testFormStatePersistence

Test that form state persists correctly after being submitted and rebuilt.

File

core/modules/system/tests/src/Kernel/Form/FormStatePersistTest.php, line 122

Class

FormStatePersistTest
Tests that the form state persists across multiple requests.

Namespace

Drupal\Tests\system\Kernel\Form

Code

public function testFormStatePersistence() : void {
  // Simulate the initial GET request without submitted values for a form.
  $form_state = new FormState();
  $form = \Drupal::formBuilder()->buildForm($this, $form_state);
  /** @var \Drupal\Core\Render\RendererInterface $renderer */
  $renderer = \Drupal::service('renderer');
  $renderer->renderRoot($form);
  // The form has a #post_render callback that displays whether form state
  // properties set during the #process callback are cached. On the first
  // request to the form, the values are not populated because there is no
  // form caching on a GET request.
  $this->assertFalse(static::$postRenderStoragePersist['process']);
  $this->assertFalse(static::$postRenderStoragePersist['rebuild']);
  // Simulate a form submission.
  $request = Request::create('/', 'POST', [
    'form_id' => $this->getFormId(),
    'form_build_id' => $form['#build_id'],
    'title' => 'DEFAULT',
  ]);
  $request->setSession(new Session(new MockArraySessionStorage()));
  \Drupal::requestStack()->push($request);
  $form_state = new FormState();
  static::$submitStoragePersist = [];
  static::$postRenderStoragePersist = [];
  $form = \Drupal::formBuilder()->buildForm($this, $form_state);
  // In the form submit handler, the form state 'build' property set in
  // buildForm should have persisted. The 'process' property set in the
  // #process callback should have persisted. The 'rebuild' property set
  // in the #process hook after form rebuild will not show as persisted,
  // because that value gets set after the submit handler has run.
  $this->assertTrue(static::$submitStoragePersist['build']);
  $this->assertTrue(static::$submitStoragePersist['process']);
  $this->assertFalse(static::$submitStoragePersist['rebuild']);
  // Values set in the#post_render callback should now show that 'process' and
  // 'rebuild' form state properties are now cached.
  static::$submitStoragePersist = [];
  static::$postRenderStoragePersist = [];
  $renderer->renderRoot($form);
  $this->assertTrue(static::$postRenderStoragePersist['process']);
  $this->assertTrue(static::$postRenderStoragePersist['rebuild']);
  // Submit the form again to show continued persistence.
  $form_state = new FormState();
  static::$submitStoragePersist = [];
  static::$postRenderStoragePersist = [];
  $request->request
    ->set('form_build_id', $form['#build_id']);
  $form = \Drupal::formBuilder()->buildForm($this, $form_state);
  // After submitting the form a second time, the 'rebuild' property set
  // during the rebuild after the first submission should have persisted in
  // the cache.
  $this->assertTrue(static::$submitStoragePersist['build']);
  $this->assertTrue(static::$submitStoragePersist['process']);
  $this->assertTrue(static::$submitStoragePersist['rebuild']);
  $renderer->renderRoot($form);
  $this->assertTrue(static::$postRenderStoragePersist['process']);
  $this->assertTrue(static::$postRenderStoragePersist['rebuild']);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.