diff --git a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install index a6ba792d2f966d74cde1b6080210a1a14f530633..0479caf550404e4163efd873c974a9d3c2182591 100644 --- a/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install +++ b/modules/oe_whitelabel_paragraphs/oe_whitelabel_paragraphs.install @@ -7,19 +7,52 @@ declare(strict_types = 1); +use Drupal\field\Entity\FieldConfig; use Drupal\oe_bootstrap_theme\ConfigImporter; /** * Implements hook_install(). * - * Customise fields for whitelabel paragraphs. + * Customizes paragraphs fields and display configuration. + * + * If oe_bootstrap_theme_paragraphs was installed in the past, this will also + * migrate field data and clean up fields that have been renamed. */ -function oe_whitelabel_paragraphs_install($is_syncing): void { - // If we are installing from config, we bail out. +function oe_whitelabel_paragraphs_install(bool $is_syncing): void { + // Find legacy fields from oe_bootstrap_theme_paragraphs. + // This needs to happen at the start, to allow for early abort. + $field_names_by_bundle = _oe_whitelabel_paragraphs_install_get_legacy_fields_map(); + if ($is_syncing) { + // The module is being installed as part of a config import. + if ($field_names_by_bundle) { + // There is data to be migrated. This should not happen as a side effect + // of config-import. Instead, the installation should be enacted from an + // update hook. + throw new \Exception('This module should be installed through an update hook, not through config-import, if there is still leftover data from oe_bootstrap_theme_paragraphs to migrate.'); + } + // No data needs to be migrated, but still, no configuration should be + // imported in hook_install() during config-import. return; } + // The module is being installed explicitly, e.g. via a hook_update_N(). + // Configuration needs to be imported explicitly. + _oe_whitelabel_paragraphs_install_config(); + + if (!$field_names_by_bundle) { + // No fields to migrate and clean up - finished. + return; + } + + _oe_whitelabel_paragraphs_install_migrate_field_data($field_names_by_bundle); + _oe_whitelabel_paragraphs_install_drop_legacy_fields($field_names_by_bundle); +} + +/** + * Imports configuration on module install. + */ +function _oe_whitelabel_paragraphs_install_config(): void { $configs = [ 'core.entity_form_display.paragraph.oe_accordion_item.default', 'core.entity_form_display.paragraph.oe_description_list.default', @@ -39,3 +72,122 @@ function oe_whitelabel_paragraphs_install($is_syncing): void { ConfigImporter::importMultiple('oe_whitelabel_paragraphs', '/config/overrides/', $configs); } + +/** + * Gets a map of legacy fields to be migrated on install. + * + * @return string[][] + * Legacy field names, indexed by paragraph type and destination field name. + * Only contains entries where both the legacy field name and the destination + * field name do exist. + * Empty, if oe_bootstrap_theme_paragraphs was not installed in the past. + */ +function _oe_whitelabel_paragraphs_install_get_legacy_fields_map(): array { + /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */ + $entity_field_manager = \Drupal::service('entity_field.manager'); + $fields_map = $entity_field_manager->getFieldMap()['paragraph'] ?? []; + + $field_names_by_bundle = [ + 'oe_description_list' => [ + 'oe_w_orientation' => 'oe_bt_orientation', + ], + 'oe_facts_figures' => [ + 'oe_w_n_columns' => 'oe_bt_n_columns', + ], + 'oe_links_block' => [ + 'oe_w_links_block_background' => 'oe_bt_links_block_background', + 'oe_w_links_block_orientation' => 'oe_bt_links_block_orientation', + ], + 'oe_social_media_follow' => [ + 'oe_w_links_block_background' => 'oe_bt_links_block_background', + ], + ]; + + foreach ($field_names_by_bundle as $bundle => $field_names) { + foreach ($field_names as $dest_field_name => $source_field_name) { + if (!isset($fields_map[$source_field_name]['bundles'][$bundle])) { + // The legacy field does not exist. + // Perhaps the field or the paragraph type were removed manually. + unset($field_names_by_bundle[$bundle][$dest_field_name]); + continue; + } + if (!isset($fields_map[$dest_field_name]['bundles'][$bundle])) { + // A destination field is missing, that should have been created + // earlier. This could happen if a paragraph type was removed manually, + // but in that case the install should have already failed earlier. + // Either way, this case is not supported. + throw new \RuntimeException("Destination field 'paragraph.$bundle.$dest_field_name' was not properly created."); + } + } + } + + return $field_names_by_bundle; +} + +/** + * Migrates field data from the old oe_bootstrap_theme_paragraphs module. + * + * This should happen through a batch process, e.g. via $sandbox in a + * hook_update_N(). Unfortunately, hook_install() does not support batch + * processes. + * + * @param string[][] $field_names_by_bundle + * Legacy field names, indexed by paragraph type and destination field name. + */ +function _oe_whitelabel_paragraphs_install_migrate_field_data(array $field_names_by_bundle): void { + $paragraphs_storage = \Drupal::entityTypeManager()->getStorage('paragraph'); + + // Load all the paragraph ids. + $query = $paragraphs_storage->getQuery(); + $query->allRevisions(); + $query->condition('type', array_keys($field_names_by_bundle), 'IN'); + $paragraph_ids = $query->execute(); + + foreach ($paragraph_ids as $revision_id => $paragraph_id) { + // Revision can't be NULL. + /** @var \Drupal\paragraphs\ParagraphInterface $paragraph_revision */ + $paragraph_revision = $paragraphs_storage->loadRevision($revision_id); + $field_names_map = $field_names_by_bundle[$paragraph_revision->bundle()]; + $modified = FALSE; + foreach ($field_names_map as $dest_field_name => $source_field_name) { + if ($paragraph_revision->get($source_field_name)->isEmpty()) { + // Source field has no data. + continue; + } + if (!$paragraph_revision->get($dest_field_name)->isEmpty()) { + // Destination already has data. + continue; + } + // Copy the field value. + // For these simple field types, magic __set() does the job. + $paragraph_revision->$dest_field_name = $paragraph_revision->$source_field_name; + // Do not unset the old field, because it might be required. + // Remember that the revision needs saving. + $modified = TRUE; + } + if (!$modified) { + // No saving is needed. + continue; + } + $paragraph_revision->setNewRevision(FALSE); + $paragraph_revision->save(); + } +} + +/** + * Removes legacy field instances from oe_bootstrap_theme_paragraphs module. + * + * @param string[][] $field_names_by_bundle + * Legacy field names, indexed by paragraph type and destination field name. + */ +function _oe_whitelabel_paragraphs_install_drop_legacy_fields(array $field_names_by_bundle): void { + foreach ($field_names_by_bundle as $bundle => $legacy_field_names) { + foreach ($legacy_field_names as $legacy_field_name) { + $field_config = FieldConfig::loadByName('paragraph', $bundle, $legacy_field_name); + if ($field_config === NULL) { + throw new \RuntimeException("Legacy field 'paragraph.$bundle.$legacy_field_name' not found."); + } + $field_config->delete(); + } + } +} diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..73b09a472d8fca82e66e5c1a1ccda494d88fb33c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_description_list.oe_bt_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_orientation + - paragraphs.paragraphs_type.oe_description_list + module: + - options +id: paragraph.oe_description_list.oe_bt_orientation +field_name: oe_bt_orientation +entity_type: paragraph +bundle: oe_description_list +label: Orientation +description: 'Sets the orientation (vertical|horizontal) for the paragraph.' +required: true +translatable: false +default_value: + - + value: horizontal +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..eec70a14e1e037db51893287df01d018fc6b868e --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_facts_figures.oe_bt_n_columns.yml @@ -0,0 +1,24 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_n_columns + - paragraphs.paragraphs_type.oe_facts_figures +id: paragraph.oe_facts_figures.oe_bt_n_columns +field_name: oe_bt_n_columns +entity_type: paragraph +bundle: oe_facts_figures +label: 'Number of columns' +description: 'Sets the number of grid columns. Minimum number is 1 column and maximum is 3.' +required: false +translatable: false +default_value: + - + value: 1 +default_value_callback: '' +settings: + min: 1 + max: 3 + prefix: '' + suffix: '' +field_type: integer diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..de66c69713d5ed89c8815b1dbdb3f599a21eb2cd --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_background + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +bundle: oe_links_block +label: Background +description: 'Allows to select the background color of the links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..610c35d3739f035f44364e2852bebd7247e1698c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_links_block.oe_bt_links_block_orientation.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_orientation + - paragraphs.paragraphs_type.oe_links_block + module: + - options +id: paragraph.oe_links_block.oe_bt_links_block_orientation +field_name: oe_bt_links_block_orientation +entity_type: paragraph +bundle: oe_links_block +label: Orientation +description: 'Allows to select the direction of the links block.' +required: false +translatable: false +default_value: + - + value: vertical +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..8e167195da6f02c6d387c8ad0c0426a04a6123cb --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.field.paragraph.oe_social_media_follow.oe_bt_links_block_background.yml @@ -0,0 +1,22 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.oe_bt_links_block_background + - paragraphs.paragraphs_type.oe_social_media_follow + module: + - options +id: paragraph.oe_social_media_follow.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +bundle: oe_social_media_follow +label: Background +description: 'Allows to select the background color of the Social Media Links block.' +required: false +translatable: false +default_value: + - + value: gray +default_value_callback: '' +settings: { } +field_type: list_string diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml new file mode 100644 index 0000000000000000000000000000000000000000..1a7dbec06489349b31b105c506d6256d6ca9d4f8 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_background.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_links_block_background +field_name: oe_bt_links_block_background +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: gray + label: Gray + - + value: transparent + label: Transparent + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..d582eb8126c744b0643c987431a6cc6dfa4cbd20 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_links_block_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_links_block_orientation +field_name: oe_bt_links_block_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: horizontal + label: Horizontal + - + value: vertical + label: Vertical + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml new file mode 100644 index 0000000000000000000000000000000000000000..f2a740718db02227ad37f1ae65b8a425745e32e1 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_n_columns.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - paragraphs +id: paragraph.oe_bt_n_columns +field_name: oe_bt_n_columns +entity_type: paragraph +type: integer +settings: + unsigned: false + size: normal +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml new file mode 100644 index 0000000000000000000000000000000000000000..94f290a8e681aa0e93bef75192d167d80ea24ae5 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/config/install/field.storage.paragraph.oe_bt_orientation.yml @@ -0,0 +1,26 @@ +langcode: en +status: true +dependencies: + module: + - options + - paragraphs +id: paragraph.oe_bt_orientation +field_name: oe_bt_orientation +entity_type: paragraph +type: list_string +settings: + allowed_values: + - + value: vertical + label: Vertical + - + value: horizontal + label: Horizontal + allowed_values_function: '' +module: options +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..4cb09829c9ca4f6105cbd9ca32deef9ca7f258d5 --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/modules/oe_whitelabel_legacy_paragraphs_test/oe_whitelabel_legacy_paragraphs_test.info.yml @@ -0,0 +1,9 @@ +name: OE Whitelabel - Legacy Paragraphs Test +type: module +description: Provides legacy configuration as in oe_bootstrap_theme_paragraphs. +package: Testing +hidden: true +dependencies: + - drupal:description_list_field + - oe_paragraphs:oe_paragraphs + - oe_paragraphs:oe_paragraphs_description_list diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e6a20318f1f4f0c372696edcb19f4ec561651a8c --- /dev/null +++ b/modules/oe_whitelabel_paragraphs/tests/src/Functional/InstallTest.php @@ -0,0 +1,218 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\oe_whitelabel_paragraphs\Functional; + +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\paragraphs\Entity\Paragraph; +use Drupal\Tests\BrowserTestBase; + +/** + * Tests installation of oe_whitelabel_paragraphs. + * + * @see oe_whitelabel_paragraphs_install() + */ +class InstallTest extends BrowserTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'oe_whitelabel_legacy_paragraphs_test', + ]; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * Test installation with legacy fields and data present. + */ + public function testInstallWithLegacyParagraphs(): void { + $paragraphs_data = []; + $paragraphs_data['oe_description_list'] = [ + 'type' => 'oe_description_list', + 'field_oe_title' => 'Description list paragraph', + // This field will be renamed. + 'oe_bt_orientation' => 'horizontal', + 'field_oe_description_list_items' => [ + // One item is enough for this test. + [ + 'term' => 'Aliquam ultricies', + 'description' => 'Donec et leo ac velit posuere tempor mattis ac mi. Vivamus nec dictum lectus. Aliquam ultricies placerat eros, vitae ornare sem.', + ], + ], + ]; + $paragraphs_data['oe_facts_figures'] = [ + 'type' => 'oe_facts_figures', + 'field_oe_title' => 'Fact and figures block', + 'field_oe_link' => [ + 'uri' => 'https://www.readmore.com', + 'title' => 'Read more', + ], + // This field will be renamed. + 'oe_bt_n_columns' => 3, + 'field_oe_paragraphs' => [ + 'type' => 'oe_fact', + 'field_oe_icon' => 'box-arrow-up', + 'field_oe_title' => '1529 JIRA Ticket', + 'field_oe_subtitle' => 'Jira Tickets', + 'field_oe_plain_text_long' => 'Nunc condimentum sapien ut nibh finibus suscipit vitae at justo. Morbi quis odio faucibus, commodo tortor id, elementum libero.', + ], + ]; + $paragraphs_data['oe_links_block'] = [ + 'type' => 'oe_links_block', + 'field_oe_text' => 'More information', + // These fields will be renamed. + 'oe_bt_links_block_orientation' => 'vertical', + 'oe_bt_links_block_background' => 'gray', + 'field_oe_links' => [ + // One link is enough for this test. + [ + 'title' => 'European Commission', + 'uri' => 'https://example.com', + ], + ], + ]; + $paragraphs_data['oe_social_media_follow'] = [ + 'type' => 'oe_social_media_follow', + 'field_oe_title' => 'Social media title', + 'field_oe_social_media_variant' => 'horizontal', + // This field will be renamed. + 'oe_bt_links_block_background' => 'gray', + // One link is enough for this test. + 'field_oe_social_media_links' => [ + [ + 'title' => 'Email', + 'uri' => 'mailto:example@com', + 'link_type' => 'email', + ], + ], + 'field_oe_social_media_see_more' => [ + 'title' => 'Other social networks', + 'uri' => 'https://europa.eu/european-union/contact/social-networks_en', + ], + ]; + + $revision_ids = []; + foreach ($paragraphs_data as $name => $paragraph_data) { + $paragraph = Paragraph::create($paragraph_data); + $paragraph->save(); + $revision_ids[$name] = $paragraph->getRevisionId(); + if ($name !== 'oe_links_block') { + // Don't create a revision for most of the paragraphs. + continue; + } + // Make this paragraph a revision. + $paragraph->setNewRevision(); + $paragraph->oe_bt_links_block_orientation = 'horizontal'; + $paragraph->save(); + $revision_ids[$name . ':modified'] = $paragraph->getRevisionId(); + } + + $legacy_field_config_ids = [ + 'paragraph.oe_description_list.oe_bt_orientation', + 'paragraph.oe_facts_figures.oe_bt_n_columns', + 'paragraph.oe_links_block.oe_bt_links_block_background', + 'paragraph.oe_links_block.oe_bt_links_block_orientation', + 'paragraph.oe_social_media_follow.oe_bt_links_block_background', + ]; + $legacy_field_storage_ids = [ + 'paragraph.oe_bt_links_block_background', + 'paragraph.oe_bt_links_block_orientation', + 'paragraph.oe_bt_n_columns', + 'paragraph.oe_bt_orientation', + ]; + $this->assertEqualsCanonicalizing( + $legacy_field_config_ids, + array_keys(FieldConfig::loadMultiple($legacy_field_config_ids)), + ); + $this->assertEqualsCanonicalizing( + $legacy_field_storage_ids, + array_keys(FieldStorageConfig::loadMultiple($legacy_field_storage_ids)), + ); + + /** @var \Drupal\Core\Extension\ModuleInstallerInterface $installer */ + $installer = \Drupal::service('module_installer'); + $installer->install(['oe_whitelabel_paragraphs']); + + $this->assertTrue( + \Drupal::moduleHandler()->moduleExists('oe_whitelabel_paragraphs'), + "Module 'oe_whitelabel_paragraphs was successfully installed."); + + $this->assertEmpty(FieldConfig::loadMultiple($legacy_field_config_ids)); + $this->assertEmpty(FieldStorageConfig::loadMultiple($legacy_field_storage_ids)); + + $expected_created = [ + 'oe_description_list' => [ + 'oe_w_orientation' => 'horizontal', + ], + 'oe_facts_figures' => [ + 'oe_w_n_columns' => '3', + ], + 'oe_links_block' => [ + 'oe_w_links_block_orientation' => 'vertical', + 'oe_w_links_block_background' => 'gray', + ], + 'oe_links_block:modified' => [ + 'oe_w_links_block_orientation' => 'horizontal', + 'oe_w_links_block_background' => 'gray', + ], + 'oe_social_media_follow' => [ + 'oe_w_links_block_background' => 'gray', + ], + ]; + + $expected_deleted = [ + 'oe_description_list' => [ + 'oe_bt_orientation' => TRUE, + ], + 'oe_facts_figures' => [ + 'oe_bt_n_columns' => TRUE, + ], + 'oe_links_block' => [ + 'oe_bt_links_block_orientation' => TRUE, + 'oe_bt_links_block_background' => TRUE, + ], + 'oe_links_block:modified' => [ + 'oe_bt_links_block_orientation' => TRUE, + 'oe_bt_links_block_background' => TRUE, + ], + 'oe_social_media_follow' => [ + 'oe_bt_links_block_background' => TRUE, + ], + ]; + + $storage = \Drupal::entityTypeManager()->getStorage('paragraph'); + + // Produce reports instead of many individual assertions. This is less + // simple in code, but produces more useful output on test failure. + $actual_updated = []; + $actual_deleted = []; + foreach ($revision_ids as $name => $revision_id) { + $updated_revision = $storage->loadRevision($revision_id); + $this->assertNotNull($updated_revision); + foreach ($expected_created[$name] as $field_name => $value) { + if (!$updated_revision->hasField($field_name)) { + // The expected field was not created. + // Omit this entry in $actual_updated, to cause a fail below. + continue; + } + // The expected field was created, but the value might be wrong. + $actual_updated[$name][$field_name] = $updated_revision->get($field_name)->value; + } + foreach ($expected_deleted[$name] as $field_name => $deleted) { + $actual_deleted[$name][$field_name] = !$updated_revision->hasField($field_name); + } + } + + // Compare the reports to the expected values. + $this->assertSame($expected_created, $actual_updated); + $this->assertSame($expected_deleted, $actual_deleted); + } + +}