You are here

CKEditor5IntegrationTest.php in Drupal 10

File

core/modules/quickedit/tests/src/FunctionalJavascript/CKEditor5IntegrationTest.php
View source
<?php

namespace Drupal\Tests\quickedit\FunctionalJavascript;

use Drupal\ckeditor5\Plugin\Editor\CKEditor5;
use Drupal\editor\Entity\Editor;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
use Symfony\Component\Validator\ConstraintViolation;

/**
 * Tests that Quick Edit can load CKEditor 5.
 *
 * @group quickedit
 * @internal
 */
class CKEditor5IntegrationTest extends QuickEditJavascriptTestBase {
  use EntityReferenceTestTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node',
    'editor',
    'ckeditor5',
    'hold_test',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * A user with permissions to edit Articles and use Quick Edit.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $contentAuthorUser;

  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();

    // Create text format, associate CKEditor 5, validate.
    FilterFormat::create([
      'format' => 'some_format',
      'name' => 'Some format',
      'filters' => [
        'filter_html' => [
          'status' => TRUE,
          'settings' => [
            'allowed_html' => '<p> <br> <h2> <h3> <h4> <h5> <h6> <strong> <em>',
          ],
        ],
      ],
    ])
      ->save();
    Editor::create([
      'format' => 'some_format',
      'editor' => 'ckeditor5',
      'settings' => [
        'toolbar' => [
          'items' => [
            'heading',
            'bold',
            'italic',
          ],
        ],
        'plugins' => [
          'ckeditor5_heading' => [
            'enabled_headings' => [
              'heading2',
              'heading3',
              'heading4',
              'heading5',
              'heading6',
            ],
          ],
        ],
      ],
      'image_upload' => [
        'status' => FALSE,
      ],
    ])
      ->save();
    $this
      ->assertSame([], array_map(function (ConstraintViolation $v) {
      return (string) $v
        ->getMessage();
    }, iterator_to_array(CKEditor5::validatePair(Editor::load('some_format'), FilterFormat::load('some_format')))));

    // Create the Article node type.
    $this
      ->drupalCreateContentType([
      'type' => 'article',
      'name' => 'Article',
    ]);

