Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/quickedit/tests/src/FunctionalJavascript/QuickEditLoadingTest.php @ 5:12f9dff5fda9 tip
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:34:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:a9cd425dd02b | 5:12f9dff5fda9 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\quickedit\FunctionalJavascript; | |
4 | |
5 use Behat\Mink\Session; | |
6 use Drupal\block_content\Entity\BlockContent; | |
7 use Drupal\Core\Entity\Entity\EntityViewDisplay; | |
8 use Drupal\field\Entity\FieldConfig; | |
9 use Drupal\field\Entity\FieldStorageConfig; | |
10 use Drupal\FunctionalJavascriptTests\WebDriverTestBase; | |
11 use Drupal\node\Entity\Node; | |
12 use Drupal\node\Entity\NodeType; | |
13 use Drupal\filter\Entity\FilterFormat; | |
14 use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait; | |
15 use Drupal\Tests\TestFileCreationTrait; | |
16 | |
17 /** | |
18 * Tests loading of in-place editing functionality and lazy loading of its | |
19 * in-place editors. | |
20 * | |
21 * @group quickedit | |
22 */ | |
23 class QuickEditLoadingTest extends WebDriverTestBase { | |
24 | |
25 use ContextualLinkClickTrait; | |
26 | |
27 use TestFileCreationTrait { | |
28 getTestFiles as drupalGetTestFiles; | |
29 } | |
30 | |
31 /** | |
32 * Modules to enable. | |
33 * | |
34 * @var array | |
35 */ | |
36 public static $modules = [ | |
37 'contextual', | |
38 'quickedit', | |
39 'filter', | |
40 'node', | |
41 'image', | |
42 ]; | |
43 | |
44 /** | |
45 * An user with permissions to create and edit articles. | |
46 * | |
47 * @var \Drupal\user\UserInterface | |
48 */ | |
49 protected $authorUser; | |
50 | |
51 /** | |
52 * A test node. | |
53 * | |
54 * @var \Drupal\node\NodeInterface | |
55 */ | |
56 protected $testNode; | |
57 | |
58 /** | |
59 * A author user with permissions to access in-place editor. | |
60 * | |
61 * @var \Drupal\user\UserInterface | |
62 */ | |
63 protected $editorUser; | |
64 | |
65 /** | |
66 * {@inheritdoc} | |
67 */ | |
68 protected function setUp() { | |
69 parent::setUp(); | |
70 | |
71 // Create a text format. | |
72 $filtered_html_format = FilterFormat::create([ | |
73 'format' => 'filtered_html', | |
74 'name' => 'Filtered HTML', | |
75 'weight' => 0, | |
76 'filters' => [], | |
77 ]); | |
78 $filtered_html_format->save(); | |
79 | |
80 // Create a node type. | |
81 $this->drupalCreateContentType([ | |
82 'type' => 'article', | |
83 'name' => 'Article', | |
84 ]); | |
85 | |
86 // Set the node type to initially not have revisions. | |
87 // Testing with revisions will be done later. | |
88 $node_type = NodeType::load('article'); | |
89 $node_type->setNewRevision(FALSE); | |
90 $node_type->save(); | |
91 | |
92 // Create one node of the above node type using the above text format. | |
93 $this->testNode = $this->drupalCreateNode([ | |
94 'type' => 'article', | |
95 'body' => [ | |
96 0 => [ | |
97 'value' => '<p>How are you?</p>', | |
98 'format' => 'filtered_html', | |
99 ], | |
100 ], | |
101 'revision_log' => $this->randomString(), | |
102 ]); | |
103 | |
104 // Create 2 users, the only difference being the ability to use in-place | |
105 // editing | |
106 $basic_permissions = [ | |
107 'access content', | |
108 'create article content', | |
109 'edit any article content', | |
110 'use text format filtered_html', | |
111 'access contextual links', | |
112 ]; | |
113 $this->authorUser = $this->drupalCreateUser($basic_permissions); | |
114 $this->editorUser = $this->drupalCreateUser(array_merge($basic_permissions, ['access in-place editing'])); | |
115 } | |
116 | |
117 /** | |
118 * Test the loading of Quick Edit with different permissions. | |
119 */ | |
120 public function testUserPermissions() { | |
121 $assert = $this->assertSession(); | |
122 $this->drupalLogin($this->authorUser); | |
123 $this->drupalGet('node/1'); | |
124 | |
125 // Library and in-place editors. | |
126 $this->assertNoRaw('core/modules/quickedit/js/quickedit.js', 'Quick Edit library not loaded.'); | |
127 $this->assertNoRaw('core/modules/quickedit/js/editors/formEditor.js', "'form' in-place editor not loaded."); | |
128 | |
129 // HTML annotation and title class does not exist for users without | |
130 // permission to in-place edit. | |
131 $this->assertNoRaw('data-quickedit-entity-id="node/1"'); | |
132 $this->assertNoRaw('data-quickedit-field-id="node/1/body/en/full"'); | |
133 $this->assertNoFieldByXPath('//h1[contains(@class, "js-quickedit-page-title")]'); | |
134 $assert->linkNotExists('Quick edit'); | |
135 | |
136 // Tests the loading of Quick Edit when a user does have access to it. | |
137 // Also ensures lazy loading of in-place editors works. | |
138 $nid = $this->testNode->id(); | |
139 // There should be only one revision so far. | |
140 $node = Node::load($nid); | |
141 $vids = \Drupal::entityManager()->getStorage('node')->revisionIds($node); | |
142 $this->assertCount(1, $vids, 'The node has only one revision.'); | |
143 $original_log = $node->revision_log->value; | |
144 | |
145 $this->drupalLogin($this->editorUser); | |
146 $this->drupalGet('node/' . $nid); | |
147 $page = $this->getSession()->getPage(); | |
148 | |
149 // Wait "Quick edit" button for node. | |
150 $assert->waitForElement('css', '[data-quickedit-entity-id="node/' . $nid . '"] .contextual .quickedit'); | |
151 // Click by "Quick edit". | |
152 $this->clickContextualLink('[data-quickedit-entity-id="node/' . $nid . '"]', 'Quick edit'); | |
153 // Switch to body field. | |
154 $page->find('css', '[data-quickedit-field-id="node/' . $nid . '/body/en/full"]')->click(); | |
155 $assert->assertWaitOnAjaxRequest(); | |
156 | |
157 // Wait and update body field. | |
158 $body_field_locator = '[name="body[0][value]"]'; | |
159 $body_text = 'Fine thanks.'; | |
160 $assert->waitForElementVisible('css', $body_field_locator)->setValue('<p>' . $body_text . '</p>'); | |
161 | |
162 // Wait and click by "Save" button after body field was changed. | |
163 $assert->waitForElementVisible('css', '.quickedit-toolgroup.ops [type="submit"][aria-hidden="false"]')->click(); | |
164 $assert->assertWaitOnAjaxRequest(); | |
165 | |
166 $node = Node::load($nid); | |
167 $vids = \Drupal::entityManager()->getStorage('node')->revisionIds($node); | |
168 $this->assertCount(1, $vids, 'The node has only one revision.'); | |
169 $this->assertSame($original_log, $node->revision_log->value, 'The revision log message is unchanged.'); | |
170 | |
171 // Ensure that the changes take effect. | |
172 $assert->responseMatches("|\s*$body_text\s*|"); | |
173 | |
174 // Reload the page and check for updated body. | |
175 $this->drupalGet('node/' . $nid); | |
176 $assert->pageTextContains($body_text); | |
177 } | |
178 | |
179 /** | |
180 * Test Quick Edit does not appear for entities with pending revisions. | |
181 */ | |
182 public function testWithPendingRevision() { | |
183 $this->drupalLogin($this->editorUser); | |
184 | |
185 // Verify that the preview is loaded correctly. | |
186 $this->drupalPostForm('node/add/article', ['title[0][value]' => 'foo'], 'Preview'); | |
187 // Verify that quickedit is not active on preview. | |
188 $this->assertNoRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"'); | |
189 $this->assertNoRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"'); | |
190 | |
191 $this->drupalGet('node/' . $this->testNode->id()); | |
192 $this->assertRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"'); | |
193 $this->assertRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"'); | |
194 | |
195 // Wait for the page to completely load before making any changes to the | |
196 // node. This allows Quick Edit to fetch the metadata without causing | |
197 // database locks on SQLite. | |
198 $this->assertSession()->assertWaitOnAjaxRequest(); | |
199 $this->testNode->title = 'Updated node'; | |
200 $this->testNode->setNewRevision(TRUE); | |
201 $this->testNode->isDefaultRevision(FALSE); | |
202 $this->testNode->save(); | |
203 | |
204 $this->drupalGet('node/' . $this->testNode->id()); | |
205 $this->assertNoRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"'); | |
206 $this->assertNoRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"'); | |
207 } | |
208 | |
209 /** | |
210 * Tests the loading of Quick Edit for the title base field. | |
211 */ | |
212 public function testTitleBaseField() { | |
213 $page = $this->getSession()->getPage(); | |
214 $assert = $this->assertSession(); | |
215 $nid = $this->testNode->id(); | |
216 | |
217 $this->drupalLogin($this->editorUser); | |
218 $this->drupalGet('node/' . $nid); | |
219 | |
220 // Wait "Quick edit" button for node. | |
221 $assert->waitForElement('css', '[data-quickedit-entity-id="node/' . $nid . '"] .contextual .quickedit'); | |
222 // Click by "Quick edit". | |
223 $this->clickContextualLink('[data-quickedit-entity-id="node/' . $nid . '"]', 'Quick edit'); | |
224 // Switch to title field. | |
225 $page->find('css', '[data-quickedit-field-id="node/' . $nid . '/title/en/full"]')->click(); | |
226 $assert->assertWaitOnAjaxRequest(); | |
227 | |
228 // Wait and update title field. | |
229 $field_locator = '.field--name-title'; | |
230 $text_new = 'Obligatory question'; | |
231 $assert->waitForElementVisible('css', $field_locator)->setValue($text_new); | |
232 | |
233 // Wait and click by "Save" button after title field was changed. | |
234 $this->assertSession()->waitForElementVisible('css', '.quickedit-toolgroup.ops [type="submit"][aria-hidden="false"]')->click(); | |
235 $assert->assertWaitOnAjaxRequest(); | |
236 | |
237 // Ensure that the changes take effect. | |
238 $assert->responseMatches("|\s*$text_new\s*|"); | |
239 | |
240 // Reload the page and check for updated title. | |
241 $this->drupalGet('node/' . $nid); | |
242 $assert->pageTextContains($text_new); | |
243 } | |
244 | |
245 /** | |
246 * Tests that Quick Edit doesn't make fields rendered with display options | |
247 * editable. | |
248 */ | |
249 public function testDisplayOptions() { | |
250 $node = Node::load('1'); | |
251 $display_settings = [ | |
252 'label' => 'inline', | |
253 ]; | |
254 $build = $node->body->view($display_settings); | |
255 $output = \Drupal::service('renderer')->renderRoot($build); | |
256 $this->assertFalse(strpos($output, 'data-quickedit-field-id'), 'data-quickedit-field-id attribute not added when rendering field using dynamic display options.'); | |
257 } | |
258 | |
259 /** | |
260 * Tests Quick Edit on a node that was concurrently edited on the full node | |
261 * form. | |
262 */ | |
263 public function testConcurrentEdit() { | |
264 $nid = $this->testNode->id(); | |
265 $this->drupalLogin($this->authorUser); | |
266 | |
267 // Open the edit page in the default session. | |
268 $this->drupalGet('node/' . $nid . '/edit'); | |
269 | |
270 // Switch to a concurrent session and save a quick edit change. | |
271 // We need to do some bookkeeping to keep track of the logged in user. | |
272 $logged_in_user = $this->loggedInUser; | |
273 $this->loggedInUser = FALSE; | |
274 // Register a session to preform concurrent editing. | |
275 $driver = $this->getDefaultDriverInstance(); | |
276 $session = new Session($driver); | |
277 $this->mink->registerSession('concurrent', $session); | |
278 $this->mink->setDefaultSessionName('concurrent'); | |
279 $this->initFrontPage(); | |
280 $this->drupalLogin($this->editorUser); | |
281 $this->drupalGet('node/' . $nid); | |
282 | |
283 $assert = $this->assertSession(); | |
284 $page = $this->getSession()->getPage(); | |
285 | |
286 // Wait "Quick edit" button for node. | |
287 $assert->waitForElement('css', '[data-quickedit-entity-id="node/' . $nid . '"] .contextual .quickedit'); | |
288 // Click by "Quick edit". | |
289 $this->clickContextualLink('[data-quickedit-entity-id="node/' . $nid . '"]', 'Quick edit'); | |
290 // Switch to body field. | |
291 $page->find('css', '[data-quickedit-field-id="node/' . $nid . '/body/en/full"]')->click(); | |
292 $assert->assertWaitOnAjaxRequest(); | |
293 | |
294 // Wait and update body field. | |
295 $body_field_locator = '[name="body[0][value]"]'; | |
296 $body_text = 'Fine thanks.'; | |
297 $assert->waitForElementVisible('css', $body_field_locator)->setValue('<p>' . $body_text . '</p>'); | |
298 | |
299 // Wait and click by "Save" button after body field was changed. | |
300 $assert->waitForElementVisible('css', '.quickedit-toolgroup.ops [type="submit"][aria-hidden="false"]')->click(); | |
301 $assert->assertWaitOnAjaxRequest(); | |
302 | |
303 // Ensure that the changes take effect. | |
304 $assert->responseMatches("|\s*$body_text\s*|"); | |
305 | |
306 // Switch back to the default session. | |
307 $this->mink->setDefaultSessionName('default'); | |
308 $this->loggedInUser = $logged_in_user; | |
309 // Ensure different save timestamps for field editing. | |
310 sleep(2); | |
311 $this->drupalPostForm(NULL, ['body[0][value]' => '<p>Concurrent edit!</p>'], 'Save'); | |
312 | |
313 $this->getSession()->getPage()->hasContent('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'); | |
314 } | |
315 | |
316 /** | |
317 * Tests that Quick Edit's data- attributes are present for content blocks. | |
318 */ | |
319 public function testContentBlock() { | |
320 \Drupal::service('module_installer')->install(['block_content']); | |
321 | |
322 // Create and place a content_block block. | |
323 $block = BlockContent::create([ | |
324 'info' => $this->randomMachineName(), | |
325 'type' => 'basic', | |
326 'langcode' => 'en', | |
327 ]); | |
328 $block->save(); | |
329 $this->drupalPlaceBlock('block_content:' . $block->uuid()); | |
330 | |
331 // Check that the data- attribute is present. | |
332 $this->drupalLogin($this->editorUser); | |
333 $this->drupalGet(''); | |
334 $this->assertRaw('data-quickedit-entity-id="block_content/1"'); | |
335 } | |
336 | |
337 /** | |
338 * Tests that Quick Edit can handle an image field. | |
339 */ | |
340 public function testImageField() { | |
341 $page = $this->getSession()->getPage(); | |
342 $assert = $this->assertSession(); | |
343 | |
344 // Add an image field to the content type. | |
345 FieldStorageConfig::create([ | |
346 'field_name' => 'field_image', | |
347 'type' => 'image', | |
348 'entity_type' => 'node', | |
349 ])->save(); | |
350 FieldConfig::create([ | |
351 'field_name' => 'field_image', | |
352 'field_type' => 'image', | |
353 'label' => t('Image'), | |
354 'entity_type' => 'node', | |
355 'bundle' => 'article', | |
356 ])->save(); | |
357 entity_get_form_display('node', 'article', 'default') | |
358 ->setComponent('field_image', [ | |
359 'type' => 'image_image', | |
360 ]) | |
361 ->save(); | |
362 $display = EntityViewDisplay::load('node.article.default'); | |
363 $display->setComponent('field_image', [ | |
364 'type' => 'image', | |
365 ])->save(); | |
366 | |
367 // Add an image to the node. | |
368 $this->drupalLogin($this->editorUser); | |
369 $this->drupalGet('node/1/edit'); | |
370 $image = $this->drupalGetTestFiles('image')[0]; | |
371 $image_path = $this->container->get('file_system')->realpath($image->uri); | |
372 $page->attachFileToField('files[field_image_0]', $image_path); | |
373 $alt_field = $assert->waitForField('field_image[0][alt]'); | |
374 $this->assertNotEmpty($alt_field); | |
375 $this->drupalPostForm(NULL, [ | |
376 'field_image[0][alt]' => 'Vivamus aliquet elit', | |
377 ], t('Save')); | |
378 | |
379 // The image field form should load normally. | |
380 // Wait "Quick edit" button for node. | |
381 $assert->waitForElement('css', '[data-quickedit-entity-id="node/1"] .contextual .quickedit'); | |
382 // Click by "Quick edit". | |
383 $this->clickContextualLink('[data-quickedit-entity-id="node/1"]', 'Quick edit'); | |
384 // Switch to body field. | |
385 $assert->waitForElement('css', '[data-quickedit-field-id="node/1/field_image/en/full"]')->click(); | |
386 $assert->assertWaitOnAjaxRequest(); | |
387 | |
388 $field_locator = '.field--name-field-image'; | |
389 $assert->waitForElementVisible('css', $field_locator); | |
390 } | |
391 | |
392 } |