View source
<?php
declare (strict_types=1);
namespace Drupal\Tests\ckeditor5\Kernel;
use Drupal\ckeditor\CKEditorPluginConfigurableInterface;
use Drupal\ckeditor5\HTMLRestrictions;
use Drupal\ckeditor5\Plugin\CKEditor5PluginElementsSubsetInterface;
use Drupal\Component\Assertion\Inspector;
use Drupal\Component\Utility\NestedArray;
use Drupal\filter\Entity\FilterFormat;
use Drupal\KernelTests\KernelTestBase;
class CKEditor4to5UpgradeCompletenessTest extends KernelTestBase {
const CONTRIB_BUTTONS_NOW_IN_CORE = [
'Code',
];
protected $cke4PluginManager;
protected $cke5PluginManager;
protected $upgradePluginManager;
protected $smartDefaultSettings;
protected static $modules = [
'ckeditor',
'ckeditor5',
'filter',
'media',
'media_library',
'views',
'filter',
'editor',
];
protected function setUp() : void {
parent::setUp();
$this->container
->setAlias('sut', 'plugin.manager.ckeditor4to5upgrade.plugin');
$this->cke4PluginManager = $this->container
->get('plugin.manager.ckeditor.plugin');
$this->cke5PluginManager = $this->container
->get('plugin.manager.ckeditor5.plugin');
$this->upgradePluginManager = $this->container
->get('sut');
$this->smartDefaultSettings = $this->container
->get('ckeditor5.smart_default_settings');
}
public function testButtons() : void {
$cke4_buttons = array_keys(NestedArray::mergeDeepArray($this->cke4PluginManager
->getButtons()));
$cke4_buttons = array_merge($cke4_buttons, self::CONTRIB_BUTTONS_NOW_IN_CORE);
foreach ($cke4_buttons as $button) {
$equivalent = $this->upgradePluginManager
->mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem($button, HTMLRestrictions::emptySet());
$this
->assertTrue($equivalent === NULL || is_array($equivalent) && Inspector::assertAllStrings($equivalent));
if (is_string($equivalent)) {
foreach (explode(',', $equivalent) as $equivalent_cke5_toolbar_item) {
$this
->assertArrayHasKey($equivalent_cke5_toolbar_item, $this->cke5PluginManager
->getToolbarItems());
}
}
}
}
public function testButtonsWithTestOnlyModule() : void {
$this
->enableModules([
'ckeditor_test',
]);
$this->cke4PluginManager = $this->container
->get('plugin.manager.ckeditor.plugin');
$this
->expectException(\OutOfBoundsException::class);
$this
->expectExceptionMessage('No upgrade path found for the "LlamaCSS" button.');
$this
->testButtons();
}
public function testSettings() : void {
$cke4_configurable_plugins = [];
foreach ($this->cke4PluginManager
->getDefinitions() as $plugin_id => $definition) {
if ($plugin_id === 'drupalimage') {
continue;
}
if (is_subclass_of($definition['class'], CKEditorPluginConfigurableInterface::class)) {
$cke4_configurable_plugins[] = $plugin_id;
}
}
foreach ($cke4_configurable_plugins as $plugin_id) {
$cke5_plugin_settings = $this->upgradePluginManager
->mapCKEditor4SettingsToCKEditor5Configuration($plugin_id, []);
$this
->assertTrue($cke5_plugin_settings === NULL || is_array($cke5_plugin_settings));
if (is_array($cke5_plugin_settings)) {
$cke5_plugin_id = array_keys($cke5_plugin_settings)[0];
$this
->assertArrayHasKey($cke5_plugin_id, $this->cke5PluginManager
->getDefinitions());
}
}
}
public function testSettingsWithTestOnlyModule() : void {
$this
->enableModules([
'ckeditor_test',
]);
$this->cke4PluginManager = $this->container
->get('plugin.manager.ckeditor.plugin');
$this
->expectException(\OutOfBoundsException::class);
$this
->expectExceptionMessage('No upgrade path found for the "llama_contextual_and_button" plugin settings.');
$this
->testSettings();
}
public function testCKEditor5ConfigurableSubsetPlugins() : void {
$cke5_elements_subset_plugins = [];
foreach ($this->cke5PluginManager
->getDefinitions() as $plugin_id => $definition) {
if ($plugin_id === 'ckeditor5_sourceEditing') {
continue;
}
if (is_a($definition
->getClass(), CKEditor5PluginElementsSubsetInterface::class, TRUE)) {
$cke5_elements_subset_plugins[] = $plugin_id;
}
}
foreach ($cke5_elements_subset_plugins as $plugin_id) {
$cke5_plugin_configuration = $this->upgradePluginManager
->computeCKEditor5PluginSubsetConfiguration($plugin_id, FilterFormat::create());
$this
->assertTrue($cke5_plugin_configuration === NULL || is_array($cke5_plugin_configuration));
}
}
public function testOnlyOneUpgradePluginAllowedPerCKEditor4Button() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'duplicate_button');
$this
->expectException(\OutOfBoundsException::class);
$this
->expectExceptionMessage('The "DrupalImage" CKEditor 4 button is already being upgraded by the "core" CKEditor4To5Upgrade plugin, the "foo" plugin is as well. This conflict needs to be resolved.');
$this->upgradePluginManager
->mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem('foo', HTMLRestrictions::emptySet());
}
public function testLyingUpgradePluginForCKEditor4Button() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'lying_button');
$this
->expectException(\LogicException::class);
$this
->expectExceptionMessage('The "foo" CKEditor4To5Upgrade plugin claims to provide an upgrade path for the "foo" CKEditor 4 button but does not.');
$this->upgradePluginManager
->mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem('foo', HTMLRestrictions::emptySet());
}
public function testOnlyOneUpgradePluginAllowedPerCKEditor4PluginSettings() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'duplicate_plugin_settings');
$this
->expectException(\OutOfBoundsException::class);
$this
->expectExceptionMessage('The "stylescombo" CKEditor 4 plugin\'s settings are already being upgraded by the "core" CKEditor4To5Upgrade plugin, the "foo" plugin is as well. This conflict needs to be resolved.');
$this->upgradePluginManager
->mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem('foo', HTMLRestrictions::emptySet());
}
public function testLyingUpgradePluginForCKEditor4PluginSettings() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'lying_plugin_settings');
$this
->expectException(\LogicException::class);
$this
->expectExceptionMessage('The "foo" CKEditor4To5Upgrade plugin claims to provide an upgrade path for the "foo" CKEditor 4 plugin settings but does not.');
$this->upgradePluginManager
->mapCKEditor4SettingsToCKEditor5Configuration('foo', []);
}
public function testOnlyOneUpgradePluginAllowedPerCKEditor5ConfigurableSubsetPlugin() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'duplicate_subset');
$this
->expectException(\OutOfBoundsException::class);
$this
->expectExceptionMessage('The "ckeditor5_heading" CKEditor 5 plugin\'s elements subset configuration is already being computed by the "core" CKEditor4To5Upgrade plugin, the "foo" plugin is as well. This conflict needs to be resolved.');
$this->upgradePluginManager
->computeCKEditor5PluginSubsetConfiguration('foo', FilterFormat::create());
}
public function testLyingUpgradePluginForCKEditor5ConfigurableSubsetPlugin() : void {
$this
->enableModules([
'ckeditor4to5upgrade_plugin_test',
]);
\Drupal::state()
->set('ckeditor4to5upgrade_plugin_test', 'lying_subset');
$this
->expectException(\LogicException::class);
$this
->expectExceptionMessage('The "foo" CKEditor4To5Upgrade plugin claims to provide an upgrade path for the "foo" CKEditor 4 plugin settings but does not.');
$this->upgradePluginManager
->computeCKEditor5PluginSubsetConfiguration('foo', FilterFormat::create());
}
}