Chris@17
|
1 <?php
|
Chris@17
|
2
|
Chris@17
|
3 namespace Drupal\Tests\quickedit\FunctionalJavascript;
|
Chris@17
|
4
|
Chris@17
|
5 use Drupal\block_content\Entity\BlockContent;
|
Chris@17
|
6 use Drupal\block_content\Entity\BlockContentType;
|
Chris@17
|
7 use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
Chris@17
|
8 use Drupal\editor\Entity\Editor;
|
Chris@17
|
9 use Drupal\filter\Entity\FilterFormat;
|
Chris@17
|
10 use Drupal\taxonomy\Entity\Term;
|
Chris@17
|
11 use Drupal\taxonomy\Entity\Vocabulary;
|
Chris@17
|
12 use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
Chris@17
|
13
|
Chris@17
|
14 /**
|
Chris@17
|
15 * @group quickedit
|
Chris@17
|
16 */
|
Chris@17
|
17 class QuickEditIntegrationTest extends QuickEditJavascriptTestBase {
|
Chris@17
|
18
|
Chris@17
|
19 use EntityReferenceTestTrait;
|
Chris@17
|
20
|
Chris@17
|
21 /**
|
Chris@17
|
22 * {@inheritdoc}
|
Chris@17
|
23 */
|
Chris@17
|
24 public static $modules = [
|
Chris@17
|
25 'node',
|
Chris@17
|
26 'editor',
|
Chris@17
|
27 'ckeditor',
|
Chris@17
|
28 'taxonomy',
|
Chris@17
|
29 'block',
|
Chris@17
|
30 'block_content',
|
Chris@17
|
31 'hold_test',
|
Chris@17
|
32 ];
|
Chris@17
|
33
|
Chris@17
|
34 /**
|
Chris@17
|
35 * A user with permissions to edit Articles and use Quick Edit.
|
Chris@17
|
36 *
|
Chris@17
|
37 * @var \Drupal\user\UserInterface
|
Chris@17
|
38 */
|
Chris@17
|
39 protected $contentAuthorUser;
|
Chris@17
|
40
|
Chris@17
|
41 /**
|
Chris@17
|
42 * {@inheritdoc}
|
Chris@17
|
43 */
|
Chris@17
|
44 protected function setUp() {
|
Chris@17
|
45 parent::setUp();
|
Chris@17
|
46 // Create text format, associate CKEditor.
|
Chris@17
|
47 FilterFormat::create([
|
Chris@17
|
48 'format' => 'some_format',
|
Chris@17
|
49 'name' => 'Some format',
|
Chris@17
|
50 'weight' => 0,
|
Chris@17
|
51 'filters' => [
|
Chris@17
|
52 'filter_html' => [
|
Chris@17
|
53 'status' => 1,
|
Chris@17
|
54 'settings' => [
|
Chris@17
|
55 'allowed_html' => '<h2 id> <h3> <h4> <h5> <h6> <p> <br> <strong> <a href hreflang>',
|
Chris@17
|
56 ],
|
Chris@17
|
57 ],
|
Chris@17
|
58 ],
|
Chris@17
|
59 ])->save();
|
Chris@17
|
60 Editor::create([
|
Chris@17
|
61 'format' => 'some_format',
|
Chris@17
|
62 'editor' => 'ckeditor',
|
Chris@17
|
63 ])->save();
|
Chris@17
|
64
|
Chris@17
|
65 // Create the Article node type.
|
Chris@17
|
66 $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
Chris@17
|
67
|
Chris@17
|
68 // Add "tags" vocabulary + field to the Article node type.
|
Chris@17
|
69 $vocabulary = Vocabulary::create([
|
Chris@17
|
70 'name' => 'Tags',
|
Chris@17
|
71 'vid' => 'tags',
|
Chris@17
|
72 ]);
|
Chris@17
|
73 $vocabulary->save();
|
Chris@17
|
74 $field_name = 'field_' . $vocabulary->id();
|
Chris@17
|
75 $handler_settings = [
|
Chris@17
|
76 'target_bundles' => [
|
Chris@17
|
77 $vocabulary->id() => $vocabulary->id(),
|
Chris@17
|
78 ],
|
Chris@17
|
79 'auto_create' => TRUE,
|
Chris@17
|
80 ];
|
Chris@17
|
81 $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
Chris@17
|
82
|
Chris@17
|
83 // Add formatter & widget for "tags" field.
|
Chris@17
|
84 \Drupal::entityTypeManager()
|
Chris@17
|
85 ->getStorage('entity_form_display')
|
Chris@17
|
86 ->load('node.article.default')
|
Chris@17
|
87 ->setComponent($field_name, ['type' => 'entity_reference_autocomplete_tags'])
|
Chris@17
|
88 ->save();
|
Chris@17
|
89 \Drupal::entityTypeManager()
|
Chris@17
|
90 ->getStorage('entity_view_display')
|
Chris@17
|
91 ->load('node.article.default')
|
Chris@17
|
92 ->setComponent($field_name, ['type' => 'entity_reference_label'])
|
Chris@17
|
93 ->save();
|
Chris@17
|
94
|
Chris@17
|
95 $this->drupalPlaceBlock('page_title_block');
|
Chris@17
|
96 $this->drupalPlaceBlock('system_main_block');
|
Chris@17
|
97
|
Chris@17
|
98 // Log in as a content author who can use Quick Edit and edit Articles.
|
Chris@17
|
99 $this->contentAuthorUser = $this->drupalCreateUser([
|
Chris@17
|
100 'access contextual links',
|
Chris@17
|
101 'access toolbar',
|
Chris@17
|
102 'access in-place editing',
|
Chris@17
|
103 'access content',
|
Chris@17
|
104 'create article content',
|
Chris@17
|
105 'edit any article content',
|
Chris@17
|
106 'use text format some_format',
|
Chris@17
|
107 'edit terms in tags',
|
Chris@17
|
108 'administer blocks',
|
Chris@17
|
109 ]);
|
Chris@17
|
110 $this->drupalLogin($this->contentAuthorUser);
|
Chris@17
|
111 }
|
Chris@17
|
112
|
Chris@17
|
113 /**
|
Chris@17
|
114 * Tests if an article node can be in-place edited with Quick Edit.
|
Chris@17
|
115 */
|
Chris@17
|
116 public function testArticleNode() {
|
Chris@17
|
117 $term = Term::create([
|
Chris@17
|
118 'name' => 'foo',
|
Chris@17
|
119 'vid' => 'tags',
|
Chris@17
|
120 ]);
|
Chris@17
|
121 $term->save();
|
Chris@17
|
122
|
Chris@17
|
123 $node = $this->drupalCreateNode([
|
Chris@17
|
124 'type' => 'article',
|
Chris@17
|
125 'title' => t('My Test Node'),
|
Chris@17
|
126 'body' => [
|
Chris@17
|
127 'value' => '<p>Hello world!</p><p>I do not know what to say…</p><p>I wish I were eloquent.</p>',
|
Chris@17
|
128 'format' => 'some_format',
|
Chris@17
|
129 ],
|
Chris@17
|
130 'field_tags' => [
|
Chris@17
|
131 ['target_id' => $term->id()],
|
Chris@17
|
132 ],
|
Chris@17
|
133 ]);
|
Chris@17
|
134
|
Chris@17
|
135 $this->drupalGet('node/' . $node->id());
|
Chris@17
|
136
|
Chris@17
|
137 // Initial state.
|
Chris@17
|
138 $this->awaitQuickEditForEntity('node', 1);
|
Chris@17
|
139 $this->assertEntityInstanceStates([
|
Chris@17
|
140 'node/1[0]' => 'closed',
|
Chris@17
|
141 ]);
|
Chris@17
|
142 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
143 'node/1/title/en/full' => 'inactive',
|
Chris@17
|
144 'node/1/uid/en/full' => 'inactive',
|
Chris@17
|
145 'node/1/created/en/full' => 'inactive',
|
Chris@17
|
146 'node/1/body/en/full' => 'inactive',
|
Chris@17
|
147 'node/1/field_tags/en/full' => 'inactive',
|
Chris@17
|
148 ]);
|
Chris@17
|
149
|
Chris@17
|
150 // Start in-place editing of the article node.
|
Chris@17
|
151 $this->startQuickEditViaToolbar('node', 1, 0);
|
Chris@17
|
152 $this->assertEntityInstanceStates([
|
Chris@17
|
153 'node/1[0]' => 'opened',
|
Chris@17
|
154 ]);
|
Chris@17
|
155 $this->assertQuickEditEntityToolbar((string) $node->label(), NULL);
|
Chris@17
|
156 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
157 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
158 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
159 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
160 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
161 'node/1/field_tags/en/full' => 'candidate',
|
Chris@17
|
162 ]);
|
Chris@17
|
163
|
Chris@17
|
164 $assert_session = $this->assertSession();
|
Chris@17
|
165
|
Chris@17
|
166 // Click the title field.
|
Chris@17
|
167 $this->click('[data-quickedit-field-id="node/1/title/en/full"].quickedit-candidate');
|
Chris@17
|
168 $assert_session->waitForElement('css', '.quickedit-toolbar-field div[id*="title"]');
|
Chris@17
|
169 $this->assertQuickEditEntityToolbar((string) $node->label(), 'Title');
|
Chris@17
|
170 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
171 'node/1/title/en/full' => 'active',
|
Chris@17
|
172 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
173 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
174 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
175 'node/1/field_tags/en/full' => 'candidate',
|
Chris@17
|
176 ]);
|
Chris@17
|
177 $this->assertEntityInstanceFieldMarkup('node', 1, 0, [
|
Chris@17
|
178 'node/1/title/en/full' => '[contenteditable="true"]',
|
Chris@17
|
179 ]);
|
Chris@17
|
180
|
Chris@17
|
181 // Append something to the title.
|
Chris@17
|
182 $this->typeInPlainTextEditor('[data-quickedit-field-id="node/1/title/en/full"].quickedit-candidate', ' Llamas are awesome!');
|
Chris@17
|
183 $this->awaitEntityInstanceFieldState('node', 1, 0, 'title', 'en', 'changed');
|
Chris@17
|
184 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
185 'node/1/title/en/full' => 'changed',
|
Chris@17
|
186 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
187 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
188 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
189 'node/1/field_tags/en/full' => 'candidate',
|
Chris@17
|
190 ]);
|
Chris@17
|
191
|
Chris@17
|
192 // Click the body field.
|
Chris@17
|
193 hold_test_response(TRUE);
|
Chris@17
|
194 $this->click('[data-quickedit-entity-id="node/1"] .field--name-body');
|
Chris@17
|
195 $assert_session->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
|
Chris@17
|
196 $this->assertQuickEditEntityToolbar((string) $node->label(), 'Body');
|
Chris@17
|
197 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
198 'node/1/title/en/full' => 'saving',
|
Chris@17
|
199 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
200 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
201 'node/1/body/en/full' => 'active',
|
Chris@17
|
202 'node/1/field_tags/en/full' => 'candidate',
|
Chris@17
|
203 ]);
|
Chris@17
|
204 hold_test_response(FALSE);
|
Chris@17
|
205
|
Chris@17
|
206 // Wait for CKEditor to load, then verify it has.
|
Chris@17
|
207 $this->assertJsCondition('CKEDITOR.status === "loaded"');
|
Chris@17
|
208 $this->assertEntityInstanceFieldMarkup('node', 1, 0, [
|
Chris@17
|
209 'node/1/body/en/full' => '.cke_editable_inline',
|
Chris@17
|
210 'node/1/field_tags/en/full' => ':not(.quickedit-editor-is-popup)',
|
Chris@17
|
211 ]);
|
Chris@17
|
212 $this->assertSession()->elementExists('css', '#quickedit-entity-toolbar .quickedit-toolgroup.wysiwyg-main > .cke_chrome .cke_top[role="presentation"] .cke_toolbar[role="toolbar"] .cke_toolgroup[role="presentation"] > .cke_button[title~="Bold"][role="button"]');
|
Chris@17
|
213
|
Chris@17
|
214 // Wait for the validating & saving of the title to complete.
|
Chris@17
|
215 $this->awaitEntityInstanceFieldState('node', 1, 0, 'title', 'en', 'candidate');
|
Chris@17
|
216
|
Chris@17
|
217 // Click the tags field.
|
Chris@17
|
218 hold_test_response(TRUE);
|
Chris@17
|
219 $this->click('[data-quickedit-field-id="node/1/field_tags/en/full"]');
|
Chris@17
|
220 $assert_session->waitForElement('css', '.quickedit-toolbar-field div[id*="tags"]');
|
Chris@17
|
221 $this->assertQuickEditEntityToolbar((string) $node->label(), 'Tags');
|
Chris@17
|
222 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
223 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
224 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
225 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
226 'node/1/field_tags/en/full' => 'activating',
|
Chris@17
|
227 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
228 ]);
|
Chris@17
|
229 $this->assertEntityInstanceFieldMarkup('node', 1, 0, [
|
Chris@17
|
230 'node/1/title/en/full' => '.quickedit-changed',
|
Chris@17
|
231 'node/1/field_tags/en/full' => '.quickedit-editor-is-popup',
|
Chris@17
|
232 ]);
|
Chris@17
|
233 // Assert the "Loading…" popup appears.
|
Chris@17
|
234 $this->assertSession()->elementExists('css', '.quickedit-form-container > .quickedit-form[role="dialog"] > .placeholder');
|
Chris@17
|
235 hold_test_response(FALSE);
|
Chris@17
|
236 // Wait for the form to load.
|
Chris@17
|
237 $this->assertJsCondition('document.querySelector(\'.quickedit-form-container > .quickedit-form[role="dialog"] > .placeholder\') === null');
|
Chris@17
|
238 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
239 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
240 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
241 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
242 'node/1/field_tags/en/full' => 'active',
|
Chris@17
|
243 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
244 ]);
|
Chris@17
|
245
|
Chris@17
|
246 // Enter an additional tag.
|
Chris@17
|
247 $this->typeInFormEditorTextInputField('field_tags[target_id]', 'foo, bar');
|
Chris@17
|
248 $this->awaitEntityInstanceFieldState('node', 1, 0, 'field_tags', 'en', 'changed');
|
Chris@17
|
249 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
250 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
251 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
252 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
253 'node/1/field_tags/en/full' => 'changed',
|
Chris@17
|
254 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
255 ]);
|
Chris@17
|
256
|
Chris@17
|
257 // Click 'Save'.
|
Chris@17
|
258 hold_test_response(TRUE);
|
Chris@17
|
259 $this->saveQuickEdit();
|
Chris@17
|
260 $this->assertEntityInstanceStates([
|
Chris@17
|
261 'node/1[0]' => 'committing',
|
Chris@17
|
262 ]);
|
Chris@17
|
263 $this->assertEntityInstanceFieldStates('node', 1, 0, [
|
Chris@17
|
264 'node/1/uid/en/full' => 'candidate',
|
Chris@17
|
265 'node/1/created/en/full' => 'candidate',
|
Chris@17
|
266 'node/1/body/en/full' => 'candidate',
|
Chris@17
|
267 'node/1/field_tags/en/full' => 'saving',
|
Chris@17
|
268 'node/1/title/en/full' => 'candidate',
|
Chris@17
|
269 ]);
|
Chris@17
|
270 hold_test_response(FALSE);
|
Chris@17
|
271 $this->assertEntityInstanceFieldMarkup('node', 1, 0, [
|
Chris@17
|
272 'node/1/title/en/full' => '.quickedit-changed',
|
Chris@17
|
273 'node/1/field_tags/en/full' => '.quickedit-changed',
|
Chris@17
|
274 ]);
|
Chris@17
|
275
|
Chris@17
|
276 // Wait for the saving of the tags field to complete.
|
Chris@17
|
277 $this->assertJsCondition("Drupal.quickedit.collections.entities.get('node/1[0]').get('state') === 'closed'");
|
Chris@17
|
278 $this->assertEntityInstanceStates([
|
Chris@17
|
279 'node/1[0]' => 'closed',
|
Chris@17
|
280 ]);
|
Chris@17
|
281 }
|
Chris@17
|
282
|
Chris@17
|
283 /**
|
Chris@17
|
284 * Tests if a custom can be in-place edited with Quick Edit.
|
Chris@17
|
285 */
|
Chris@17
|
286 public function testCustomBlock() {
|
Chris@17
|
287 $block_content_type = BlockContentType::create([
|
Chris@17
|
288 'id' => 'basic',
|
Chris@17
|
289 'label' => 'basic',
|
Chris@17
|
290 'revision' => FALSE,
|
Chris@17
|
291 ]);
|
Chris@17
|
292 $block_content_type->save();
|
Chris@17
|
293 block_content_add_body_field($block_content_type->id());
|
Chris@17
|
294
|
Chris@17
|
295 $block_content = BlockContent::create([
|
Chris@17
|
296 'info' => 'Llama',
|
Chris@17
|
297 'type' => 'basic',
|
Chris@17
|
298 'body' => [
|
Chris@17
|
299 'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
|
Chris@17
|
300 'format' => 'some_format',
|
Chris@17
|
301 ],
|
Chris@17
|
302 ]);
|
Chris@17
|
303 $block_content->save();
|
Chris@17
|
304 $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), [
|
Chris@17
|
305 'label' => 'My custom block!',
|
Chris@17
|
306 ]);
|
Chris@17
|
307
|
Chris@17
|
308 $this->drupalGet('');
|
Chris@17
|
309
|
Chris@17
|
310 // Initial state.
|
Chris@17
|
311 $this->awaitQuickEditForEntity('block_content', 1);
|
Chris@17
|
312 $this->assertEntityInstanceStates([
|
Chris@17
|
313 'block_content/1[0]' => 'closed',
|
Chris@17
|
314 ]);
|
Chris@17
|
315
|
Chris@17
|
316 // Start in-place editing of the article node.
|
Chris@17
|
317 $this->startQuickEditViaToolbar('block_content', 1, 0);
|
Chris@17
|
318 $this->assertEntityInstanceStates([
|
Chris@17
|
319 'block_content/1[0]' => 'opened',
|
Chris@17
|
320 ]);
|
Chris@17
|
321 $this->assertQuickEditEntityToolbar((string) $block_content->label(), 'Body');
|
Chris@17
|
322 $this->assertEntityInstanceFieldStates('block_content', 1, 0, [
|
Chris@17
|
323 'block_content/1/body/en/full' => 'highlighted',
|
Chris@17
|
324 ]);
|
Chris@17
|
325
|
Chris@17
|
326 // Click the body field.
|
Chris@17
|
327 $this->click('[data-quickedit-entity-id="block_content/1"] .field--name-body');
|
Chris@17
|
328 $assert_session = $this->assertSession();
|
Chris@17
|
329 $assert_session->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
|
Chris@17
|
330 $this->assertQuickEditEntityToolbar((string) $block_content->label(), 'Body');
|
Chris@17
|
331 $this->assertEntityInstanceFieldStates('block_content', 1, 0, [
|
Chris@17
|
332 'block_content/1/body/en/full' => 'active',
|
Chris@17
|
333 ]);
|
Chris@17
|
334
|
Chris@17
|
335 // Wait for CKEditor to load, then verify it has.
|
Chris@17
|
336 $this->assertJsCondition('CKEDITOR.status === "loaded"');
|
Chris@17
|
337 $this->assertEntityInstanceFieldMarkup('block_content', 1, 0, [
|
Chris@17
|
338 'block_content/1/body/en/full' => '.cke_editable_inline',
|
Chris@17
|
339 ]);
|
Chris@17
|
340 $this->assertSession()->elementExists('css', '#quickedit-entity-toolbar .quickedit-toolgroup.wysiwyg-main > .cke_chrome .cke_top[role="presentation"] .cke_toolbar[role="toolbar"] .cke_toolgroup[role="presentation"] > .cke_button[title~="Bold"][role="button"]');
|
Chris@17
|
341 }
|
Chris@17
|
342
|
Chris@17
|
343 }
|