Newer
Older
Dries Buytaert
committed
<?php
/**
* @file
* Contains \Drupal\ckeditor\Tests\CKEditorAdminTest.
Dries Buytaert
committed
*/
namespace Drupal\ckeditor\Tests;
use Drupal\Component\Serialization\Json;
use Drupal\editor\Entity\Editor;
use Drupal\filter\FilterFormatInterface;
Dries Buytaert
committed
use Drupal\simpletest\WebTestBase;
/**
* Tests administration of CKEditor.
*
* @group ckeditor
Dries Buytaert
committed
*/
class CKEditorAdminTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('filter', 'editor', 'ckeditor');
/**
* A user with the 'administer filters' permission.
*
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
Alex Pott
committed
protected function setUp() {
Dries Buytaert
committed
parent::setUp();
// Create text format.
$filtered_html_format = entity_create('filter_format', array(
'format' => 'filtered_html',
'name' => 'Filtered HTML',
'weight' => 0,
'filters' => array(),
));
$filtered_html_format->save();
// Create admin user.
$this->adminUser = $this->drupalCreateUser(array('administer filters'));
Dries Buytaert
committed
}
/**
* Tests configuring a text editor for an existing text format.
*/
function testExistingFormat() {
Angie Byron
committed
$ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor');
Dries Buytaert
committed
$this->drupalLogin($this->adminUser);
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Dries Buytaert
committed
// Ensure no Editor config entity exists yet.
$editor = entity_load('editor', 'filtered_html');
$this->assertFalse($editor, 'No Editor config entity exists yet.');
// Verify the "Text Editor" <select> when a text editor is available.
$select = $this->xpath('//select[@name="editor[editor]"]');
$select_is_disabled = $this->xpath('//select[@name="editor[editor]" and @disabled="disabled"]');
$options = $this->xpath('//select[@name="editor[editor]"]/option');
$this->assertTrue(count($select) === 1, 'The Text Editor select exists.');
$this->assertTrue(count($select_is_disabled) === 0, 'The Text Editor select is not disabled.');
$this->assertTrue(count($options) === 2, 'The Text Editor select has two options.');
$this->assertTrue(((string) $options[0]) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertTrue(((string) $options[1]) === 'CKEditor', 'Option 2 in the Text Editor select is "CKEditor".');
$this->assertTrue(((string) $options[0]['selected']) === 'selected', 'Option 1 ("None") is selected.');
Alex Pott
committed
// Select the "CKEditor" editor and click the "Save configuration" button.
$edit = array(
'editor[editor]' => 'ckeditor',
);
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
Alex Pott
committed
$this->assertRaw(t('You must configure the selected text editor.'));
Dries Buytaert
committed
// Ensure the CKEditor editor returns the expected default settings.
$expected_default_settings = array(
'toolbar' => array(
Angie Byron
committed
'rows' => array(
// Button groups
Dries Buytaert
committed
array(
Angie Byron
committed
array(
'name' => t('Formatting'),
'items' => array('Bold', 'Italic',),
),
array(
'name' => t('Links'),
'items' => array('DrupalLink', 'DrupalUnlink',),
),
array(
'name' => t('Lists'),
'items' => array('BulletedList', 'NumberedList',),
),
array(
'name' => t('Media'),
'items' => array('Blockquote', 'DrupalImage',),
),
array(
'name' => t('Tools'),
'items' => array('Source',),
),
Dries Buytaert
committed
),
),
),
'plugins' => array(),
);
$this->assertIdentical($ckeditor->getDefaultSettings(), $expected_default_settings);
Alex Pott
committed
// Keep the "CKEditor" editor selected and click the "Configure" button.
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
Dries Buytaert
committed
$editor = entity_load('editor', 'filtered_html');
$this->assertFalse($editor, 'No Editor config entity exists yet.');
// Ensure that drupalSettings is correct.
$ckeditor_settings_toolbar = array(
'#theme' => 'ckeditor_settings_toolbar',
'#editor' => Editor::create(['editor' => 'ckeditor']),
'#plugins' => $this->container->get('plugin.manager.ckeditor.plugin')->getButtons(),
);
$this->assertEqual(
$this->drupalSettings['ckeditor']['toolbarAdmin'],
$this->container->get('renderer')->renderPlain($ckeditor_settings_toolbar),
'CKEditor toolbar settings are rendered as part of drupalSettings.'
);
Dries Buytaert
committed
// Ensure the toolbar buttons configuration value is initialized to the
// expected default value.
Angie Byron
committed
$expected_buttons_value = json_encode($expected_default_settings['toolbar']['rows']);
$this->assertFieldByName('editor[settings][toolbar][button_groups]', $expected_buttons_value);
Dries Buytaert
committed
// Ensure the styles textarea exists and is initialized empty.
$styles_textarea = $this->xpath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]');
$this->assertFieldByXPath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]', '', 'The styles textarea exists and is empty.');
$this->assertTrue(count($styles_textarea) === 1, 'The "styles" textarea exists.');
// Submit the form to save the selection of CKEditor as the chosen editor.
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
Dries Buytaert
committed
// Ensure an Editor object exists now, with the proper settings.
$expected_settings = $expected_default_settings;
$expected_settings['plugins']['stylescombo']['styles'] = '';
$editor = entity_load('editor', 'filtered_html');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists now.');
Angie Byron
committed
$this->assertIdentical($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
Dries Buytaert
committed
// Configure the Styles plugin, and ensure the updated settings are saved.
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Dries Buytaert
committed
$edit = array(
'editor[settings][plugins][stylescombo][styles]' => "h1.title|Title\np.callout|Callout\n\n",
);
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
Dries Buytaert
committed
$expected_settings['plugins']['stylescombo']['styles'] = "h1.title|Title\np.callout|Callout\n\n";
$editor = entity_load('editor', 'filtered_html');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists.');
Angie Byron
committed
$this->assertIdentical($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
Dries Buytaert
committed
// Change the buttons that appear on the toolbar (in JavaScript, this is
// done via drag and drop, but here we can only emulate the end result of
// that interaction). Test multiple toolbar rows and a divider within a row.
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Angie Byron
committed
$expected_settings['toolbar']['rows'][0][] = array(
'name' => 'Action history',
Alex Pott
committed
'items' => array('Undo', '|', 'Redo', 'JustifyCenter'),
Dries Buytaert
committed
);
$edit = array(
Angie Byron
committed
'editor[settings][toolbar][button_groups]' => json_encode($expected_settings['toolbar']['rows']),
Dries Buytaert
committed
);
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
Dries Buytaert
committed
$editor = entity_load('editor', 'filtered_html');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists.');
Angie Byron
committed
$this->assertIdentical($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
Dries Buytaert
committed
// Check that the markup we're setting for the toolbar buttons (actually in
// JavaScript's drupalSettings, and Unicode-escaped) is correctly rendered.
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
// Create function to encode HTML as we expect it in drupalSettings.
$json_encode = function($html) {
return trim(Json::encode($html), '"');
};
// Check the Button separator.
$this->assertRaw($json_encode('<li data-drupal-ckeditor-button-name="-" class="ckeditor-button-separator ckeditor-multiple-button" data-drupal-ckeditor-type="separator"><a href="#" role="button" aria-label="Button separator" class="ckeditor-separator"></a></li>'));
// Check the Format dropdown.
$this->assertRaw($json_encode('<li data-drupal-ckeditor-button-name="Format" class="ckeditor-button"><a href="#" role="button" aria-label="Format"><span class="ckeditor-button-dropdown">Format<span class="ckeditor-button-arrow"></span></span></a></li>'));
// Check the Styles dropdown.
$this->assertRaw($json_encode('<li data-drupal-ckeditor-button-name="Styles" class="ckeditor-button"><a href="#" role="button" aria-label="Styles"><span class="ckeditor-button-dropdown">Styles<span class="ckeditor-button-arrow"></span></span></a></li>'));
// Check strikethrough.
$this->assertRaw($json_encode('<li data-drupal-ckeditor-button-name="Strike" class="ckeditor-button"><a href="#" class="cke-icon-only cke_ltr" role="button" title="strike" aria-label="strike"><span class="cke_button_icon cke_button__strike_icon">strike</span></a></li>'));
Dries Buytaert
committed
// Now enable the ckeditor_test module, which provides one configurable
// CKEditor plugin — this should not affect the Editor config entity.
Alex Pott
committed
\Drupal::service('module_installer')->install(array('ckeditor_test'));
$this->resetAll();
Angie Byron
committed
$this->container->get('plugin.manager.ckeditor.plugin')->clearCachedDefinitions();
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Dries Buytaert
committed
$ultra_llama_mode_checkbox = $this->xpath('//input[@type="checkbox" and @name="editor[settings][plugins][llama_contextual_and_button][ultra_llama_mode]" and not(@checked)]');
$this->assertTrue(count($ultra_llama_mode_checkbox) === 1, 'The "Ultra llama mode" checkbox exists and is not checked.');
$editor = entity_load('editor', 'filtered_html');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists.');
Angie Byron
committed
$this->assertIdentical($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
Dries Buytaert
committed
// Finally, check the "Ultra llama mode" checkbox.
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Dries Buytaert
committed
$edit = array(
'editor[settings][plugins][llama_contextual_and_button][ultra_llama_mode]' => '1',
);
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
$this->drupalGet('admin/config/content/formats/manage/filtered_html');
Dries Buytaert
committed
$ultra_llama_mode_checkbox = $this->xpath('//input[@type="checkbox" and @name="editor[settings][plugins][llama_contextual_and_button][ultra_llama_mode]" and @checked="checked"]');
$this->assertTrue(count($ultra_llama_mode_checkbox) === 1, 'The "Ultra llama mode" checkbox exists and is checked.');
Alex Pott
committed
$expected_settings['plugins']['llama_contextual_and_button']['ultra_llama_mode'] = TRUE;
Dries Buytaert
committed
$editor = entity_load('editor', 'filtered_html');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists.');
Angie Byron
committed
$this->assertIdentical($expected_settings, $editor->getSettings());
Dries Buytaert
committed
}
/**
* Tests configuring a text editor for a new text format.
*
* This test only needs to ensure that the basics of the CKEditor
* configuration form work; details are tested in testExistingFormat().
*/
function testNewFormat() {
$this->drupalLogin($this->adminUser);
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
$this->drupalGet('admin/config/content/formats/add');
// Verify the "Text Editor" <select> when a text editor is available.
$select = $this->xpath('//select[@name="editor[editor]"]');
$select_is_disabled = $this->xpath('//select[@name="editor[editor]" and @disabled="disabled"]');
$options = $this->xpath('//select[@name="editor[editor]"]/option');
$this->assertTrue(count($select) === 1, 'The Text Editor select exists.');
$this->assertTrue(count($select_is_disabled) === 0, 'The Text Editor select is not disabled.');
$this->assertTrue(count($options) === 2, 'The Text Editor select has two options.');
$this->assertTrue(((string) $options[0]) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertTrue(((string) $options[1]) === 'CKEditor', 'Option 2 in the Text Editor select is "CKEditor".');
$this->assertTrue(((string) $options[0]['selected']) === 'selected', 'Option 1 ("None") is selected.');
// Name our fancy new text format, select the "CKEditor" editor and click
// the "Configure" button.
$edit = array(
'name' => 'My amazing text format',
'format' => 'amazing_format',
'editor[editor]' => 'ckeditor',
);
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
$filter_format = entity_load('filter_format', 'amazing_format');
$this->assertFalse($filter_format, 'No FilterFormat config entity exists yet.');
$editor = entity_load('editor', 'amazing_format');
$this->assertFalse($editor, 'No Editor config entity exists yet.');
// Ensure the toolbar buttons configuration value is initialized to the
// default value.
$ckeditor = $this->container->get('plugin.manager.editor')->createInstance('ckeditor');
$default_settings = $ckeditor->getDefaultSettings();
$expected_buttons_value = json_encode($default_settings['toolbar']['rows']);
$this->assertFieldByName('editor[settings][toolbar][button_groups]', $expected_buttons_value);
// Ensure the styles textarea exists and is initialized empty.
$styles_textarea = $this->xpath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]');
$this->assertFieldByXPath('//textarea[@name="editor[settings][plugins][stylescombo][styles]"]', '', 'The styles textarea exists and is empty.');
$this->assertTrue(count($styles_textarea) === 1, 'The "styles" textarea exists.');
// Submit the form to create both a new text format and an associated text
// editor.
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
// Ensure a FilterFormat object exists now.
$filter_format = entity_load('filter_format', 'amazing_format');
$this->assertTrue($filter_format instanceof FilterFormatInterface, 'A FilterFormat config entity exists now.');
// Ensure an Editor object exists now, with the proper settings.
$expected_settings = $default_settings;
$expected_settings['plugins']['stylescombo']['styles'] = '';
$editor = entity_load('editor', 'amazing_format');
$this->assertTrue($editor instanceof Editor, 'An Editor config entity exists now.');
$this->assertIdentical($expected_settings, $editor->getSettings(), 'The Editor config entity has the correct settings.');
}