Pull merge.
[yaffs-website] / web / core / modules / system / tests / src / FunctionalJavascript / Form / RebuildTest.php
1 <?php
2
3 namespace Drupal\Tests\system\FunctionalJavascript\Form;
4
5 use Drupal\Core\Field\FieldStorageDefinitionInterface;
6 use Drupal\Core\Url;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\field\Entity\FieldStorageConfig;
9 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
10
11 /**
12  * Tests functionality of \Drupal\Core\Form\FormBuilderInterface::rebuildForm().
13  *
14  * @group Form
15  * @todo Add tests for other aspects of form rebuilding.
16  */
17 class RebuildTest extends WebDriverTestBase {
18
19   /**
20    * {@inheritdoc}
21    */
22   protected static $modules = ['node', 'form_test'];
23
24   /**
25    * A user for testing.
26    *
27    * @var \Drupal\user\UserInterface
28    */
29   protected $webUser;
30
31   /**
32    * {@inheritdoc}
33    */
34   protected function setUp() {
35     parent::setUp();
36
37     $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
38
39     $this->webUser = $this->drupalCreateUser(['access content']);
40     $this->drupalLogin($this->webUser);
41   }
42
43   /**
44    * Tests that a form's action is retained after an Ajax submission.
45    *
46    * The 'action' attribute of a form should not change after an Ajax submission
47    * followed by a non-Ajax submission, which triggers a validation error.
48    */
49   public function testPreserveFormActionAfterAJAX() {
50     $page = $this->getSession()->getPage();
51     // Create a multi-valued field for 'page' nodes to use for Ajax testing.
52     $field_name = 'field_ajax_test';
53     FieldStorageConfig::create([
54       'field_name' => $field_name,
55       'entity_type' => 'node',
56       'type' => 'text',
57       'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
58     ])->save();
59     FieldConfig::create([
60       'field_name' => $field_name,
61       'entity_type' => 'node',
62       'bundle' => 'page',
63     ])->save();
64
65     // Also create a file field to test server side validation error.
66     $field_file_name = 'field_file_test';
67     FieldStorageConfig::create([
68       'field_name' => $field_file_name,
69       'entity_type' => 'node',
70       'type' => 'file',
71       'cardinality' => 1,
72     ])->save();
73     FieldConfig::create([
74       'field_name' => $field_file_name,
75       'entity_type' => 'node',
76       'bundle' => 'page',
77       'label' => 'Test file',
78       'required' => TRUE,
79     ])->save();
80
81     entity_get_form_display('node', 'page', 'default')
82       ->setComponent($field_name, ['type' => 'text_textfield'])
83       ->setComponent($field_file_name, ['type' => 'file_generic'])
84       ->save();
85
86     // Log in a user who can create 'page' nodes.
87     $this->webUser = $this->drupalCreateUser(['create page content']);
88     $this->drupalLogin($this->webUser);
89
90     // Get the form for adding a 'page' node. Submit an "add another item" Ajax
91     // submission and verify it worked by ensuring the updated page has two text
92     // field items in the field for which we just added an item.
93     $this->drupalGet('node/add/page');
94     $page->find('css', '[value="Add another item"]')->click();
95     $this->assertSession()->assertWaitOnAjaxRequest();
96     $this->assertTrue(count($this->xpath('//div[contains(@class, "field--name-field-ajax-test")]//input[@type="text"]')) == 2, 'AJAX submission succeeded.');
97
98     // Submit the form with the non-Ajax "Save" button, leaving the file field
99     // blank to trigger a validation error, and ensure that a validation error
100     // occurred, because this test is for testing what happens when a form is
101     // re-rendered without being re-built, which is what happens when there's
102     // a server side validation error.
103     $edit = [
104       'title[0][value]' => $this->randomString(),
105     ];
106     $this->drupalPostForm(NULL, $edit, 'Save');
107     $this->assertSession()->pageTextContains('Test file field is required.', 'Non-AJAX submission correctly triggered a validation error.');
108
109     // Ensure that the form contains two items in the multi-valued field, so we
110     // know we're testing a form that was correctly retrieved from cache.
111     $this->assertTrue(count($this->xpath('//form[contains(@id, "node-page-form")]//div[contains(@class, "js-form-item-field-ajax-test")]//input[@type="text"]')) == 2, 'Form retained its state from cache.');
112
113     // Ensure that the form's action is correct.
114     $forms = $this->xpath('//form[contains(@class, "node-page-form")]');
115     $this->assertEquals(1, count($forms));
116     // Strip query params off the action before asserting.
117     $url = parse_url($forms[0]->getAttribute('action'))['path'];
118     $this->assertEquals(Url::fromRoute('node.add', ['node_type' => 'page'])->toString(), $url);
119   }
120
121 }