    // Log in as a content author who can use Quick Edit and edit Articles.
    $this->contentAuthorUser = $this
      ->drupalCreateUser([
      'access contextual links',
      'access toolbar',
      'access in-place editing',
      'access content',
      'create article content',
      'edit any article content',
      'use text format some_format',
    ]);
    $this
      ->drupalLogin($this->contentAuthorUser);
  }

  /**
   * Tests that changes can be discarded.
   */
  public function testDiscard() {
    $page = $this
      ->getSession()
      ->getPage();
    $node = $this
      ->drupalCreateNode([
      'type' => 'article',
      'title' => t('My Test Node'),
      'body' => [
        'value' => '<p>Hello world!</p><p>I do not know what to say…</p><p>I wish I were eloquent.</p>',
        'format' => 'some_format',
      ],
    ]);
    $this
      ->drupalGet('node/' . $node
      ->id());

    // Initial state.
    $this
      ->awaitQuickEditForEntity('node', 1);
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'closed',
    ]);
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'inactive',
      'node/1/body/en/full' => 'inactive',
    ]);

    // Start in-place editing of the article node.
    $this
      ->startQuickEditViaToolbar('node', 1, 0);
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'opened',
    ]);
    $this
      ->assertQuickEditEntityToolbar((string) $node
      ->label(), NULL);
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'candidate',
    ]);
    $assert_session = $this
      ->assertSession();

    // Click the body field.
    hold_test_response(TRUE);
    $this
      ->click('[data-quickedit-field-id="node/1/body/en/full"]');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
    $this
      ->assertQuickEditEntityToolbar((string) $node
      ->label(), 'Body');
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'active',
    ]);
    hold_test_response(FALSE);
    $this
      ->assertEntityInstanceFieldMarkup([
      'node/1/body/en/full' => '.ck-editor__editable_inline',
    ]);
    $this
      ->assertSession()
      ->elementExists('css', '#quickedit-entity-toolbar .quickedit-toolgroup.wysiwyg-main .ck-toolbar[role="toolbar"] .ck-toolbar__items > .ck-button[type="button"]');

    // Click the body field.
    $this
      ->click('[data-quickedit-field-id="node/1/body/en/full"]');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
    $this
      ->typeInPlainTextEditor('[data-quickedit-field-id="node/1/body/en/full"]', ' I am not wanted here');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"].quickedit-changed');
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'changed',
    ]);
    $assert_session
      ->pageTextContains('I am not wanted here');

    // Click the 'Cancel' button.
    $page
      ->find('css', '.action-cancel.quickedit-button')
      ->press();
    hold_test_response(TRUE);

    // Click the 'Discard Changes' button.
    $discard_changes_button = $page
      ->findAll('css', '.ui-dialog-buttonset .button')[1];
    $this
      ->assertEquals('Discard changes', $discard_changes_button
      ->getText());
    $discard_changes_button
      ->press();
    $assert_session
      ->pageTextNotContains('I am not wanted here');
    hold_test_response(FALSE);
  }

  /**
   * Tests if an article node can be in-place edited with Quick Edit.
   */
  public function testArticleNode() {
    $assert_session = $this
      ->assertSession();
    $node = $this
      ->drupalCreateNode([
      'type' => 'article',
      'title' => t('My Test Node'),
      'body' => [
        'value' => '<p>Hello world!</p><p>I do not know what to say…</p><p>I wish I were eloquent.</p>',
        'format' => 'some_format',
      ],
    ]);
    $this
      ->drupalGet('node/' . $node
      ->id());

    // Initial state.
    $this
      ->awaitQuickEditForEntity('node', 1);
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'closed',
    ]);
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'inactive',
      'node/1/body/en/full' => 'inactive',
    ]);

    // Start in-place editing of the article node.
    $this
      ->startQuickEditViaToolbar('node', 1, 0);
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'opened',
    ]);
    $this
      ->assertQuickEditEntityToolbar((string) $node
      ->label(), NULL);
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'candidate',
    ]);

    // Click the body field.
    hold_test_response(TRUE);
    $this
      ->click('[data-quickedit-field-id="node/1/body/en/full"]');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
    $this
      ->assertQuickEditEntityToolbar((string) $node
      ->label(), 'Body');
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'active',
    ]);
    hold_test_response(FALSE);
    $this
      ->assertEntityInstanceFieldMarkup([
      'node/1/body/en/full' => '.ck-editor__editable_inline',
    ]);
    $this
      ->assertSession()
      ->elementExists('css', '#quickedit-entity-toolbar .quickedit-toolgroup.wysiwyg-main .ck-toolbar[role="toolbar"] .ck-toolbar__items > .ck-button[type="button"]');

    // Click the body field.
    $this
      ->click('[data-quickedit-field-id="node/1/body/en/full"]');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"]');
    $this
      ->typeInPlainTextEditor('[data-quickedit-field-id="node/1/body/en/full"]', ' Added text with CKEditor 5');
    $assert_session
      ->waitForElement('css', '.quickedit-toolbar-field div[id*="body"].quickedit-changed');
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'changed',
    ]);

    // Click 'Save'.
    hold_test_response(TRUE);
    $this
      ->saveQuickEdit();
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'committing',
    ]);
    $this
      ->assertEntityInstanceFieldStates('node', 1, 0, [
      'node/1/title/en/full' => 'candidate',
      'node/1/body/en/full' => 'saving',
    ]);
    $this
      ->assertEntityInstanceFieldMarkup([
      'node/1/body/en/full' => '.quickedit-changed',
    ]);
    hold_test_response(FALSE);
    $this
      ->assertJsCondition("Drupal.quickedit.collections.entities.get('node/1[0]').get('state') === 'closed'");
    $this
      ->assertEntityInstanceStates([
      'node/1[0]' => 'closed',
    ]);

    // Get the load again and ensure the values are the expected values.
    $this
      ->drupalGet('node/' . $node
      ->id());
    $this
      ->assertSession()
      ->pageTextContains('I wish I were eloquent.');
    $this
      ->assertSession()
      ->pageTextContains('Added text with CKEditor 5');
  }

}

Classes

Namesort descending Description
CKEditor5IntegrationTest Tests that Quick Edit can load CKEditor 5.