diff --git a/composer.lock b/composer.lock index da7b39f56..a5df556bc 100644 --- a/composer.lock +++ b/composer.lock @@ -2362,10 +2362,10 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_audio", - "reference": "7693fd5974833102c32922fcba20bb5739087007" + "reference": "f3ecf71a424fa9f60f58d7f51da4be535b2468fa" }, "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", + "drupal/field_group": "^3.4", "drupal/media_entity_soundcloud": "^3.1" }, "type": "drupal-module", @@ -2542,10 +2542,7 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_document", - "reference": "d4ff4d0cd000a6b69d87a8285ba8e77695f20b7d" - }, - "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1" + "reference": "b540fd85d2f2e1e99a486f0e588fcc299873f6ef" }, "type": "drupal-module", "extra": { @@ -2670,10 +2667,9 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_image", - "reference": "501adc8b92147541e809976b25e71b881a4fb924" + "reference": "0ea611dd109ffbd040a11108593c6025a0ac021e" }, "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/focal_point": "^2.1", "drupal/imagemagick": "^3.4 || ^4.0", "drupal/imce": "^2.2 || ^3.0" @@ -2700,9 +2696,10 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_page", - "reference": "7f5ea3e0492ecec8f60af6f7b74fbef65327a153" + "reference": "e8eb0e38594080963b4ccca068cadff6564ff65e" }, "require": { + "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/acquia_cms_image": "^1.5.10" }, "conflict": { @@ -2758,9 +2755,10 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_place", - "reference": "f9c3c4f4f5625dd3a989c19345327e836467d937" + "reference": "aa2c2ebe75c12d30e8b2c724bf6ee1d12cdc2456" }, "require": { + "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/acquia_cms_image": "^1.5.10", "drupal/address": "^1.11 || ^2.0", "drupal/geocoder": "^3.35 || ^4.10", @@ -2980,10 +2978,7 @@ "dist": { "type": "path", "url": "./modules/acquia_cms_video", - "reference": "2532213d18e7aba5922eaca5b99fa85d59464542" - }, - "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1" + "reference": "43379fe5250c30753c63a5066e524b83131dc968" }, "type": "drupal-module", "extra": { diff --git a/modules/acquia_cms_audio/acquia_cms_audio.info.yml b/modules/acquia_cms_audio/acquia_cms_audio.info.yml index ee1330f4b..bf8817534 100644 --- a/modules/acquia_cms_audio/acquia_cms_audio.info.yml +++ b/modules/acquia_cms_audio/acquia_cms_audio.info.yml @@ -4,8 +4,8 @@ description: "Provides an Audio media type and related configuration." type: module core_version_requirement: ^9.4 || ^10 || ^11 dependencies: - - acquia_cms_common:acquia_cms_common - drupal:media - drupal:media_library + - drupal:taxonomy - media_entity_soundcloud:media_entity_soundcloud - field_group:field_group diff --git a/modules/acquia_cms_audio/acquia_cms_audio.install b/modules/acquia_cms_audio/acquia_cms_audio.install index 07dde2b7f..44037c5c9 100644 --- a/modules/acquia_cms_audio/acquia_cms_audio.install +++ b/modules/acquia_cms_audio/acquia_cms_audio.install @@ -5,11 +5,53 @@ * Install, update and uninstall functions for the acquia_cms_audio module. */ +use Drupal\acquia_cms_audio\EntityOperations\PermissionManager; +use Drupal\editor\Entity\Editor; + /** * Implements hook_install(). */ function acquia_cms_audio_install($is_syncing) { if (!$is_syncing) { - _acquia_cms_common_editor_config_rewrite(); + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles(); + _acquia_cms_audio_editor_config_rewrite(); + } +} + +/** + * Function to rewrite filtered_html & full_html configurations. + */ +function _acquia_cms_audio_editor_config_rewrite(): void { + if(!\Drupal::moduleHandler()->moduleExists('editor')) { + return; + } + $editors = [ + "filtered_html", + "full_html", + ]; + foreach ($editors as $editor) { + try { + $editorObject = \Drupal::entityTypeManager()->getStorage('editor')->load($editor); + if ($editorObject instanceof Editor) { + $settings = $editorObject->getSettings(); + $items = &$settings["toolbar"]["items"]; + $plugins = &$settings['plugins']; + if (!in_array('drupalMedia', $items)) { + $items[] = 'drupalMedia'; + } + if (!in_array('', $plugins['ckeditor5_sourceEditing']['allowed_tags'])) { + $plugins['ckeditor5_sourceEditing']['allowed_tags'][] = ''; + } + if ($plugins["media_media"]["allow_view_mode_override"] === FALSE) { + $plugins["media_media"]["allow_view_mode_override"] = TRUE; + } + $editorObject->setSettings($settings)->save(); + } + } + catch (\Exception $e) { + \Drupal::logger("acquia_cms_audio_config_rewrite")->error($e->getMessage()); + } } } diff --git a/modules/acquia_cms_audio/acquia_cms_audio.module b/modules/acquia_cms_audio/acquia_cms_audio.module index 9e8e82967..c3a317452 100644 --- a/modules/acquia_cms_audio/acquia_cms_audio.module +++ b/modules/acquia_cms_audio/acquia_cms_audio.module @@ -5,27 +5,16 @@ * Install, update and uninstall functions for the acquia_cms_audio module. */ +use Drupal\acquia_cms_audio\EntityOperations\PermissionManager; use Drupal\user\RoleInterface; /** - * Implements hook_content_model_role_presave_alter(). + * Implements hook_entity_insert(). */ -function acquia_cms_audio_content_model_role_presave_alter(RoleInterface &$role) { - switch ($role->id()) { - case 'content_author': - foreach ([ - 'create audio media', - 'edit own audio media', - 'delete own audio media', - ] as $permission) { - $role->grantPermission($permission); - } - break; - - case 'content_editor': - foreach (['edit any audio media', 'delete any audio media'] as $permission) { - $role->grantPermission($permission); - } - break; +function acquia_cms_audio_user_role_insert(RoleInterface $role) { + if(!$role->isSyncing()) { + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles([$role->id()]); } } diff --git a/modules/acquia_cms_audio/composer.json b/modules/acquia_cms_audio/composer.json index 80105f5a8..745e8fbde 100644 --- a/modules/acquia_cms_audio/composer.json +++ b/modules/acquia_cms_audio/composer.json @@ -4,7 +4,7 @@ "license": "GPL-2.0-or-later", "type": "drupal-module", "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", + "drupal/field_group": "^3.4", "drupal/media_entity_soundcloud": "^3.1" }, "repositories": { diff --git a/modules/acquia_cms_common/config/optional/field.storage.media.field_categories.yml b/modules/acquia_cms_audio/config/optional/field.storage.media.field_categories.yml similarity index 100% rename from modules/acquia_cms_common/config/optional/field.storage.media.field_categories.yml rename to modules/acquia_cms_audio/config/optional/field.storage.media.field_categories.yml diff --git a/modules/acquia_cms_common/config/install/field.storage.media.field_tags.yml b/modules/acquia_cms_audio/config/optional/field.storage.media.field_tags.yml similarity index 100% rename from modules/acquia_cms_common/config/install/field.storage.media.field_tags.yml rename to modules/acquia_cms_audio/config/optional/field.storage.media.field_tags.yml diff --git a/modules/acquia_cms_audio/config/optional/media.type.audio.yml b/modules/acquia_cms_audio/config/optional/media.type.audio.yml index df956cfe3..bef371cee 100644 --- a/modules/acquia_cms_audio/config/optional/media.type.audio.yml +++ b/modules/acquia_cms_audio/config/optional/media.type.audio.yml @@ -6,9 +6,6 @@ dependencies: enforced: module: - acquia_cms_audio -third_party_settings: - crop: - image_field: null id: audio label: Audio description: 'Remotely hosted audio from external sources soundcloud.' diff --git a/modules/acquia_cms_common/config/install/taxonomy.vocabulary.categories.yml b/modules/acquia_cms_audio/config/optional/taxonomy.vocabulary.categories.yml similarity index 100% rename from modules/acquia_cms_common/config/install/taxonomy.vocabulary.categories.yml rename to modules/acquia_cms_audio/config/optional/taxonomy.vocabulary.categories.yml diff --git a/modules/acquia_cms_audio/config/optional/taxonomy.vocabulary.tags.yml b/modules/acquia_cms_audio/config/optional/taxonomy.vocabulary.tags.yml new file mode 100644 index 000000000..2dce29541 --- /dev/null +++ b/modules/acquia_cms_audio/config/optional/taxonomy.vocabulary.tags.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Tags +vid: tags +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_audio/src/EntityOperations/PermissionManager.php b/modules/acquia_cms_audio/src/EntityOperations/PermissionManager.php new file mode 100644 index 000000000..8b58f4c6b --- /dev/null +++ b/modules/acquia_cms_audio/src/EntityOperations/PermissionManager.php @@ -0,0 +1,71 @@ +get('entity_type.manager') + ); + } + + /** + * Update role permission handler. + * + * @param array|null $role_ids + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function grantPermissionToRoles(array $role_ids = NULL): void { + $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple($role_ids ?? [ + 'content_author', + 'content_editor', + ]); + foreach ($roles as $role) { + switch ($role->id()) { + case 'content_author': + foreach ([ + 'create audio media', + 'edit own audio media', + 'delete own audio media', + ] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + + case 'content_editor': + foreach (['edit any audio media', 'delete any audio media'] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + } + } + } + +} diff --git a/modules/acquia_cms_audio/tests/src/Functional/AudioTest.php b/modules/acquia_cms_audio/tests/src/Functional/AudioTest.php index 9951ff2c5..d7350c9be 100644 --- a/modules/acquia_cms_audio/tests/src/Functional/AudioTest.php +++ b/modules/acquia_cms_audio/tests/src/Functional/AudioTest.php @@ -2,8 +2,9 @@ namespace Drupal\Tests\acquia_cms_audio\Functional; +use Drupal\Component\Utility\SortArray; use Drupal\taxonomy\Entity\Term; -use Drupal\Tests\acquia_cms_common\Functional\MediaTypeTestBase; +use Drupal\Tests\BrowserTestBase; /** * Tests the Audio media type that ships with Acquia CMS. @@ -14,48 +15,38 @@ * @group push * @group pr */ -class AudioTest extends MediaTypeTestBase { +class AudioTest extends BrowserTestBase { /** * {@inheritdoc} */ - protected static $modules = ['acquia_cms_audio']; - - /** - * Disable strict config schema checks in this test. - * - * Cohesion has a lot of config schema errors, and until they are all fixed, - * this test cannot pass unless we disable strict config schema checking - * altogether. Since strict config schema isn't critically important in - * testing this functionality, it's okay to disable it for now, but it should - * be re-enabled (i.e., this property should be removed) as soon as possible. - * - * @var bool - */ - // @codingStandardsIgnoreStart - protected $strictConfigSchema = FALSE; - // @codingStandardsIgnoreEnd + protected $defaultTheme = 'stark'; /** * {@inheritdoc} */ - protected $mediaType = 'audio'; + protected static $modules = [ + 'ckeditor5', + 'acquia_cms_audio', + ]; /** * {@inheritdoc} */ - protected function doTestEditForm() : void { - $page = $this->getSession()->getPage(); + public function testAudio() : void { + $this->drupalLogin($this->rootUser); + + $session = $this->getSession(); + $page = $session->getPage(); $assert_session = $this->assertSession(); - $account = $this->drupalCreateUser(); - $account->addRole('content_author'); - $account->save(); - $this->drupalLogin($account); + // Add Categories vocabulary terms to the select list. + $this->drupalGet("admin/structure/taxonomy/manage/categories/add"); + $page->fillField('Name', 'Music'); + $page->pressButton('Save'); + $assert_session->pageTextContains('Created new term Music.'); - $this->drupalGet('media/add/' . $this->mediaType); - // Assert that the current user can access the form to create a video media. - // Note that status codes cannot be asserted in functional JavaScript tests. + $this->drupalGet("/media/add/audio"); $assert_session->statusCodeEquals(200); // Assert that the expected fields show up. @@ -63,8 +54,28 @@ protected function doTestEditForm() : void { $assert_session->fieldExists('Soundcloud audio URL'); $assert_session->fieldExists('Categories'); $assert_session->fieldExists('Tags'); + // The standard Categories and Tags fields should be present. - $this->assertCategoriesAndTagsFieldsExist(); + $group = $assert_session->elementExists('css', '#edit-group-taxonomy'); + + $tags = $assert_session->fieldExists('Tags', $group); + $this->assertTrue($tags->hasAttribute('data-autocomplete-path')); + + $categories = $assert_session->selectExists('Categories', $group); + // No item added to the select list. + $this->assertTrue($categories->hasAttribute('multiple')); + + // Ensure that the select list has every term in the Categories vocabulary. + $terms = $this->container->get('entity_type.manager') + ->getStorage('taxonomy_term') + ->loadByProperties([ + 'vid' => 'categories', + ]); + + /** @var \Drupal\taxonomy\TermInterface $term */ + foreach ($terms as $term) { + $assert_session->optionExists('Categories', $term->label(), $group); + } // Assert that the fields are in the correct order. $this->assertFieldsOrder([ @@ -84,21 +95,52 @@ protected function doTestEditForm() : void { // For convenience, the parent class creates a few categories during set-up. // @see \Drupal\Tests\acquia_cms_common\Functional\ContentModelTestBase::setUp() $page->selectFieldOption('Categories', 'Music'); - $page->fillField('Tags', 'techno'); + $page->fillField('Tags', 'Techno'); $page->pressButton('Save'); $assert_session->pageTextContains('Audio Decoupled Drupal Podcast with Third & Grove and Acquia has been created.'); // Assert that the techno tag was created dynamically in the correct // vocabulary. /** @var \Drupal\taxonomy\TermInterface $tag */ - $tag = Term::load(4); + $tag = Term::load(2); $this->assertInstanceOf(Term::class, $tag); $this->assertSame('tags', $tag->bundle()); - $this->assertSame('techno', $tag->getName()); + $this->assertSame('Techno', $tag->getName()); // Media items are not normally exposed at standalone URLs, so assert that // the URL alias field does not show up. $assert_session->fieldNotExists('path[0][alias]'); } + /** + * Asserts that the fields are in the correct order. + * + * @param string[] $expected_order + * The machine names of the fields we expect in media type's form display, + * in the order we expect them to have. + */ + protected function assertFieldsOrder(array $expected_order): void { + $components = $this->container->get('entity_display.repository') + ->getFormDisplay('media', 'audio') + ->getComponents(); + + $this->assertDisplayComponentsOrder($components, $expected_order, "The fields of the 'audio' media type's edit form were not in the expected order."); + } + + /** + * Asserts that the components of an entity display are in a specific order. + * + * @param array[] $components + * The components in the entity display. + * @param string[] $expected_order + * The components' keys, in the expected order. + * @param string $message + * (optional) A message if the assertion fails. + */ + protected function assertDisplayComponentsOrder(array $components, array $expected_order, string $message = ''): void { + uasort($components, SortArray::class . '::sortByWeightElement'); + $components = array_intersect(array_keys($components), $expected_order); + $this->assertSame($expected_order, array_values($components), $message); + } + } diff --git a/modules/acquia_cms_audio/tests/src/Functional/PermissionsTest.php b/modules/acquia_cms_audio/tests/src/Functional/PermissionsTest.php new file mode 100644 index 000000000..9953702bb --- /dev/null +++ b/modules/acquia_cms_audio/tests/src/Functional/PermissionsTest.php @@ -0,0 +1,75 @@ +drupalCreateRole([], 'content_author'); + $this->entityTypeManager = $this->container->get("entity_type.manager"); + } + + /** + * Tests permissions are granted to role created before module install. + */ + public function testGrantPermissionsOnInstall(): void { + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_author')->getPermissions(); + $permissions = [ + 'create audio media', + 'delete own audio media', + 'edit own audio media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + + /** + * Tests permissions are granted to role created after module install. + */ + public function testGrantPermissionsOnRoleCreate(): void { + // Create a new role. + $this->drupalCreateRole([], 'content_editor'); + + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_editor')->getPermissions(); + $permissions = [ + 'delete any audio media', + 'edit any audio media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + +} diff --git a/modules/acquia_cms_audio/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php b/modules/acquia_cms_audio/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php deleted file mode 100644 index 2a14fc773..000000000 --- a/modules/acquia_cms_audio/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php +++ /dev/null @@ -1,31 +0,0 @@ -getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles(); + _acquia_cms_document_editor_config_rewrite(); + } +} + +/** + * Function to rewrite filtered_html & full_html configurations. + */ +function _acquia_cms_document_editor_config_rewrite(): void { + if(!\Drupal::moduleHandler()->moduleExists('editor')) { + return; + } + $editors = [ + "filtered_html", + "full_html", + ]; + foreach ($editors as $editor) { + try { + $editorObject = \Drupal::entityTypeManager()->getStorage('editor')->load($editor); + if ($editorObject instanceof Editor) { + $settings = $editorObject->getSettings(); + $items = &$settings["toolbar"]["items"]; + $plugins = &$settings['plugins']; + if (!in_array('drupalMedia', $items)) { + $items[] = 'drupalMedia'; + } + if (!in_array('', $plugins['ckeditor5_sourceEditing']['allowed_tags'])) { + $plugins['ckeditor5_sourceEditing']['allowed_tags'][] = ''; + } + if ($plugins["media_media"]["allow_view_mode_override"] === FALSE) { + $plugins["media_media"]["allow_view_mode_override"] = TRUE; + } + $editorObject->setSettings($settings)->save(); + } + } + catch (\Exception $e) { + \Drupal::logger("acquia_cms_document_config_rewrite")->error($e->getMessage()); + } } } diff --git a/modules/acquia_cms_document/acquia_cms_document.module b/modules/acquia_cms_document/acquia_cms_document.module index 211c75fc1..3b3f7021d 100644 --- a/modules/acquia_cms_document/acquia_cms_document.module +++ b/modules/acquia_cms_document/acquia_cms_document.module @@ -5,27 +5,16 @@ * Install, update and uninstall functions for the acquia_cms_document module. */ +use Drupal\acquia_cms_document\EntityOperations\PermissionManager; use Drupal\user\RoleInterface; /** - * Implements hook_content_model_role_presave_alter(). + * Implements hook_entity_insert(). */ -function acquia_cms_document_content_model_role_presave_alter(RoleInterface &$role) { - switch ($role->id()) { - case 'content_author': - foreach ([ - 'create document media', - 'edit own document media', - 'delete own document media', - ] as $permission) { - $role->grantPermission($permission); - } - break; - - case 'content_editor': - foreach (['edit any document media', 'delete any document media'] as $permission) { - $role->grantPermission($permission); - } - break; +function acquia_cms_document_user_role_insert(RoleInterface $role) { + if(!$role->isSyncing()) { + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles([$role->id()]); } } diff --git a/modules/acquia_cms_document/composer.json b/modules/acquia_cms_document/composer.json index fcb3f4de2..657513095 100644 --- a/modules/acquia_cms_document/composer.json +++ b/modules/acquia_cms_document/composer.json @@ -3,9 +3,6 @@ "description": "Provides a Document media type and related configuration.", "license": "GPL-2.0-or-later", "type": "drupal-module", - "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1" - }, "repositories": { "assets": { "type": "composer", diff --git a/modules/acquia_cms_document/config/optional/core.entity_view_mode.media.embedded.yml b/modules/acquia_cms_document/config/optional/core.entity_view_mode.media.embedded.yml new file mode 100644 index 000000000..d952d04aa --- /dev/null +++ b/modules/acquia_cms_document/config/optional/core.entity_view_mode.media.embedded.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: + module: + - media +id: media.embedded +label: Embedded +targetEntityType: media +cache: true diff --git a/modules/acquia_cms_document/config/optional/field.storage.media.field_categories.yml b/modules/acquia_cms_document/config/optional/field.storage.media.field_categories.yml new file mode 100644 index 000000000..88e2ad3eb --- /dev/null +++ b/modules/acquia_cms_document/config/optional/field.storage.media.field_categories.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_categories +field_name: field_categories +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_document/config/optional/field.storage.media.field_tags.yml b/modules/acquia_cms_document/config/optional/field.storage.media.field_tags.yml new file mode 100644 index 000000000..07883d27e --- /dev/null +++ b/modules/acquia_cms_document/config/optional/field.storage.media.field_tags.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_tags +field_name: field_tags +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.categories.yml b/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.categories.yml new file mode 100644 index 000000000..64e07442a --- /dev/null +++ b/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.categories.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Categories +vid: categories +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.tags.yml b/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.tags.yml new file mode 100644 index 000000000..2dce29541 --- /dev/null +++ b/modules/acquia_cms_document/config/optional/taxonomy.vocabulary.tags.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Tags +vid: tags +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_document/src/EntityOperations/PermissionManager.php b/modules/acquia_cms_document/src/EntityOperations/PermissionManager.php new file mode 100644 index 000000000..3174d8ca9 --- /dev/null +++ b/modules/acquia_cms_document/src/EntityOperations/PermissionManager.php @@ -0,0 +1,71 @@ +get('entity_type.manager') + ); + } + + /** + * Update role permission handler. + * + * @param array|null $role_ids + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function grantPermissionToRoles(array $role_ids = NULL): void { + $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple($role_ids ?? [ + 'content_author', + 'content_editor', + ]); + foreach ($roles as $role) { + switch ($role->id()) { + case 'content_author': + foreach ([ + 'create document media', + 'edit own document media', + 'delete own document media', + ] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + + case 'content_editor': + foreach (['edit any document media', 'delete any document media'] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + } + } + } + +} diff --git a/modules/acquia_cms_document/tests/src/Functional/DocumentPermissionsTest.php b/modules/acquia_cms_document/tests/src/Functional/DocumentPermissionsTest.php deleted file mode 100644 index e42415c90..000000000 --- a/modules/acquia_cms_document/tests/src/Functional/DocumentPermissionsTest.php +++ /dev/null @@ -1,30 +0,0 @@ -drupalLogin($this->rootUser); - /** - * {@inheritdoc} - */ - protected function doTestEditForm() : void { $session = $this->getSession(); $page = $session->getPage(); $assert_session = $this->assertSession(); - $account = $this->drupalCreateUser(); - $account->addRole('content_author'); - $account->save(); - $this->drupalLogin($account); + // Add Categories vocabulary terms to the select list. + $this->drupalGet("admin/structure/taxonomy/manage/categories/add"); + $page->fillField('Name', 'Music'); + $page->pressButton('Save'); + $assert_session->pageTextContains('Created new term Music.'); - $this->drupalGet('media/add/' . $this->mediaType); - // Assert that the current user can create a document media. + $this->drupalGet("/media/add/document"); $assert_session->statusCodeEquals(200); // Assert that the expected fields show up. @@ -69,12 +56,30 @@ protected function doTestEditForm() : void { $assert_session->fieldExists('Categories'); $assert_session->fieldExists('Tags'); // The standard Categories and Tags fields should be present. - $this->assertCategoriesAndTagsFieldsExist(); - // Ensure File field group is present and has file field. + $group = $assert_session->elementExists('css', '#edit-group-taxonomy'); + + $tags = $assert_session->fieldExists('Tags', $group); + $this->assertTrue($tags->hasAttribute('data-autocomplete-path')); + + $categories = $assert_session->selectExists('Categories', $group); + // No item added to the select list. + $this->assertTrue($categories->hasAttribute('multiple')); + + // Ensure that the select list has every term in the Categories vocabulary. + $terms = $this->container->get('entity_type.manager') + ->getStorage('taxonomy_term') + ->loadByProperties([ + 'vid' => 'categories', + ]); + + /** @var \Drupal\taxonomy\TermInterface $term */ + foreach ($terms as $term) { + $assert_session->optionExists('Categories', $term->label(), $group); + } + + // Ensure Document field group is present and has document field. $group = $assert_session->elementExists('css', '#edit-field-media-file-wrapper'); $assert_session->fieldExists('files[field_media_file_0]', $group); - // We should be able to select the language of the media item. - $assert_session->selectExists('Language'); // Assert that the fields are in the correct order. $this->assertFieldsOrder([ @@ -89,26 +94,64 @@ protected function doTestEditForm() : void { $assert_session->pageTextContains('Name field is required.'); $assert_session->pageTextContains('File field is required.'); + // Create a media asset. + file_put_contents('public://file.txt', str_repeat('t', 10)); + $file = File::create([ + 'uri' => 'public://file.txt', + 'filename' => 'file.txt', + ]); + $file->save(); + // Fill in the required fields and assert that things went as expected. $page->fillField('Name', 'A sample document'); - // For convenience, the parent class creates a few categories during set-up. - // @see \Drupal\Tests\acquia_cms_common\Functional\ContentModelTestBase::setUp() $page->selectFieldOption('Categories', 'Music'); - $page->fillField('Tags', 'techno'); - $this->fillSourceField(); + $page->fillField('Tags', 'Techno'); + $page->attachFileToField("files[field_media_file_0]", $this->container->get('file_system')->realpath('public://file.txt')); $page->pressButton('Save'); $assert_session->pageTextContains('A sample document has been created.'); // Assert that the techno tag was created dynamically in the correct // vocabulary. + $this->drupalGet("/admin/structure/taxonomy/manage/tags/overview"); /** @var \Drupal\taxonomy\TermInterface $tag */ - $tag = Term::load(4); + $tag = Term::load(2); $this->assertInstanceOf(Term::class, $tag); $this->assertSame('tags', $tag->bundle()); - $this->assertSame('techno', $tag->getName()); + $this->assertSame('Techno', $tag->getName()); // See if the URL alias field is not shown. $assert_session->fieldNotExists('path[0][alias]'); } + /** + * Asserts that the fields are in the correct order. + * + * @param string[] $expected_order + * The machine names of the fields we expect in media type's form display, + * in the order we expect them to have. + */ + protected function assertFieldsOrder(array $expected_order) { + $components = $this->container->get('entity_display.repository') + ->getFormDisplay('media', 'document') + ->getComponents(); + + $this->assertDisplayComponentsOrder($components, $expected_order, "The fields of the 'document' media type's edit form were not in the expected order."); + } + + /** + * Asserts that the components of an entity display are in a specific order. + * + * @param array[] $components + * The components in the entity display. + * @param string[] $expected_order + * The components' keys, in the expected order. + * @param string $message + * (optional) A message if the assertion fails. + */ + protected function assertDisplayComponentsOrder(array $components, array $expected_order, string $message = '') { + uasort($components, SortArray::class . '::sortByWeightElement'); + $components = array_intersect(array_keys($components), $expected_order); + $this->assertSame($expected_order, array_values($components), $message); + } + } diff --git a/modules/acquia_cms_document/tests/src/Functional/PermissionsTest.php b/modules/acquia_cms_document/tests/src/Functional/PermissionsTest.php new file mode 100644 index 000000000..bed5a8285 --- /dev/null +++ b/modules/acquia_cms_document/tests/src/Functional/PermissionsTest.php @@ -0,0 +1,75 @@ +drupalCreateRole([], 'content_author'); + $this->entityTypeManager = $this->container->get("entity_type.manager"); + } + + /** + * Tests permissions are granted to role created before module install. + */ + public function testGrantPermissionsOnInstall(): void { + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_author')->getPermissions(); + $permissions = [ + 'create document media', + 'delete own document media', + 'edit own document media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + + /** + * Tests permissions are granted to role created after module install. + */ + public function testGrantPermissionsOnRoleCreate(): void { + // Create a new role. + $this->drupalCreateRole([], 'content_editor'); + + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_editor')->getPermissions(); + $permissions = [ + 'delete any document media', + 'edit any document media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + +} diff --git a/modules/acquia_cms_document/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php b/modules/acquia_cms_document/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php deleted file mode 100644 index 91f876b64..000000000 --- a/modules/acquia_cms_document/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php +++ /dev/null @@ -1,31 +0,0 @@ -doTestCreateMedia(); - } - - /** - * {@inheritdoc} - */ - protected function addMedia() { - $this->getSession() - ->getPage() - ->attachFileToField('Add file', $this->getTestFilePath('text')); - } - - /** - * {@inheritdoc} - */ - protected function assertAddedMedia(ElementInterface $added_media) { - // Ensure that the "File" field is not present in the required fields. - $this->assertSession() - ->hiddenFieldNotExists('media[0][fields][field_media_file][0][fids]', $added_media); - } - -} diff --git a/modules/acquia_cms_image/acquia_cms_image.info.yml b/modules/acquia_cms_image/acquia_cms_image.info.yml index 6cc77aca5..ae8107da4 100644 --- a/modules/acquia_cms_image/acquia_cms_image.info.yml +++ b/modules/acquia_cms_image/acquia_cms_image.info.yml @@ -4,10 +4,10 @@ description: "Provides an Image media type and related configuration." type: module core_version_requirement: ^9.4 || ^10 || ^11 dependencies: - - acquia_cms_common:acquia_cms_common - drupal:media - drupal:media_library - - imce:imce - drupal:image + - drupal:taxonomy - field_group:field_group - focal_point:focal_point + - imce:imce diff --git a/modules/acquia_cms_image/acquia_cms_image.install b/modules/acquia_cms_image/acquia_cms_image.install index 6ad91889f..a942b06e7 100644 --- a/modules/acquia_cms_image/acquia_cms_image.install +++ b/modules/acquia_cms_image/acquia_cms_image.install @@ -5,7 +5,9 @@ * Install, update and uninstall functions for the acquia_cms_image module. */ +use Drupal\acquia_cms_image\EntityOperations\PermissionManager; use Drupal\acquia_cms_image\SiteLogo; +use Drupal\editor\Entity\Editor; use Drupal\image\Entity\ImageStyle; /** @@ -13,11 +15,56 @@ use Drupal\image\Entity\ImageStyle; */ function acquia_cms_image_install($is_syncing) { if (!$is_syncing) { - _acquia_cms_common_editor_config_rewrite(TRUE); + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles(); + _acquia_cms_image_editor_config_rewrite(TRUE); \Drupal::classResolver(SiteLogo::class)->createLogo()->setLogo(); } } +/** + * Function to rewrite filtered_html & full_html configurations. + * + * @param bool $include_imce_plugin + * Decides If imce_image plugin to add in editor toolbar settings. + */ +function _acquia_cms_image_editor_config_rewrite(bool $include_imce_plugin = FALSE): void { + if(!\Drupal::moduleHandler()->moduleExists('editor')) { + return; + } + $editors = [ + "filtered_html", + "full_html", + ]; + foreach ($editors as $editor) { + try { + $editorObject = \Drupal::entityTypeManager()->getStorage('editor')->load($editor); + if ($editorObject instanceof Editor) { + $settings = $editorObject->getSettings(); + $items = &$settings["toolbar"]["items"]; + $plugins = &$settings['plugins']; + if (!in_array('drupalMedia', $items)) { + $items[] = 'drupalMedia'; + } + if ($include_imce_plugin && !in_array('imce_image', $items)) { + $items[] = 'imce_image'; + } + if (!in_array('', $plugins['ckeditor5_sourceEditing']['allowed_tags'])) { + $plugins['ckeditor5_sourceEditing']['allowed_tags'][] = ''; + } + if ($plugins["media_media"]["allow_view_mode_override"] === FALSE) { + $plugins["media_media"]["allow_view_mode_override"] = TRUE; + } + $editorObject->setSettings($settings)->save(); + } + } + catch (\Exception $e) { + \Drupal::logger("acquia_cms_image_config_rewrite")->error($e->getMessage()); + } + } +} + /** * Update image style to use 'Focal point scale and crop' effect. */ diff --git a/modules/acquia_cms_image/acquia_cms_image.module b/modules/acquia_cms_image/acquia_cms_image.module index 30751fd8e..d014b8bd9 100644 --- a/modules/acquia_cms_image/acquia_cms_image.module +++ b/modules/acquia_cms_image/acquia_cms_image.module @@ -5,27 +5,16 @@ * Install, update and uninstall functions for the acquia_cms_image module. */ +use Drupal\acquia_cms_image\EntityOperations\PermissionManager; use Drupal\user\RoleInterface; /** - * Implements hook_content_model_role_presave_alter(). + * Implements hook_entity_insert(). */ -function acquia_cms_image_content_model_role_presave_alter(RoleInterface &$role) { - switch ($role->id()) { - case 'content_author': - foreach ([ - 'create image media', - 'edit own image media', - 'delete own image media', - ] as $permission) { - $role->grantPermission($permission); - } - break; - - case 'content_editor': - foreach (['edit any image media', 'delete any image media'] as $permission) { - $role->grantPermission($permission); - } - break; +function acquia_cms_image_user_role_insert(RoleInterface $role) { + if(!$role->isSyncing()) { + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles([$role->id()]); } } diff --git a/modules/acquia_cms_image/composer.json b/modules/acquia_cms_image/composer.json index 1368ed317..c9d0aa5f5 100644 --- a/modules/acquia_cms_image/composer.json +++ b/modules/acquia_cms_image/composer.json @@ -4,7 +4,6 @@ "license": "GPL-2.0-or-later", "type": "drupal-module", "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/focal_point": "^2.1", "drupal/imagemagick": "^3.4 || ^4.0", "drupal/imce": "^2.2 || ^3.0" diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.card.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.card.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.card.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.card.yml diff --git a/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.embedded.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.embedded.yml new file mode 100644 index 000000000..d952d04aa --- /dev/null +++ b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.embedded.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: + module: + - media +id: media.embedded +label: Embedded +targetEntityType: media +cache: true diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.large.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.large.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.large.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.large.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.large_landscape.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.large_landscape.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.large_landscape.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.large_landscape.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.medium.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.medium.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.medium.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.medium.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.medium_landscape.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.medium_landscape.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.medium_landscape.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.medium_landscape.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.small.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.small.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.small.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.small.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.small_landscape.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.small_landscape.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.small_landscape.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.small_landscape.yml diff --git a/modules/acquia_cms_common/config/install/core.entity_view_mode.media.thumbnail.yml b/modules/acquia_cms_image/config/optional/core.entity_view_mode.media.thumbnail.yml similarity index 100% rename from modules/acquia_cms_common/config/install/core.entity_view_mode.media.thumbnail.yml rename to modules/acquia_cms_image/config/optional/core.entity_view_mode.media.thumbnail.yml diff --git a/modules/acquia_cms_image/config/optional/field.storage.media.field_categories.yml b/modules/acquia_cms_image/config/optional/field.storage.media.field_categories.yml new file mode 100644 index 000000000..88e2ad3eb --- /dev/null +++ b/modules/acquia_cms_image/config/optional/field.storage.media.field_categories.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_categories +field_name: field_categories +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_image/config/optional/field.storage.media.field_tags.yml b/modules/acquia_cms_image/config/optional/field.storage.media.field_tags.yml new file mode 100644 index 000000000..07883d27e --- /dev/null +++ b/modules/acquia_cms_image/config/optional/field.storage.media.field_tags.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_tags +field_name: field_tags +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.categories.yml b/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.categories.yml new file mode 100644 index 000000000..64e07442a --- /dev/null +++ b/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.categories.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Categories +vid: categories +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.tags.yml b/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.tags.yml new file mode 100644 index 000000000..2dce29541 --- /dev/null +++ b/modules/acquia_cms_image/config/optional/taxonomy.vocabulary.tags.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Tags +vid: tags +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_image/src/EntityOperations/PermissionManager.php b/modules/acquia_cms_image/src/EntityOperations/PermissionManager.php new file mode 100644 index 000000000..f9537b56b --- /dev/null +++ b/modules/acquia_cms_image/src/EntityOperations/PermissionManager.php @@ -0,0 +1,71 @@ +get('entity_type.manager') + ); + } + + /** + * Update role permission handler. + * + * @param array|null $role_ids + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function grantPermissionToRoles(array $role_ids = NULL): void { + $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple($role_ids ?? [ + 'content_author', + 'content_editor', + ]); + foreach ($roles as $role) { + switch ($role->id()) { + case 'content_author': + foreach ([ + 'create image media', + 'edit own image media', + 'delete own image media', + ] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + + case 'content_editor': + foreach (['edit any image media', 'delete any image media'] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + } + } + } + +} diff --git a/modules/acquia_cms_image/tests/src/Functional/ImagePermissionsTest.php b/modules/acquia_cms_image/tests/src/Functional/ImagePermissionsTest.php deleted file mode 100644 index c63040de6..000000000 --- a/modules/acquia_cms_image/tests/src/Functional/ImagePermissionsTest.php +++ /dev/null @@ -1,30 +0,0 @@ -drupalLogin($this->rootUser); - /** - * {@inheritdoc} - */ - protected function doTestEditForm() : void { $session = $this->getSession(); $page = $session->getPage(); $assert_session = $this->assertSession(); - $account = $this->drupalCreateUser(); - $account->addRole('content_author'); - $account->save(); - $this->drupalLogin($account); + // Add Categories vocabulary terms to the select list. + $this->drupalGet("admin/structure/taxonomy/manage/categories/add"); + $page->fillField('Name', 'Music'); + $page->pressButton('Save'); + $assert_session->pageTextContains('Created new term Music.'); - $this->drupalGet('media/add/' . $this->mediaType); - // Assert that the current user can access the form to create a image media. - // Note that status codes cannot be asserted in functional JavaScript tests. + $this->drupalGet("/media/add/image"); $assert_session->statusCodeEquals(200); // Assert that the expected fields show up. @@ -68,8 +53,32 @@ protected function doTestEditForm() : void { $assert_session->fieldExists('Image'); $assert_session->fieldExists('Categories'); $assert_session->fieldExists('Tags'); + // The standard Categories and Tags fields should be present. - $this->assertCategoriesAndTagsFieldsExist(); + $group = $assert_session->elementExists('css', '#edit-group-taxonomy'); + + $tags = $assert_session->fieldExists('Tags', $group); + $this->assertTrue($tags->hasAttribute('data-autocomplete-path')); + + $categories = $assert_session->selectExists('Categories', $group); + // No item added to the select list. + $this->assertTrue($categories->hasAttribute('multiple')); + + // Ensure that the select list has every term in the Categories vocabulary. + $terms = $this->container->get('entity_type.manager') + ->getStorage('taxonomy_term') + ->loadByProperties([ + 'vid' => 'categories', + ]); + + /** @var \Drupal\taxonomy\TermInterface $term */ + foreach ($terms as $term) { + $assert_session->optionExists('Categories', $term->label(), $group); + } + + // Ensure Document field group is present and has document field. + $group = $assert_session->elementExists('css', '#edit-image-wrapper'); + $assert_session->fieldExists('files[image_0]', $group); // Assert that the fields are in the correct order. $this->assertFieldsOrder([ @@ -89,69 +98,56 @@ protected function doTestEditForm() : void { // For convenience, the parent class creates a few categories during set-up. // @see \Drupal\Tests\acquia_cms_common\Functional\ContentModelTestBase::setUp() $page->selectFieldOption('Categories', 'Music'); - $page->fillField('Tags', 'techno'); - $this->fillSourceField(); + $page->fillField('Tags', 'Techno'); + $page->attachFileToField('files[image_0]', $this->root . '/core/modules/media/tests/fixtures/example_1.jpeg'); $page->pressButton('Save'); $assert_session->pageTextContains('Image Living with Image has been created.'); // Assert that the techno tag was created dynamically in the correct // vocabulary. /** @var \Drupal\taxonomy\TermInterface $tag */ - $tag = Term::load(4); + $tag = Term::load(2); $this->assertInstanceOf(Term::class, $tag); $this->assertSame('tags', $tag->bundle()); - $this->assertSame('techno', $tag->getName()); + $this->assertSame('Techno', $tag->getName()); // Media items are not normally exposed at standalone URLs, so assert that // the URL alias field does not show up. $assert_session->fieldNotExists('path[0][alias]'); + $this->testAuthorAccess(); + $this->testEditorAccess(); } /** - * Tests the media type as a content administrator. + * Tests the media type as a content editor. * * Lets override parent's method so that we can change * media id here because we are adding one addition image * as default content for site logo, which breaks the * test if we use parents method. * - * Asserts that content administrators: - * - Can create media of the type under test. - * - Can edit their own media. + * Asserts that content editor: * - Can edit others' media. - * - Can delete their own media. * - Can delete others' media. */ - protected function doTestAdministratorAccess() { + protected function testEditorAccess() { + $this->drupalCreateRole([], 'content_editor'); $account = $this->drupalCreateUser(); - $account->addRole('content_administrator'); + $account->addRole('content_editor'); $account->save(); $this->drupalLogin($account); $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); - // Test that we can create media. - $this->drupalGet("/media/add/$this->mediaType"); - $assert_session->statusCodeEquals(200); - // We should be able to select the language of the media item. - $assert_session->selectExists('Language'); - $page->fillField('Name', 'Pastafazoul!'); - $this->fillSourceField(); - $page->pressButton('Save'); - $assert_session->statusCodeEquals(200); - // Test that we can edit our own media. - $this->drupalGet('/media/4/edit'); + $this->drupalGet('/media/1/edit'); $assert_session->statusCodeEquals(200); // Test that we can delete our own media. - $this->drupalGet('/media/4/delete'); - $assert_session->statusCodeEquals(200); - - // Test that we can delete others' media. $this->drupalGet('/media/2/delete'); $assert_session->statusCodeEquals(200); + } /** @@ -169,7 +165,8 @@ protected function doTestAdministratorAccess() { * - Can delete their own media. * - Cannot delete others' media. */ - protected function doTestAuthorAccess() { + protected function testAuthorAccess() { + $this->drupalCreateRole([], 'content_author'); $account = $this->drupalCreateUser(); $account->addRole('content_author'); $account->save(); @@ -178,12 +175,10 @@ protected function doTestAuthorAccess() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); - $this->drupalGet("/media/add/$this->mediaType"); + $this->drupalGet("/media/add/image"); $assert_session->statusCodeEquals(200); - // We should be able to select the language of the media item. - $assert_session->selectExists('Language'); $page->fillField('Name', 'Pastafazoul!'); - $this->fillSourceField(); + $page->attachFileToField('files[image_0]', $this->root . '/core/modules/media/tests/fixtures/example_1.jpeg'); $page->pressButton('Save'); $assert_session->statusCodeEquals(200); @@ -200,4 +195,35 @@ protected function doTestAuthorAccess() { $assert_session->statusCodeEquals(403); } + /** + * Asserts that the fields are in the correct order. + * + * @param string[] $expected_order + * The machine names of the fields we expect in media type's form display, + * in the order we expect them to have. + */ + protected function assertFieldsOrder(array $expected_order) { + $components = $this->container->get('entity_display.repository') + ->getFormDisplay('media', 'image') + ->getComponents(); + + $this->assertDisplayComponentsOrder($components, $expected_order, "The fields of the 'image' media type's edit form were not in the expected order."); + } + + /** + * Asserts that the components of an entity display are in a specific order. + * + * @param array[] $components + * The components in the entity display. + * @param string[] $expected_order + * The components' keys, in the expected order. + * @param string $message + * (optional) A message if the assertion fails. + */ + protected function assertDisplayComponentsOrder(array $components, array $expected_order, string $message = '') { + uasort($components, SortArray::class . '::sortByWeightElement'); + $components = array_intersect(array_keys($components), $expected_order); + $this->assertSame($expected_order, array_values($components), $message); + } + } diff --git a/modules/acquia_cms_image/tests/src/Functional/PermissionsTest.php b/modules/acquia_cms_image/tests/src/Functional/PermissionsTest.php new file mode 100644 index 000000000..db8abb21c --- /dev/null +++ b/modules/acquia_cms_image/tests/src/Functional/PermissionsTest.php @@ -0,0 +1,75 @@ +drupalCreateRole([], 'content_author'); + $this->entityTypeManager = $this->container->get("entity_type.manager"); + } + + /** + * Tests permissions are granted to role created before module install. + */ + public function testGrantPermissionsOnInstall(): void { + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_author')->getPermissions(); + $permissions = [ + 'create image media', + 'delete own image media', + 'edit own image media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + + /** + * Tests permissions are granted to role created after module install. + */ + public function testGrantPermissionsOnRoleCreate(): void { + // Create a new role. + $this->drupalCreateRole([], 'content_editor'); + + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_editor')->getPermissions(); + $permissions = [ + 'delete any image media', + 'edit any image media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + +} diff --git a/modules/acquia_cms_image/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php b/modules/acquia_cms_image/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php deleted file mode 100644 index 64b87d72b..000000000 --- a/modules/acquia_cms_image/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php +++ /dev/null @@ -1,31 +0,0 @@ -container->get('entity_display.repository') - ->getFormDisplay('media', 'image', 'media_library') - ->setComponent('image', [ - 'type' => 'image_focal_point', - 'settings' => [ - 'preview_image_style' => 'thumbnail', - 'preview_link' => TRUE, - 'offsets' => '50,50', - 'progress_indicator' => 'throbber', - ], - ]) - ->save(); - } - - /** - * {@inheritdoc} - */ - public function testEmbedMedia() { - parent::testEmbedMedia(); - $this->doTestCreateMedia(); - } - - /** - * {@inheritdoc} - */ - protected function addMedia() { - $this->getSession() - ->getPage() - ->attachFileToField('Add file', $this->getTestFilePath('image')); - } - - /** - * {@inheritdoc} - */ - protected function assertAddedMedia(ElementInterface $added_media) { - // Check that the focal point widget is being used when adding an image - // in the media library. - $indicator = $added_media->waitFor(10, function (ElementInterface $added_media) { - $indicator = $added_media->find('css', '.focal-point-indicator'); - return $indicator && $indicator->isVisible(); - }); - $this->assertTrue($indicator); - } - -} diff --git a/modules/acquia_cms_page/acquia_cms_page.info.yml b/modules/acquia_cms_page/acquia_cms_page.info.yml index 4eb37138b..37cd42b64 100644 --- a/modules/acquia_cms_page/acquia_cms_page.info.yml +++ b/modules/acquia_cms_page/acquia_cms_page.info.yml @@ -4,6 +4,7 @@ description: "Provides an unstructured Page content type and related configurati type: module core_version_requirement: ^9.5 || ^10 || ^11 dependencies: + - acquia_cms_common:acquia_cms_common - acquia_cms_image:acquia_cms_image - drupal:path - field_group:field_group diff --git a/modules/acquia_cms_page/composer.json b/modules/acquia_cms_page/composer.json index 9f3e9790d..f12406fd7 100644 --- a/modules/acquia_cms_page/composer.json +++ b/modules/acquia_cms_page/composer.json @@ -4,6 +4,7 @@ "license": "GPL-2.0-or-later", "type": "drupal-module", "require": { + "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/acquia_cms_image": "^1.5.10" }, "require-dev": { diff --git a/modules/acquia_cms_place/acquia_cms_place.info.yml b/modules/acquia_cms_place/acquia_cms_place.info.yml index 026a98eef..512175823 100644 --- a/modules/acquia_cms_place/acquia_cms_place.info.yml +++ b/modules/acquia_cms_place/acquia_cms_place.info.yml @@ -4,6 +4,7 @@ description: 'Provides a Place content type and related configuration.' type: module core_version_requirement: ^9.4 || ^10 || ^11 dependencies: + - acquia_cms_common:acquia_cms_common - acquia_cms_image:acquia_cms_image - address:address - drupal:path diff --git a/modules/acquia_cms_place/composer.json b/modules/acquia_cms_place/composer.json index 8e4474207..c41888547 100644 --- a/modules/acquia_cms_place/composer.json +++ b/modules/acquia_cms_place/composer.json @@ -4,6 +4,7 @@ "license": "GPL-2.0-or-later", "type": "drupal-module", "require": { + "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1", "drupal/acquia_cms_image": "^1.5.10", "drupal/address": "^1.11 || ^2.0", "drupal/geocoder": "^3.35 || ^4.10", diff --git a/modules/acquia_cms_video/acquia_cms_video.info.yml b/modules/acquia_cms_video/acquia_cms_video.info.yml index 8264b0145..e9b96aad6 100644 --- a/modules/acquia_cms_video/acquia_cms_video.info.yml +++ b/modules/acquia_cms_video/acquia_cms_video.info.yml @@ -4,7 +4,7 @@ description: "Provides a Video media type and related configuration." type: module core_version_requirement: ^9.4 || ^10 || ^11 dependencies: - - acquia_cms_common:acquia_cms_common - drupal:media - drupal:media_library + - drupal:taxonomy - field_group:field_group diff --git a/modules/acquia_cms_video/acquia_cms_video.install b/modules/acquia_cms_video/acquia_cms_video.install index 3dd8dd47e..57be0ec9b 100644 --- a/modules/acquia_cms_video/acquia_cms_video.install +++ b/modules/acquia_cms_video/acquia_cms_video.install @@ -5,12 +5,54 @@ * Install, update and uninstall functions for the acquia_cms_video module. */ +use Drupal\acquia_cms_video\EntityOperations\PermissionManager; +use Drupal\editor\Entity\Editor; + /** * Implements hook_install(). */ function acquia_cms_video_install($is_syncing) { if (!$is_syncing) { - _acquia_cms_common_editor_config_rewrite(); + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles(); + _acquia_cms_video_editor_config_rewrite(); + } +} + +/** + * Function to rewrite filtered_html & full_html configurations. + */ +function _acquia_cms_video_editor_config_rewrite(): void { + if(!\Drupal::moduleHandler()->moduleExists('editor')) { + return; + } + $editors = [ + "filtered_html", + "full_html", + ]; + foreach ($editors as $editor) { + try { + $editorObject = \Drupal::entityTypeManager()->getStorage('editor')->load($editor); + if ($editorObject instanceof Editor) { + $settings = $editorObject->getSettings(); + $items = &$settings["toolbar"]["items"]; + $plugins = &$settings['plugins']; + if (!in_array('drupalMedia', $items)) { + $items[] = 'drupalMedia'; + } + if (!in_array('', $plugins['ckeditor5_sourceEditing']['allowed_tags'])) { + $plugins['ckeditor5_sourceEditing']['allowed_tags'][] = ''; + } + if ($plugins["media_media"]["allow_view_mode_override"] === FALSE) { + $plugins["media_media"]["allow_view_mode_override"] = TRUE; + } + $editorObject->setSettings($settings)->save(); + } + } + catch (\Exception $e) { + \Drupal::logger("acquia_cms_video_config_rewrite")->error($e->getMessage()); + } } } diff --git a/modules/acquia_cms_video/acquia_cms_video.module b/modules/acquia_cms_video/acquia_cms_video.module index e4a43d9bb..3d6e87ff9 100644 --- a/modules/acquia_cms_video/acquia_cms_video.module +++ b/modules/acquia_cms_video/acquia_cms_video.module @@ -5,27 +5,16 @@ * Install, update and uninstall functions for the acquia_cms_video module. */ +use Drupal\acquia_cms_video\EntityOperations\PermissionManager; use Drupal\user\RoleInterface; /** - * Implements hook_content_model_role_presave_alter(). + * Implements hook_entity_insert(). */ -function acquia_cms_video_content_model_role_presave_alter(RoleInterface &$role) { - switch ($role->id()) { - case 'content_author': - foreach ([ - 'create video media', - 'edit own video media', - 'delete own video media', - ] as $permission) { - $role->grantPermission($permission); - } - break; - - case 'content_editor': - foreach (['edit any video media', 'delete any video media'] as $permission) { - $role->grantPermission($permission); - } - break; +function acquia_cms_video_user_role_insert(RoleInterface $role) { + if(!$role->isSyncing()) { + $class_resolver = \Drupal::service('class_resolver'); + $class_resolver->getInstanceFromDefinition(PermissionManager::class) + ->grantPermissionToRoles([$role->id()]); } } diff --git a/modules/acquia_cms_video/composer.json b/modules/acquia_cms_video/composer.json index a3d9da69f..ae53ead5c 100644 --- a/modules/acquia_cms_video/composer.json +++ b/modules/acquia_cms_video/composer.json @@ -3,9 +3,6 @@ "description": "Provides a Video media type and related configuration.", "license": "GPL-2.0-or-later", "type": "drupal-module", - "require": { - "drupal/acquia_cms_common": "^1.9 || ^2.1 || ^3.1" - }, "repositories": { "assets": { "type": "composer", diff --git a/modules/acquia_cms_video/config/optional/core.entity_view_mode.media.embedded.yml b/modules/acquia_cms_video/config/optional/core.entity_view_mode.media.embedded.yml new file mode 100644 index 000000000..d952d04aa --- /dev/null +++ b/modules/acquia_cms_video/config/optional/core.entity_view_mode.media.embedded.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: + module: + - media +id: media.embedded +label: Embedded +targetEntityType: media +cache: true diff --git a/modules/acquia_cms_video/config/optional/field.storage.media.field_categories.yml b/modules/acquia_cms_video/config/optional/field.storage.media.field_categories.yml new file mode 100644 index 000000000..88e2ad3eb --- /dev/null +++ b/modules/acquia_cms_video/config/optional/field.storage.media.field_categories.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_categories +field_name: field_categories +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_video/config/optional/field.storage.media.field_tags.yml b/modules/acquia_cms_video/config/optional/field.storage.media.field_tags.yml new file mode 100644 index 000000000..07883d27e --- /dev/null +++ b/modules/acquia_cms_video/config/optional/field.storage.media.field_tags.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - media + - taxonomy +id: media.field_tags +field_name: field_tags +entity_type: media +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.categories.yml b/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.categories.yml new file mode 100644 index 000000000..64e07442a --- /dev/null +++ b/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.categories.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Categories +vid: categories +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.tags.yml b/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.tags.yml new file mode 100644 index 000000000..2dce29541 --- /dev/null +++ b/modules/acquia_cms_video/config/optional/taxonomy.vocabulary.tags.yml @@ -0,0 +1,7 @@ +langcode: en +status: true +dependencies: { } +name: Tags +vid: tags +description: 'Descriptive metadata, for categorizing content and making search engines happy.' +weight: 0 diff --git a/modules/acquia_cms_video/src/EntityOperations/PermissionManager.php b/modules/acquia_cms_video/src/EntityOperations/PermissionManager.php new file mode 100644 index 000000000..48745caec --- /dev/null +++ b/modules/acquia_cms_video/src/EntityOperations/PermissionManager.php @@ -0,0 +1,71 @@ +get('entity_type.manager') + ); + } + + /** + * Update role permission handler. + * + * @param array|null $role_ids + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function grantPermissionToRoles(array $role_ids = NULL): void { + $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple($role_ids ?? [ + 'content_author', + 'content_editor', + ]); + foreach ($roles as $role) { + switch ($role->id()) { + case 'content_author': + foreach ([ + 'create video media', + 'edit own video media', + 'delete own video media', + ] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + + case 'content_editor': + foreach (['edit any video media', 'delete any video media'] as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + break; + } + } + } + +} diff --git a/modules/acquia_cms_video/tests/src/Functional/PermissionsTest.php b/modules/acquia_cms_video/tests/src/Functional/PermissionsTest.php new file mode 100644 index 000000000..1a22f7c14 --- /dev/null +++ b/modules/acquia_cms_video/tests/src/Functional/PermissionsTest.php @@ -0,0 +1,75 @@ +drupalCreateRole([], 'content_author'); + $this->entityTypeManager = $this->container->get("entity_type.manager"); + } + + /** + * Tests permissions are granted to role created before module install. + */ + public function testGrantPermissionsOnInstall(): void { + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_author')->getPermissions(); + $permissions = [ + 'create video media', + 'delete own video media', + 'edit own video media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + + /** + * Tests permissions are granted to role created after module install. + */ + public function testGrantPermissionsOnRoleCreate(): void { + // Create a new role. + $this->drupalCreateRole([], 'content_editor'); + + // Load the role and check its permissions. + $role_permissions = $this->entityTypeManager->getStorage('user_role')->load('content_editor')->getPermissions(); + $permissions = [ + 'delete any video media', + 'edit any video media', + ]; + $this->assertEquals($permissions, $role_permissions); + } + +} diff --git a/modules/acquia_cms_video/tests/src/Functional/VideoPermissionsTest.php b/modules/acquia_cms_video/tests/src/Functional/VideoPermissionsTest.php deleted file mode 100644 index 32b7c2765..000000000 --- a/modules/acquia_cms_video/tests/src/Functional/VideoPermissionsTest.php +++ /dev/null @@ -1,30 +0,0 @@ -mediaType, 'field_media_oembed_video'); - $fieldConfig - ->setDefaultValue('https://www.youtube.com/watch?v=6e8QyfvQMmU&list=PLpVC00PAQQxHzlDeQvCNDKkyKRV1G3_vT') - ->save(); - } + public function testVideo(): void { + $this->drupalLogin($this->rootUser); - /** - * {@inheritdoc} - */ - protected function doTestEditForm(): void { - $page = $this->getSession()->getPage(); + $session = $this->getSession(); + $page = $session->getPage(); $assert_session = $this->assertSession(); - $account = $this->drupalCreateUser(); - $account->addRole('content_author'); - $account->save(); - $this->drupalLogin($account); + // Add Categories vocabulary terms to the select list. + $this->drupalGet("admin/structure/taxonomy/manage/categories/add"); + $page->fillField('Name', 'Music'); + $page->pressButton('Save'); + $assert_session->pageTextContains('Created new term Music.'); - $this->drupalGet('media/add/' . $this->mediaType); - // Assert that the current user can access the form to create a video media. - // Note that status codes cannot be asserted in functional JavaScript tests. + $this->drupalGet("/media/add/video"); $assert_session->statusCodeEquals(200); // Assert that the expected fields show up. @@ -79,8 +59,28 @@ protected function doTestEditForm(): void { $assert_session->fieldExists('Remote video URL'); $assert_session->fieldExists('Categories'); $assert_session->fieldExists('Tags'); + // The standard Categories and Tags fields should be present. - $this->assertCategoriesAndTagsFieldsExist(); + $group = $assert_session->elementExists('css', '#edit-group-taxonomy'); + + $tags = $assert_session->fieldExists('Tags', $group); + $this->assertTrue($tags->hasAttribute('data-autocomplete-path')); + + $categories = $assert_session->selectExists('Categories', $group); + // No item added to the select list. + $this->assertTrue($categories->hasAttribute('multiple')); + + // Ensure that the select list has every term in the Categories vocabulary. + $terms = $this->container->get('entity_type.manager') + ->getStorage('taxonomy_term') + ->loadByProperties([ + 'vid' => 'categories', + ]); + + /** @var \Drupal\taxonomy\TermInterface $term */ + foreach ($terms as $term) { + $assert_session->optionExists('Categories', $term->label(), $group); + } // Assert that the fields are in the correct order. $this->assertFieldsOrder([ @@ -93,24 +93,23 @@ protected function doTestEditForm(): void { // Submit the form and ensure that we see the expected error message(s). $page->pressButton('Save'); $assert_session->pageTextContains('Name field is required.'); + $assert_session->pageTextContains('Remote video URL field is required.'); // Fill in the required fields and assert that things went as expected. $page->fillField('Name', 'Drupal 8 Beginners, Lesson 01: Intro to the Course'); $page->fillField('Remote video URL', 'https://www.youtube.com/watch?v=6e8QyfvQMmU&list=PLpVC00PAQQxHzlDeQvCNDKkyKRV1G3_vT'); - // For convenience, the parent class creates a few categories during set-up. - // @see \Drupal\Tests\acquia_cms_common\Functional\ContentModelTestBase::setUp() $page->selectFieldOption('Categories', 'Music'); - $page->fillField('Tags', 'techno'); + $page->fillField('Tags', 'Techno'); $page->pressButton('Save'); $assert_session->pageTextContains('Video Drupal 8 Beginners, Lesson 01: Intro to the Course has been created.'); // Assert that the techno tag was created dynamically in the correct // vocabulary. /** @var \Drupal\taxonomy\TermInterface $tag */ - $tag = Term::load(4); + $tag = Term::load(2); $this->assertInstanceOf(Term::class, $tag); $this->assertSame('tags', $tag->bundle()); - $this->assertSame('techno', $tag->getName()); + $this->assertSame('Techno', $tag->getName()); // Media items are not normally exposed at standalone URLs, so assert that // the URL alias field does not show up. @@ -118,13 +117,34 @@ protected function doTestEditForm(): void { } /** - * {@inheritdoc} + * Asserts that the fields are in the correct order. + * + * @param string[] $expected_order + * The machine names of the fields we expect in media type's form display, + * in the order we expect them to have. + */ + protected function assertFieldsOrder(array $expected_order): void { + $components = $this->container->get('entity_display.repository') + ->getFormDisplay('media', 'video') + ->getComponents(); + + $this->assertDisplayComponentsOrder($components, $expected_order, "The fields of the 'video' media type's edit form were not in the expected order."); + } + + /** + * Asserts that the components of an entity display are in a specific order. + * + * @param array[] $components + * The components in the entity display. + * @param string[] $expected_order + * The components' keys, in the expected order. + * @param string $message + * (optional) A message if the assertion fails. */ - protected function fillSourceField($value = NULL): void { - // Override this method so that it does not do anything with - // field_media_oembed_video. We are setting default value already in setUp() - // so that we can bypass the oEmbed system's URL validation, since it is not - // needed in this test and actively gets in the way. + protected function assertDisplayComponentsOrder(array $components, array $expected_order, string $message = ''): void { + uasort($components, SortArray::class . '::sortByWeightElement'); + $components = array_intersect(array_keys($components), $expected_order); + $this->assertSame($expected_order, array_values($components), $message); } } diff --git a/modules/acquia_cms_video/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php b/modules/acquia_cms_video/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php deleted file mode 100644 index 57f6a5cbb..000000000 --- a/modules/acquia_cms_video/tests/src/FunctionalJavascript/Ckeditor5ConfigurationTest.php +++ /dev/null @@ -1,31 +0,0 @@ -markTestSkipped(); - $node_type = $this->drupalCreateContentType()->id(); - user_role_grant_permissions('content_author', [ - "create $node_type content", - ]); - - $account = $this->drupalCreateUser(); - $account->addRole('content_author'); - $account->save(); - $this->drupalLogin($account); - - $this->drupalGet("/node/add/$node_type"); - $this->doTestCreateMedia(); - } - - /** - * {@inheritdoc} - * - * @throws \Behat\Mink\Exception\ElementNotFoundException - */ - protected function addMedia(): void { - $this->getSession() - ->getPage()->fillField('Add Video via URL', 'https://youtu.be/lg879YYbihU'); - $this->getSession()->getPage()->pressButton('Add'); - } - -}