.../QuickEditIntegrationTest.php | 184 ++++++++++++++++++--- 1 file changed, 158 insertions(+), 26 deletions(-) diff --git a/core/modules/quickedit/tests/src/FunctionalJavaScript/QuickEditIntegrationTest.php b/core/modules/quickedit/tests/src/FunctionalJavaScript/QuickEditIntegrationTest.php index 1ba5cf0..857bf79 100644 --- a/core/modules/quickedit/tests/src/FunctionalJavaScript/QuickEditIntegrationTest.php +++ b/core/modules/quickedit/tests/src/FunctionalJavaScript/QuickEditIntegrationTest.php @@ -2,19 +2,25 @@ namespace Drupal\Tests\quickedit\FunctionalJavascript; +use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\editor\Entity\Editor; +use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\filter\Entity\FilterFormat; use Drupal\FunctionalJavascriptTests\JavascriptTestBase; +use Drupal\taxonomy\Entity\Term; +use Drupal\taxonomy\Entity\Vocabulary; /** * @group quickedit */ class QuickEditIntegrationTest extends JavascriptTestBase { + use EntityReferenceTestTrait; + /** * {@inheritdoc} */ - public static $modules = ['node', 'editor', 'ckeditor', 'contextual', 'quickedit', 'toolbar']; + public static $modules = ['node', 'editor', 'ckeditor', 'contextual', 'quickedit', 'toolbar', 'taxonomy']; /** * A user with permissions to edit Articles and use Quick Edit. @@ -24,7 +30,13 @@ class QuickEditIntegrationTest extends JavascriptTestBase { protected $contentAuthorUser; protected static $expectedFieldStateAttributes = [ - 'candidate' => '.quickedit-field.quickedit-editable.quickedit-candidate:not(.quickedit-highlighted):not(.quickedit-editing):not(.quickedit-changed)', + 'inactive' => '.quickedit-field:not(.quickedit-editable):not(.quickedit-candidate):not(.quickedit-highlighted):not(.quickedit-editing):not(.quickedit-changed)', + // A field in 'candidate' state may still have the .quickedit-changed class + // because when its changes were saved to tempstore, it'll still be changed. + // It's just not currently being edited, so that's why it is not in the + // 'changed' state. + 'candidate' => '.quickedit-field.quickedit-editable.quickedit-candidate:not(.quickedit-highlighted):not(.quickedit-editing)', + 'activating' => '.quickedit-field.quickedit-editable.quickedit-candidate.quickedit-highlighted.quickedit-editing:not(.quickedit-changed)', 'active' => '.quickedit-field.quickedit-editable.quickedit-candidate.quickedit-highlighted.quickedit-editing:not(.quickedit-changed)', 'changed' => '.quickedit-field.quickedit-editable.quickedit-candidate.quickedit-highlighted.quickedit-editing.quickedit-changed', 'saving' => '.quickedit-field.quickedit-editable.quickedit-candidate.quickedit-highlighted.quickedit-editing.quickedit-changed', @@ -58,6 +70,31 @@ protected function setUp() { // Create the Article node type. $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + // Add "tags" vocabulary + field to the Article node type. + $vocabulary = Vocabulary::create([ + 'name' => 'Tags', + 'vid' => 'tags', + ]); + $vocabulary->save(); + $field_name = 'field_' . $vocabulary->id(); + $handler_settings = [ + 'target_bundles' => [ + $vocabulary->id() => $vocabulary->id(), + ], + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + // Add formatter & widget for "tags" field. + entity_get_form_display('node', 'article', 'default') + ->setComponent($field_name, [ + 'type' => 'entity_reference_autocomplete_tags', + ]) + ->save(); + entity_get_display('node', 'article', 'default') + ->setComponent($field_name, ['type' => 'entity_reference_label']) + ->save(); + // Log in as a content author who can use Quick Edit and edit Articles. $this->contentAuthorUser = $this->drupalCreateUser([ 'access contextual links', @@ -67,6 +104,7 @@ protected function setUp() { 'create article content', 'edit any article content', 'use text format some_format', + 'edit terms in tags', ]); $this->drupalLogin($this->contentAuthorUser); } @@ -232,13 +270,22 @@ function () { * Tests if an article node can be in-place edited with Quick Edit. */ public function testArticleNode() { + $term = Term::create([ + 'name' => 'foo', + 'vid' => 'tags', + ]); + $term->save(); + $node = $this->drupalCreateNode([ 'type' => 'article', 'title' => t('My Test Node'), 'body' => [ - 'value' => 'Hello world!', + 'value' => '

Hello world!

I do not know what to say…

I wish I were eloquent.

', 'format' => 'some_format', ], + 'field_tags' => [ + ['target_id' => $term->id()], + ] ]); $this->drupalGet('node/' . $node->id()); @@ -248,6 +295,13 @@ public function testArticleNode() { $this->assertEntityStates([ 'node/1[0]' => 'closed', ]); + $this->assertEntityFieldStates('node', 1, 0, [ + 'node/1/title/en/full' => 'inactive', + 'node/1/uid/en/full' => 'inactive', + 'node/1/created/en/full' => 'inactive', + 'node/1/body/en/full' => 'inactive', + 'node/1/field_tags/en/full' => 'inactive', + ]); // Start in-place editing of the article node. $this->startQuickEditViaToolbar('node', 1); @@ -256,25 +310,30 @@ public function testArticleNode() { ]); $this->assertQuickEditEntityToolbar((string) $node->label(), NULL); $this->assertEntityFieldStates('node', 1, 0, [ - 'node/1/title/en/full' => 'candidate', - 'node/1/uid/en/full' => 'candidate', - 'node/1/created/en/full' => 'candidate', - 'node/1/body/en/full' => 'candidate', + 'node/1/title/en/full' => 'candidate', + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'candidate', ]); // Click the title field. $this->click('h1.js-quickedit-page-title > span'); $this->assertQuickEditEntityToolbar((string) $node->label(), 'Title'); $this->assertEntityFieldStates('node', 1, 0, [ - 'node/1/title/en/full' => 'active', - 'node/1/uid/en/full' => 'candidate', - 'node/1/created/en/full' => 'candidate', - 'node/1/body/en/full' => 'candidate', + 'node/1/title/en/full' => 'active', + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'candidate', + ]); + $this->assertEntityFieldMarkup('node', 1, 0, [ + 'node/1/title/en/full' => '[contenteditable="true"]', ]); - // Type in the title field. + // Append something to the title. // @todo Clean this up once PhantomJS is fixed, see http://sticksnglue.com/wordpress/phantomjs-1-9-and-keyboardevent/. - $text_to_type = $node->get('body')->value . ' Llamas are awesome!'; + $text_to_type = $node->label() . ' Llamas are awesome!'; $js_simulate_user_typing = <<getSession()->evaluateScript($js_simulate_user_typing); $this->assertEntityFieldStates('node', 1, 0, [ - 'node/1/title/en/full' => 'changed', - 'node/1/uid/en/full' => 'candidate', - 'node/1/created/en/full' => 'candidate', - 'node/1/body/en/full' => 'candidate', + 'node/1/title/en/full' => 'changed', + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'candidate', ]); // Click the body field. $this->click('[data-quickedit-entity-id="node/1"] .field--name-body'); $this->assertQuickEditEntityToolbar((string) $node->label(), 'Body'); $this->assertEntityFieldStates('node', 1, 0, [ - 'node/1/title/en/full' => 'saving', - 'node/1/uid/en/full' => 'candidate', - 'node/1/created/en/full' => 'candidate', - 'node/1/body/en/full' => 'active', + 'node/1/title/en/full' => 'saving', + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'active', + 'node/1/field_tags/en/full' => 'candidate', + ]); + + // Wait for CKEditor to load, then verify it has. + $this->assertJsCondition('CKEDITOR.status === "loaded"'); + $this->assertEntityFieldMarkup('node', 1, 0, [ + 'node/1/body/en/full' => '.cke_editable_inline', + 'node/1/field_tags/en/full' => ':not(.quickedit-editor-is-popup)', ]); + $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"]'); - $this->createScreenshot('/tmp/screenshot.png'); + // Wait for the saving of the title field to complete. + $this->assertJsCondition("Drupal.quickedit.collections.fields.get('node/1/field_tags/en/full[0]').get('state') === 'candidate'"); - // @todo wait for CKEditor instance to load + // Click the tags field. + $this->click('.field--name-field-tags'); + $this->assertQuickEditEntityToolbar((string) $node->label(), 'Tags'); + $this->assertEntityFieldStates('node', 1, 0, [ + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'activating', + 'node/1/title/en/full' => 'candidate', + ]); + $this->assertEntityFieldMarkup('node', 1, 0, [ + 'node/1/title/en/full' => '.quickedit-changed', + 'node/1/field_tags/en/full' => '.quickedit-editor-is-popup', + ]); + // Assert the "Loading…" popup appears. + $this->assertSession()->elementExists('css', '.quickedit-form-container > .quickedit-form[role="dialog"] > .placeholder'); + // Wait for the form to load. + $this->assertJsCondition('document.querySelector(\'.quickedit-form-container > .quickedit-form[role="dialog"] > .placeholder\') === null'); + $this->assertEntityFieldStates('node', 1, 0, [ + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'active', + 'node/1/title/en/full' => 'candidate', + ]); - // @todo type something + // Enter an additional tag. + $input = $this->cssSelect('.quickedit-form-container > .quickedit-form[role="dialog"] form.quickedit-field-form input[name="field_tags[target_id]"]')[0]; + $input->setValue($input->getValue() . ', bar'); + $js_simulate_user_typing = << .quickedit-form[role="dialog"] form.quickedit-field-form input[name="field_tags[target_id]"]'); + window.jQuery(el).trigger('formUpdated'); +}() +JS; + $this->getSession()->evaluateScript($js_simulate_user_typing); + $this->assertEntityFieldStates('node', 1, 0, [ + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'changed', + 'node/1/title/en/full' => 'candidate', + ]); - // @todo change another field + // Click 'Save'. + $quickedit_entity_toolbar = $this->getSession()->getPage()->findById('quickedit-entity-toolbar'); + $save_button = $quickedit_entity_toolbar->find('css', 'button.action-save'); + $save_button->press(); + $this->assertSame('Saving', $save_button->getText()); + $this->assertEntityStates([ + 'node/1[0]' => 'committing', + ]); + $this->assertEntityFieldStates('node', 1, 0, [ + 'node/1/uid/en/full' => 'candidate', + 'node/1/created/en/full' => 'candidate', + 'node/1/body/en/full' => 'candidate', + 'node/1/field_tags/en/full' => 'saving', + 'node/1/title/en/full' => 'candidate', + ]); + $this->assertEntityFieldMarkup('node', 1, 0, [ + 'node/1/title/en/full' => '.quickedit-changed', + 'node/1/field_tags/en/full' => '.quickedit-changed', + ]); - // @todo save + // Wait for the saving of the tags field to complete. + $this->assertJsCondition("Drupal.quickedit.collections.entities.get('node/1[0]').get('state') === 'closed'"); + $this->assertEntityStates([ + 'node/1[0]' => 'closed', + ]); } // @todo test custom block