17f0734f697c8102998ca1bfaeb197d7b93eacb1
[yaffs-website] / web / core / modules / node / tests / src / Functional / NodeEditFormTest.php
1 <?php
2
3 namespace Drupal\Tests\node\Functional;
4
5 use Drupal\node\NodeInterface;
6 use Drupal\user\Entity\User;
7
8 /**
9  * Create a node and test node edit functionality.
10  *
11  * @group node
12  */
13 class NodeEditFormTest extends NodeTestBase {
14
15   /**
16    * A normal logged in user.
17    *
18    * @var \Drupal\user\UserInterface
19    */
20   protected $webUser;
21
22   /**
23    * A user with permission to bypass content access checks.
24    *
25    * @var \Drupal\user\UserInterface
26    */
27   protected $adminUser;
28
29   /**
30    * The node storage.
31    *
32    * @var \Drupal\node\NodeStorageInterface
33    */
34   protected $nodeStorage;
35
36   /**
37    * Modules to enable.
38    *
39    * @var string[]
40    */
41   public static $modules = ['block', 'node', 'datetime'];
42
43   protected function setUp() {
44     parent::setUp();
45
46     $this->webUser = $this->drupalCreateUser(['edit own page content', 'create page content']);
47     $this->adminUser = $this->drupalCreateUser(['bypass node access', 'administer nodes']);
48     $this->drupalPlaceBlock('local_tasks_block');
49
50     $this->nodeStorage = $this->container->get('entity.manager')->getStorage('node');
51   }
52
53   /**
54    * Checks node edit functionality.
55    */
56   public function testNodeEdit() {
57     $this->drupalLogin($this->webUser);
58
59     $title_key = 'title[0][value]';
60     $body_key = 'body[0][value]';
61     // Create node to edit.
62     $edit = [];
63     $edit[$title_key] = $this->randomMachineName(8);
64     $edit[$body_key] = $this->randomMachineName(16);
65     $this->drupalPostForm('node/add/page', $edit, t('Save'));
66
67     // Check that the node exists in the database.
68     $node = $this->drupalGetNodeByTitle($edit[$title_key]);
69     $this->assertTrue($node, 'Node found in database.');
70
71     // Check that "edit" link points to correct page.
72     $this->clickLink(t('Edit'));
73     $this->assertUrl($node->url('edit-form', ['absolute' => TRUE]));
74
75     // Check that the title and body fields are displayed with the correct values.
76     // @todo Ideally assertLink would support HTML, but it doesn't.
77     $this->assertRaw('Edit<span class="visually-hidden">(active tab)</span>', 'Edit tab found and marked active.');
78     $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
79     $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
80
81     // Edit the content of the node.
82     $edit = [];
83     $edit[$title_key] = $this->randomMachineName(8);
84     $edit[$body_key] = $this->randomMachineName(16);
85     // Stay on the current page, without reloading.
86     $this->drupalPostForm(NULL, $edit, t('Save'));
87
88     // Check that the title and body fields are displayed with the updated values.
89     $this->assertText($edit[$title_key], 'Title displayed.');
90     $this->assertText($edit[$body_key], 'Body displayed.');
91
92     // Log in as a second administrator user.
93     $second_web_user = $this->drupalCreateUser(['administer nodes', 'edit any page content']);
94     $this->drupalLogin($second_web_user);
95     // Edit the same node, creating a new revision.
96     $this->drupalGet("node/" . $node->id() . "/edit");
97     $edit = [];
98     $edit['title[0][value]'] = $this->randomMachineName(8);
99     $edit[$body_key] = $this->randomMachineName(16);
100     $edit['revision'] = TRUE;
101     $this->drupalPostForm(NULL, $edit, t('Save'));
102
103     // Ensure that the node revision has been created.
104     $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE);
105     $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.');
106     // Ensure that the node author is preserved when it was not changed in the
107     // edit form.
108     $this->assertIdentical($node->getOwnerId(), $revised_node->getOwnerId(), 'The node author has been preserved.');
109     // Ensure that the revision authors are different since the revisions were
110     // made by different users.
111     $first_node_version = node_revision_load($node->getRevisionId());
112     $second_node_version = node_revision_load($revised_node->getRevisionId());
113     $this->assertNotIdentical($first_node_version->getRevisionUser()->id(), $second_node_version->getRevisionUser()->id(), 'Each revision has a distinct user.');
114
115     // Check if the node revision checkbox is rendered on node edit form.
116     $this->drupalGet('node/' . $node->id() . '/edit');
117     $this->assertFieldById('edit-revision', NULL, 'The revision field is present.');
118
119     // Check that details form element opens when there are errors on child
120     // elements.
121     $this->drupalGet('node/' . $node->id() . '/edit');
122     $edit = [];
123     // This invalid date will trigger an error.
124     $edit['created[0][value][date]'] = $this->randomMachineName(8);
125     // Get the current amount of open details elements.
126     $open_details_elements = count($this->cssSelect('details[open="open"]'));
127     $this->drupalPostForm(NULL, $edit, t('Save'));
128     // The node author details must be open.
129     $this->assertRaw('<details class="node-form-author js-form-wrapper form-wrapper" data-drupal-selector="edit-author" id="edit-author" open="open">');
130     // Only one extra details element should now be open.
131     $open_details_elements++;
132     $this->assertEqual(count($this->cssSelect('details[open="open"]')), $open_details_elements, 'Exactly one extra open &lt;details&gt; element found.');
133
134     // Edit the same node, save it and verify it's unpublished after unchecking
135     // the 'Published' boolean_checkbox and clicking 'Save'.
136     $this->drupalGet("node/" . $node->id() . "/edit");
137     $edit = ['status[value]' => FALSE];
138     $this->drupalPostForm(NULL, $edit, t('Save'));
139     $this->nodeStorage->resetCache([$node->id()]);
140     $node = $this->nodeStorage->load($node->id());
141     $this->assertFalse($node->isPublished(), 'Node is unpublished');
142   }
143
144   /**
145    * Tests changing a node's "authored by" field.
146    */
147   public function testNodeEditAuthoredBy() {
148     $this->drupalLogin($this->adminUser);
149
150     // Create node to edit.
151     $body_key = 'body[0][value]';
152     $edit = [];
153     $edit['title[0][value]'] = $this->randomMachineName(8);
154     $edit[$body_key] = $this->randomMachineName(16);
155     $this->drupalPostForm('node/add/page', $edit, t('Save'));
156
157     // Check that the node was authored by the currently logged in user.
158     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
159     $this->assertIdentical($node->getOwnerId(), $this->adminUser->id(), 'Node authored by admin user.');
160
161     $this->checkVariousAuthoredByValues($node, 'uid[0][target_id]');
162
163     // Check that normal users cannot change the authored by information.
164     $this->drupalLogin($this->webUser);
165     $this->drupalGet('node/' . $node->id() . '/edit');
166     $this->assertNoFieldByName('uid[0][target_id]');
167
168     // Now test with the Autocomplete (Tags) field widget.
169     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
170     $form_display = \Drupal::entityManager()->getStorage('entity_form_display')->load('node.page.default');
171     $widget = $form_display->getComponent('uid');
172     $widget['type'] = 'entity_reference_autocomplete_tags';
173     $widget['settings'] = [
174       'match_operator' => 'CONTAINS',
175       'size' => 60,
176       'placeholder' => '',
177     ];
178     $form_display->setComponent('uid', $widget);
179     $form_display->save();
180
181     $this->drupalLogin($this->adminUser);
182
183     // Save the node without making any changes.
184     $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
185     $this->nodeStorage->resetCache([$node->id()]);
186     $node = $this->nodeStorage->load($node->id());
187     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
188
189     $this->checkVariousAuthoredByValues($node, 'uid[target_id]');
190
191     // Hide the 'authored by' field from the form.
192     $form_display->removeComponent('uid')->save();
193
194     // Check that saving the node without making any changes keeps the proper
195     // author ID.
196     $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
197     $this->nodeStorage->resetCache([$node->id()]);
198     $node = $this->nodeStorage->load($node->id());
199     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
200   }
201
202   /**
203    * Tests the node meta information.
204    */
205   public function testNodeMetaInformation() {
206     // Check that regular users (i.e. without the 'administer nodes' permission)
207     // can not see the meta information.
208     $this->drupalLogin($this->webUser);
209     $this->drupalGet('node/add/page');
210     $this->assertNoText('Not saved yet');
211
212     // Create node to edit.
213     $edit['title[0][value]'] = $this->randomMachineName(8);
214     $edit['body[0][value]'] = $this->randomMachineName(16);
215     $this->drupalPostForm(NULL, $edit, t('Save'));
216
217     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
218     $this->drupalGet("node/" . $node->id() . "/edit");
219     $this->assertNoText('Published');
220     $this->assertNoText(format_date($node->getChangedTime(), 'short'));
221
222     // Check that users with the 'administer nodes' permission can see the meta
223     // information.
224     $this->drupalLogin($this->adminUser);
225     $this->drupalGet('node/add/page');
226     $this->assertText('Not saved yet');
227
228     // Create node to edit.
229     $edit['title[0][value]'] = $this->randomMachineName(8);
230     $edit['body[0][value]'] = $this->randomMachineName(16);
231     $this->drupalPostForm(NULL, $edit, t('Save'));
232
233     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
234     $this->drupalGet("node/" . $node->id() . "/edit");
235     $this->assertText('Published');
236     $this->assertText(format_date($node->getChangedTime(), 'short'));
237   }
238
239   /**
240    * Checks that the "authored by" works correctly with various values.
241    *
242    * @param \Drupal\node\NodeInterface $node
243    *   A node object.
244    * @param string $form_element_name
245    *   The name of the form element to populate.
246    */
247   protected function checkVariousAuthoredByValues(NodeInterface $node, $form_element_name) {
248     // Try to change the 'authored by' field to an invalid user name.
249     $edit = [
250       $form_element_name => 'invalid-name',
251     ];
252     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
253     $this->assertRaw(t('There are no entities matching "%name".', ['%name' => 'invalid-name']));
254
255     // Change the authored by field to an empty string, which should assign
256     // authorship to the anonymous user (uid 0).
257     $edit[$form_element_name] = '';
258     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
259     $this->nodeStorage->resetCache([$node->id()]);
260     $node = $this->nodeStorage->load($node->id());
261     $uid = $node->getOwnerId();
262     // Most SQL database drivers stringify fetches but entities are not
263     // necessarily stored in a SQL database. At the same time, NULL/FALSE/""
264     // won't do.
265     $this->assertTrue($uid === 0 || $uid === '0', 'Node authored by anonymous user.');
266
267     // Go back to the edit form and check that the correct value is displayed
268     // in the author widget.
269     $this->drupalGet('node/' . $node->id() . '/edit');
270     $anonymous_user = User::getAnonymousUser();
271     $expected = $anonymous_user->label() . ' (' . $anonymous_user->id() . ')';
272     $this->assertFieldByName($form_element_name, $expected, 'Authored by field displays the correct value for the anonymous user.');
273
274     // Change the authored by field to another user's name (that is not
275     // logged in).
276     $edit[$form_element_name] = $this->webUser->getUsername();
277     $this->drupalPostForm(NULL, $edit, t('Save'));
278     $this->nodeStorage->resetCache([$node->id()]);
279     $node = $this->nodeStorage->load($node->id());
280     $this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.');
281   }
282
283 }