Initial Drupal 11 with DDEV setup
This commit is contained in:
		
							
								
								
									
										50912
									
								
								web/core/modules/migrate_drupal/tests/fixtures/drupal6.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50912
									
								
								web/core/modules/migrate_drupal/tests/fixtures/drupal6.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										66653
									
								
								web/core/modules/migrate_drupal/tests/fixtures/drupal7.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66653
									
								
								web/core/modules/migrate_drupal/tests/fixtures/drupal7.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
name: 'Migrate drupal field discovery tet'
 | 
			
		||||
type: module
 | 
			
		||||
description: 'Module containing a test class exposing protected field discovery methods'
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,95 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\field_discovery_test;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
 | 
			
		||||
use Drupal\migrate_drupal\FieldDiscovery;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A test class to expose protected methods.
 | 
			
		||||
 */
 | 
			
		||||
class FieldDiscoveryTestClass extends FieldDiscovery {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * An array of test data.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $testData;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a FieldDiscoveryTestClass object.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_plugin_manager
 | 
			
		||||
   *   The field plugin manager.
 | 
			
		||||
   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
 | 
			
		||||
   *   The migration plugin manager.
 | 
			
		||||
   * @param \Psr\Log\LoggerInterface $logger
 | 
			
		||||
   *   The logger.
 | 
			
		||||
   * @param array $test_data
 | 
			
		||||
   *   An array of test data, keyed by method name, for overridden methods to
 | 
			
		||||
   *   return for the purposes of testing other methods.
 | 
			
		||||
   */
 | 
			
		||||
  public function __construct(MigrateFieldPluginManagerInterface $field_plugin_manager, MigrationPluginManagerInterface $migration_plugin_manager, LoggerInterface $logger, array $test_data = []) {
 | 
			
		||||
    parent::__construct($field_plugin_manager, $migration_plugin_manager, $logger);
 | 
			
		||||
    $this->testData = $test_data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getAllFields($core) {
 | 
			
		||||
    if (!empty($this->testData['getAllFields'][$core])) {
 | 
			
		||||
      return $this->testData['getAllFields'][$core];
 | 
			
		||||
    }
 | 
			
		||||
    return parent::getAllFields($core);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getBundleFields($core, $entity_type_id, $bundle) {
 | 
			
		||||
    return parent::getBundleFields($core, $entity_type_id, $bundle);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getEntityFields($core, $entity_type_id) {
 | 
			
		||||
    return parent::getEntityFields($core, $entity_type_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getFieldInstanceStubMigrationDefinition($core) {
 | 
			
		||||
    return parent::getFieldInstanceStubMigrationDefinition($core);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getCoreVersion(MigrationInterface $migration) {
 | 
			
		||||
    return parent::getCoreVersion($migration);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getFieldPlugin($field_type, MigrationInterface $migration) {
 | 
			
		||||
    return parent::getFieldPlugin($field_type, $migration);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getSourcePlugin($core) {
 | 
			
		||||
    return parent::getSourcePlugin($core);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
name: 'Migrate field plugin manager test'
 | 
			
		||||
type: module
 | 
			
		||||
description: 'Example module demonstrating the field plugin manager in the Migrate API.'
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\migrate_field_plugin_manager_test\Plugin\migrate\field;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\Attribute\MigrateField;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MigrateField Plugin for Drupal 6 file fields.
 | 
			
		||||
 */
 | 
			
		||||
#[MigrateField(
 | 
			
		||||
  id: 'd6_file',
 | 
			
		||||
  core: [6],
 | 
			
		||||
  type_map: [
 | 
			
		||||
    'file' => 'file',
 | 
			
		||||
  ],
 | 
			
		||||
  source_module: 'foo',
 | 
			
		||||
  destination_module: 'bar',
 | 
			
		||||
)]
 | 
			
		||||
class D6FileField extends FieldPluginBase {}
 | 
			
		||||
@ -0,0 +1,18 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\migrate_field_plugin_manager_test\Plugin\migrate\field;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\Attribute\MigrateField;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MigrateField Plugin for migrating fields without core version specification.
 | 
			
		||||
 */
 | 
			
		||||
#[MigrateField(
 | 
			
		||||
  id: 'd6_no_core_version_specified',
 | 
			
		||||
  source_module: 'foo',
 | 
			
		||||
  destination_module: 'bar',
 | 
			
		||||
)]
 | 
			
		||||
class D6NoCoreVersionSpecified extends FieldPluginBase {}
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
name: 'Migrate property overwrite test'
 | 
			
		||||
type: module
 | 
			
		||||
description: 'Example module demonstrating property overwrite support in the Migrate API.'
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,31 @@
 | 
			
		||||
id: users
 | 
			
		||||
label: User migration
 | 
			
		||||
migration_tags:
 | 
			
		||||
  - Drupal 6
 | 
			
		||||
  - Drupal 7
 | 
			
		||||
source:
 | 
			
		||||
  plugin: d6_user
 | 
			
		||||
process:
 | 
			
		||||
  # If the entity's ID is migrated, the Migrate API will try to update
 | 
			
		||||
  # an existing entity with that ID. If no entity with that ID already
 | 
			
		||||
  # exists, it will be created.
 | 
			
		||||
  uid: uid
 | 
			
		||||
  name: name
 | 
			
		||||
  mail: mail
 | 
			
		||||
  password: password
 | 
			
		||||
  'signature/value':
 | 
			
		||||
    plugin: default_value
 | 
			
		||||
    default_value: 'The answer is 42.'
 | 
			
		||||
destination:
 | 
			
		||||
  plugin: entity:user
 | 
			
		||||
  # If the destination is going to update an existing user, you can optionally
 | 
			
		||||
  # specify the properties that should be overwritten. For example, if the
 | 
			
		||||
  # migration tries to import user 31 and user 31 already exists in the
 | 
			
		||||
  # destination database, only the 'name' and 'mail' properties of the user
 | 
			
		||||
  # will be overwritten. If user 31 doesn't exist, it will be created and
 | 
			
		||||
  # the overwrite_properties list will be ignored.
 | 
			
		||||
  overwrite_properties:
 | 
			
		||||
    - name
 | 
			
		||||
    - mail
 | 
			
		||||
    # It's possible to overwrite nested properties too.
 | 
			
		||||
    - 'signature/value'
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
name: Migrate state active test
 | 
			
		||||
type: module
 | 
			
		||||
description: Tests the 'active' migrate state
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,19 @@
 | 
			
		||||
id: migrate_state_finished_test
 | 
			
		||||
label: Block content body field configuration
 | 
			
		||||
migration_tags:
 | 
			
		||||
  - Drupal 6
 | 
			
		||||
  - Drupal 7
 | 
			
		||||
  - Configuration
 | 
			
		||||
source:
 | 
			
		||||
  plugin: embedded_data
 | 
			
		||||
  data_rows:
 | 
			
		||||
    -
 | 
			
		||||
      id: 1
 | 
			
		||||
  ids:
 | 
			
		||||
    id:
 | 
			
		||||
      type: string
 | 
			
		||||
  source_module: action
 | 
			
		||||
process: []
 | 
			
		||||
destination:
 | 
			
		||||
  plugin: entity:field_config
 | 
			
		||||
  destination_module: migrate_state_finished_test
 | 
			
		||||
@ -0,0 +1,19 @@
 | 
			
		||||
id: migrate_state_finished_test1
 | 
			
		||||
label: Block content body field configuration
 | 
			
		||||
migration_tags:
 | 
			
		||||
  - Drupal 6
 | 
			
		||||
  - Drupal 7
 | 
			
		||||
  - Configuration
 | 
			
		||||
source:
 | 
			
		||||
  plugin: embedded_data
 | 
			
		||||
  data_rows:
 | 
			
		||||
    -
 | 
			
		||||
      id: 1
 | 
			
		||||
  ids:
 | 
			
		||||
    id:
 | 
			
		||||
      type: string
 | 
			
		||||
  source_module: action
 | 
			
		||||
process: []
 | 
			
		||||
destination:
 | 
			
		||||
  plugin: entity:field_config
 | 
			
		||||
  destination_module: migrate_state_not_finished_test
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    action:
 | 
			
		||||
      - migrate_state_finished_test
 | 
			
		||||
      - migrate_state_not_finished_test
 | 
			
		||||
  7:
 | 
			
		||||
    # Migrations
 | 
			
		||||
    action:
 | 
			
		||||
      - migrate_state_finished_test
 | 
			
		||||
      - migrate_state_not_finished_test
 | 
			
		||||
not_finished:
 | 
			
		||||
  7:
 | 
			
		||||
    # Migrations
 | 
			
		||||
    action: system
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
name: Migrate state no migration and no migrate_drupal.yml file test
 | 
			
		||||
type: module
 | 
			
		||||
description: Does not have a migration or migrate_drupal.yml file.
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
name: Migrate state incomplete test
 | 
			
		||||
type: module
 | 
			
		||||
description: Tests the 'incomplete' migrate state
 | 
			
		||||
package: Testing
 | 
			
		||||
version: VERSION
 | 
			
		||||
@ -0,0 +1,20 @@
 | 
			
		||||
id: migrate_state_not_finished_test
 | 
			
		||||
label: Migrate state incomplete test
 | 
			
		||||
migration_tags:
 | 
			
		||||
  - Drupal 6
 | 
			
		||||
  - Drupal 7
 | 
			
		||||
  - Configuration
 | 
			
		||||
source:
 | 
			
		||||
  plugin: embedded_data
 | 
			
		||||
  data_rows:
 | 
			
		||||
    -
 | 
			
		||||
      entity_type: block_content
 | 
			
		||||
  ids:
 | 
			
		||||
    entity_type:
 | 
			
		||||
      type: string
 | 
			
		||||
  source_module: block
 | 
			
		||||
process:
 | 
			
		||||
  entity_type: entity_type
 | 
			
		||||
destination:
 | 
			
		||||
  plugin: entity:field_config
 | 
			
		||||
  destination_module: migrate_state_not_finished_test
 | 
			
		||||
@ -0,0 +1,12 @@
 | 
			
		||||
# cspell:ignore optionwidgets
 | 
			
		||||
not_finished:
 | 
			
		||||
  6:
 | 
			
		||||
    block: migrate_state_not_finished_test
 | 
			
		||||
    # Override any finished declarations for this field plugin.
 | 
			
		||||
    optionwidgets: options
 | 
			
		||||
  7:
 | 
			
		||||
    # Override any finished declarations for this field plugin.
 | 
			
		||||
    options: options
 | 
			
		||||
    # Override any finished declarations for this migration.
 | 
			
		||||
    action: migrate_state_not_finished_test
 | 
			
		||||
    block: migrate_state_not_finished_test
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Functional;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic module test for migrate_drupal.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class GenericTest extends GenericModuleTestBase {}
 | 
			
		||||
@ -0,0 +1,91 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests instantiating migrate source plugins using I18nQueryTrait.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class I18nQueryTraitTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'block_content',
 | 
			
		||||
    'menu_link_content',
 | 
			
		||||
    'migrate',
 | 
			
		||||
    'migrate_drupal',
 | 
			
		||||
    'taxonomy',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests instantiating migrate source plugins using I18nQueryTrait.
 | 
			
		||||
   *
 | 
			
		||||
   * I18nQueryTrait was originally in the content_translation module, which
 | 
			
		||||
   * could lead to fatal errors instantiating the source plugins that use it
 | 
			
		||||
   * when the content_translation module was not installed.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $plugin_id
 | 
			
		||||
   *   The ID of a Migrate source plugin that uses I18nQueryTrait.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerI18nQueryTraitPlugins
 | 
			
		||||
   */
 | 
			
		||||
  public function testMigrateSourcePluginUsingI18nQueryTraitDiscovery(string $plugin_id): void {
 | 
			
		||||
    // Namespace for uninstalled module content_translation needs to be removed
 | 
			
		||||
    // for this test.
 | 
			
		||||
    $this->disablePsr4ForUninstalledModules(['content_translation']);
 | 
			
		||||
 | 
			
		||||
    $migration = $this->createMock(MigrationInterface::class);
 | 
			
		||||
    $this->assertInstanceOf(SourcePluginBase::class, \Drupal::service('plugin.manager.migrate.source')->createInstance($plugin_id, [], $migration));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Removes PSR-4 namespaces from class loader for uninstalled modules.
 | 
			
		||||
   *
 | 
			
		||||
   * TestRunnerKernel registers namespaces for all modules, including
 | 
			
		||||
   * uninstalled modules. This method removes the PSR-4 namespace for the list
 | 
			
		||||
   * of modules passed in after confirming they are all uninstalled.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string[] $remove_psr4_modules
 | 
			
		||||
   *   List of machine names of modules that are uninstalled and whose PSR-4
 | 
			
		||||
   *   namespaces should be removed from the class loader.
 | 
			
		||||
   */
 | 
			
		||||
  protected function disablePsr4ForUninstalledModules(array $remove_psr4_modules): void {
 | 
			
		||||
    /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
 | 
			
		||||
    $module_list = \Drupal::service('extension.list.module');
 | 
			
		||||
    $available_modules = $module_list->getAllAvailableInfo();
 | 
			
		||||
    $installed_modules = $module_list->getAllInstalledInfo();
 | 
			
		||||
    $prefixes = $this->classLoader->getPrefixesPsr4();
 | 
			
		||||
    foreach ($remove_psr4_modules as $module) {
 | 
			
		||||
      $this->assertArrayHasKey($module, $available_modules);
 | 
			
		||||
      $this->assertArrayNotHasKey($module, $installed_modules);
 | 
			
		||||
      if (isset($prefixes["Drupal\\$module\\"])) {
 | 
			
		||||
        // Cannot actually remove the PSR4 prefix from the class loader, so set
 | 
			
		||||
        // the path to a wrong location.
 | 
			
		||||
        $this->classLoader->setPsr4("Drupal\\$module\\", '');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testMigrateSourcePluginUsingI18nQueryTraitDiscovery().
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerI18nQueryTraitPlugins(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      ['d6_box_translation'],
 | 
			
		||||
      ['d7_block_custom_translation'],
 | 
			
		||||
      ['d6_menu_link_translation'],
 | 
			
		||||
      ['d7_menu_link_translation'],
 | 
			
		||||
      ['d7_term_localized_translation'],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test that no dummy migrate_map tables are created.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class IdMapTableNoDummyTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migration plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $pluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->pluginManager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $this->pluginManager->createInstance('d6_user');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that dummy map tables do not exist.
 | 
			
		||||
   */
 | 
			
		||||
  public function testNoDummyTables(): void {
 | 
			
		||||
    $database = \Drupal::database();
 | 
			
		||||
    $tables = $database->schema()->findTables('%migrate_map%');
 | 
			
		||||
    $dummy_tables = preg_grep("/.*migrate_map_([0-9a-fA-F]){13}/", $tables);
 | 
			
		||||
    $this->assertCount(0, $dummy_tables);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,68 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Database\Database;
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for Drupal migration tests.
 | 
			
		||||
 */
 | 
			
		||||
abstract class MigrateDrupalTestBase extends MigrateTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'system',
 | 
			
		||||
    'user',
 | 
			
		||||
    'field',
 | 
			
		||||
    'migrate_drupal',
 | 
			
		||||
    'options',
 | 
			
		||||
    'file',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    $module_handler = \Drupal::moduleHandler();
 | 
			
		||||
    if ($module_handler->moduleExists('node')) {
 | 
			
		||||
      $this->installEntitySchema('node');
 | 
			
		||||
    }
 | 
			
		||||
    if ($module_handler->moduleExists('comment')) {
 | 
			
		||||
      $this->installEntitySchema('comment');
 | 
			
		||||
    }
 | 
			
		||||
    if ($module_handler->moduleExists('taxonomy')) {
 | 
			
		||||
      $this->installEntitySchema('taxonomy_term');
 | 
			
		||||
    }
 | 
			
		||||
    if ($module_handler->moduleExists('user')) {
 | 
			
		||||
      $this->installEntitySchema('user');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $this->installConfig(['migrate_drupal', 'system']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Loads a database fixture into the source database connection.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $path
 | 
			
		||||
   *   Path to the dump file.
 | 
			
		||||
   */
 | 
			
		||||
  protected function loadFixture($path) {
 | 
			
		||||
    $default_db = Database::getConnection()->getKey();
 | 
			
		||||
    Database::setActiveConnection($this->sourceDatabase->getKey());
 | 
			
		||||
 | 
			
		||||
    if (str_ends_with($path, '.gz')) {
 | 
			
		||||
      $path = 'compress.zlib://' . $path;
 | 
			
		||||
    }
 | 
			
		||||
    require $path;
 | 
			
		||||
 | 
			
		||||
    Database::setActiveConnection($default_db);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test migrate_drupal module uninstall.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrateDrupalUninstallTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate', 'migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @covers migrate_drupal_uninstall
 | 
			
		||||
   */
 | 
			
		||||
  public function testUninstall(): void {
 | 
			
		||||
    $state = \Drupal::state();
 | 
			
		||||
    $data = [
 | 
			
		||||
      'key' => 'upgrade',
 | 
			
		||||
      'database' => [],
 | 
			
		||||
    ];
 | 
			
		||||
    $state->set('migrate_drupal_6', $data);
 | 
			
		||||
    $state->set('migrate_drupal_7', $data);
 | 
			
		||||
 | 
			
		||||
    $this->assertEquals($data, $state->get('migrate_drupal_6'));
 | 
			
		||||
    $this->assertEquals($data, $state->get('migrate_drupal_7'));
 | 
			
		||||
 | 
			
		||||
    $this->container->get('module_installer')->uninstall(['migrate_drupal']);
 | 
			
		||||
 | 
			
		||||
    $this->assertNull($state->get('migrate_drupal_6'));
 | 
			
		||||
    $this->assertNull($state->get('migrate_drupal_7'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,128 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the field plugin manager.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager
 | 
			
		||||
 */
 | 
			
		||||
class MigrateFieldPluginManagerTest extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The field plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $pluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'system',
 | 
			
		||||
    'user',
 | 
			
		||||
    'field',
 | 
			
		||||
    'migrate_drupal',
 | 
			
		||||
    'options',
 | 
			
		||||
    'file',
 | 
			
		||||
    'image',
 | 
			
		||||
    'text',
 | 
			
		||||
    'link',
 | 
			
		||||
    'migrate_field_plugin_manager_test',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->pluginManager = $this->container->get('plugin.manager.migrate.field');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that the correct MigrateField plugins are used.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getPluginIdFromFieldType
 | 
			
		||||
   */
 | 
			
		||||
  public function testPluginSelection(): void {
 | 
			
		||||
    $this->assertSame('link', $this->pluginManager->getPluginIdFromFieldType('link', ['core' => 6]));
 | 
			
		||||
    $this->assertSame('link_field', $this->pluginManager->getPluginIdFromFieldType('link_field', ['core' => 7]));
 | 
			
		||||
    $this->assertSame('image', $this->pluginManager->getPluginIdFromFieldType('image', ['core' => 7]));
 | 
			
		||||
    $this->assertSame('file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 7]));
 | 
			
		||||
    $this->assertSame('d6_file', $this->pluginManager->getPluginIdFromFieldType('file', ['core' => 6]));
 | 
			
		||||
    $this->assertSame('d6_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 6]));
 | 
			
		||||
    $this->assertSame('d7_text', $this->pluginManager->getPluginIdFromFieldType('text', ['core' => 7]));
 | 
			
		||||
 | 
			
		||||
    // Test that the deprecated d6 'date' plugin is not returned.
 | 
			
		||||
    $this->assertSame('datetime', $this->pluginManager->getPluginIdFromFieldType('date', ['core' => 6]));
 | 
			
		||||
 | 
			
		||||
    // Test fallback when no core version is specified.
 | 
			
		||||
    $this->assertSame('d6_no_core_version_specified', $this->pluginManager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 6]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that a PluginNotFoundException is thrown when a plugin isn't found.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getPluginIdFromFieldType
 | 
			
		||||
   * @dataProvider nonExistentPluginExceptionsData
 | 
			
		||||
   */
 | 
			
		||||
  public function testNonExistentPluginExceptions($core, $field_type): void {
 | 
			
		||||
    $this->expectException(PluginNotFoundException::class);
 | 
			
		||||
    $this->expectExceptionMessage(sprintf("Plugin ID '%s' was not found.", $field_type));
 | 
			
		||||
    $this->pluginManager->getPluginIdFromFieldType($field_type, ['core' => $core]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testNonExistentPluginExceptions.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function nonExistentPluginExceptionsData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'D7 Filefield' => [
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'field_type' => 'filefield',
 | 
			
		||||
      ],
 | 
			
		||||
      'D6 linkfield' => [
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'field_type' => 'link_field',
 | 
			
		||||
      ],
 | 
			
		||||
      'D7 link' => [
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'field_type' => 'link',
 | 
			
		||||
      ],
 | 
			
		||||
      'D7 no core version' => [
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'field_type' => 'd6_no_core_version_specified',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that plugins with no explicit weight are given a weight of 0.
 | 
			
		||||
   */
 | 
			
		||||
  public function testDefaultWeight(): void {
 | 
			
		||||
    $definitions = $this->pluginManager->getDefinitions();
 | 
			
		||||
    $deprecated_plugins = [
 | 
			
		||||
      'date',
 | 
			
		||||
    ];
 | 
			
		||||
    foreach ($definitions as $id => $definition) {
 | 
			
		||||
      $this->assertArrayHasKey('weight', $definition);
 | 
			
		||||
      if (in_array($id, $deprecated_plugins, TRUE)) {
 | 
			
		||||
        $this->assertSame(9999999, $definition['weight']);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $this->assertSame(0, $definition['weight']);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,59 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Database\Database;
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests that a migration can be instantiated without a database connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrateMissingDatabaseTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate', 'migrate_drupal', 'node'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migration plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate\Plugin\MigrationPluginManager
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
 | 
			
		||||
 | 
			
		||||
    // Set the 'migrate' database connection to use a missing host.
 | 
			
		||||
    $info = Database::getConnectionInfo('default')['default'];
 | 
			
		||||
    $info['host'] = 'does_not_exist';
 | 
			
		||||
    Database::addConnectionInfo('migrate', 'default', $info);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that a migration can be instantiated with the node module enabled.
 | 
			
		||||
   *
 | 
			
		||||
   * When the migrate_drupal and node modules are enabled, the migration
 | 
			
		||||
   * derivers call checkRequirements() whenever createInstance() is used. If the
 | 
			
		||||
   * database connection is not available, then Migration::setUpDatabase()
 | 
			
		||||
   * throws an exception. Check that the exception is caught and the migration
 | 
			
		||||
   * can still be used to access its IdMap.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMissingDatabase(): void {
 | 
			
		||||
    $migration = $this->migrationPluginManager->createInstance('d7_node_type');
 | 
			
		||||
    $this->assertInstanceOf(MigrationInterface::class, $migration);
 | 
			
		||||
    $this->assertInstanceOf(MigrateIdMapInterface::class, $migration->getIdMap());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,173 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\NodeMigrateType;
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateTestBase;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
 | 
			
		||||
use Drupal\migrate_drupal\Hook\MigrateDrupalHooks;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the assignment of the node migration type in migrations_plugin_alter.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class NodeMigrationTypePluginAlterTest extends MigrateTestBase {
 | 
			
		||||
 | 
			
		||||
  use NodeMigrateTypeTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal', 'node'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->setupDb();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the assignment of the node migration type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $type
 | 
			
		||||
   *   The type of node migration, 'classic' or 'complete'.
 | 
			
		||||
   * @param array $migration_definitions
 | 
			
		||||
   *   An array of migration definitions.
 | 
			
		||||
   * @param array $expected
 | 
			
		||||
   *   The expected results.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerMigrationPluginAlter
 | 
			
		||||
   *
 | 
			
		||||
   * @throws \Exception
 | 
			
		||||
   */
 | 
			
		||||
  public function testMigrationPluginAlter($type, array $migration_definitions, array $expected): void {
 | 
			
		||||
    $this->makeNodeMigrateMapTable($type, '7');
 | 
			
		||||
    $migrateDrupalMigrationPluginsAlter = new MigrateDrupalHooks();
 | 
			
		||||
    $migrateDrupalMigrationPluginsAlter->migrationPluginsAlter($migration_definitions);
 | 
			
		||||
    $this->assertSame($expected, $migration_definitions);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Data provider for testMigrationPluginAlter().
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerMigrationPluginAlter() {
 | 
			
		||||
    $tests = [];
 | 
			
		||||
 | 
			
		||||
    $migrations = [
 | 
			
		||||
      // The 'system_site' migration is needed to get the legacy Drupal version.
 | 
			
		||||
      'system_site' => [
 | 
			
		||||
        'id' => 'system_site',
 | 
			
		||||
        'source' => [
 | 
			
		||||
          'plugin' => 'variable',
 | 
			
		||||
          'variables' => [
 | 
			
		||||
            'site_name',
 | 
			
		||||
            'site_mail',
 | 
			
		||||
          ],
 | 
			
		||||
          'source_module' => 'system',
 | 
			
		||||
        ],
 | 
			
		||||
        'process' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'no_dependencies_not_altered' => [
 | 
			
		||||
        'id' => 'no_dependencies_not_altered',
 | 
			
		||||
        'no_dependencies' => 'test',
 | 
			
		||||
        'process' => [
 | 
			
		||||
          'nid' => 'nid',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'dependencies_altered_if_complete' => [
 | 
			
		||||
        'id' => 'test',
 | 
			
		||||
        'migration_dependencies' => [
 | 
			
		||||
          'required' => [
 | 
			
		||||
            'd7_node',
 | 
			
		||||
          ],
 | 
			
		||||
          'optional' => [
 | 
			
		||||
            'd7_node_translation',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'dependencies_not_altered' => [
 | 
			
		||||
        'id' => 'd7_node',
 | 
			
		||||
        'migration_dependencies' => [
 | 
			
		||||
          'required' => [
 | 
			
		||||
            'd7_node',
 | 
			
		||||
          ],
 | 
			
		||||
          'optional' => [
 | 
			
		||||
            'd7_node_translation',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test migrations are not altered when classic node migrations is in use.
 | 
			
		||||
    $tests[0]['type'] = NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC;
 | 
			
		||||
    $tests[0]['migration_definitions'] = $migrations;
 | 
			
		||||
    $tests[0]['expected'] = $tests[0]['migration_definitions'];
 | 
			
		||||
 | 
			
		||||
    // Test migrations are altered when complete node migrations is in use.
 | 
			
		||||
    $tests[1] = $tests[0];
 | 
			
		||||
    $tests[1]['type'] = NodeMigrateType::NODE_MIGRATE_TYPE_COMPLETE;
 | 
			
		||||
    $tests[1]['expected']['dependencies_altered_if_complete']['migration_dependencies'] = [
 | 
			
		||||
      'required' => [
 | 
			
		||||
        'd7_node_complete',
 | 
			
		||||
      ],
 | 
			
		||||
      'optional' => [
 | 
			
		||||
        'd7_node_complete',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    return $tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates data in the source database.
 | 
			
		||||
   */
 | 
			
		||||
  protected function setupDb(): void {
 | 
			
		||||
    $this->sourceDatabase->schema()->createTable('system', [
 | 
			
		||||
      'fields' => [
 | 
			
		||||
        'name' => [
 | 
			
		||||
          'type' => 'varchar',
 | 
			
		||||
          'not null' => TRUE,
 | 
			
		||||
          'length' => '255',
 | 
			
		||||
          'default' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        'type' => [
 | 
			
		||||
          'type' => 'varchar',
 | 
			
		||||
          'not null' => TRUE,
 | 
			
		||||
          'length' => '255',
 | 
			
		||||
          'default' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        'status' => [
 | 
			
		||||
          'type' => 'int',
 | 
			
		||||
          'not null' => TRUE,
 | 
			
		||||
          'size' => 'normal',
 | 
			
		||||
          'default' => '0',
 | 
			
		||||
        ],
 | 
			
		||||
        'schema_version' => [
 | 
			
		||||
          'type' => 'int',
 | 
			
		||||
          'not null' => TRUE,
 | 
			
		||||
          'size' => 'normal',
 | 
			
		||||
          'default' => '-1',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ]);
 | 
			
		||||
    $this->sourceDatabase->insert('system')
 | 
			
		||||
      ->fields([
 | 
			
		||||
        'name',
 | 
			
		||||
        'type',
 | 
			
		||||
        'status',
 | 
			
		||||
        'schema_version',
 | 
			
		||||
      ])
 | 
			
		||||
      ->values([
 | 
			
		||||
        'name' => 'system',
 | 
			
		||||
        'type' => 'module',
 | 
			
		||||
        'status' => '1',
 | 
			
		||||
        'schema_version' => '7001',
 | 
			
		||||
      ])
 | 
			
		||||
      ->execute();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,251 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate\Plugin\Exception\BadPluginDefinitionException;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore entityreference filefield imagefield nodereference
 | 
			
		||||
// cspell:ignore optionwidgets userreference
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests that modules exist for all source and destination plugins.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrationProvidersExistTest extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that a missing source_module property raises an exception.
 | 
			
		||||
   */
 | 
			
		||||
  public function testSourceProvider(): void {
 | 
			
		||||
    $this->enableModules(['migration_provider_test']);
 | 
			
		||||
    $this->expectException(BadPluginDefinitionException::class);
 | 
			
		||||
    $this->expectExceptionMessage('The no_source_module plugin must define the source_module property.');
 | 
			
		||||
    $this->container->get('plugin.manager.migration')->getDefinition('migration_provider_no_annotation');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that modules exist for all source plugins.
 | 
			
		||||
   */
 | 
			
		||||
  public function testProvidersExist(): void {
 | 
			
		||||
    $this->enableAllModules();
 | 
			
		||||
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\MigrateSourcePluginManager $plugin_manager */
 | 
			
		||||
    $plugin_manager = $this->container->get('plugin.manager.migrate.source');
 | 
			
		||||
 | 
			
		||||
    foreach ($plugin_manager->getDefinitions() as $definition) {
 | 
			
		||||
      // If the source plugin uses annotations, then the 'provider' key is the
 | 
			
		||||
      // array of providers and the 'providers' key is not defined.
 | 
			
		||||
      $providers = $definition['providers'] ?? $definition['provider'];
 | 
			
		||||
      if (in_array('migrate_drupal', $providers, TRUE)) {
 | 
			
		||||
        $id = $definition['id'];
 | 
			
		||||
        $this->assertArrayHasKey('source_module', $definition, "No source_module property in '$id'");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Enable all available modules.
 | 
			
		||||
   */
 | 
			
		||||
  protected function enableAllModules(): void {
 | 
			
		||||
    // Install all available modules.
 | 
			
		||||
    $module_handler = $this->container->get('module_handler');
 | 
			
		||||
    $modules = $this->coreModuleListDataProvider();
 | 
			
		||||
    $modules_enabled = $module_handler->getModuleList();
 | 
			
		||||
    $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
 | 
			
		||||
    $this->enableModules($modules_to_enable);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that modules exist for all field plugins.
 | 
			
		||||
   */
 | 
			
		||||
  public function testFieldProvidersExist(): void {
 | 
			
		||||
    $expected_mappings = [
 | 
			
		||||
      'userreference' => [
 | 
			
		||||
        'source_module' => 'userreference',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'nodereference' => [
 | 
			
		||||
        'source_module' => 'nodereference',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'optionwidgets' => [
 | 
			
		||||
        'source_module' => 'optionwidgets',
 | 
			
		||||
        'destination_module' => 'options',
 | 
			
		||||
      ],
 | 
			
		||||
      'list' => [
 | 
			
		||||
        'source_module' => 'list',
 | 
			
		||||
        'destination_module' => 'options',
 | 
			
		||||
      ],
 | 
			
		||||
      'options' => [
 | 
			
		||||
        'source_module' => 'options',
 | 
			
		||||
        'destination_module' => 'options',
 | 
			
		||||
      ],
 | 
			
		||||
      'filefield' => [
 | 
			
		||||
        'source_module' => 'filefield',
 | 
			
		||||
        'destination_module' => 'file',
 | 
			
		||||
      ],
 | 
			
		||||
      'imagefield' => [
 | 
			
		||||
        'source_module' => 'imagefield',
 | 
			
		||||
        'destination_module' => 'image',
 | 
			
		||||
      ],
 | 
			
		||||
      'file' => [
 | 
			
		||||
        'source_module' => 'file',
 | 
			
		||||
        'destination_module' => 'file',
 | 
			
		||||
      ],
 | 
			
		||||
      'image' => [
 | 
			
		||||
        'source_module' => 'image',
 | 
			
		||||
        'destination_module' => 'image',
 | 
			
		||||
      ],
 | 
			
		||||
      'phone' => [
 | 
			
		||||
        'source_module' => 'phone',
 | 
			
		||||
        'destination_module' => 'telephone',
 | 
			
		||||
      ],
 | 
			
		||||
      'telephone' => [
 | 
			
		||||
        'source_module' => 'telephone',
 | 
			
		||||
        'destination_module' => 'telephone',
 | 
			
		||||
      ],
 | 
			
		||||
      'link' => [
 | 
			
		||||
        'source_module' => 'link',
 | 
			
		||||
        'destination_module' => 'link',
 | 
			
		||||
      ],
 | 
			
		||||
      'link_field' => [
 | 
			
		||||
        'source_module' => 'link',
 | 
			
		||||
        'destination_module' => 'link',
 | 
			
		||||
      ],
 | 
			
		||||
      'd6_text' => [
 | 
			
		||||
        'source_module' => 'text',
 | 
			
		||||
        'destination_module' => 'text',
 | 
			
		||||
      ],
 | 
			
		||||
      'd7_text' => [
 | 
			
		||||
        'source_module' => 'text',
 | 
			
		||||
        'destination_module' => 'text',
 | 
			
		||||
      ],
 | 
			
		||||
      'taxonomy_term_reference' => [
 | 
			
		||||
        'source_module' => 'taxonomy',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'date' => [
 | 
			
		||||
        'source_module' => 'date',
 | 
			
		||||
        'destination_module' => 'datetime',
 | 
			
		||||
      ],
 | 
			
		||||
      'datetime' => [
 | 
			
		||||
        'source_module' => 'date',
 | 
			
		||||
        'destination_module' => 'datetime',
 | 
			
		||||
      ],
 | 
			
		||||
      'email' => [
 | 
			
		||||
        'source_module' => 'email',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'number_default' => [
 | 
			
		||||
        'source_module' => 'number',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'entityreference' => [
 | 
			
		||||
        'source_module' => 'entityreference',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'node_reference' => [
 | 
			
		||||
        'source_module' => 'node_reference',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'user_reference' => [
 | 
			
		||||
        'source_module' => 'user_reference',
 | 
			
		||||
        'destination_module' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $this->enableAllModules();
 | 
			
		||||
 | 
			
		||||
    $definitions = $this->container->get('plugin.manager.migrate.field')->getDefinitions();
 | 
			
		||||
    foreach ($definitions as $key => $definition) {
 | 
			
		||||
      $this->assertArrayHasKey($key, $expected_mappings);
 | 
			
		||||
      $this->assertEquals($expected_mappings[$key]['source_module'], $definition['source_module']);
 | 
			
		||||
      $this->assertEquals($expected_mappings[$key]['destination_module'], $definition['destination_module']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests a missing required definition.
 | 
			
		||||
   *
 | 
			
		||||
   * @param array $definitions
 | 
			
		||||
   *   A field plugin definition.
 | 
			
		||||
   * @param string $missing_property
 | 
			
		||||
   *   The name of the property missing from the definition.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider fieldPluginDefinitionsProvider
 | 
			
		||||
   */
 | 
			
		||||
  public function testFieldProviderMissingRequiredProperty(array $definitions, $missing_property): void {
 | 
			
		||||
    $discovery = $this->getMockBuilder(MigrateFieldPluginManager::class)
 | 
			
		||||
      ->disableOriginalConstructor()
 | 
			
		||||
      ->onlyMethods(['getDefinitions'])
 | 
			
		||||
      ->getMock();
 | 
			
		||||
    $discovery->method('getDefinitions')
 | 
			
		||||
      ->willReturn($definitions);
 | 
			
		||||
 | 
			
		||||
    $plugin_manager = $this->getMockBuilder(MigrateFieldPluginManager::class)
 | 
			
		||||
      ->disableOriginalConstructor()
 | 
			
		||||
      ->onlyMethods(['getDiscovery'])
 | 
			
		||||
      ->getMock();
 | 
			
		||||
    $plugin_manager->method('getDiscovery')
 | 
			
		||||
      ->willReturn($discovery);
 | 
			
		||||
 | 
			
		||||
    $this->expectException(BadPluginDefinitionException::class);
 | 
			
		||||
    $this->expectExceptionMessage("The missing_{$missing_property} plugin must define the $missing_property property.");
 | 
			
		||||
    $plugin_manager->getDefinitions();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Data provider for field plugin definitions.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   Array of plugin definitions.
 | 
			
		||||
   */
 | 
			
		||||
  public static function fieldPluginDefinitionsProvider() {
 | 
			
		||||
    return [
 | 
			
		||||
      'missing_core_scenario' => [
 | 
			
		||||
        'definitions' => [
 | 
			
		||||
          'missing_core' => [
 | 
			
		||||
            'source_module' => 'migrate',
 | 
			
		||||
            'destination_module' => 'migrate',
 | 
			
		||||
            'id' => 'missing_core',
 | 
			
		||||
            'class' => 'foo',
 | 
			
		||||
            'provider' => 'foo',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'missing_property' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
      'missing_source_scenario' => [
 | 
			
		||||
        'definitions' => [
 | 
			
		||||
          'missing_source_module' => [
 | 
			
		||||
            'core' => [6, 7],
 | 
			
		||||
            'destination_module' => 'migrate',
 | 
			
		||||
            'id' => 'missing_source_module',
 | 
			
		||||
            'class' => 'foo',
 | 
			
		||||
            'provider' => 'foo',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'missing_property' => 'source_module',
 | 
			
		||||
      ],
 | 
			
		||||
      'missing_destination_scenario' => [
 | 
			
		||||
        'definitions' => [
 | 
			
		||||
          'missing_destination_module' => [
 | 
			
		||||
            'core' => [6, 7],
 | 
			
		||||
            'source_module' => 'migrate',
 | 
			
		||||
            'id' => 'missing_destination_module',
 | 
			
		||||
            'class' => 'foo',
 | 
			
		||||
            'provider' => 'foo',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'missing_property' => 'destination_module',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,129 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate;
 | 
			
		||||
 | 
			
		||||
use Drupal\ban\Plugin\migrate\destination\BlockedIp;
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate\Plugin\migrate\destination\ComponentEntityDisplayBase;
 | 
			
		||||
use Drupal\migrate\Plugin\migrate\destination\Config;
 | 
			
		||||
use Drupal\migrate\Plugin\migrate\destination\EntityConfigBase;
 | 
			
		||||
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
 | 
			
		||||
use Drupal\shortcut\Plugin\migrate\destination\ShortcutSetUsers;
 | 
			
		||||
use Drupal\system\Plugin\migrate\destination\d7\ThemeSettings;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\CreateMigrationsTrait;
 | 
			
		||||
use Drupal\user\Plugin\migrate\destination\UserData;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests that all migrations are tagged as either content or configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class DestinationCategoryTest extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
  use CreateMigrationsTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migration plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate\Plugin\MigrationPluginManager
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    // Enable all modules.
 | 
			
		||||
    self::$modules = array_keys($this->coreModuleListDataProvider());
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->migrationManager = \Drupal::service('plugin.manager.migration');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that all D6 migrations are tagged as either Configuration or Content.
 | 
			
		||||
   */
 | 
			
		||||
  public function testD6Categories(): void {
 | 
			
		||||
    $migrations = $this->drupal6Migrations();
 | 
			
		||||
    $this->assertArrayHasKey('d6_node:page', $migrations);
 | 
			
		||||
    $this->assertCategories($migrations);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that all D7 migrations are tagged as either Configuration or Content.
 | 
			
		||||
   */
 | 
			
		||||
  public function testD7Categories(): void {
 | 
			
		||||
    $migrations = $this->drupal7Migrations();
 | 
			
		||||
    $this->assertArrayHasKey('d7_node:page', $migrations);
 | 
			
		||||
    $this->assertCategories($migrations);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Asserts that all migrations are tagged as either Configuration or Content.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations
 | 
			
		||||
   *   The migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @internal
 | 
			
		||||
   */
 | 
			
		||||
  protected function assertCategories(array $migrations): void {
 | 
			
		||||
    foreach ($migrations as $id => $migration) {
 | 
			
		||||
      $object_classes = class_parents($migration->getDestinationPlugin());
 | 
			
		||||
      $object_classes[] = get_class($migration->getDestinationPlugin());
 | 
			
		||||
 | 
			
		||||
      // Ensure that the destination plugin is an instance of at least one of
 | 
			
		||||
      // the expected classes.
 | 
			
		||||
      if (in_array('Configuration', $migration->getMigrationTags(), TRUE)) {
 | 
			
		||||
        $this->assertNotEmpty(array_intersect($object_classes, $this->getConfigurationClasses()), "The migration $id is tagged as Configuration.");
 | 
			
		||||
      }
 | 
			
		||||
      elseif (in_array('Content', $migration->getMigrationTags(), TRUE)) {
 | 
			
		||||
        $this->assertNotEmpty(array_intersect($object_classes, $this->getContentClasses()), "The migration $id is tagged as Content.");
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $this->fail("The migration $id is not tagged as either 'Content' or 'Configuration'.");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get configuration classes.
 | 
			
		||||
   *
 | 
			
		||||
   * Configuration migrations should have a destination plugin that is an
 | 
			
		||||
   * instance of one of the following classes.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The configuration class names.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getConfigurationClasses(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      Config::class,
 | 
			
		||||
      EntityConfigBase::class,
 | 
			
		||||
      ThemeSettings::class,
 | 
			
		||||
      ComponentEntityDisplayBase::class,
 | 
			
		||||
      ShortcutSetUsers::class,
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get content classes.
 | 
			
		||||
   *
 | 
			
		||||
   * Content migrations should have a destination plugin that is an instance
 | 
			
		||||
   * of one of the following classes.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The content class names.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getContentClasses(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      EntityContentBase::class,
 | 
			
		||||
      // @todo Remove BlockedIp in https://www.drupal.org/project/drupal/issues/3488827
 | 
			
		||||
      BlockedIp::class,
 | 
			
		||||
      UserData::class,
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,75 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source;
 | 
			
		||||
 | 
			
		||||
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\migrate\source\ContentEntity;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the constructor of the entity content source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @group legacy
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class ContentEntityConstructorTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'migrate',
 | 
			
		||||
    'migrate_drupal',
 | 
			
		||||
    'node',
 | 
			
		||||
    'system',
 | 
			
		||||
    'user',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the constructor.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerTestConstructor
 | 
			
		||||
   */
 | 
			
		||||
  public function testConstructor($configuration, $plugin_definition, $exception_class, $expected): void {
 | 
			
		||||
    $migration = $this->prophesize(MigrationInterface::class)->reveal();
 | 
			
		||||
    $this->expectException($exception_class);
 | 
			
		||||
    $this->expectExceptionMessage($expected);
 | 
			
		||||
    ContentEntity::create($this->container, $configuration, 'content_entity', $plugin_definition, $migration);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for constructor tests.
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerTestConstructor() {
 | 
			
		||||
    return [
 | 
			
		||||
      'entity type missing' => [
 | 
			
		||||
        [],
 | 
			
		||||
        ['entity_type' => ''],
 | 
			
		||||
        InvalidPluginDefinitionException::class,
 | 
			
		||||
        'Missing required "entity_type" definition.',
 | 
			
		||||
      ],
 | 
			
		||||
      'non content entity' => [
 | 
			
		||||
        [],
 | 
			
		||||
        ['entity_type' => 'node_type'],
 | 
			
		||||
        InvalidPluginDefinitionException::class,
 | 
			
		||||
        'The entity type (node_type) is not supported. The "content_entity" source plugin only supports content entities.',
 | 
			
		||||
      ],
 | 
			
		||||
      'not bundleable' => [
 | 
			
		||||
        ['bundle' => 'foo'],
 | 
			
		||||
        ['entity_type' => 'user'],
 | 
			
		||||
        \InvalidArgumentException::class,
 | 
			
		||||
        'A bundle was provided but the entity type (user) is not bundleable.',
 | 
			
		||||
      ],
 | 
			
		||||
      'invalid bundle' => [
 | 
			
		||||
        ['bundle' => 'foo'],
 | 
			
		||||
        ['entity_type' => 'node'],
 | 
			
		||||
        \InvalidArgumentException::class,
 | 
			
		||||
        'The provided bundle (foo) is not valid for the (node) entity type.',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,61 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore multirow
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the variable multirow source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @covers \Drupal\migrate_drupal\Plugin\migrate\source\VariableMultiRow
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class VariableMultiRowTest extends MigrateSqlSourceTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerSource() {
 | 
			
		||||
    $tests = [];
 | 
			
		||||
 | 
			
		||||
    // The source data.
 | 
			
		||||
    $tests[0]['source_data']['variable'] = [
 | 
			
		||||
      ['name' => 'foo', 'value' => 'i:1;'],
 | 
			
		||||
      ['name' => 'bar', 'value' => 'b:0;'],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected results.
 | 
			
		||||
    $tests[0]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'foo',
 | 
			
		||||
        'value' => 1,
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'bar',
 | 
			
		||||
        'value' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected count.
 | 
			
		||||
    $tests[0]['expected_count'] = NULL;
 | 
			
		||||
 | 
			
		||||
    // The source plugin configuration.
 | 
			
		||||
    $tests[0]['configuration']['variables'] = [
 | 
			
		||||
      'foo',
 | 
			
		||||
      'bar',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,210 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the variable source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @covers \Drupal\migrate_drupal\Plugin\migrate\source\Variable
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class VariableTest extends MigrateSqlSourceTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerSource() {
 | 
			
		||||
    $tests = [];
 | 
			
		||||
 | 
			
		||||
    // The source data.
 | 
			
		||||
    $tests[0]['source_data']['variable'] = [
 | 
			
		||||
      ['name' => 'foo', 'value' => 'i:1;'],
 | 
			
		||||
      ['name' => 'bar', 'value' => 'b:0;'],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected results.
 | 
			
		||||
    $tests[0]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'id' => 'foo',
 | 
			
		||||
        'foo' => 1,
 | 
			
		||||
        'bar' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected count.
 | 
			
		||||
    $tests[0]['expected_count'] = 1;
 | 
			
		||||
 | 
			
		||||
    // The source plugin configuration.
 | 
			
		||||
    $tests[0]['configuration']['variables'] = [
 | 
			
		||||
      'foo',
 | 
			
		||||
      'bar',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Tests getting one of two variables.
 | 
			
		||||
    $tests[1]['source_data']['variable'] = [
 | 
			
		||||
      ['name' => 'foo', 'value' => 'i:1;'],
 | 
			
		||||
      ['name' => 'bar', 'value' => 'b:0;'],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $tests[1]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'id' => 'foo',
 | 
			
		||||
        'foo' => 1,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $tests[1]['expected_count'] = 1;
 | 
			
		||||
 | 
			
		||||
    $tests[1]['configuration']['variables'] = [
 | 
			
		||||
      'foo',
 | 
			
		||||
      'bar0',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Tests requesting mis-spelled variable names. If none of the required
 | 
			
		||||
    // variables are available, this plugin still returns a single row.
 | 
			
		||||
    $tests[2]['source_data']['variable'] = [
 | 
			
		||||
      ['name' => 'foo', 'value' => 'i:1;'],
 | 
			
		||||
      ['name' => 'bar', 'value' => 'b:0;'],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[2]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'id' => 'foo0',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[2]['expected_count'] = 1;
 | 
			
		||||
    $tests[2]['configuration']['variables'] = [
 | 
			
		||||
      'foo0',
 | 
			
		||||
      'bar0',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $source_data = [
 | 
			
		||||
      'variable' => [
 | 
			
		||||
        ['name' => 'foo', 'value' => 'i:1;'],
 | 
			
		||||
        ['name' => 'bar', 'value' => 'b:0;'],
 | 
			
		||||
        ['name' => 'baz', 'value' => 's:6:"foobar";'],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test cases with only 'variables_no_row_if_missing' configuration.
 | 
			
		||||
    $variables_no_row_if_missing_tests = [
 | 
			
		||||
      'Two required variables, all of them are available' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [
 | 
			
		||||
          [
 | 
			
		||||
            'id' => 'foo',
 | 
			
		||||
            'foo' => 1,
 | 
			
		||||
            'bar' => FALSE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'expected_count' => 1,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables_no_row_if_missing' => [
 | 
			
		||||
            'foo',
 | 
			
		||||
            'bar',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Two required variables, only one is available' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [],
 | 
			
		||||
        'expected_count' => 0,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables_no_row_if_missing' => [
 | 
			
		||||
            'foo',
 | 
			
		||||
            'bar0',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'One required and available variable' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [
 | 
			
		||||
          [
 | 
			
		||||
            'id' => 'baz',
 | 
			
		||||
            'baz' => 'foobar',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'expected_count' => 1,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables_no_row_if_missing' => [
 | 
			
		||||
            'baz',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'One required, but missing variable' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [],
 | 
			
		||||
        'expected_count' => 0,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables_no_row_if_missing' => [
 | 
			
		||||
            'bar0',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      // Test cases with both 'variables' and 'variables_no_row_if_missing'
 | 
			
		||||
      // configuration.
 | 
			
		||||
      'One optional and two required variables, all of them are available' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [
 | 
			
		||||
          [
 | 
			
		||||
            'id' => 'foo',
 | 
			
		||||
            'foo' => 1,
 | 
			
		||||
            'bar' => FALSE,
 | 
			
		||||
            'baz' => 'foobar',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'expected_count' => 1,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables' => ['foo'],
 | 
			
		||||
          'variables_no_row_if_missing' => ['bar', 'baz'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'One optional and two required variables, only one required is available' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [],
 | 
			
		||||
        'expected_count' => 0,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables' => ['foo'],
 | 
			
		||||
          'variables_no_row_if_missing' => ['bar', 'foobar'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Two optional and one required and available variable, every optional is missing' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [
 | 
			
		||||
          [
 | 
			
		||||
            'id' => 'qux',
 | 
			
		||||
            'bar' => FALSE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
        'expected_count' => 1,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables' => ['qux', 'waldo'],
 | 
			
		||||
          'variables_no_row_if_missing' => ['bar'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Two available optional and a required, but missing variable' => [
 | 
			
		||||
        'source_data' => $source_data,
 | 
			
		||||
        'expected_data' => [],
 | 
			
		||||
        'expected_count' => 0,
 | 
			
		||||
        'configuration' => [
 | 
			
		||||
          'variables' => ['baz', 'foo'],
 | 
			
		||||
          'variables_no_row_if_missing' => [
 | 
			
		||||
            'foo_bar_baz',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $tests + $variables_no_row_if_missing_tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,79 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the variable source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @covers \Drupal\migrate_drupal\Plugin\migrate\source\d6\VariableTranslation
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class VariableTranslationTest extends MigrateSqlSourceTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerSource() {
 | 
			
		||||
    $tests = [];
 | 
			
		||||
 | 
			
		||||
    // The source data.
 | 
			
		||||
    $tests[0]['source_data']['i18n_variable'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'site_slogan',
 | 
			
		||||
        'language' => 'fr',
 | 
			
		||||
        'value' => 's:23:"fr - migrate is awesome";',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'site_name',
 | 
			
		||||
        'language' => 'fr',
 | 
			
		||||
        'value' => 's:14:"fr - site name";',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'site_slogan',
 | 
			
		||||
        'language' => 'mi',
 | 
			
		||||
        'value' => 's:23:"mi - migrate is awesome";',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'site_name',
 | 
			
		||||
        'language' => 'mi',
 | 
			
		||||
        'value' => 's:14:"mi - site name";',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected results.
 | 
			
		||||
    $tests[0]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'language' => 'fr',
 | 
			
		||||
        'site_slogan' => 'fr - migrate is awesome',
 | 
			
		||||
        'site_name' => 'fr - site name',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'language' => 'mi',
 | 
			
		||||
        'site_slogan' => 'mi - migrate is awesome',
 | 
			
		||||
        'site_name' => 'mi - site name',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected count.
 | 
			
		||||
    $tests[0]['expected_count'] = NULL;
 | 
			
		||||
 | 
			
		||||
    // The migration configuration.
 | 
			
		||||
    $tests[0]['configuration']['variables'] = [
 | 
			
		||||
      'site_slogan',
 | 
			
		||||
      'site_name',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,79 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the variable source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @covers \Drupal\migrate_drupal\Plugin\migrate\source\d7\VariableTranslation
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class VariableTranslationTest extends MigrateSqlSourceTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerSource() {
 | 
			
		||||
    $tests = [];
 | 
			
		||||
 | 
			
		||||
    // The source data.
 | 
			
		||||
    $tests[0]['source_data']['variable_store'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'realm' => 'language',
 | 
			
		||||
        'realm_key' => 'fr',
 | 
			
		||||
        'name' => 'site_slogan',
 | 
			
		||||
        'value' => 'fr - site slogan',
 | 
			
		||||
        'serialized' => '0',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'realm' => 'language',
 | 
			
		||||
        'realm_key' => 'fr',
 | 
			
		||||
        'name' => 'user_mail_status_blocked_subject',
 | 
			
		||||
        'value' => 'fr - BEGONE!',
 | 
			
		||||
        'serialized' => '0',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'realm' => 'language',
 | 
			
		||||
        'realm_key' => 'is',
 | 
			
		||||
        'name' => 'site_slogan',
 | 
			
		||||
        'value' => 's:16:"is - site slogan";',
 | 
			
		||||
        'serialized' => '1',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected results.
 | 
			
		||||
    $tests[0]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'language' => 'fr',
 | 
			
		||||
        'site_slogan' => 'fr - site slogan',
 | 
			
		||||
        'user_mail_status_blocked_subject' => 'fr - BEGONE!',
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'language' => 'is',
 | 
			
		||||
        'site_slogan' => 'is - site slogan',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected count.
 | 
			
		||||
    $tests[0]['expected_count'] = NULL;
 | 
			
		||||
 | 
			
		||||
    // The migration configuration.
 | 
			
		||||
    $tests[0]['configuration']['variables'] = [
 | 
			
		||||
      'site_slogan',
 | 
			
		||||
      'user_mail_status_blocked_subject',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,118 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\Plugin\migrate\source\d8;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the config source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @covers \Drupal\migrate_drupal\Plugin\migrate\source\d8\Config
 | 
			
		||||
 * @group legacy
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class ConfigTest extends MigrateSqlSourceTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_drupal'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerSource() {
 | 
			
		||||
    $data = [];
 | 
			
		||||
 | 
			
		||||
    // The source database tables.
 | 
			
		||||
    $data[0]['source_data'] = [
 | 
			
		||||
      'config' => [
 | 
			
		||||
        [
 | 
			
		||||
          'collection' => 'language.af',
 | 
			
		||||
          'name' => 'user.settings',
 | 
			
		||||
          'data' => 'a:1:{s:9:"anonymous";s:14:"af - Anonymous";}',
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
          'collection' => '',
 | 
			
		||||
          'name' => 'user.settings',
 | 
			
		||||
          'data' => 'a:1:{s:9:"anonymous";s:9:"Anonymous";}',
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
          'collection' => 'language.de',
 | 
			
		||||
          'name' => 'user.settings',
 | 
			
		||||
          'data' => 'a:1:{s:9:"anonymous";s:14:"de - Anonymous";}',
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
          'collection' => 'language.af',
 | 
			
		||||
          'name' => 'bar',
 | 
			
		||||
          'data' => 'b:0;',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // The expected results.
 | 
			
		||||
    $data[0]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'collection' => 'language.af',
 | 
			
		||||
        'name' => 'user.settings',
 | 
			
		||||
        'data' => [
 | 
			
		||||
          'anonymous' => 'af - Anonymous',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'collection' => 'language.af',
 | 
			
		||||
        'name' => 'bar',
 | 
			
		||||
        'data' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $data[0]['expected_count'] = NULL;
 | 
			
		||||
    $data[0]['configuration'] = [
 | 
			
		||||
      'names' => [
 | 
			
		||||
        'user.settings',
 | 
			
		||||
        'bar',
 | 
			
		||||
      ],
 | 
			
		||||
      'collections' => [
 | 
			
		||||
        'language.af',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test with name and no collection in configuration.
 | 
			
		||||
    $data[1]['source_data'] = $data[0]['source_data'];
 | 
			
		||||
    $data[1]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'collection' => 'language.af',
 | 
			
		||||
        'name' => 'bar',
 | 
			
		||||
        'data' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $data[1]['expected_count'] = NULL;
 | 
			
		||||
    $data[1]['configuration'] = [
 | 
			
		||||
      'names' => [
 | 
			
		||||
        'bar',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test with collection and no name in configuration.
 | 
			
		||||
    $data[2]['source_data'] = $data[0]['source_data'];
 | 
			
		||||
    $data[2]['expected_data'] = [
 | 
			
		||||
      [
 | 
			
		||||
        'collection' => 'language.de',
 | 
			
		||||
        'name' => 'user.settings',
 | 
			
		||||
        'data' => [
 | 
			
		||||
          'anonymous' => 'de - Anonymous',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $data[2]['expected_count'] = NULL;
 | 
			
		||||
    $data[2]['configuration'] = [
 | 
			
		||||
      'collections' => [
 | 
			
		||||
        'language.de',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,103 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\Component\Discovery\YamlDiscovery;
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate_drupal\MigrationConfigurationTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests that core modules have a migrate_drupal.yml file as needed.
 | 
			
		||||
 *
 | 
			
		||||
 * Checks that each module that requires a migrate_drupal.yml has the file.
 | 
			
		||||
 * Because more that one migrate_drupal.yml file may have the same entry the
 | 
			
		||||
 * ValidateMigrationStateTest, which validates the file contents, is not able
 | 
			
		||||
 * to determine that all the required files exits.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class StateFileExistsTest extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
  use MigrationConfigurationTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    // Test migrations states.
 | 
			
		||||
    'migrate_state_finished_test',
 | 
			
		||||
    'migrate_state_not_finished_test',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Modules that should have a migrate_drupal.yml file.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $stateFileRequired = [
 | 
			
		||||
    // @todo Remove ban in https://www.drupal.org/project/drupal/issues/3488827
 | 
			
		||||
    'ban',
 | 
			
		||||
    'block',
 | 
			
		||||
    'block_content',
 | 
			
		||||
    'comment',
 | 
			
		||||
    'config_translation',
 | 
			
		||||
    'contact',
 | 
			
		||||
    'content_translation',
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'dblog',
 | 
			
		||||
    'field',
 | 
			
		||||
    'file',
 | 
			
		||||
    'filter',
 | 
			
		||||
    'image',
 | 
			
		||||
    'language',
 | 
			
		||||
    'link',
 | 
			
		||||
    'locale',
 | 
			
		||||
    'menu_link_content',
 | 
			
		||||
    'migrate_state_finished_test',
 | 
			
		||||
    'migrate_state_not_finished_test',
 | 
			
		||||
    'menu_ui',
 | 
			
		||||
    'migrate_drupal',
 | 
			
		||||
    'node',
 | 
			
		||||
    'options',
 | 
			
		||||
    'path',
 | 
			
		||||
    'responsive_image',
 | 
			
		||||
    'search',
 | 
			
		||||
    'shortcut',
 | 
			
		||||
    'syslog',
 | 
			
		||||
    'system',
 | 
			
		||||
    'taxonomy',
 | 
			
		||||
    'telephone',
 | 
			
		||||
    'text',
 | 
			
		||||
    'update',
 | 
			
		||||
    'user',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that the migrate_drupal.yml files exist as needed.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMigrationState(): void {
 | 
			
		||||
    // Install all available modules.
 | 
			
		||||
    $module_handler = $this->container->get('module_handler');
 | 
			
		||||
    $all_modules = $this->coreModuleListDataProvider();
 | 
			
		||||
    $modules_enabled = $module_handler->getModuleList();
 | 
			
		||||
    $modules_to_enable = array_keys(array_diff_key($all_modules, $modules_enabled));
 | 
			
		||||
    $this->enableModules($modules_to_enable);
 | 
			
		||||
    // Note that the kernel has rebuilt the container in enableModules this
 | 
			
		||||
    // $module_handler is no longer the $module_handler instance from above.
 | 
			
		||||
    $module_handler = $this->container->get('module_handler');
 | 
			
		||||
 | 
			
		||||
    // Modules with a migrate_drupal.yml file.
 | 
			
		||||
    $has_state_file = (new YamlDiscovery('migrate_drupal', array_map(function ($value) {
 | 
			
		||||
      return $value . '/migrations/state';
 | 
			
		||||
    }, $module_handler->getModuleDirectories())))->findAll();
 | 
			
		||||
 | 
			
		||||
    foreach ($this->stateFileRequired as $module) {
 | 
			
		||||
      $this->assertArrayHasKey($module, $has_state_file, sprintf("Module '%s' should have a migrate_drupal.yml file", $module));
 | 
			
		||||
    }
 | 
			
		||||
    $this->assertSameSize($this->stateFileRequired, $has_state_file);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,131 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\field\Entity\FieldConfig;
 | 
			
		||||
use Drupal\field\Entity\FieldStorageConfig;
 | 
			
		||||
use Drupal\migrate\MigrateExecutable;
 | 
			
		||||
use Drupal\migrate\MigrateMessageInterface;
 | 
			
		||||
use Drupal\user\Entity\User;
 | 
			
		||||
use Prophecy\Argument;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class EntityContentBaseTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['migrate_overwrite_test'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    // Create a field on the user entity so that we can test nested property
 | 
			
		||||
    // overwrites.
 | 
			
		||||
    // @see static::testOverwriteSelectedNestedProperty()
 | 
			
		||||
    FieldStorageConfig::create([
 | 
			
		||||
      'field_name' => 'signature',
 | 
			
		||||
      'entity_type' => 'user',
 | 
			
		||||
      'type' => 'text_long',
 | 
			
		||||
    ])->save();
 | 
			
		||||
 | 
			
		||||
    FieldConfig::create([
 | 
			
		||||
      'field_name' => 'signature',
 | 
			
		||||
      'entity_type' => 'user',
 | 
			
		||||
      'bundle' => 'user',
 | 
			
		||||
    ])->save();
 | 
			
		||||
 | 
			
		||||
    User::create([
 | 
			
		||||
      'uid' => 2,
 | 
			
		||||
      'name' => 'Ford Prefect',
 | 
			
		||||
      'mail' => 'ford.prefect@localhost',
 | 
			
		||||
      'signature' => [
 | 
			
		||||
        [
 | 
			
		||||
          'value' => 'Bring a towel.',
 | 
			
		||||
          'format' => 'filtered_html',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'init' => 'proto@zo.an',
 | 
			
		||||
    ])->save();
 | 
			
		||||
 | 
			
		||||
    $this->executeMigrations(['d6_filter_format', 'd6_user_role']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests overwriting all mapped properties in the destination entity.
 | 
			
		||||
   *
 | 
			
		||||
   * This is the default behavior.
 | 
			
		||||
   */
 | 
			
		||||
  public function testOverwriteAllMappedProperties(): void {
 | 
			
		||||
    $this->executeMigration('d6_user');
 | 
			
		||||
    /** @var \Drupal\user\UserInterface $account */
 | 
			
		||||
    $account = User::load(2);
 | 
			
		||||
    $this->assertSame('john.doe', $account->label());
 | 
			
		||||
    $this->assertSame('john.doe@example.com', $account->getEmail());
 | 
			
		||||
    $this->assertSame('doe@example.com', $account->getInitialEmail());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests overwriting selected properties in the destination entity.
 | 
			
		||||
   *
 | 
			
		||||
   * The selected properties are specified in the destination configuration.
 | 
			
		||||
   */
 | 
			
		||||
  public function testOverwriteProperties(): void {
 | 
			
		||||
    // Execute the migration in migrate_overwrite_test, which documents how
 | 
			
		||||
    // property overwrites work.
 | 
			
		||||
    $this->executeMigration('users');
 | 
			
		||||
 | 
			
		||||
    /** @var \Drupal\user\UserInterface $account */
 | 
			
		||||
    $account = User::load(2);
 | 
			
		||||
    $this->assertSame('john.doe', $account->label());
 | 
			
		||||
    $this->assertSame('john.doe@example.com', $account->getEmail());
 | 
			
		||||
    $this->assertSame('The answer is 42.', $account->signature->value);
 | 
			
		||||
    // This value is not overwritten because it's not listed in
 | 
			
		||||
    // overwrite_properties.
 | 
			
		||||
    $this->assertSame('proto@zo.an', $account->getInitialEmail());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that translation destination fails for untranslatable entities.
 | 
			
		||||
   */
 | 
			
		||||
  public function testUntranslatable(): void {
 | 
			
		||||
    $this->enableModules(['language_test']);
 | 
			
		||||
    $this->installEntitySchema('no_language_entity_test');
 | 
			
		||||
 | 
			
		||||
    /** @var MigrationInterface $migration */
 | 
			
		||||
    $migration = \Drupal::service('plugin.manager.migration')->createStubMigration([
 | 
			
		||||
      'source' => [
 | 
			
		||||
        'plugin' => 'embedded_data',
 | 
			
		||||
        'ids' => ['id' => ['type' => 'integer']],
 | 
			
		||||
        'data_rows' => [['id' => 1]],
 | 
			
		||||
      ],
 | 
			
		||||
      'process' => [
 | 
			
		||||
        'id' => 'id',
 | 
			
		||||
      ],
 | 
			
		||||
      'destination' => [
 | 
			
		||||
        'plugin' => 'entity:no_language_entity_test',
 | 
			
		||||
        'translations' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    $message = $this->prophesize(MigrateMessageInterface::class);
 | 
			
		||||
    // Match the expected message. Can't use default argument types, because
 | 
			
		||||
    // we need to convert to string from TranslatableMarkup.
 | 
			
		||||
    $argument = Argument::that(function ($msg) {
 | 
			
		||||
      return str_contains((string) $msg, htmlentities('The "no_language_entity_test" entity type does not support translations.'));
 | 
			
		||||
    });
 | 
			
		||||
    $message->display($argument, Argument::any())
 | 
			
		||||
      ->shouldBeCalled();
 | 
			
		||||
 | 
			
		||||
    $executable = new MigrateExecutable($migration, $message->reveal());
 | 
			
		||||
    $executable->import();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,318 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\field\Plugin\migrate\source\d6\FieldInstance;
 | 
			
		||||
use Drupal\field_discovery_test\FieldDiscoveryTestClass;
 | 
			
		||||
use Drupal\migrate_drupal\FieldDiscoveryInterface;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\FieldDiscoveryTestTrait;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore filefield imagefield imagelink nodelink nodereference
 | 
			
		||||
// cspell:ignore selectlist spamspan userreference
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests FieldDiscovery service against Drupal 6.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\FieldDiscovery
 | 
			
		||||
 */
 | 
			
		||||
class FieldDiscoveryTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  use FieldDiscoveryTestTrait;
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'menu_ui',
 | 
			
		||||
    'comment',
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'file',
 | 
			
		||||
    'image',
 | 
			
		||||
    'link',
 | 
			
		||||
    'node',
 | 
			
		||||
    'system',
 | 
			
		||||
    'taxonomy',
 | 
			
		||||
    'telephone',
 | 
			
		||||
    'text',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The Field discovery service.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\FieldDiscoveryInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $fieldDiscovery;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The field plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $fieldPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migration plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationPluginManager;
 | 
			
		||||
  /**
 | 
			
		||||
   * The logger.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\Core\Logger\LoggerChannelInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $logger;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->installConfig(['node']);
 | 
			
		||||
    $this->executeMigration('d6_node_type');
 | 
			
		||||
    $this->executeMigration('d6_field');
 | 
			
		||||
    $this->executeMigration('d6_field_instance');
 | 
			
		||||
    $this->fieldDiscovery = $this->container->get('migrate_drupal.field_discovery');
 | 
			
		||||
    $this->migrationPluginManager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $this->fieldPluginManager = $this->container->get('plugin.manager.migrate.field');
 | 
			
		||||
    $this->logger = $this->container->get('logger.channel.migrate_drupal');
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the addAllFieldProcesses method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::addAllFieldProcesses
 | 
			
		||||
   */
 | 
			
		||||
  public function testAddAllFieldProcesses(): void {
 | 
			
		||||
    $expected_process_keys = [
 | 
			
		||||
      'field_commander',
 | 
			
		||||
      'field_company',
 | 
			
		||||
      'field_company_2',
 | 
			
		||||
      'field_company_3',
 | 
			
		||||
      'field_company_4',
 | 
			
		||||
      'field_sync',
 | 
			
		||||
      'field_multivalue',
 | 
			
		||||
      'field_test_text_single_checkbox',
 | 
			
		||||
      'field_reference',
 | 
			
		||||
      'field_reference_2',
 | 
			
		||||
      'field_test',
 | 
			
		||||
      'field_test_date',
 | 
			
		||||
      'field_test_datestamp',
 | 
			
		||||
      'field_test_datetime',
 | 
			
		||||
      'field_test_decimal_radio_buttons',
 | 
			
		||||
      'field_test_email',
 | 
			
		||||
      'field_test_exclude_unset',
 | 
			
		||||
      'field_test_filefield',
 | 
			
		||||
      'field_test_float_single_checkbox',
 | 
			
		||||
      'field_test_four',
 | 
			
		||||
      'field_test_identical1',
 | 
			
		||||
      'field_test_identical2',
 | 
			
		||||
      'field_test_imagefield',
 | 
			
		||||
      'field_test_integer_selectlist',
 | 
			
		||||
      'field_test_link',
 | 
			
		||||
      'field_test_phone',
 | 
			
		||||
      'field_test_string_selectlist',
 | 
			
		||||
      'field_test_text_single_checkbox2',
 | 
			
		||||
      'field_test_three',
 | 
			
		||||
      'field_test_two',
 | 
			
		||||
    ];
 | 
			
		||||
    $this->assertFieldProcessKeys($this->fieldDiscovery, $this->migrationPluginManager, FieldDiscoveryInterface::DRUPAL_6, $expected_process_keys);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the addAllFieldProcesses method for field migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::addAllFieldProcesses
 | 
			
		||||
   * @dataProvider addAllFieldProcessesAltersData
 | 
			
		||||
   */
 | 
			
		||||
  public function testAddAllFieldProcessesAlters($field_plugin_method, $expected_process): void {
 | 
			
		||||
    $this->assertFieldProcess($this->fieldDiscovery, $this->migrationPluginManager, FieldDiscoveryInterface::DRUPAL_6, $field_plugin_method, $expected_process);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testAddAllFieldProcessesAlters.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function addAllFieldProcessesAltersData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Field Formatter' => [
 | 
			
		||||
        'field_plugin_method' => 'alterFieldFormatterMigration',
 | 
			
		||||
        'expected_process' => [
 | 
			
		||||
          'options/type' => [
 | 
			
		||||
            0 => [
 | 
			
		||||
              'map' => [
 | 
			
		||||
                'email' => [
 | 
			
		||||
                  'email_formatter_default' => 'email_mailto',
 | 
			
		||||
                  'email_formatter_contact' => 'basic_string',
 | 
			
		||||
                  'email_formatter_plain' => 'basic_string',
 | 
			
		||||
                  'email_formatter_spamspan' => 'basic_string',
 | 
			
		||||
                  'email_default' => 'email_mailto',
 | 
			
		||||
                  'email_contact' => 'basic_string',
 | 
			
		||||
                  'email_plain' => 'basic_string',
 | 
			
		||||
                  'email_spamspan' => 'basic_string',
 | 
			
		||||
                ],
 | 
			
		||||
                'text' => [
 | 
			
		||||
                  'default' => 'text_default',
 | 
			
		||||
                  'trimmed' => 'text_trimmed',
 | 
			
		||||
                  'plain' => 'basic_string',
 | 
			
		||||
                ],
 | 
			
		||||
                'datetime' => [
 | 
			
		||||
                  'date_default' => 'datetime_default',
 | 
			
		||||
                  'format_interval' => 'datetime_time_ago',
 | 
			
		||||
                  'date_plain' => 'datetime_plain',
 | 
			
		||||
                ],
 | 
			
		||||
                'filefield' => [
 | 
			
		||||
                  'default' => 'file_default',
 | 
			
		||||
                  'url_plain' => 'file_url_plain',
 | 
			
		||||
                  'path_plain' => 'file_url_plain',
 | 
			
		||||
                  'image_plain' => 'image',
 | 
			
		||||
                  'image_nodelink' => 'image',
 | 
			
		||||
                  'image_imagelink' => 'image',
 | 
			
		||||
                ],
 | 
			
		||||
                'link' => [
 | 
			
		||||
                  'default' => 'link',
 | 
			
		||||
                  'plain' => 'link',
 | 
			
		||||
                  'absolute' => 'link',
 | 
			
		||||
                  'title_plain' => 'link',
 | 
			
		||||
                  'url' => 'link',
 | 
			
		||||
                  'short' => 'link',
 | 
			
		||||
                  'label' => 'link',
 | 
			
		||||
                  'separate' => 'link_separate',
 | 
			
		||||
                ],
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Field Widget' => [
 | 
			
		||||
        'field_plugin_method' => 'alterFieldWidgetMigration',
 | 
			
		||||
        'expected_process' => [
 | 
			
		||||
          'options/type' => [
 | 
			
		||||
            'type' => [
 | 
			
		||||
              'map' => [
 | 
			
		||||
                'userreference_select' => 'options_select',
 | 
			
		||||
                'userreference_buttons' => 'options_buttons',
 | 
			
		||||
                'userreference_autocomplete' => 'entity_reference_autocomplete_tags',
 | 
			
		||||
                'nodereference_select' => 'options_select',
 | 
			
		||||
                'nodereference_buttons' => 'options_buttons',
 | 
			
		||||
                'nodereference_autocomplete' => 'entity_reference_autocomplete_tags',
 | 
			
		||||
                'email_textfield' => 'email_default',
 | 
			
		||||
                'text_textfield' => 'text_textfield',
 | 
			
		||||
                'date' => 'datetime_default',
 | 
			
		||||
                'datetime' => 'datetime_default',
 | 
			
		||||
                'datestamp' => 'datetime_timestamp',
 | 
			
		||||
                'filefield_widget' => 'file_generic',
 | 
			
		||||
                'link' => 'link_default',
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the addFields method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::addAllFieldProcesses
 | 
			
		||||
   */
 | 
			
		||||
  public function testAddFields(): void {
 | 
			
		||||
    $this->migrateFields();
 | 
			
		||||
    $field_discovery = $this->container->get('migrate_drupal.field_discovery');
 | 
			
		||||
    $migration_plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $definition = [
 | 
			
		||||
      'migration_tags' => ['Drupal 6'],
 | 
			
		||||
    ];
 | 
			
		||||
    $migration = $migration_plugin_manager->createStubMigration($definition);
 | 
			
		||||
    $field_discovery->addBundleFieldProcesses($migration, 'node', 'test_planet');
 | 
			
		||||
    $actual_process = $migration->getProcess();
 | 
			
		||||
    $expected_process = [
 | 
			
		||||
      'field_multivalue' => [
 | 
			
		||||
        0 => [
 | 
			
		||||
          'plugin' => 'get',
 | 
			
		||||
          'source' => 'field_multivalue',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'field_test_text_single_checkbox' => [
 | 
			
		||||
        0 => [
 | 
			
		||||
          'plugin' => 'sub_process',
 | 
			
		||||
          'source' => 'field_test_text_single_checkbox',
 | 
			
		||||
          'process' => [
 | 
			
		||||
            'value' => 'value',
 | 
			
		||||
            'format' => [
 | 
			
		||||
              0 => [
 | 
			
		||||
                'plugin' => 'static_map',
 | 
			
		||||
                'bypass' => TRUE,
 | 
			
		||||
                'source' => 'format',
 | 
			
		||||
                'map' => [
 | 
			
		||||
                  0 => NULL,
 | 
			
		||||
                ],
 | 
			
		||||
              ],
 | 
			
		||||
              1 => [
 | 
			
		||||
                'plugin' => 'skip_on_empty',
 | 
			
		||||
                'method' => 'process',
 | 
			
		||||
              ],
 | 
			
		||||
              2 => [
 | 
			
		||||
                'plugin' => 'migration_lookup',
 | 
			
		||||
                'migration' => [
 | 
			
		||||
                  0 => 'd6_filter_format',
 | 
			
		||||
                  1 => 'd7_filter_format',
 | 
			
		||||
                ],
 | 
			
		||||
                'source' => 'format',
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $this->assertEquals($expected_process, $actual_process);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the getAllFields method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getAllFields
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetAllFields(): void {
 | 
			
		||||
    $field_discovery_test = new FieldDiscoveryTestClass($this->fieldPluginManager, $this->migrationPluginManager, $this->logger);
 | 
			
		||||
    $actual_fields = $field_discovery_test->getAllFields('6');
 | 
			
		||||
    $actual_node_types = array_keys($actual_fields['node']);
 | 
			
		||||
    sort($actual_node_types);
 | 
			
		||||
    $this->assertSame(['node'], array_keys($actual_fields));
 | 
			
		||||
    $this->assertSame(['employee', 'page', 'story', 'test_page', 'test_planet'], $actual_node_types);
 | 
			
		||||
    $this->assertCount(25, $actual_fields['node']['story']);
 | 
			
		||||
    foreach ($actual_fields['node'] as $bundle => $fields) {
 | 
			
		||||
      foreach ($fields as $field_info) {
 | 
			
		||||
        $this->assertArrayHasKey('type', $field_info);
 | 
			
		||||
        $this->assertCount(22, $field_info);
 | 
			
		||||
        $this->assertEquals($bundle, $field_info['type_name']);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the getSourcePlugin method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getSourcePlugin
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetSourcePlugin(): void {
 | 
			
		||||
    $this->assertSourcePlugin('6', FieldInstance::class, [
 | 
			
		||||
      'requirements_met' => TRUE,
 | 
			
		||||
      'id' => 'd6_field_instance',
 | 
			
		||||
      'source_module' => 'content',
 | 
			
		||||
      'class' => 'Drupal\\field\\Plugin\\migrate\\source\\d6\\FieldInstance',
 | 
			
		||||
      'provider' => [
 | 
			
		||||
        0 => 'field',
 | 
			
		||||
        1 => 'migrate_drupal',
 | 
			
		||||
        2 => 'migrate',
 | 
			
		||||
        4 => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,80 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\node\Entity\Node;
 | 
			
		||||
use Drupal\Tests\node\Kernel\Migrate\d6\MigrateNodeTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests follow-up migrations.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class FollowUpMigrationsTest extends MigrateNodeTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'content_translation',
 | 
			
		||||
    'language',
 | 
			
		||||
    'menu_ui',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->executeMigrations([
 | 
			
		||||
      'language',
 | 
			
		||||
      'd6_language_content_settings',
 | 
			
		||||
      'd6_node',
 | 
			
		||||
      'd6_node_translation',
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests entity reference translations.
 | 
			
		||||
   */
 | 
			
		||||
  public function testEntityReferenceTranslations(): void {
 | 
			
		||||
    // Test the entity reference field before the follow-up migrations.
 | 
			
		||||
    $node = Node::load(10);
 | 
			
		||||
    $this->assertSame('13', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('13', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('fr');
 | 
			
		||||
    $this->assertSame('20', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('20', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $node = Node::load(12)->getTranslation('en');
 | 
			
		||||
    $this->assertSame('10', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('10', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('fr');
 | 
			
		||||
    $this->assertSame('11', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('11', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    // Run the follow-up migrations.
 | 
			
		||||
    $migration_plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $migration_plugin_manager->clearCachedDefinitions();
 | 
			
		||||
    $follow_up_migrations = $migration_plugin_manager->createInstances('d6_entity_reference_translation');
 | 
			
		||||
    $this->executeMigrations(array_keys($follow_up_migrations));
 | 
			
		||||
 | 
			
		||||
    // Test the entity reference field after the follow-up migrations.
 | 
			
		||||
    $node = Node::load(10);
 | 
			
		||||
    $this->assertSame('12', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('12', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('fr');
 | 
			
		||||
    $this->assertSame('12', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('12', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $node = Node::load(12)->getTranslation('en');
 | 
			
		||||
    $this->assertSame('10', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('10', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('fr');
 | 
			
		||||
    $this->assertSame('10', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('10', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,210 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate\Audit\AuditResult;
 | 
			
		||||
use Drupal\migrate\Audit\IdAuditor;
 | 
			
		||||
use Drupal\node\Entity\Node;
 | 
			
		||||
use Drupal\node\Entity\NodeType;
 | 
			
		||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore sourceid
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the migration auditor for ID conflicts.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrateDrupal6AuditIdsTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
  use CreateTestContentEntitiesTrait;
 | 
			
		||||
  use ContentModerationTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    // Enable all modules.
 | 
			
		||||
    self::$modules = array_keys($this->coreModuleListDataProvider());
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    // Install required entity schemas.
 | 
			
		||||
    $this->installEntitySchema('block_content');
 | 
			
		||||
    $this->installEntitySchema('comment');
 | 
			
		||||
    $this->installEntitySchema('file');
 | 
			
		||||
    $this->installEntitySchema('menu_link_content');
 | 
			
		||||
    $this->installEntitySchema('node');
 | 
			
		||||
    $this->installEntitySchema('path_alias');
 | 
			
		||||
    $this->installEntitySchema('taxonomy_term');
 | 
			
		||||
    $this->installEntitySchema('user');
 | 
			
		||||
 | 
			
		||||
    // Install required schemas.
 | 
			
		||||
    $this->installSchema('dblog', ['watchdog']);
 | 
			
		||||
    $this->installSchema('node', ['node_access']);
 | 
			
		||||
    $this->installSchema('search', ['search_dataset']);
 | 
			
		||||
 | 
			
		||||
    // Enable content moderation for nodes of type page.
 | 
			
		||||
    $this->installEntitySchema('content_moderation_state');
 | 
			
		||||
    $this->installConfig('content_moderation');
 | 
			
		||||
    NodeType::create([
 | 
			
		||||
      'type' => 'page',
 | 
			
		||||
      'name' => 'Page',
 | 
			
		||||
    ])->save();
 | 
			
		||||
    $workflow = $this->createEditorialWorkflow();
 | 
			
		||||
    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
 | 
			
		||||
    $workflow->save();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests multiple migrations to the same destination with no ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMultipleMigrationWithoutIdConflicts(): void {
 | 
			
		||||
    // Create a node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Insert data in the d6_node:page migration mapping table to simulate a
 | 
			
		||||
    // previously migrated node.
 | 
			
		||||
    $id_map = $this->getMigration('d6_node:page')->getIdMap();
 | 
			
		||||
    $table_name = $id_map->mapTableName();
 | 
			
		||||
    $id_map->getDatabase()->insert($table_name)
 | 
			
		||||
      ->fields([
 | 
			
		||||
        'source_ids_hash' => 1,
 | 
			
		||||
        'sourceid1' => 1,
 | 
			
		||||
        'destid1' => 1,
 | 
			
		||||
      ])
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d6_node migrations for the page & article node type.
 | 
			
		||||
    // There should be no conflicts since the highest destination ID should be
 | 
			
		||||
    // equal to the highest migrated ID, as found in the aggregated mapping
 | 
			
		||||
    // tables of the two node migrations.
 | 
			
		||||
    $migrations = [
 | 
			
		||||
      $this->getMigration('d6_node:page'),
 | 
			
		||||
      $this->getMigration('d6_node:article'),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $results = (new IdAuditor())->auditMultiple($migrations);
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    foreach ($results as $result) {
 | 
			
		||||
      $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
      $this->assertTrue($result->passed());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests all migrations with no ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testAllMigrationsWithNoIdConflicts(): void {
 | 
			
		||||
    $migrations = $this->container
 | 
			
		||||
      ->get('plugin.manager.migration')
 | 
			
		||||
      ->createInstancesByTag('Drupal 6');
 | 
			
		||||
 | 
			
		||||
    // Audit all Drupal 6 migrations that support it. There should be no
 | 
			
		||||
    // conflicts since no content has been created.
 | 
			
		||||
    $results = (new IdAuditor())->auditMultiple($migrations);
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    foreach ($results as $result) {
 | 
			
		||||
      $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
      $this->assertTrue($result->passed());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests all migrations with ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testAllMigrationsWithIdConflicts(): void {
 | 
			
		||||
    // Get all Drupal 6 migrations.
 | 
			
		||||
    $migrations = $this->container
 | 
			
		||||
      ->get('plugin.manager.migration')
 | 
			
		||||
      ->createInstancesByTag('Drupal 6');
 | 
			
		||||
 | 
			
		||||
    // Create content.
 | 
			
		||||
    $this->createContent();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of all migrations. There should be conflicts since content
 | 
			
		||||
    // has been created.
 | 
			
		||||
    $conflicts = array_map(
 | 
			
		||||
      function (AuditResult $result) {
 | 
			
		||||
        return $result->passed() ? NULL : $result->getMigration()->getBaseId();
 | 
			
		||||
      },
 | 
			
		||||
      (new IdAuditor())->auditMultiple($migrations)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    $expected = [
 | 
			
		||||
      'd6_comment',
 | 
			
		||||
      'd6_custom_block',
 | 
			
		||||
      'd6_file',
 | 
			
		||||
      'd6_menu_links',
 | 
			
		||||
      'd6_node',
 | 
			
		||||
      'd6_node_complete',
 | 
			
		||||
      'd6_node_revision',
 | 
			
		||||
      'd6_taxonomy_term',
 | 
			
		||||
      'd6_term_node_revision',
 | 
			
		||||
      'd6_user',
 | 
			
		||||
      'node_translation_menu_links',
 | 
			
		||||
    ];
 | 
			
		||||
    $this->assertEmpty(array_diff(array_filter($conflicts), $expected));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests draft revisions ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testDraftRevisionIdConflicts(): void {
 | 
			
		||||
    // Create a published node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Create a draft revision.
 | 
			
		||||
    $node->moderation_state->value = 'draft';
 | 
			
		||||
    $node->setNewRevision(TRUE);
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Insert data in the d6_node_revision:page migration mapping table to
 | 
			
		||||
    // simulate a previously migrated node revision.
 | 
			
		||||
    $id_map = $this->getMigration('d6_node_revision:page')->getIdMap();
 | 
			
		||||
    $table_name = $id_map->mapTableName();
 | 
			
		||||
    $id_map->getDatabase()->insert($table_name)
 | 
			
		||||
      ->fields([
 | 
			
		||||
        'source_ids_hash' => 1,
 | 
			
		||||
        'sourceid1' => 1,
 | 
			
		||||
        'destid1' => 1,
 | 
			
		||||
      ])
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d6_node_revision migration. There should be
 | 
			
		||||
    // conflicts since a draft revision has been created.
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    $result = (new IdAuditor())->audit($this->getMigration('d6_node_revision:page'));
 | 
			
		||||
    $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
    $this->assertFalse($result->passed());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests ID conflicts for inaccessible nodes.
 | 
			
		||||
   */
 | 
			
		||||
  public function testNodeGrantsIdConflicts(): void {
 | 
			
		||||
    // Enable the node_test module to restrict access to page nodes.
 | 
			
		||||
    $this->enableModules(['node_test']);
 | 
			
		||||
 | 
			
		||||
    // Create a published node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d6_node migration. There should be conflicts
 | 
			
		||||
    // even though the new node is not accessible.
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    $result = (new IdAuditor())->audit($this->getMigration('d6_node:page'));
 | 
			
		||||
    $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
    $this->assertFalse($result->passed());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,138 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\NodeMigrateType;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for Drupal 6 migration tests.
 | 
			
		||||
 */
 | 
			
		||||
abstract class MigrateDrupal6TestBase extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  use NodeMigrateTypeTestTrait;
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'filter',
 | 
			
		||||
    'image',
 | 
			
		||||
    'link',
 | 
			
		||||
    'node',
 | 
			
		||||
    'options',
 | 
			
		||||
    'telephone',
 | 
			
		||||
    'text',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    // Add a node classic migrate table to the destination site so that tests
 | 
			
		||||
    // run by default with the classic node migrations.
 | 
			
		||||
    $this->makeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '6');
 | 
			
		||||
    $this->loadFixture($this->getFixtureFilePath());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the path to the fixture file.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getFixtureFilePath() {
 | 
			
		||||
    return __DIR__ . '/../../../fixtures/drupal6.php';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all user migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @param bool $include_pictures
 | 
			
		||||
   *   If TRUE, migrates user pictures.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateUsers($include_pictures = TRUE) {
 | 
			
		||||
    $this->executeMigrations(['d6_filter_format', 'd6_user_role']);
 | 
			
		||||
 | 
			
		||||
    if ($include_pictures) {
 | 
			
		||||
      $this->installEntitySchema('file');
 | 
			
		||||
      $this->executeMigrations([
 | 
			
		||||
        'd6_file',
 | 
			
		||||
        'd6_user_picture_file',
 | 
			
		||||
        'user_picture_field',
 | 
			
		||||
        'user_picture_field_instance',
 | 
			
		||||
        'user_picture_entity_display',
 | 
			
		||||
        'user_picture_entity_form_display',
 | 
			
		||||
      ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $this->executeMigration('d6_user');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Migrates node types.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateContentTypes() {
 | 
			
		||||
    $this->installConfig(['node']);
 | 
			
		||||
    $this->executeMigration('d6_node_type');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all field migrations.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateFields() {
 | 
			
		||||
    $this->migrateContentTypes();
 | 
			
		||||
    $this->executeMigrations([
 | 
			
		||||
      'd6_field',
 | 
			
		||||
      'd6_field_instance',
 | 
			
		||||
      'd6_field_instance_widget_settings',
 | 
			
		||||
      'd6_view_modes',
 | 
			
		||||
      'd6_field_formatter_settings',
 | 
			
		||||
      'd6_upload_field',
 | 
			
		||||
      'd6_upload_field_instance',
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all content migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @param array $include
 | 
			
		||||
   *   Extra things to include as part of the migrations. Values may be
 | 
			
		||||
   *   'revisions' or 'translations'.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateContent(array $include = []) {
 | 
			
		||||
    if (in_array('translations', $include)) {
 | 
			
		||||
      $this->executeMigrations(['language']);
 | 
			
		||||
    }
 | 
			
		||||
    $this->migrateUsers(FALSE);
 | 
			
		||||
    $this->migrateFields();
 | 
			
		||||
 | 
			
		||||
    $this->installEntitySchema('node');
 | 
			
		||||
    $this->executeMigrations(['d6_node_settings', 'd6_node']);
 | 
			
		||||
 | 
			
		||||
    if (in_array('translations', $include)) {
 | 
			
		||||
      $this->executeMigrations(['d6_node_translation']);
 | 
			
		||||
    }
 | 
			
		||||
    if (in_array('revisions', $include)) {
 | 
			
		||||
      $this->executeMigrations(['d6_node_revision']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all taxonomy migrations.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateTaxonomy() {
 | 
			
		||||
    $this->migrateContentTypes();
 | 
			
		||||
    $this->installEntitySchema('taxonomy_term');
 | 
			
		||||
    $this->executeMigrations([
 | 
			
		||||
      'd6_taxonomy_vocabulary',
 | 
			
		||||
      'd6_vocabulary_field',
 | 
			
		||||
      'd6_vocabulary_field_instance',
 | 
			
		||||
      'd6_vocabulary_entity_display',
 | 
			
		||||
      'd6_vocabulary_entity_form_display',
 | 
			
		||||
      'd6_taxonomy_term',
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the getProcess() method of all Drupal 6 migrations.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrationProcessTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    self::$modules = array_keys($this->coreModuleListDataProvider());
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that calling getProcess() on a migration does not throw an exception.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws \Exception
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetProcess(): void {
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface $plugin_manager */
 | 
			
		||||
    $plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $migrations = $plugin_manager->createInstancesByTag('Drupal 6');
 | 
			
		||||
    foreach ($migrations as $migration) {
 | 
			
		||||
      try {
 | 
			
		||||
        $process = $migration->getProcess();
 | 
			
		||||
      }
 | 
			
		||||
      catch (\Exception $e) {
 | 
			
		||||
        $this->fail(sprintf("Migration %s process failed with error: %s", $migration->label(), $e->getMessage()));
 | 
			
		||||
      }
 | 
			
		||||
      $this->assertNotNull($process);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\ValidateMigrationStateTestTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the migration state information in module.migrate_drupal.yml.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class ValidateMigrationStateTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  use ValidateMigrationStateTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    // Test migrations states.
 | 
			
		||||
    'migrate_state_finished_test',
 | 
			
		||||
    'migrate_state_not_finished_test',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,40 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate\Exception\RequirementsException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests check requirements for variable translation source plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class VariableTranslationCheckRequirementsTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['config_translation'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->sourceDatabase->schema()->dropTable('i18n_variable');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests exception in thrown when the i18n_variable table does not exist.
 | 
			
		||||
   */
 | 
			
		||||
  public function testCheckRequirements(): void {
 | 
			
		||||
    $this->expectException(RequirementsException::class);
 | 
			
		||||
    $this->expectExceptionMessage("Source database table 'i18n_variable' does not exist");
 | 
			
		||||
    $this->getMigration('d6_system_maintenance_translation')
 | 
			
		||||
      ->getSourcePlugin()
 | 
			
		||||
      ->checkRequirements();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,367 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\comment\Entity\CommentType;
 | 
			
		||||
use Drupal\field\Plugin\migrate\source\d7\FieldInstance;
 | 
			
		||||
use Drupal\migrate_drupal\FieldDiscoveryInterface;
 | 
			
		||||
use Drupal\node\Entity\NodeType;
 | 
			
		||||
use Drupal\taxonomy\Entity\Vocabulary;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\FieldDiscoveryTestTrait;
 | 
			
		||||
use Drupal\field_discovery_test\FieldDiscoveryTestClass;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore filefield imagelink entityreference nodelink spamspan
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test FieldDiscovery Service against Drupal 7.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @group #slow
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\FieldDiscovery
 | 
			
		||||
 */
 | 
			
		||||
class FieldDiscoveryTest extends MigrateDrupal7TestBase {
 | 
			
		||||
 | 
			
		||||
  use FieldDiscoveryTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'comment',
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'datetime_range',
 | 
			
		||||
    'file',
 | 
			
		||||
    'image',
 | 
			
		||||
    'link',
 | 
			
		||||
    'node',
 | 
			
		||||
    'system',
 | 
			
		||||
    'taxonomy',
 | 
			
		||||
    'telephone',
 | 
			
		||||
    'text',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The Field discovery service.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\FieldDiscoveryInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $fieldDiscovery;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The field plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $fieldPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migration plugin manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The logger.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\Core\Logger\LoggerChannelInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $logger;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->installConfig(static::$modules);
 | 
			
		||||
    $node_types = [
 | 
			
		||||
      'page' => 'comment_node_page',
 | 
			
		||||
      'article' => 'comment_node_article',
 | 
			
		||||
      'blog' => 'comment_node_blog',
 | 
			
		||||
      'book' => 'comment_node_book',
 | 
			
		||||
      'et' => 'comment_node_et',
 | 
			
		||||
      'forum' => 'comment_forum',
 | 
			
		||||
      'test_content_type' => 'comment_node_test_content_type',
 | 
			
		||||
      'a_thirty_two_character_type_name' => 'a_thirty_two_character_type_name',
 | 
			
		||||
    ];
 | 
			
		||||
    foreach ($node_types as $node_type => $comment_type) {
 | 
			
		||||
      NodeType::create([
 | 
			
		||||
        'type' => $node_type,
 | 
			
		||||
        'name' => $this->randomString(),
 | 
			
		||||
      ])->save();
 | 
			
		||||
 | 
			
		||||
      CommentType::create([
 | 
			
		||||
        'id' => $comment_type,
 | 
			
		||||
        'label' => $this->randomString(),
 | 
			
		||||
        'target_entity_type_id' => 'node',
 | 
			
		||||
      ])->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Vocabulary::create(['vid' => 'test_vocabulary', 'name' => 'Test'])->save();
 | 
			
		||||
    $this->executeMigrations([
 | 
			
		||||
      'd7_field',
 | 
			
		||||
      'd7_comment_type',
 | 
			
		||||
      'd7_taxonomy_vocabulary',
 | 
			
		||||
      'd7_field_instance',
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    $this->fieldDiscovery = $this->container->get('migrate_drupal.field_discovery');
 | 
			
		||||
    $this->migrationPluginManager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $this->fieldPluginManager = $this->container->get('plugin.manager.migrate.field');
 | 
			
		||||
    $this->logger = $this->container->get('logger.channel.migrate_drupal');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the addAllFieldProcesses method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::addAllFieldProcesses
 | 
			
		||||
   */
 | 
			
		||||
  public function testAddAllFieldProcesses(): void {
 | 
			
		||||
    $expected_process_keys = [
 | 
			
		||||
      'comment_body',
 | 
			
		||||
      'field_integer',
 | 
			
		||||
      'body',
 | 
			
		||||
      'field_text_plain',
 | 
			
		||||
      'field_text_filtered',
 | 
			
		||||
      'field_text_plain_filtered',
 | 
			
		||||
      'field_text_long_plain',
 | 
			
		||||
      'field_text_long_filtered',
 | 
			
		||||
      'field_text_long_plain_filtered',
 | 
			
		||||
      'field_text_sum_plain',
 | 
			
		||||
      'field_text_sum_filtered',
 | 
			
		||||
      'field_text_sum_plain_filtered',
 | 
			
		||||
      'field_tags',
 | 
			
		||||
      'field_image',
 | 
			
		||||
      'field_link',
 | 
			
		||||
      'field_reference',
 | 
			
		||||
      'field_reference_2',
 | 
			
		||||
      'taxonomy_forums',
 | 
			
		||||
      'field_boolean',
 | 
			
		||||
      'field_email',
 | 
			
		||||
      'field_phone',
 | 
			
		||||
      'field_date',
 | 
			
		||||
      'field_date_with_end_time',
 | 
			
		||||
      'field_file',
 | 
			
		||||
      'field_float',
 | 
			
		||||
      'field_images',
 | 
			
		||||
      'field_text_list',
 | 
			
		||||
      'field_integer_list',
 | 
			
		||||
      'field_long_text',
 | 
			
		||||
      'field_term_reference',
 | 
			
		||||
      'field_text',
 | 
			
		||||
      'field_node_entityreference',
 | 
			
		||||
      'field_user_entityreference',
 | 
			
		||||
      'field_term_entityreference',
 | 
			
		||||
      'field_node_reference',
 | 
			
		||||
      'field_user_reference',
 | 
			
		||||
      'field_private_file',
 | 
			
		||||
      'field_datetime_without_time',
 | 
			
		||||
      'field_date_without_time',
 | 
			
		||||
      'field_float_list',
 | 
			
		||||
      'field_training',
 | 
			
		||||
      'field_sector',
 | 
			
		||||
      'field_chancellor',
 | 
			
		||||
    ];
 | 
			
		||||
    $this->assertFieldProcessKeys($this->fieldDiscovery, $this->migrationPluginManager, '7', $expected_process_keys);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the addAllFieldProcesses method for field migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::addAllFieldProcesses
 | 
			
		||||
   * @dataProvider addAllFieldProcessesAltersData
 | 
			
		||||
   */
 | 
			
		||||
  public function testAddAllFieldProcessesAlters($field_plugin_method, $expected_process): void {
 | 
			
		||||
    $this->assertFieldProcess($this->fieldDiscovery, $this->migrationPluginManager, FieldDiscoveryInterface::DRUPAL_7, $field_plugin_method, $expected_process);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testAddAllFieldProcessesAlters.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function addAllFieldProcessesAltersData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Field Instance' => [
 | 
			
		||||
        'field_plugin_method' => 'alterFieldInstanceMigration',
 | 
			
		||||
        'expected_process' => [
 | 
			
		||||
          'settings/title' => [
 | 
			
		||||
            0 => [
 | 
			
		||||
              'plugin' => 'static_map',
 | 
			
		||||
              'source' => 'settings/title',
 | 
			
		||||
              'bypass' => TRUE,
 | 
			
		||||
              'map' => [
 | 
			
		||||
                'disabled' => 0,
 | 
			
		||||
                'optional' => 1,
 | 
			
		||||
                'required' => 2,
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Field Formatter' => [
 | 
			
		||||
        'field_plugin_method' => 'alterFieldFormatterMigration',
 | 
			
		||||
        'expected_process' => [
 | 
			
		||||
          'options/type' => [
 | 
			
		||||
            0 => [
 | 
			
		||||
              'map' => [
 | 
			
		||||
                'taxonomy_term_reference' => [
 | 
			
		||||
                  'taxonomy_term_reference_link' => 'entity_reference_label',
 | 
			
		||||
                  'taxonomy_term_reference_plain' => 'entity_reference_label',
 | 
			
		||||
                  'taxonomy_term_reference_rss_category' => 'entity_reference_label',
 | 
			
		||||
                  'i18n_taxonomy_term_reference_link' => 'entity_reference_label',
 | 
			
		||||
                  'i18n_taxonomy_term_reference_plain' => 'entity_reference_label',
 | 
			
		||||
                  'entityreference_entity_view' => 'entity_reference_entity_view',
 | 
			
		||||
                ],
 | 
			
		||||
                'link_field' => [
 | 
			
		||||
                  'link_default' => 'link',
 | 
			
		||||
                  'link_title_plain' => 'link',
 | 
			
		||||
                  'link_host' => 'link',
 | 
			
		||||
                  'link_url' => 'link',
 | 
			
		||||
                  'link_plain' => 'link',
 | 
			
		||||
                  'link_absolute' => 'link',
 | 
			
		||||
                  'link_domain' => 'link',
 | 
			
		||||
                  'link_no_protocol' => 'link',
 | 
			
		||||
                  'link_short' => 'link',
 | 
			
		||||
                  'link_label' => 'link',
 | 
			
		||||
                  'link_separate' => 'link_separate',
 | 
			
		||||
                ],
 | 
			
		||||
                'entityreference' => [
 | 
			
		||||
                  'entityreference_label' => 'entity_reference_label',
 | 
			
		||||
                  'entityreference_entity_id' => 'entity_reference_entity_id',
 | 
			
		||||
                  'entityreference_entity_view' => 'entity_reference_entity_view',
 | 
			
		||||
                ],
 | 
			
		||||
                'node_reference' => [
 | 
			
		||||
                  'node_reference_default' => 'entity_reference_label',
 | 
			
		||||
                  'node_reference_plain' => 'entity_reference_label',
 | 
			
		||||
                  'node_reference_nid' => 'entity_reference_entity_id',
 | 
			
		||||
                  'node_reference_node' => 'entity_reference_entity_view',
 | 
			
		||||
                  'node_reference_path' => 'entity_reference_label',
 | 
			
		||||
                ],
 | 
			
		||||
                'user_reference' => [
 | 
			
		||||
                  'user_reference_default' => 'entity_reference_label',
 | 
			
		||||
                  'user_reference_plain' => 'entity_reference_label',
 | 
			
		||||
                  'user_reference_uid' => 'entity_reference_entity_id',
 | 
			
		||||
                  'user_reference_user' => 'entity_reference_entity_view',
 | 
			
		||||
                  'user_reference_path' => 'entity_reference_label',
 | 
			
		||||
                ],
 | 
			
		||||
                'file' => [
 | 
			
		||||
                  'default' => 'file_default',
 | 
			
		||||
                  'url_plain' => 'file_url_plain',
 | 
			
		||||
                  'path_plain' => 'file_url_plain',
 | 
			
		||||
                  'image_plain' => 'image',
 | 
			
		||||
                  'image_nodelink' => 'image',
 | 
			
		||||
                  'image_imagelink' => 'image',
 | 
			
		||||
                ],
 | 
			
		||||
                'datetime' => [
 | 
			
		||||
                  'date_default' => 'datetime_default',
 | 
			
		||||
                  'format_interval' => 'datetime_time_ago',
 | 
			
		||||
                  'date_plain' => 'datetime_plain',
 | 
			
		||||
                ],
 | 
			
		||||
                'email' => [
 | 
			
		||||
                  'email_formatter_default' => 'email_mailto',
 | 
			
		||||
                  'email_formatter_contact' => 'basic_string',
 | 
			
		||||
                  'email_formatter_plain' => 'basic_string',
 | 
			
		||||
                  'email_formatter_spamspan' => 'basic_string',
 | 
			
		||||
                  'email_default' => 'email_mailto',
 | 
			
		||||
                  'email_contact' => 'basic_string',
 | 
			
		||||
                  'email_plain' => 'basic_string',
 | 
			
		||||
                  'email_spamspan' => 'basic_string',
 | 
			
		||||
                ],
 | 
			
		||||
                'phone' => [
 | 
			
		||||
                  'phone' => 'basic_string',
 | 
			
		||||
                ],
 | 
			
		||||
                'telephone' => [
 | 
			
		||||
                  'text_plain' => 'string',
 | 
			
		||||
                  'telephone_link' => 'telephone_link',
 | 
			
		||||
                ],
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Field Widget' => [
 | 
			
		||||
        'field_plugin_method' => 'alterFieldWidgetMigration',
 | 
			
		||||
        'expected_process' => [
 | 
			
		||||
          'options/type' => [
 | 
			
		||||
            'type' => [
 | 
			
		||||
              'map' => [
 | 
			
		||||
                'd7_text' => 'd7_text_default',
 | 
			
		||||
                'number_default' => 'number_default_default',
 | 
			
		||||
                'taxonomy_term_reference' => 'taxonomy_term_reference_default',
 | 
			
		||||
                'image' => 'image_default',
 | 
			
		||||
                'image_miw' => 'image_image',
 | 
			
		||||
                'link_field' => 'link_default',
 | 
			
		||||
                'entityreference' => 'entityreference_default',
 | 
			
		||||
                'node_reference_select' => 'options_select',
 | 
			
		||||
                'node_reference_buttons' => 'options_buttons',
 | 
			
		||||
                'node_reference_autocomplete' => 'entity_reference_autocomplete_tags',
 | 
			
		||||
                'user_reference_select' => 'options_select',
 | 
			
		||||
                'user_reference_buttons' => 'options_buttons',
 | 
			
		||||
                'user_reference_autocomplete' => 'entity_reference_autocomplete_tags',
 | 
			
		||||
                'list' => 'list_default',
 | 
			
		||||
                'file_mfw' => 'file_generic',
 | 
			
		||||
                'filefield_widget' => 'file_generic',
 | 
			
		||||
                'date' => 'datetime_default',
 | 
			
		||||
                'datetime' => 'datetime_default',
 | 
			
		||||
                'datestamp' => 'datetime_timestamp',
 | 
			
		||||
                'email_textfield' => 'email_default',
 | 
			
		||||
                'phone' => 'phone_default',
 | 
			
		||||
              ],
 | 
			
		||||
            ],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the getAllFields method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getAllFields
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetAllFields(): void {
 | 
			
		||||
    $field_discovery_test = new FieldDiscoveryTestClass($this->fieldPluginManager, $this->migrationPluginManager, $this->logger);
 | 
			
		||||
    $actual_fields = $field_discovery_test->getAllFields('7');
 | 
			
		||||
    $this->assertSame(['comment', 'node', 'user', 'taxonomy_term'], array_keys($actual_fields));
 | 
			
		||||
    $this->assertArrayHasKey('test_vocabulary', $actual_fields['taxonomy_term']);
 | 
			
		||||
    $this->assertArrayHasKey('user', $actual_fields['user']);
 | 
			
		||||
    $this->assertArrayHasKey('test_content_type', $actual_fields['node']);
 | 
			
		||||
    $this->assertCount(8, $actual_fields['node']);
 | 
			
		||||
    $this->assertCount(8, $actual_fields['comment']);
 | 
			
		||||
    $this->assertCount(23, $actual_fields['node']['test_content_type']);
 | 
			
		||||
    foreach ($actual_fields as $entity_type_id => $bundles) {
 | 
			
		||||
      foreach ($bundles as $bundle => $fields) {
 | 
			
		||||
        foreach ($fields as $field_info) {
 | 
			
		||||
          $this->assertArrayHasKey('field_definition', $field_info);
 | 
			
		||||
          $this->assertEquals($entity_type_id, $field_info['entity_type']);
 | 
			
		||||
          $this->assertEquals($bundle, $field_info['bundle']);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the getSourcePlugin method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getSourcePlugin
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetSourcePlugin(): void {
 | 
			
		||||
    $this->assertSourcePlugin('7', FieldInstance::class, [
 | 
			
		||||
      'requirements_met' => TRUE,
 | 
			
		||||
      'id' => 'd7_field_instance',
 | 
			
		||||
      'source_module' => 'field',
 | 
			
		||||
      'class' => 'Drupal\\field\\Plugin\\migrate\\source\\d7\\FieldInstance',
 | 
			
		||||
      'provider' => [
 | 
			
		||||
        0 => 'field',
 | 
			
		||||
        1 => 'migrate_drupal',
 | 
			
		||||
        2 => 'migrate',
 | 
			
		||||
        4 => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,136 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\node\Entity\Node;
 | 
			
		||||
use Drupal\Tests\file\Kernel\Migrate\d7\FileMigrationSetupTrait;
 | 
			
		||||
use Drupal\user\Entity\User;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests follow-up migrations.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @group #slow
 | 
			
		||||
 */
 | 
			
		||||
class FollowUpMigrationsTest extends MigrateDrupal7TestBase {
 | 
			
		||||
 | 
			
		||||
  use FileMigrationSetupTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    'content_translation',
 | 
			
		||||
    'comment',
 | 
			
		||||
    'datetime',
 | 
			
		||||
    'datetime_range',
 | 
			
		||||
    'image',
 | 
			
		||||
    'language',
 | 
			
		||||
    'link',
 | 
			
		||||
    'menu_ui',
 | 
			
		||||
    'node',
 | 
			
		||||
    'taxonomy',
 | 
			
		||||
    'telephone',
 | 
			
		||||
    'text',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    $this->fileMigrationSetup();
 | 
			
		||||
 | 
			
		||||
    $this->installEntitySchema('comment');
 | 
			
		||||
    $this->installSchema('node', ['node_access']);
 | 
			
		||||
 | 
			
		||||
    $this->migrateFields();
 | 
			
		||||
    $this->migrateUsers();
 | 
			
		||||
    $this->executeMigrations([
 | 
			
		||||
      'language',
 | 
			
		||||
      'd7_language_content_settings',
 | 
			
		||||
      'd7_taxonomy_vocabulary',
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function getFileMigrationInfo(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      'path' => 'public://sites/default/files/cube.jpeg',
 | 
			
		||||
      'size' => 3620,
 | 
			
		||||
      'base_path' => 'public://',
 | 
			
		||||
      'plugin_id' => 'd7_file',
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests entity reference translations.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerTestEntityReferenceTranslations
 | 
			
		||||
   */
 | 
			
		||||
  public function testEntityReferenceTranslations($node_migrations): void {
 | 
			
		||||
    $this->executeMigrations($node_migrations);
 | 
			
		||||
 | 
			
		||||
    // Test the entity reference field before the follow-up migrations.
 | 
			
		||||
    $node = Node::load(2);
 | 
			
		||||
    $this->assertSame('5', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('6', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('is');
 | 
			
		||||
    $this->assertSame('4', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('4', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $node = Node::load(4);
 | 
			
		||||
    $this->assertSame('3', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('3', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('en');
 | 
			
		||||
    $this->assertSame('2', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('2', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $user = User::load(2);
 | 
			
		||||
    $this->assertSame('3', $user->get('field_reference')->target_id);
 | 
			
		||||
 | 
			
		||||
    // Run the follow-up migrations.
 | 
			
		||||
    $migration_plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $migration_plugin_manager->clearCachedDefinitions();
 | 
			
		||||
    $follow_up_migrations = $migration_plugin_manager->createInstances('d7_entity_reference_translation');
 | 
			
		||||
    $this->executeMigrations(array_keys($follow_up_migrations));
 | 
			
		||||
 | 
			
		||||
    // Test the entity reference field after the follow-up migrations.
 | 
			
		||||
    $node = Node::load(2);
 | 
			
		||||
    $this->assertSame('4', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('6', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('is');
 | 
			
		||||
    $this->assertSame('4', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('4', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $node = Node::load(4);
 | 
			
		||||
    $this->assertSame('2', $node->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('2', $node->get('field_reference_2')->target_id);
 | 
			
		||||
    $translation = $node->getTranslation('en');
 | 
			
		||||
    $this->assertSame('2', $translation->get('field_reference')->target_id);
 | 
			
		||||
    $this->assertSame('2', $translation->get('field_reference_2')->target_id);
 | 
			
		||||
 | 
			
		||||
    $user = User::load(2);
 | 
			
		||||
    $this->assertSame('2', $user->get('field_reference')->target_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Data provider for testEntityReferenceTranslations().
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerTestEntityReferenceTranslations() {
 | 
			
		||||
    return [
 | 
			
		||||
      [
 | 
			
		||||
        ['d7_node', 'd7_node_translation'],
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        ['d7_node_complete'],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,208 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate\Audit\AuditResult;
 | 
			
		||||
use Drupal\migrate\Audit\IdAuditor;
 | 
			
		||||
use Drupal\node\Entity\Node;
 | 
			
		||||
use Drupal\node\Entity\NodeType;
 | 
			
		||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the migration auditor for ID conflicts.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @group #slow
 | 
			
		||||
 */
 | 
			
		||||
class MigrateDrupal7AuditIdsTest extends MigrateDrupal7TestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
  use CreateTestContentEntitiesTrait;
 | 
			
		||||
  use ContentModerationTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    // Enable all modules.
 | 
			
		||||
    self::$modules = array_keys($this->coreModuleListDataProvider());
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    // Install required entity schemas.
 | 
			
		||||
    $this->installEntitySchema('block_content');
 | 
			
		||||
    $this->installEntitySchema('comment');
 | 
			
		||||
    $this->installEntitySchema('file');
 | 
			
		||||
    $this->installEntitySchema('menu_link_content');
 | 
			
		||||
    $this->installEntitySchema('node');
 | 
			
		||||
    $this->installEntitySchema('path_alias');
 | 
			
		||||
    $this->installEntitySchema('taxonomy_term');
 | 
			
		||||
    $this->installEntitySchema('user');
 | 
			
		||||
 | 
			
		||||
    // Install required schemas.
 | 
			
		||||
    $this->installSchema('dblog', ['watchdog']);
 | 
			
		||||
    $this->installSchema('node', ['node_access']);
 | 
			
		||||
    $this->installSchema('search', ['search_dataset']);
 | 
			
		||||
 | 
			
		||||
    // Enable content moderation for nodes of type page.
 | 
			
		||||
    $this->installEntitySchema('content_moderation_state');
 | 
			
		||||
    $this->installConfig('content_moderation');
 | 
			
		||||
    NodeType::create([
 | 
			
		||||
      'type' => 'page',
 | 
			
		||||
      'name' => 'Page',
 | 
			
		||||
    ])->save();
 | 
			
		||||
    $workflow = $this->createEditorialWorkflow();
 | 
			
		||||
    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
 | 
			
		||||
    $workflow->save();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests multiple migrations to the same destination with no ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMultipleMigrationWithoutIdConflicts(): void {
 | 
			
		||||
    // Create a node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Insert data in the d7_node:page migration mapping table to simulate a
 | 
			
		||||
    // previously migrated node.
 | 
			
		||||
    $id_map = $this->getMigration('d7_node:page')->getIdMap();
 | 
			
		||||
    $table_name = $id_map->mapTableName();
 | 
			
		||||
    $id_map->getDatabase()->insert($table_name)
 | 
			
		||||
      ->fields([
 | 
			
		||||
        'source_ids_hash' => 1,
 | 
			
		||||
        'sourceid1' => 1,
 | 
			
		||||
        'destid1' => 1,
 | 
			
		||||
      ])
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d7_node migrations for the page & article node type.
 | 
			
		||||
    // There should be no conflicts since the highest destination ID should be
 | 
			
		||||
    // equal to the highest migrated ID, as found in the aggregated mapping
 | 
			
		||||
    // tables of the two node migrations.
 | 
			
		||||
    $migrations = [
 | 
			
		||||
      $this->getMigration('d7_node:page'),
 | 
			
		||||
      $this->getMigration('d7_node:article'),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $results = (new IdAuditor())->auditMultiple($migrations);
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    foreach ($results as $result) {
 | 
			
		||||
      $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
      $this->assertTrue($result->passed());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests all migrations with no ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testAllMigrationsWithNoIdConflicts(): void {
 | 
			
		||||
    $migrations = $this->container
 | 
			
		||||
      ->get('plugin.manager.migration')
 | 
			
		||||
      ->createInstancesByTag('Drupal 7');
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of all Drupal 7 migrations. There should be no conflicts
 | 
			
		||||
    // since no content has been created.
 | 
			
		||||
    $results = (new IdAuditor())->auditMultiple($migrations);
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    foreach ($results as $result) {
 | 
			
		||||
      $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
      $this->assertTrue($result->passed());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests all migrations with ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testAllMigrationsWithIdConflicts(): void {
 | 
			
		||||
    $migrations = $this->container
 | 
			
		||||
      ->get('plugin.manager.migration')
 | 
			
		||||
      ->createInstancesByTag('Drupal 7');
 | 
			
		||||
 | 
			
		||||
    // Create content.
 | 
			
		||||
    $this->createContent();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of all Drupal 7 migrations. There should be conflicts since
 | 
			
		||||
    // content has been created.
 | 
			
		||||
    $conflicts = array_map(
 | 
			
		||||
      function (AuditResult $result) {
 | 
			
		||||
        return $result->passed() ? NULL : $result->getMigration()->getBaseId();
 | 
			
		||||
      },
 | 
			
		||||
      (new IdAuditor())->auditMultiple($migrations)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    $expected = [
 | 
			
		||||
      'd7_comment',
 | 
			
		||||
      'd7_custom_block',
 | 
			
		||||
      'd7_file',
 | 
			
		||||
      'd7_file_private',
 | 
			
		||||
      'd7_menu_links',
 | 
			
		||||
      'd7_node',
 | 
			
		||||
      'd7_node_complete',
 | 
			
		||||
      'd7_node_revision',
 | 
			
		||||
      'd7_taxonomy_term',
 | 
			
		||||
      'd7_user',
 | 
			
		||||
      'node_translation_menu_links',
 | 
			
		||||
    ];
 | 
			
		||||
    $this->assertEmpty(array_diff(array_filter($conflicts), $expected));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests draft revisions ID conflicts.
 | 
			
		||||
   */
 | 
			
		||||
  public function testDraftRevisionIdConflicts(): void {
 | 
			
		||||
    // Create a published node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Create a draft revision.
 | 
			
		||||
    $node->moderation_state->value = 'draft';
 | 
			
		||||
    $node->setNewRevision(TRUE);
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Insert data in the d7_node_revision:page migration mapping table to
 | 
			
		||||
    // simulate a previously migrated node revision.
 | 
			
		||||
    $id_map = $this->getMigration('d7_node_revision:page')->getIdMap();
 | 
			
		||||
    $table_name = $id_map->mapTableName();
 | 
			
		||||
    $id_map->getDatabase()->insert($table_name)
 | 
			
		||||
      ->fields([
 | 
			
		||||
        'source_ids_hash' => 1,
 | 
			
		||||
        'sourceid1' => 1,
 | 
			
		||||
        'destid1' => 1,
 | 
			
		||||
      ])
 | 
			
		||||
      ->execute();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d7_node_revision migration. There should be
 | 
			
		||||
    // conflicts since a draft revision has been created.
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    $result = (new IdAuditor())->audit($this->getMigration('d7_node_revision:page'));
 | 
			
		||||
    $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
    $this->assertFalse($result->passed());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests ID conflicts for inaccessible nodes.
 | 
			
		||||
   */
 | 
			
		||||
  public function testNodeGrantsIdConflicts(): void {
 | 
			
		||||
    // Enable the node_test module to restrict access to page nodes.
 | 
			
		||||
    $this->enableModules(['node_test']);
 | 
			
		||||
 | 
			
		||||
    // Create a published node of type page.
 | 
			
		||||
    $node = Node::create(['type' => 'page', 'title' => 'foo']);
 | 
			
		||||
    $node->moderation_state->value = 'published';
 | 
			
		||||
    $node->save();
 | 
			
		||||
 | 
			
		||||
    // Audit the IDs of the d7_node migration. There should be conflicts
 | 
			
		||||
    // even though the new node is not accessible.
 | 
			
		||||
    /** @var \Drupal\migrate\Audit\AuditResult $result */
 | 
			
		||||
    $result = (new IdAuditor())->audit($this->getMigration('d7_node:page'));
 | 
			
		||||
    $this->assertInstanceOf(AuditResult::class, $result);
 | 
			
		||||
    $this->assertFalse($result->passed());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,117 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\NodeMigrateType;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\NodeMigrateTypeTestTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for Drupal 7 migration tests.
 | 
			
		||||
 */
 | 
			
		||||
abstract class MigrateDrupal7TestBase extends MigrateDrupalTestBase {
 | 
			
		||||
 | 
			
		||||
  use NodeMigrateTypeTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    // Add a node classic migrate table to the destination site so that tests
 | 
			
		||||
    // run by default with the classic node migrations.
 | 
			
		||||
    $this->makeNodeMigrateMapTable(NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, '7');
 | 
			
		||||
    $this->loadFixture($this->getFixtureFilePath());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the path to the fixture file.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getFixtureFilePath() {
 | 
			
		||||
    return __DIR__ . '/../../../fixtures/drupal7.php';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all field migrations.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateFields() {
 | 
			
		||||
    $this->executeMigration('d7_field');
 | 
			
		||||
    $this->migrateContentTypes();
 | 
			
		||||
    $this->migrateCommentTypes();
 | 
			
		||||
    $this->executeMigrations(['d7_taxonomy_vocabulary', 'd7_field_instance']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all user migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @param bool $include_pictures
 | 
			
		||||
   *   (optional) If TRUE, migrates user pictures. Defaults to TRUE.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateUsers($include_pictures = TRUE) {
 | 
			
		||||
    $migrations = ['d7_user_role', 'd7_user'];
 | 
			
		||||
 | 
			
		||||
    if ($include_pictures) {
 | 
			
		||||
      // Prepare to migrate user pictures as well.
 | 
			
		||||
      $this->installEntitySchema('file');
 | 
			
		||||
      $migrations = array_merge([
 | 
			
		||||
        'user_picture_field',
 | 
			
		||||
        'user_picture_field_instance',
 | 
			
		||||
      ], $migrations);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $this->executeMigrations($migrations);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Migrates node types.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateContentTypes() {
 | 
			
		||||
    $this->installConfig(['node']);
 | 
			
		||||
    $this->installEntitySchema('node');
 | 
			
		||||
    $this->executeMigration('d7_node_type');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Migrates comment types.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateCommentTypes() {
 | 
			
		||||
    $this->installConfig(['comment']);
 | 
			
		||||
    $this->executeMigration('d7_comment_type');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all content migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @param bool $include_revisions
 | 
			
		||||
   *   (optional) If TRUE, migrates node revisions. Defaults to FALSE.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateContent($include_revisions = FALSE) {
 | 
			
		||||
    $this->migrateContentTypes();
 | 
			
		||||
    $this->migrateCommentTypes();
 | 
			
		||||
 | 
			
		||||
    $this->migrateUsers(FALSE);
 | 
			
		||||
    // Uses executeMigrations() rather than executeMigration() because the
 | 
			
		||||
    // former includes all of the migration derivatives, e.g.
 | 
			
		||||
    // d7_node:article.
 | 
			
		||||
    $this->executeMigrations(['d7_node']);
 | 
			
		||||
 | 
			
		||||
    if ($include_revisions) {
 | 
			
		||||
      $this->executeMigrations(['d7_node_revision']);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes all taxonomy term migrations.
 | 
			
		||||
   */
 | 
			
		||||
  protected function migrateTaxonomyTerms() {
 | 
			
		||||
    $this->installEntitySchema('taxonomy_term');
 | 
			
		||||
    $this->migrateFields();
 | 
			
		||||
    // Uses executeMigrations() rather than executeMigration() because the
 | 
			
		||||
    // former includes all of the migration derivatives, e.g.
 | 
			
		||||
    // d7_taxonomy_term:tags.
 | 
			
		||||
    $this->executeMigrations(['d7_taxonomy_term']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the getProcess() method of all Drupal 7 migrations.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrationProcessTest extends MigrateDrupal7TestBase {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    self::$modules = array_keys($this->coreModuleListDataProvider());
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that calling getProcess() on a migration does not throw an exception.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws \Exception
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetProcess(): void {
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface $plugin_manager */
 | 
			
		||||
    $plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $migrations = $plugin_manager->createInstancesByTag('Drupal 7');
 | 
			
		||||
    foreach ($migrations as $migration) {
 | 
			
		||||
      try {
 | 
			
		||||
        $process = $migration->getProcess();
 | 
			
		||||
      }
 | 
			
		||||
      catch (\Exception $e) {
 | 
			
		||||
        $this->fail(sprintf("Migration %s process failed with error: %s", $migration->label(), $e->getMessage()));
 | 
			
		||||
      }
 | 
			
		||||
      $this->assertNotNull($process);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\d7;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Traits\ValidateMigrationStateTestTrait;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the migration state information in module.migrate_drupal.yml.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class ValidateMigrationStateTest extends MigrateDrupal7TestBase {
 | 
			
		||||
 | 
			
		||||
  use ValidateMigrationStateTestTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = [
 | 
			
		||||
    // Test migrations states.
 | 
			
		||||
    'migrate_state_finished_test',
 | 
			
		||||
    'migrate_state_not_finished_test',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,48 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Kernel\dependencies;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate\Exception\RequirementsException;
 | 
			
		||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Ensure the consistency among the dependencies for migrate.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrateDependenciesTest extends MigrateDrupal6TestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected static $modules = ['comment'];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests that the order is correct when loading several migrations.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMigrationDependenciesOrder(): void {
 | 
			
		||||
    $migration_items = ['d6_comment', 'd6_filter_format', 'd6_node:page'];
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\RequirementsInterface[] $migrations */
 | 
			
		||||
    $migrations = $this->container->get('plugin.manager.migration')->createInstances($migration_items);
 | 
			
		||||
    $expected_order = ['d6_filter_format', 'd6_node:page', 'd6_comment'];
 | 
			
		||||
    $this->assertSame(array_keys($migrations), $expected_order);
 | 
			
		||||
 | 
			
		||||
    // Migration dependencies for comment include dependencies for node
 | 
			
		||||
    // migration as well. checkRequirements does not include migrations with
 | 
			
		||||
    // no rows in the exception, so node types with no content aren't included
 | 
			
		||||
    // in the list.
 | 
			
		||||
    try {
 | 
			
		||||
      $migrations['d6_comment']->checkRequirements();
 | 
			
		||||
      $this->fail("The requirements check failed to throw a RequirementsException");
 | 
			
		||||
    }
 | 
			
		||||
    catch (RequirementsException $e) {
 | 
			
		||||
      $this->assertEquals('Missing migrations d6_comment_type, d6_user, d6_comment_entity_display, d6_node_type, d6_comment_entity_form_display, d6_node_settings, d6_filter_format, d6_node:company, d6_node:employee, d6_node:forum, d6_node:page, d6_node:story, d6_node:test_planet.', $e->getMessage());
 | 
			
		||||
    }
 | 
			
		||||
    catch (\Exception) {
 | 
			
		||||
      $this->fail("The requirements check threw an exception, but it was not the expected RequirementsException");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,38 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Traits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test trait that provides instances of Drupal 6 and Drupal 7 migrations.
 | 
			
		||||
 */
 | 
			
		||||
trait CreateMigrationsTrait {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create instances of all Drupal 6 migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @return \Drupal\migrate\Plugin\MigrationInterface[]
 | 
			
		||||
   *   The migrations
 | 
			
		||||
   */
 | 
			
		||||
  public function drupal6Migrations() {
 | 
			
		||||
    $dirs = \Drupal::service('module_handler')->getModuleDirectories();
 | 
			
		||||
    $migrate_drupal_directory = $dirs['migrate_drupal'];
 | 
			
		||||
    $this->loadFixture("$migrate_drupal_directory/tests/fixtures/drupal6.php");
 | 
			
		||||
    return \Drupal::service('plugin.manager.migration')->createInstancesByTag('Drupal 6');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create instances of all Drupal 7 migrations.
 | 
			
		||||
   *
 | 
			
		||||
   * @return \Drupal\migrate\Plugin\MigrationInterface[]
 | 
			
		||||
   *   The migrations
 | 
			
		||||
   */
 | 
			
		||||
  public function drupal7Migrations() {
 | 
			
		||||
    $dirs = \Drupal::service('module_handler')->getModuleDirectories();
 | 
			
		||||
    $migrate_drupal_directory = $dirs['migrate_drupal'];
 | 
			
		||||
    $this->loadFixture("$migrate_drupal_directory/tests/fixtures/drupal7.php");
 | 
			
		||||
    return \Drupal::service('plugin.manager.migration')->createInstancesByTag('Drupal 7');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,180 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Traits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides helper methods for creating test content.
 | 
			
		||||
 */
 | 
			
		||||
trait CreateTestContentEntitiesTrait {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets required modules.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   An array of required modules.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getRequiredModules(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      'block_content',
 | 
			
		||||
      'comment',
 | 
			
		||||
      'field',
 | 
			
		||||
      'file',
 | 
			
		||||
      'link',
 | 
			
		||||
      'menu_link_content',
 | 
			
		||||
      'migrate_drupal',
 | 
			
		||||
      'node',
 | 
			
		||||
      'options',
 | 
			
		||||
      'system',
 | 
			
		||||
      'taxonomy',
 | 
			
		||||
      'text',
 | 
			
		||||
      'user',
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create several pieces of generic content.
 | 
			
		||||
   */
 | 
			
		||||
  protected function createContent() {
 | 
			
		||||
    $entity_type_manager = \Drupal::entityTypeManager();
 | 
			
		||||
 | 
			
		||||
    // Create a block content.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('block_content')) {
 | 
			
		||||
      $block = $entity_type_manager->getStorage('block_content')->create([
 | 
			
		||||
        'info' => 'block',
 | 
			
		||||
        'type' => 'block',
 | 
			
		||||
      ]);
 | 
			
		||||
      $block->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a node.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('node')) {
 | 
			
		||||
      $node = $entity_type_manager->getStorage('node')->create([
 | 
			
		||||
        'type' => 'page',
 | 
			
		||||
        'title' => 'page',
 | 
			
		||||
      ]);
 | 
			
		||||
      $node->save();
 | 
			
		||||
 | 
			
		||||
      // Create a comment.
 | 
			
		||||
      if ($entity_type_manager->hasDefinition('comment')) {
 | 
			
		||||
        $comment = $entity_type_manager->getStorage('comment')->create([
 | 
			
		||||
          'comment_type' => 'comment',
 | 
			
		||||
          'field_name' => 'comment',
 | 
			
		||||
          'entity_type' => 'node',
 | 
			
		||||
          'entity_id' => $node->id(),
 | 
			
		||||
        ]);
 | 
			
		||||
        $comment->save();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a file.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('file')) {
 | 
			
		||||
      $file = $entity_type_manager->getStorage('file')->create([
 | 
			
		||||
        'uri' => 'public://example.txt',
 | 
			
		||||
      ]);
 | 
			
		||||
      $file->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a menu link.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('menu_link_content')) {
 | 
			
		||||
      $menu_link = $entity_type_manager->getStorage('menu_link_content')->create([
 | 
			
		||||
        'title' => 'menu link',
 | 
			
		||||
        'link' => ['uri' => 'http://www.example.com'],
 | 
			
		||||
        'menu_name' => 'tools',
 | 
			
		||||
      ]);
 | 
			
		||||
      $menu_link->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a taxonomy term.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('taxonomy_term')) {
 | 
			
		||||
      $term = $entity_type_manager->getStorage('taxonomy_term')->create([
 | 
			
		||||
        'name' => 'term',
 | 
			
		||||
        'vid' => 'term',
 | 
			
		||||
      ]);
 | 
			
		||||
      $term->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a user.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('user')) {
 | 
			
		||||
      $user = $entity_type_manager->getStorage('user')->create([
 | 
			
		||||
        'name' => 'user',
 | 
			
		||||
        'mail' => 'user@example.com',
 | 
			
		||||
      ]);
 | 
			
		||||
      $user->save();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create several pieces of generic content.
 | 
			
		||||
   */
 | 
			
		||||
  protected function createContentPostUpgrade() {
 | 
			
		||||
    $entity_type_manager = \Drupal::entityTypeManager();
 | 
			
		||||
 | 
			
		||||
    // Create a block content.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('block_content')) {
 | 
			
		||||
      $block = $entity_type_manager->getStorage('block_content')->create([
 | 
			
		||||
        'info' => 'Post upgrade block',
 | 
			
		||||
        'type' => 'block',
 | 
			
		||||
      ]);
 | 
			
		||||
      $block->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a node.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('node')) {
 | 
			
		||||
      $node = $entity_type_manager->getStorage('node')->create([
 | 
			
		||||
        'type' => 'page',
 | 
			
		||||
        'title' => 'Post upgrade page',
 | 
			
		||||
      ]);
 | 
			
		||||
      $node->save();
 | 
			
		||||
 | 
			
		||||
      // Create a comment.
 | 
			
		||||
      if ($entity_type_manager->hasDefinition('comment')) {
 | 
			
		||||
        $comment = $entity_type_manager->getStorage('comment')->create([
 | 
			
		||||
          'comment_type' => 'comment',
 | 
			
		||||
          'field_name' => 'comment',
 | 
			
		||||
          'entity_type' => 'node',
 | 
			
		||||
          'entity_id' => $node->id(),
 | 
			
		||||
        ]);
 | 
			
		||||
        $comment->save();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a file.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('file')) {
 | 
			
		||||
      $file = $entity_type_manager->getStorage('file')->create([
 | 
			
		||||
        'uri' => 'public://post_upgrade_example.txt',
 | 
			
		||||
      ]);
 | 
			
		||||
      $file->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a menu link.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('menu_link_content')) {
 | 
			
		||||
      $menu_link = $entity_type_manager->getStorage('menu_link_content')->create([
 | 
			
		||||
        'title' => 'post upgrade menu link',
 | 
			
		||||
        'link' => ['uri' => 'http://www.example.com'],
 | 
			
		||||
        'menu_name' => 'tools',
 | 
			
		||||
      ]);
 | 
			
		||||
      $menu_link->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a taxonomy term.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('taxonomy_term')) {
 | 
			
		||||
      $term = $entity_type_manager->getStorage('taxonomy_term')->create([
 | 
			
		||||
        'name' => 'post upgrade term',
 | 
			
		||||
        'vid' => 'term',
 | 
			
		||||
      ]);
 | 
			
		||||
      $term->save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a user.
 | 
			
		||||
    if ($entity_type_manager->hasDefinition('user')) {
 | 
			
		||||
      $user = $entity_type_manager->getStorage('user')->create([
 | 
			
		||||
        'name' => 'universe',
 | 
			
		||||
        'mail' => 'universe@example.com',
 | 
			
		||||
      ]);
 | 
			
		||||
      $user->save();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,105 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Traits;
 | 
			
		||||
 | 
			
		||||
use Drupal\field_discovery_test\FieldDiscoveryTestClass;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
 | 
			
		||||
use Drupal\migrate_drupal\FieldDiscoveryInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper functions to test field discovery.
 | 
			
		||||
 */
 | 
			
		||||
trait FieldDiscoveryTestTrait {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Asserts the field discovery returns the expected processes.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\migrate_drupal\FieldDiscoveryInterface $field_discovery
 | 
			
		||||
   *   The Field Discovery service.
 | 
			
		||||
   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
 | 
			
		||||
   *   The migration plugin manager service.
 | 
			
		||||
   * @param string $core
 | 
			
		||||
   *   The Drupal core version, either '6', or '7'.
 | 
			
		||||
   * @param string $field_plugin_method
 | 
			
		||||
   *   (optional) The field plugin method to use.
 | 
			
		||||
   * @param array $expected_process
 | 
			
		||||
   *   (optional) The expected resulting process.
 | 
			
		||||
   * @param string $entity_type_id
 | 
			
		||||
   *   (optional) The entity type id.
 | 
			
		||||
   * @param string $bundle
 | 
			
		||||
   *   (optional) The bundle.
 | 
			
		||||
   */
 | 
			
		||||
  public function assertFieldProcess(FieldDiscoveryInterface $field_discovery, MigrationPluginManagerInterface $migration_plugin_manager, $core, $field_plugin_method = NULL, array $expected_process = [], $entity_type_id = NULL, $bundle = NULL) {
 | 
			
		||||
    $definition = [
 | 
			
		||||
      'migration_tags' => ['Drupal ' . $core],
 | 
			
		||||
      'field_plugin_method' => $field_plugin_method,
 | 
			
		||||
    ];
 | 
			
		||||
    $migration = $migration_plugin_manager->createStubMigration($definition);
 | 
			
		||||
    if ($bundle) {
 | 
			
		||||
      $field_discovery->addBundleFieldProcesses($migration, $entity_type_id, $bundle);
 | 
			
		||||
    }
 | 
			
		||||
    elseif ($entity_type_id) {
 | 
			
		||||
      $field_discovery->addEntityFieldProcesses($migration, $entity_type_id);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $field_discovery->addAllFieldProcesses($migration);
 | 
			
		||||
    }
 | 
			
		||||
    $actual_process = $migration->getProcess();
 | 
			
		||||
    $this->assertSame($expected_process, $actual_process);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Asserts the field discovery returns the expected processes.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\migrate_drupal\FieldDiscoveryInterface $field_discovery
 | 
			
		||||
   *   The Field Discovery service.
 | 
			
		||||
   * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
 | 
			
		||||
   *   The migration plugin manager service.
 | 
			
		||||
   * @param string $core
 | 
			
		||||
   *   The Drupal core version, either '6', or '7'.
 | 
			
		||||
   * @param array $expected_process_keys
 | 
			
		||||
   *   (optional) The expected resulting process_keys.
 | 
			
		||||
   * @param string $entity_type_id
 | 
			
		||||
   *   (optional) The entity type id.
 | 
			
		||||
   * @param string $bundle
 | 
			
		||||
   *   (optional) The bundle.
 | 
			
		||||
   */
 | 
			
		||||
  public function assertFieldProcessKeys(FieldDiscoveryInterface $field_discovery, MigrationPluginManagerInterface $migration_plugin_manager, $core, array $expected_process_keys, $entity_type_id = NULL, $bundle = NULL) {
 | 
			
		||||
    $definition = [
 | 
			
		||||
      'migration_tags' => ['Drupal ' . $core],
 | 
			
		||||
    ];
 | 
			
		||||
    $migration = $migration_plugin_manager->createStubMigration($definition);
 | 
			
		||||
    if ($bundle) {
 | 
			
		||||
      $field_discovery->addBundleFieldProcesses($migration, $entity_type_id, $bundle);
 | 
			
		||||
    }
 | 
			
		||||
    elseif ($entity_type_id) {
 | 
			
		||||
      $field_discovery->addEntityFieldProcesses($migration, $entity_type_id);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $field_discovery->addAllFieldProcesses($migration);
 | 
			
		||||
    }
 | 
			
		||||
    $actual_process = $migration->getProcess();
 | 
			
		||||
    $actual = array_keys($actual_process);
 | 
			
		||||
    $this->assertSame(sort($expected_process_keys), sort($actual));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Asserts a migrate source plugin.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $core
 | 
			
		||||
   *   The Drupal core version.
 | 
			
		||||
   * @param string $class
 | 
			
		||||
   *   The expected class of the source plugin.
 | 
			
		||||
   * @param array $expected_definition
 | 
			
		||||
   *   The expected source plugin definition.
 | 
			
		||||
   */
 | 
			
		||||
  public function assertSourcePlugin($core, $class, array $expected_definition) {
 | 
			
		||||
    $field_discovery = new FieldDiscoveryTestClass($this->fieldPluginManager, $this->migrationPluginManager, $this->logger);
 | 
			
		||||
    $source = $field_discovery->getSourcePlugin($core);
 | 
			
		||||
    $this->assertInstanceOf($class, $source);
 | 
			
		||||
    $this->assertSame($expected_definition, $source->getPluginDefinition());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,210 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Traits;
 | 
			
		||||
 | 
			
		||||
use Drupal\migrate_drupal\NodeMigrateType;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore destid sourceid
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper functions to test complete and classic node migrations.
 | 
			
		||||
 */
 | 
			
		||||
trait NodeMigrateTypeTestTrait {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The migrate_map table name.
 | 
			
		||||
   *
 | 
			
		||||
   * @var string
 | 
			
		||||
   */
 | 
			
		||||
  public $tableName = NULL;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the numbers of complete and classic node migrate_map tables.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $version
 | 
			
		||||
   *   The source database version.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   An associative array with the total number of complete and classic
 | 
			
		||||
   *   node migrate_map tables.
 | 
			
		||||
   */
 | 
			
		||||
  protected function nodeMigrateMapTableCount($version): array {
 | 
			
		||||
    $results = [];
 | 
			
		||||
    $bases = ['node', 'node_complete'];
 | 
			
		||||
    $tables = \Drupal::database()->schema()
 | 
			
		||||
      ->findTables('migrate_map_d' . $version . '_node%');
 | 
			
		||||
 | 
			
		||||
    foreach ($bases as $base) {
 | 
			
		||||
      $base_tables = preg_grep('/^migrate_map_d' . $version . '_' . $base . '_{2}.*$/', $tables);
 | 
			
		||||
      $results[$base] = count($base_tables);
 | 
			
		||||
    }
 | 
			
		||||
    return $results;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Remove the node migrate map table.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $type
 | 
			
		||||
   *   The type of node migration, 'complete' or 'classic'.
 | 
			
		||||
   * @param string $version
 | 
			
		||||
   *   The source database version.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws \Exception
 | 
			
		||||
   */
 | 
			
		||||
  protected function removeNodeMigrateMapTable($type, $version) {
 | 
			
		||||
    $name = $this->getTableName($type, $version);
 | 
			
		||||
    \Drupal::database()->schema()->dropTable($name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the migrate_map table name.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $type
 | 
			
		||||
   *   The type of node migration, 'complete' or 'classic'.
 | 
			
		||||
   * @param string $version
 | 
			
		||||
   *   The source database version.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string
 | 
			
		||||
   *   The migrate_map table name.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getTableName($type, $version) {
 | 
			
		||||
    if (!$this->tableName) {
 | 
			
		||||
      $content_type = $this->randomMachineName();
 | 
			
		||||
      $this->tableName = 'migrate_map_d' . $version . '_node_complete__' . $content_type;
 | 
			
		||||
      if ($type == NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC) {
 | 
			
		||||
        $this->tableName = 'migrate_map_d' . $version . '_node__' . $content_type;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return $this->tableName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a node migrate_map table.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $type
 | 
			
		||||
   *   The type of node migration, 'complete' or 'classic'.
 | 
			
		||||
   * @param string $version
 | 
			
		||||
   *   The source database version.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws \Exception
 | 
			
		||||
   */
 | 
			
		||||
  protected function makeNodeMigrateMapTable($type, $version) {
 | 
			
		||||
    $name = $this->getTableName($type, $version);
 | 
			
		||||
    $fields = [
 | 
			
		||||
      'source_ids_hash' => [
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'length' => '64',
 | 
			
		||||
      ],
 | 
			
		||||
      'sourceid1' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'size' => 'normal',
 | 
			
		||||
      ],
 | 
			
		||||
      'sourceid2' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'size' => 'normal',
 | 
			
		||||
      ],
 | 
			
		||||
      'sourceid3' => [
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'length' => '255',
 | 
			
		||||
      ],
 | 
			
		||||
      'destid1' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => FALSE,
 | 
			
		||||
        'size' => 'normal',
 | 
			
		||||
        'unsigned' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'destid2' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => FALSE,
 | 
			
		||||
        'size' => 'normal',
 | 
			
		||||
        'unsigned' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'destid3' => [
 | 
			
		||||
        'type' => 'varchar_ascii',
 | 
			
		||||
        'not null' => FALSE,
 | 
			
		||||
        'length' => '12',
 | 
			
		||||
      ],
 | 
			
		||||
      'source_row_status' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'size' => 'tiny',
 | 
			
		||||
        'default' => '0',
 | 
			
		||||
        'unsigned' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'rollback_action' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'size' => 'tiny',
 | 
			
		||||
        'default' => '0',
 | 
			
		||||
        'unsigned' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'last_imported' => [
 | 
			
		||||
        'type' => 'int',
 | 
			
		||||
        'not null' => TRUE,
 | 
			
		||||
        'size' => 'normal',
 | 
			
		||||
        'default' => '0',
 | 
			
		||||
        'unsigned' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'hash' => [
 | 
			
		||||
        'type' => 'varchar',
 | 
			
		||||
        'not null' => FALSE,
 | 
			
		||||
        'length' => '64',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $values = [
 | 
			
		||||
      'source_ids_hash' => '123',
 | 
			
		||||
      'sourceid1' => '4242',
 | 
			
		||||
      'sourceid2' => '4242',
 | 
			
		||||
      'sourceid3' => 'en',
 | 
			
		||||
      'destid1' => '4242',
 | 
			
		||||
      'destid2' => '4242',
 | 
			
		||||
      'destid3' => 'en',
 | 
			
		||||
      'source_row_status' => '1',
 | 
			
		||||
      'rollback_action' => '1',
 | 
			
		||||
      'last_imported' => time(),
 | 
			
		||||
      'hash' => 'abc',
 | 
			
		||||
    ];
 | 
			
		||||
    $indexes = [
 | 
			
		||||
      'source' => [
 | 
			
		||||
        'sourceid1',
 | 
			
		||||
        'sourceid2',
 | 
			
		||||
        'sourceid3',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Remove keys not used.
 | 
			
		||||
    if ($type == NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC) {
 | 
			
		||||
      $keys = ['sourceid2', 'sourceid3', 'destid2', 'destid3'];
 | 
			
		||||
      foreach ($keys as $key) {
 | 
			
		||||
        unset($fields[$key]);
 | 
			
		||||
        unset($values[$key]);
 | 
			
		||||
        if (str_contains($key, 'sourceid')) {
 | 
			
		||||
          $index_key = substr($key, -1) - 1;
 | 
			
		||||
          unset($indexes['source'][$index_key]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $connection = \Drupal::database();
 | 
			
		||||
    $connection->schema()->createTable($name, [
 | 
			
		||||
      'fields' => $fields,
 | 
			
		||||
      'primary key' => [
 | 
			
		||||
        'source_ids_hash',
 | 
			
		||||
      ],
 | 
			
		||||
      'indexes' => $indexes,
 | 
			
		||||
      'mysql_character_set' => 'utf8mb4',
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    $field_names = array_keys($fields);
 | 
			
		||||
    $connection->insert($name)
 | 
			
		||||
      ->fields($field_names)
 | 
			
		||||
      ->values($values)
 | 
			
		||||
      ->execute();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,158 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Traits;
 | 
			
		||||
 | 
			
		||||
use Drupal\Component\Discovery\YamlDiscovery;
 | 
			
		||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
use Drupal\migrate_drupal\MigrationConfigurationTrait;
 | 
			
		||||
use Drupal\migrate_drupal\MigrationState;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the migration state information in module.migrate_drupal.yml.
 | 
			
		||||
 *
 | 
			
		||||
 * This test checks that the discovered upgrade paths, which are based on the
 | 
			
		||||
 * source_module and destination_module definition matches the declared
 | 
			
		||||
 * upgrade paths in all the migrate_drupal.yml files.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
trait ValidateMigrationStateTestTrait {
 | 
			
		||||
 | 
			
		||||
  use FileSystemModuleDiscoveryDataProviderTrait;
 | 
			
		||||
  use MigrationConfigurationTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the migration information in .migrate_drupal.yml.
 | 
			
		||||
   *
 | 
			
		||||
   * Checks that every discovered pair has a corresponding declaration in the
 | 
			
		||||
   * declared pairs. The alternate check, that each declared pair has a
 | 
			
		||||
   * corresponding discovered pair is not possible because declarations can be
 | 
			
		||||
   * made for the two cases where migrations are yet to be written and where
 | 
			
		||||
   * migrations are not needed.
 | 
			
		||||
   */
 | 
			
		||||
  public function testMigrationState(): void {
 | 
			
		||||
 | 
			
		||||
    // Level separator of destination and source properties.
 | 
			
		||||
    $separator = ',';
 | 
			
		||||
 | 
			
		||||
    $this->enableAllModules();
 | 
			
		||||
 | 
			
		||||
    $version = (string) $this->getLegacyDrupalVersion($this->sourceDatabase);
 | 
			
		||||
 | 
			
		||||
    // Build an array for each migration keyed by provider. The value is a
 | 
			
		||||
    // string consisting of the version number, the provider, the source_module
 | 
			
		||||
    // and the destination module.
 | 
			
		||||
    $discovered = [];
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
 | 
			
		||||
    $plugin_manager = $this->container->get('plugin.manager.migration');
 | 
			
		||||
    $migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version);
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\Migration $migration */
 | 
			
		||||
    foreach ($migrations as $migration) {
 | 
			
		||||
      $definition = $migration->getPluginDefinition();
 | 
			
		||||
      if (is_array($definition['provider'])) {
 | 
			
		||||
        $provider = reset($definition['provider']);
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        $provider = $definition['provider'];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      $source_module = $migration->getSourcePlugin()->getSourceModule();
 | 
			
		||||
      $destination_module = $migration->getDestinationPlugin()
 | 
			
		||||
        ->getDestinationModule();
 | 
			
		||||
 | 
			
		||||
      $discovered[] = implode($separator, [
 | 
			
		||||
        $provider,
 | 
			
		||||
        $source_module,
 | 
			
		||||
        $destination_module,
 | 
			
		||||
      ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Add the field migrations.
 | 
			
		||||
    /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
 | 
			
		||||
    $definitions = $this->container->get('plugin.manager.migrate.field')
 | 
			
		||||
      ->getDefinitions();
 | 
			
		||||
    foreach ($definitions as $key => $definition) {
 | 
			
		||||
      if (isset($definition['core'][$version])) {
 | 
			
		||||
        $discovered[] = implode($separator, [
 | 
			
		||||
          $definition['provider'],
 | 
			
		||||
          $definition['source_module'],
 | 
			
		||||
          $definition['destination_module'],
 | 
			
		||||
        ]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the declared migration state information from .migrate_drupal.yml
 | 
			
		||||
    // and build an array of source modules and there migration state. The
 | 
			
		||||
    // destination is not used yet but can be later for validating the
 | 
			
		||||
    // source/destination pairs with the actual source/destination pairs in the
 | 
			
		||||
    // migrate plugins.
 | 
			
		||||
    $system_info = (new YamlDiscovery('migrate_drupal', array_map(function ($value) {
 | 
			
		||||
      return $value . '/migrations/state/';
 | 
			
		||||
    }, \Drupal::moduleHandler()->getModuleDirectories())))->findAll();
 | 
			
		||||
 | 
			
		||||
    $declared = [
 | 
			
		||||
      MigrationState::FINISHED => [],
 | 
			
		||||
      MigrationState::NOT_FINISHED => [],
 | 
			
		||||
    ];
 | 
			
		||||
    foreach ($system_info as $module => $info) {
 | 
			
		||||
      foreach (array_keys($declared) as $state) {
 | 
			
		||||
        if (isset($info[$state][$version])) {
 | 
			
		||||
          foreach ($info[$state][$version] as $source => $destination) {
 | 
			
		||||
            // Do not add the source module i18nstrings or i18_string. The
 | 
			
		||||
            // 18n migrations can have up to three source modules but only one
 | 
			
		||||
            // can be handled in the migration.
 | 
			
		||||
            if (($source !== 'i18nstrings') && ($source !== 'i18n_string')) {
 | 
			
		||||
              foreach ((array) $destination as $dest) {
 | 
			
		||||
                $key = [$module, $source, trim($dest)];
 | 
			
		||||
                $declared[$state][] = implode($separator, $key);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Sort and make the array values unique.
 | 
			
		||||
    sort($declared[MigrationState::FINISHED]);
 | 
			
		||||
    sort($declared[MigrationState::NOT_FINISHED]);
 | 
			
		||||
    $declared_unique[MigrationState::FINISHED] = array_unique($declared[MigrationState::FINISHED]);
 | 
			
		||||
    $declared_unique[MigrationState::NOT_FINISHED] = array_unique($declared[MigrationState::NOT_FINISHED]);
 | 
			
		||||
    sort($discovered);
 | 
			
		||||
    $discovered_unique = array_unique($discovered);
 | 
			
		||||
 | 
			
		||||
    // Assert that each discovered migration has a corresponding declaration
 | 
			
		||||
    // in a migrate_drupal.yml.
 | 
			
		||||
    foreach ($discovered_unique as $datum) {
 | 
			
		||||
      $data = str_getcsv($datum, escape: '');
 | 
			
		||||
      $in_finished = in_array($datum, $declared_unique[MigrationState::FINISHED]);
 | 
			
		||||
      $in_not_finished = in_array($datum, $declared_unique[MigrationState::NOT_FINISHED]);
 | 
			
		||||
      $found = $in_finished || $in_not_finished;
 | 
			
		||||
      $this->assertTrue($found, sprintf("No migration state found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $version, $data[1], $data[2], $data[0]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Remove the declared finished from the discovered, leaving just the not
 | 
			
		||||
    // finished, if there are any. These should have an entry in the declared
 | 
			
		||||
    // not finished.
 | 
			
		||||
    $discovered_not_finished = array_diff($discovered_unique, $declared_unique[MigrationState::FINISHED]);
 | 
			
		||||
    foreach ($discovered_not_finished as $datum) {
 | 
			
		||||
      $data = str_getcsv($datum, escape: '');
 | 
			
		||||
      $this->assertContains($datum, $declared_unique[MigrationState::NOT_FINISHED], sprintf("No migration found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $version, $data[1], $data[2], $data[0]));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Enable all available modules.
 | 
			
		||||
   */
 | 
			
		||||
  protected function enableAllModules() {
 | 
			
		||||
    // Install all available modules.
 | 
			
		||||
    $module_handler = $this->container->get('module_handler');
 | 
			
		||||
    $modules = $this->coreModuleListDataProvider();
 | 
			
		||||
    $modules_enabled = $module_handler->getModuleList();
 | 
			
		||||
    $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
 | 
			
		||||
    $this->enableModules($modules_to_enable);
 | 
			
		||||
    return $modules;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,361 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Logger\LoggerChannelInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
 | 
			
		||||
use Drupal\field_discovery_test\FieldDiscoveryTestClass;
 | 
			
		||||
use Drupal\migrate_drupal\FieldDiscoveryInterface;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the FieldDiscovery Class.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\FieldDiscovery
 | 
			
		||||
 */
 | 
			
		||||
class FieldDiscoveryTest extends UnitTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A MigrateFieldPluginManager prophecy.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Prophecy\Prophecy\ObjectProphecy
 | 
			
		||||
   */
 | 
			
		||||
  protected $fieldPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A MigrationPluginManager prophecy.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Prophecy\Prophecy\ObjectProphecy
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationPluginManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A LoggerChannelInterface prophecy.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Prophecy\Prophecy\ObjectProphecy
 | 
			
		||||
   */
 | 
			
		||||
  protected $logger;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->fieldPluginManager = $this->prophesize(MigrateFieldPluginManagerInterface::class);
 | 
			
		||||
    $this->migrationPluginManager = $this->prophesize(MigrationPluginManagerInterface::class);
 | 
			
		||||
    $this->logger = $this->prophesize(LoggerChannelInterface::class);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the protected getEntityFields method.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $entity_type_id
 | 
			
		||||
   *   The entity type ID.
 | 
			
		||||
   * @param array $expected_fields
 | 
			
		||||
   *   The expected fields.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getEntityFields
 | 
			
		||||
   * @dataProvider getEntityFieldsData
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetEntityFields($entity_type_id, array $expected_fields): void {
 | 
			
		||||
    $test_data = [
 | 
			
		||||
      'getAllFields' => [
 | 
			
		||||
        '7' => $this->getAllFieldData(),
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $field_discovery = new FieldDiscoveryTestClass($this->fieldPluginManager->reveal(), $this->migrationPluginManager->reveal(), $this->logger->reveal(), $test_data);
 | 
			
		||||
    $actual_fields = $field_discovery->getEntityFields('7', $entity_type_id);
 | 
			
		||||
    $this->assertSame($expected_fields, $actual_fields);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testGetEntityFields.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getEntityFieldsData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Node' => [
 | 
			
		||||
        'entity_type_id' => 'node',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'content_type_1' => [
 | 
			
		||||
            'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
            'field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
            'field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
          ],
 | 
			
		||||
          'content_type_2' => [
 | 
			
		||||
            'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
            'field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
            'field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'User' => [
 | 
			
		||||
        'entity_type_id' => 'user',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'user' => [
 | 
			
		||||
            'user_field_1' => ['field_info_key' => 'user_field_1_data'],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Comment' => [
 | 
			
		||||
        'entity_type_id' => 'comment',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'comment_node_content_type_1' => [
 | 
			
		||||
            'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
            'comment_field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
            'comment_field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
          ],
 | 
			
		||||
          'comment_node_content_type_2' => [
 | 
			
		||||
            'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
            'comment_field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
            'comment_field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Non-existent Entity' => [
 | 
			
		||||
        'entity_type_id' => 'custom_entity',
 | 
			
		||||
        'expected_fields' => [],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the protected getEntityFields method.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $entity_type_id
 | 
			
		||||
   *   The entity type ID.
 | 
			
		||||
   * @param string $bundle
 | 
			
		||||
   *   The bundle.
 | 
			
		||||
   * @param array $expected_fields
 | 
			
		||||
   *   The expected fields.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getBundleFields
 | 
			
		||||
   * @dataProvider getBundleFieldsData
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetBundleFields($entity_type_id, $bundle, array $expected_fields): void {
 | 
			
		||||
    $test_data = [
 | 
			
		||||
      'getAllFields' => [
 | 
			
		||||
        '7' => $this->getAllFieldData(),
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $field_discovery = new FieldDiscoveryTestClass($this->fieldPluginManager->reveal(), $this->migrationPluginManager->reveal(), $this->logger->reveal(), $test_data);
 | 
			
		||||
    $actual_fields = $field_discovery->getBundleFields('7', $entity_type_id, $bundle);
 | 
			
		||||
    $this->assertSame($expected_fields, $actual_fields);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testGetBundleFields.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getBundleFieldsData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Node - Content Type 1' => [
 | 
			
		||||
        'entity_type_id' => 'node',
 | 
			
		||||
        'bundle' => 'content_type_1',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
          'field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Node - Content Type 2' => [
 | 
			
		||||
        'entity_type_id' => 'node',
 | 
			
		||||
        'bundle' => 'content_type_2',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
          'field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'User' => [
 | 
			
		||||
        'entity_type_id' => 'user',
 | 
			
		||||
        'bundle' => 'user',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'user_field_1' => ['field_info_key' => 'user_field_1_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Comment - Content Type 1' => [
 | 
			
		||||
        'entity_type_id' => 'comment',
 | 
			
		||||
        'bundle' => 'comment_node_content_type_1',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'comment_field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
          'comment_field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Comment - Content Type 2' => [
 | 
			
		||||
        'entity_type_id' => 'comment',
 | 
			
		||||
        'bundle' => 'comment_node_content_type_2',
 | 
			
		||||
        'expected_fields' => [
 | 
			
		||||
          'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'comment_field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
          'comment_field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Non-existent Entity Type' => [
 | 
			
		||||
        'entity_type_id' => 'custom_entity',
 | 
			
		||||
        'bundle' => 'content_type_1',
 | 
			
		||||
        'expected_fields' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'Non-existent Bundle' => [
 | 
			
		||||
        'entity_type_id' => 'node',
 | 
			
		||||
        'bundle' => 'content_type_3',
 | 
			
		||||
        'expected_fields' => [],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the protected getCoreVersion method.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string[] $tags
 | 
			
		||||
   *   The migration tags.
 | 
			
		||||
   * @param string|bool $expected_result
 | 
			
		||||
   *   The expected return value of the method.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getCoreVersion
 | 
			
		||||
   * @dataProvider getCoreVersionData
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetCoreVersion(array $tags, $expected_result): void {
 | 
			
		||||
    $migration = $this->prophesize(MigrationInterface::class);
 | 
			
		||||
    $migration->getMigrationTags()->willReturn($tags);
 | 
			
		||||
    $field_discovery = new FieldDiscoveryTestClass($this->fieldPluginManager->reveal(), $this->migrationPluginManager->reveal(), $this->logger->reveal());
 | 
			
		||||
    if (!$expected_result) {
 | 
			
		||||
      $this->expectException(\InvalidArgumentException::class);
 | 
			
		||||
    }
 | 
			
		||||
    $actual_result = $field_discovery->getCoreVersion($migration->reveal());
 | 
			
		||||
    $this->assertEquals($expected_result, $actual_result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testGetCoreVersion()
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The test data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getCoreVersionData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Drupal 7' => [
 | 
			
		||||
        'tags' => ['Drupal 7'],
 | 
			
		||||
        'expected_result' => '7',
 | 
			
		||||
      ],
 | 
			
		||||
      'Drupal 6' => [
 | 
			
		||||
        'tags' => ['Drupal 6'],
 | 
			
		||||
        'expected_result' => '6',
 | 
			
		||||
      ],
 | 
			
		||||
      'D7 with others' => [
 | 
			
		||||
        'tags' => ['Drupal 7', 'Translation', 'Other Tag'],
 | 
			
		||||
        'expected_result' => '7',
 | 
			
		||||
      ],
 | 
			
		||||
      'Both (d7 has priority)' => [
 | 
			
		||||
        'tags' => ['Drupal 6', 'Drupal 7'],
 | 
			
		||||
        'expected_result' => '7',
 | 
			
		||||
      ],
 | 
			
		||||
      'Neither' => [
 | 
			
		||||
        'tags' => ['drupal 6', 'Drupal_6', 'This contains Drupal 7 but is not'],
 | 
			
		||||
        'expected_result' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns dummy data to test the field getters.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getAllFieldData(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      'node' => [
 | 
			
		||||
        'content_type_1' => [
 | 
			
		||||
          'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
          'field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
        ],
 | 
			
		||||
        'content_type_2' => [
 | 
			
		||||
          'field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
          'field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'user' => [
 | 
			
		||||
        'user' => [
 | 
			
		||||
          'user_field_1' => ['field_info_key' => 'user_field_1_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'comment' => [
 | 
			
		||||
        'comment_node_content_type_1' => [
 | 
			
		||||
          'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'comment_field_2' => ['field_info_key' => 'field_2_data'],
 | 
			
		||||
          'comment_field_3' => ['field_info_key' => 'field_3_data'],
 | 
			
		||||
        ],
 | 
			
		||||
        'comment_node_content_type_2' => [
 | 
			
		||||
          'comment_field_1' => ['field_info_key' => 'field_1_data'],
 | 
			
		||||
          'comment_field_4' => ['field_info_key' => 'field_4_data'],
 | 
			
		||||
          'comment_field_5' => ['field_info_key' => 'field_5_data'],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the getFieldInstanceStubMigration method.
 | 
			
		||||
   *
 | 
			
		||||
   * @param mixed $core
 | 
			
		||||
   *   The Drupal core version.
 | 
			
		||||
   * @param array|bool $expected_definition
 | 
			
		||||
   *   The expected migration definition, or false if an exception is expected.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getFieldInstanceStubMigrationDefinition
 | 
			
		||||
   * @dataProvider getFieldInstanceStubMigrationDefinition
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetFieldInstanceStubMigrationDefinition($core, $expected_definition): void {
 | 
			
		||||
    $field_discovery = new FieldDiscoveryTestClass($this->fieldPluginManager->reveal(), $this->migrationPluginManager->reveal(), $this->logger->reveal());
 | 
			
		||||
    if (!$expected_definition) {
 | 
			
		||||
      $this->expectException(\InvalidArgumentException::class);
 | 
			
		||||
      $this->expectExceptionMessage(sprintf("Drupal version %s is not supported. Valid values for Drupal core version are '6' and '7'.", $core));
 | 
			
		||||
    }
 | 
			
		||||
    $actual_definition = $field_discovery->getFieldInstanceStubMigrationDefinition($core);
 | 
			
		||||
    $this->assertSame($expected_definition, $actual_definition);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testGetFieldInstanceStubMigrationDefinition.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function getFieldInstanceStubMigrationDefinition() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Drupal 6' => [
 | 
			
		||||
        'core' => FieldDiscoveryInterface::DRUPAL_6,
 | 
			
		||||
        'expected_definition' => [
 | 
			
		||||
          'destination' => ['plugin' => 'null'],
 | 
			
		||||
          'idMap' => ['plugin' => 'null'],
 | 
			
		||||
          'source' => [
 | 
			
		||||
            'ignore_map' => TRUE,
 | 
			
		||||
            'plugin' => 'd6_field_instance',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'Drupal 7' => [
 | 
			
		||||
        'core' => FieldDiscoveryInterface::DRUPAL_7,
 | 
			
		||||
        'expected_definition' => [
 | 
			
		||||
          'destination' => ['plugin' => 'null'],
 | 
			
		||||
          'idMap' => ['plugin' => 'null'],
 | 
			
		||||
          'source' => [
 | 
			
		||||
            'ignore_map' => TRUE,
 | 
			
		||||
            'plugin' => 'd7_field_instance',
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,226 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit;
 | 
			
		||||
 | 
			
		||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
 | 
			
		||||
use Drupal\Core\Cache\CacheBackendInterface;
 | 
			
		||||
use Drupal\Core\Extension\ModuleHandlerInterface;
 | 
			
		||||
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
 | 
			
		||||
use Drupal\migrate_drupal\Annotation\MigrateField;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the MigrateFieldPluginManager class.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager
 | 
			
		||||
 */
 | 
			
		||||
class MigrateFieldPluginManagerTest extends UnitTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests the plugin weighting system.
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getPluginIdFromFieldType
 | 
			
		||||
   * @covers ::sortDefinitions
 | 
			
		||||
   * @covers ::findDefinitions
 | 
			
		||||
   * @dataProvider weightsData
 | 
			
		||||
   */
 | 
			
		||||
  public function testWeights($field_type, $core, $expected_plugin_id): void {
 | 
			
		||||
    /** @var \Drupal\Core\Cache\CacheBackendInterface $cache */
 | 
			
		||||
    $cache = $this->prophesize(CacheBackendInterface::class)->reveal();
 | 
			
		||||
    /** @var \Drupal\Core\Extension\ModuleHandlerInterfaceModuleHandlerInterface $module_handler */
 | 
			
		||||
    $module_handler = $this->prophesize(ModuleHandlerInterface::class)->reveal();
 | 
			
		||||
    $discovery = $this->prophesize(AnnotatedClassDiscovery::class);
 | 
			
		||||
    $discovery->getDefinitions()->willReturn($this->pluginFixtureData());
 | 
			
		||||
    $manager = new MigrateFieldPluginManagerTestClass('field', new \ArrayObject(), $cache, $module_handler, MigrateField::class, $discovery->reveal());
 | 
			
		||||
    if (!$expected_plugin_id) {
 | 
			
		||||
      $this->expectException(PluginNotFoundException::class);
 | 
			
		||||
      $this->expectExceptionMessage(sprintf("Plugin ID '%s' was not found.", $field_type));
 | 
			
		||||
    }
 | 
			
		||||
    $actual_plugin_id = $manager->getPluginIdFromFieldType($field_type, ['core' => $core]);
 | 
			
		||||
    $this->assertSame($expected_plugin_id, $actual_plugin_id);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testWeights().
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The data.
 | 
			
		||||
   */
 | 
			
		||||
  public static function weightsData() {
 | 
			
		||||
    return [
 | 
			
		||||
      'Field 1, D6' => [
 | 
			
		||||
        'field_type' => 'field_1',
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'expected_plugin_id' => 'core_replacement_plugin',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 2, D6' => [
 | 
			
		||||
        'field_type' => 'field_2',
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'expected_plugin_id' => 'field_1',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 3, D6' => [
 | 
			
		||||
        'field_type' => 'field_3',
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'expected_plugin_id' => 'field_3',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 4, D6' => [
 | 
			
		||||
        'field_type' => 'field_4',
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'expected_plugin_id' => 'field_4',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 5, D6' => [
 | 
			
		||||
        'field_type' => 'field_5',
 | 
			
		||||
        'core' => 6,
 | 
			
		||||
        'expected_plugin_id' => 'alphabetically_second',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 1, D7' => [
 | 
			
		||||
        'field_type' => 'field_1',
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'expected_plugin_id' => 'core_replacement_plugin',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 2, D7' => [
 | 
			
		||||
        'field_type' => 'field_2',
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'expected_plugin_id' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 3, D7' => [
 | 
			
		||||
        'field_type' => 'field_3',
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'expected_plugin_id' => 'field_3',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 4, D7' => [
 | 
			
		||||
        'field_type' => 'field_4',
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'expected_plugin_id' => 'contrib_override_plugin',
 | 
			
		||||
      ],
 | 
			
		||||
      'Field 5, D7' => [
 | 
			
		||||
        'field_type' => 'field_5',
 | 
			
		||||
        'core' => 7,
 | 
			
		||||
        'expected_plugin_id' => 'alphabetically_first',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns test plugin data for the test class to use.
 | 
			
		||||
   *
 | 
			
		||||
   * @return array
 | 
			
		||||
   *   The test plugin data.
 | 
			
		||||
   */
 | 
			
		||||
  protected function pluginFixtureData(): array {
 | 
			
		||||
    return [
 | 
			
		||||
      // Represents a deprecated core field plugin that applied to field_1
 | 
			
		||||
      // and field_2 for Drupal 6.
 | 
			
		||||
      'field_1' => [
 | 
			
		||||
        'weight' => 99999999,
 | 
			
		||||
        'core' => [6],
 | 
			
		||||
        'type_map' => [
 | 
			
		||||
          'field_1' => 'field_1',
 | 
			
		||||
          'field_2' => 'field_2',
 | 
			
		||||
        ],
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      // Replacement for deprecated plugin for field_1 in Drupal 6 and 7.
 | 
			
		||||
      // Does not provide replacement for field_2.
 | 
			
		||||
      'core_replacement_plugin' => [
 | 
			
		||||
        'weight' => 0,
 | 
			
		||||
        'core' => [6, 7],
 | 
			
		||||
        'type_map' => [
 | 
			
		||||
          'field_1' => 'field_1',
 | 
			
		||||
        ],
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      // Represents a core plugin with no type_map, applies to field_3 due to
 | 
			
		||||
      // plugin id.
 | 
			
		||||
      'field_3' => [
 | 
			
		||||
        'core' => [6, 7],
 | 
			
		||||
        'type_map' => [],
 | 
			
		||||
        'weight' => 0,
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      // Represents a core plugin with no type_map, applies to field_4 due to
 | 
			
		||||
      // plugin id.
 | 
			
		||||
      'field_4' => [
 | 
			
		||||
        'core' => [6, 7],
 | 
			
		||||
        'type_map' => [],
 | 
			
		||||
        'weight' => 0,
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      // Represents a contrib plugin overriding field_4 for Drupal 7 only.
 | 
			
		||||
      'contrib_override_plugin' => [
 | 
			
		||||
        'weight' => -100,
 | 
			
		||||
        'core' => [7],
 | 
			
		||||
        'type_map' => [
 | 
			
		||||
          'field_4' => 'field_4',
 | 
			
		||||
        ],
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      // field_5 is served by alphabetically_second in Drupal 6 and
 | 
			
		||||
      // alphabetically_first and alphabetically_second in Drupal 7.  It should
 | 
			
		||||
      // be served by the alphabetically_first in Drupal 7 regardless of the
 | 
			
		||||
      // order they appear here.
 | 
			
		||||
      'alphabetically_second' => [
 | 
			
		||||
        'weight' => 0,
 | 
			
		||||
        'core' => [6, 7],
 | 
			
		||||
        'type_map' => [
 | 
			
		||||
          'field_5' => 'field_5',
 | 
			
		||||
        ],
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
      'alphabetically_first' => [
 | 
			
		||||
        'weight' => 0,
 | 
			
		||||
        'core' => [7],
 | 
			
		||||
        'type_map' => [
 | 
			
		||||
          'field_5' => 'field_5',
 | 
			
		||||
        ],
 | 
			
		||||
        'source_module' => 'system',
 | 
			
		||||
        'destination_module' => 'system',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to test MigrateFieldPluginManager.
 | 
			
		||||
 *
 | 
			
		||||
 * Overrides the constructor to inject a mock discovery class to provide a test
 | 
			
		||||
 * list of plugins.
 | 
			
		||||
 */
 | 
			
		||||
class MigrateFieldPluginManagerTestClass extends MigrateFieldPluginManager {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a MigratePluginManagerTestClass object.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string $type
 | 
			
		||||
   *   The type of the plugin: row, source, process, destination, entity_field,
 | 
			
		||||
   *   id_map.
 | 
			
		||||
   * @param \Traversable $namespaces
 | 
			
		||||
   *   An object that implements \Traversable which contains the root paths
 | 
			
		||||
   *   keyed by the corresponding namespace to look for plugin implementations.
 | 
			
		||||
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
 | 
			
		||||
   *   Cache backend instance to use.
 | 
			
		||||
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
 | 
			
		||||
   *   The module handler to invoke the alter hook with.
 | 
			
		||||
   * @param string $annotation
 | 
			
		||||
   *   The annotation class name.
 | 
			
		||||
   * @param \Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery $discovery
 | 
			
		||||
   *   A mock plugin discovery object for the test class to use.
 | 
			
		||||
   */
 | 
			
		||||
  public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, $annotation, AnnotatedClassDiscovery $discovery) {
 | 
			
		||||
    parent::__construct($type, $namespaces, $cache_backend, $module_handler, $annotation);
 | 
			
		||||
    $this->discovery = $discovery;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,133 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
 | 
			
		||||
use Drupal\migrate_drupal\MigrationConfigurationTrait;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\MigrationConfigurationTrait
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class MigrationConfigurationTraitTest extends UnitTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @covers ::getLegacyDrupalVersion
 | 
			
		||||
   * @dataProvider providerTestGetLegacyDrupalVersion
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetLegacyDrupalVersion($expected_version_string, $schema_version, $exception, $system_table_exists): void {
 | 
			
		||||
    if ($schema_version) {
 | 
			
		||||
      $statement = $this->createMock('\Drupal\Core\Database\StatementInterface');
 | 
			
		||||
      $statement->expects($this->any())
 | 
			
		||||
        ->method('fetchField')
 | 
			
		||||
        ->willReturn($schema_version);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $schema = $this->createMock('\Drupal\Core\Database\Schema');
 | 
			
		||||
    $schema->expects($this->once())
 | 
			
		||||
      ->method('tableExists')
 | 
			
		||||
      ->willReturn($system_table_exists);
 | 
			
		||||
 | 
			
		||||
    $connection = $this->getMockBuilder('Drupal\Core\Database\Connection')
 | 
			
		||||
      ->disableOriginalConstructor()
 | 
			
		||||
      ->getMock();
 | 
			
		||||
 | 
			
		||||
    if ($exception) {
 | 
			
		||||
      $connection->expects($this->any())
 | 
			
		||||
        ->method('query')
 | 
			
		||||
        ->willThrowException($exception);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $connection->expects($this->any())
 | 
			
		||||
        ->method('query')
 | 
			
		||||
        ->willReturn($statement);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $connection->expects($this->any())
 | 
			
		||||
      ->method('schema')
 | 
			
		||||
      ->willReturn($schema);
 | 
			
		||||
 | 
			
		||||
    $actual_version_string = TestMigrationConfigurationTrait::getLegacyDrupalVersion($connection);
 | 
			
		||||
    $this->assertSame($expected_version_string, $actual_version_string);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testGetLegacyDrupalVersion.
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerTestGetLegacyDrupalVersion() {
 | 
			
		||||
    return [
 | 
			
		||||
      'D5' => [
 | 
			
		||||
        'expected_version_string' => '5',
 | 
			
		||||
        'schema_version' => '1678',
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D6' => [
 | 
			
		||||
        'expected_version_string' => '6',
 | 
			
		||||
        'schema_version' => '6057',
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D7' => [
 | 
			
		||||
        'expected_version_string' => '7',
 | 
			
		||||
        'schema_version' => '7065',
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D8' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => serialize('8976'),
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D9' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => serialize('9270'),
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D10' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => serialize('10101'),
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
      'Not drupal' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => "not drupal I guess",
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D5 almost' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => '123',
 | 
			
		||||
        'exception' => NULL,
 | 
			
		||||
        'system_table_exists' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D5/6/7 Exception' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => NULL,
 | 
			
		||||
        'exception' => new DatabaseExceptionWrapper(),
 | 
			
		||||
        'system_table_exists' => TRUE,
 | 
			
		||||
      ],
 | 
			
		||||
      'D8/9 Exception' => [
 | 
			
		||||
        'expected_version_string' => FALSE,
 | 
			
		||||
        'schema_version' => NULL,
 | 
			
		||||
        'exception' => new DatabaseExceptionWrapper(),
 | 
			
		||||
        'system_table_exists' => FALSE,
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test class that uses the trait we are testing.
 | 
			
		||||
 */
 | 
			
		||||
class TestMigrationConfigurationTrait {
 | 
			
		||||
  use MigrationConfigurationTrait;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,618 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Extension\ModuleHandlerInterface;
 | 
			
		||||
use Drupal\Core\Messenger\MessengerInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrateDestinationInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrateSourceInterface;
 | 
			
		||||
use Drupal\migrate\Plugin\MigrationInterface;
 | 
			
		||||
use Drupal\migrate_drupal\MigrationState;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
use org\bovigo\vfs\vfsStream;
 | 
			
		||||
use org\bovigo\vfs\vfsStreamDirectory;
 | 
			
		||||
use org\bovigo\vfs\vfsStreamWrapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines a class for testing \Drupal\migrate_drupal\MigrationState.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 *
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\MigrationState
 | 
			
		||||
 */
 | 
			
		||||
class MigrationStateUnitTest extends UnitTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests ::getUpgradeStates.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerGetUpgradeStates
 | 
			
		||||
   *
 | 
			
		||||
   * @covers ::getUpgradeStates
 | 
			
		||||
   * @covers ::buildDiscoveredDestinationsBySource
 | 
			
		||||
   * @covers ::buildDeclaredStateBySource
 | 
			
		||||
   * @covers ::buildUpgradeState
 | 
			
		||||
   * @covers ::getMigrationStates
 | 
			
		||||
   * @covers ::getSourceState
 | 
			
		||||
   * @covers ::getDestinationsForSource
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetUpgradeStates($modules_to_enable, $files, $field_plugins, $migrations, $source_system_data, $expected_7, $expected_6): void {
 | 
			
		||||
    $fieldPluginManager = $this->prophesize(MigrateFieldPluginManagerInterface::class);
 | 
			
		||||
    $fieldPluginManager->getDefinitions()->willReturn($field_plugins);
 | 
			
		||||
    $moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
 | 
			
		||||
    $moduleHandler->getModuleList()->willReturn($modules_to_enable);
 | 
			
		||||
    vfsStreamWrapper::register();
 | 
			
		||||
    $root = new vfsStreamDirectory('modules');
 | 
			
		||||
    vfsStreamWrapper::setRoot($root);
 | 
			
		||||
    $url = vfsStream::url('modules');
 | 
			
		||||
 | 
			
		||||
    foreach ($files as $module => $contents) {
 | 
			
		||||
      $path = $url . '/' . $module . '/migrations/state';
 | 
			
		||||
      mkdir($path, 0755, TRUE);
 | 
			
		||||
      file_put_contents($path . '/' . $module . '.migrate_drupal.yml', $contents);
 | 
			
		||||
    }
 | 
			
		||||
    $moduleHandler->getModuleDirectories()
 | 
			
		||||
      ->willReturn(array_combine(array_keys($files), array_map(function ($module) use ($url) {
 | 
			
		||||
        return $url . '/' . $module;
 | 
			
		||||
      }, array_keys($files))));
 | 
			
		||||
    $migrationState = new MigrationState($fieldPluginManager->reveal(), $moduleHandler->reveal(), $this->createMock(MessengerInterface::class), $this->getStringTranslationStub());
 | 
			
		||||
 | 
			
		||||
    $all_migrations = [];
 | 
			
		||||
    foreach ($migrations as $name => $values) {
 | 
			
		||||
      $migration = $this->prophesize(MigrationInterface::class);
 | 
			
		||||
      $source = $this->prophesize(MigrateSourceInterface::class);
 | 
			
		||||
      $destination = $this->prophesize(MigrateDestinationInterface::class);
 | 
			
		||||
      $source->getSourceModule()->willReturn($values['source_module']);
 | 
			
		||||
      $destination->getDestinationModule()
 | 
			
		||||
        ->willReturn($values['destination_module']);
 | 
			
		||||
      $migration->getSourcePlugin()->willReturn($source->reveal());
 | 
			
		||||
      $migration->getDestinationPlugin()->willReturn($destination->reveal());
 | 
			
		||||
      $migration->getPluginId()->willReturn($name);
 | 
			
		||||
      $migration->label()->willReturn($name);
 | 
			
		||||
      $all_migrations[] = $migration->reveal();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Tests Drupal 7 states.
 | 
			
		||||
    $states = $migrationState->getUpgradeStates(7, $source_system_data, $all_migrations);
 | 
			
		||||
    $this->assertEquals($expected_7, $states);
 | 
			
		||||
    $source_system_data['module']['content'] = [
 | 
			
		||||
      'name' => 'content',
 | 
			
		||||
      'status' => TRUE,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Tests Drupal 6 states.
 | 
			
		||||
    unset($source_system_data['module']['rdf'], $source_system_data['module']['filter']);
 | 
			
		||||
    $states = $migrationState->getUpgradeStates(6, $source_system_data, []);
 | 
			
		||||
    $this->assertEquals($expected_6, $states);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Data provider for testGetUpgradeStates.
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerGetUpgradeStates() {
 | 
			
		||||
 | 
			
		||||
    // Tests multiple scenarios:
 | 
			
		||||
    // Not enabled and not declared.
 | 
			
		||||
    // Destination module is not enabled.
 | 
			
		||||
    // Destination module not enabled.
 | 
			
		||||
    // Declared not finished.
 | 
			
		||||
    // Not finished.
 | 
			
		||||
    // No discovered or declared state.
 | 
			
		||||
    // Declared finished by one module but not finished by another.
 | 
			
		||||
    // Not declared and non compatible field plugin.
 | 
			
		||||
    // Update path not needed.
 | 
			
		||||
    $tests[0] = [
 | 
			
		||||
      'modules_to_enable' => [
 | 
			
		||||
        'entity_test' => [],
 | 
			
		||||
        'node' => [],
 | 
			
		||||
        'link' => [],
 | 
			
		||||
        'rdf' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'files' => [
 | 
			
		||||
        'node' => <<<NODE
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    content: node
 | 
			
		||||
    node: node
 | 
			
		||||
  7:
 | 
			
		||||
    node: node
 | 
			
		||||
NODE
 | 
			
		||||
        ,
 | 
			
		||||
        'entity_test' => <<<ENTITY_TEST
 | 
			
		||||
not_finished:
 | 
			
		||||
  6:
 | 
			
		||||
    entity_test: entity_test
 | 
			
		||||
  7:
 | 
			
		||||
    entity_test:
 | 
			
		||||
      - entity_test
 | 
			
		||||
      - entity_test_rev
 | 
			
		||||
ENTITY_TEST
 | 
			
		||||
        ,
 | 
			
		||||
        'comment' => <<<COMMENT
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    comment:
 | 
			
		||||
      - comment
 | 
			
		||||
      - node
 | 
			
		||||
  7:
 | 
			
		||||
    comment:
 | 
			
		||||
      - comment
 | 
			
		||||
      - node
 | 
			
		||||
COMMENT
 | 
			
		||||
        ,
 | 
			
		||||
        'user' => <<<USER
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    user: user
 | 
			
		||||
  7:
 | 
			
		||||
    user: user
 | 
			
		||||
USER
 | 
			
		||||
        ,
 | 
			
		||||
        'profile' => <<<PROFILE
 | 
			
		||||
not_finished:
 | 
			
		||||
  6:
 | 
			
		||||
    profile: user
 | 
			
		||||
  7:
 | 
			
		||||
    profile: user
 | 
			
		||||
PROFILE
 | 
			
		||||
        ,
 | 
			
		||||
      ],
 | 
			
		||||
      'field_plugins' => [
 | 
			
		||||
        'datetime' => [
 | 
			
		||||
          'id' => 'datetime',
 | 
			
		||||
          'core' => [7],
 | 
			
		||||
          'source_module' => 'date',
 | 
			
		||||
          'destination_module' => 'datetime',
 | 
			
		||||
        ],
 | 
			
		||||
        'link' => [
 | 
			
		||||
          'id' => 'link',
 | 
			
		||||
          'core' => [6, 7],
 | 
			
		||||
          'source_module' => 'link',
 | 
			
		||||
          'destination_module' => 'link',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'migrations' => [
 | 
			
		||||
        'rdf' => [
 | 
			
		||||
          'source_module' => 'rdf',
 | 
			
		||||
          'destination_module' => 'rdf',
 | 
			
		||||
        ],
 | 
			
		||||
        'filter' => [
 | 
			
		||||
          'source_module' => 'filter',
 | 
			
		||||
          'destination_module' => 'filter',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'source_system_data' => [
 | 
			
		||||
        'module' => [
 | 
			
		||||
          'entity_test' => [
 | 
			
		||||
            'name' => 'entity_test',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'rdf' => [
 | 
			
		||||
            'name' => 'rdf',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'node' => [
 | 
			
		||||
            'name' => 'node',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'date' => [
 | 
			
		||||
            'name' => 'date',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'link' => [
 | 
			
		||||
            'name' => 'link',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'search' => [
 | 
			
		||||
            'name' => 'search',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'filter' => [
 | 
			
		||||
            'name' => 'filter',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'comment' => [
 | 
			
		||||
            'name' => 'comment',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'standard' => [
 | 
			
		||||
            'name' => 'standard',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'color' => [
 | 
			
		||||
            'name' => 'color',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'user' => [
 | 
			
		||||
            'name' => 'user',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'profile' => [
 | 
			
		||||
            'name' => 'profile',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          // Disabled, hence ignored.
 | 
			
		||||
          'dblog' => [
 | 
			
		||||
            'name' => 'dblog',
 | 
			
		||||
            'status' => FALSE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
 | 
			
		||||
      'expected_7' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          // Not enabled and not declared.
 | 
			
		||||
          'color' => '',
 | 
			
		||||
          // Destination module comment is not enabled.
 | 
			
		||||
          'comment' => 'comment, node',
 | 
			
		||||
          // Destination module not enabled.
 | 
			
		||||
          'date' => 'datetime',
 | 
			
		||||
          // Declared not finished.
 | 
			
		||||
          'entity_test' => 'entity_test, entity_test_rev',
 | 
			
		||||
          // Destination module not enabled.
 | 
			
		||||
          'filter' => 'filter',
 | 
			
		||||
          // Not finished.
 | 
			
		||||
          'profile' => 'user',
 | 
			
		||||
          // No discovered or declared state.
 | 
			
		||||
          'search' => '',
 | 
			
		||||
          // Declared finished by one module but not finished by another.
 | 
			
		||||
          'user' => 'user',
 | 
			
		||||
          // Enabled and not declared.
 | 
			
		||||
          'rdf' => 'rdf',
 | 
			
		||||
          'link' => 'link',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'node' => 'node',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'expected_6' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          // Declared not finished.
 | 
			
		||||
          'entity_test' => 'entity_test',
 | 
			
		||||
          // Destination module comment is not enabled.
 | 
			
		||||
          'comment' => 'comment, node',
 | 
			
		||||
          'user' => 'user',
 | 
			
		||||
          // Not finished.
 | 
			
		||||
          'profile' => 'user',
 | 
			
		||||
          // Not declared and non compatible field plugin.
 | 
			
		||||
          'date' => '',
 | 
			
		||||
          // No discovered or declared state.
 | 
			
		||||
          'search' => '',
 | 
			
		||||
          'color' => '',
 | 
			
		||||
          'link' => 'link',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'node' => 'node',
 | 
			
		||||
          'content' => 'node',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test menu migration with all three required destination modules enabled.
 | 
			
		||||
    $tests[1] = [
 | 
			
		||||
      'modules_to_enable' => [
 | 
			
		||||
        'menu_link_content' => [],
 | 
			
		||||
        'menu_ui' => [],
 | 
			
		||||
        'system' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'files' => [
 | 
			
		||||
        'system' => <<<SYSTEM
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    menu:
 | 
			
		||||
      - system
 | 
			
		||||
      - menu_link_content
 | 
			
		||||
      - menu_ui
 | 
			
		||||
  7:
 | 
			
		||||
    menu:
 | 
			
		||||
      - system
 | 
			
		||||
      - menu_link_content
 | 
			
		||||
      - menu_ui
 | 
			
		||||
SYSTEM
 | 
			
		||||
        ,
 | 
			
		||||
        'menu_link_content' => <<<MENU_LINK_CONTENT
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    menu: menu_link_content
 | 
			
		||||
  7:
 | 
			
		||||
    menu: menu_link_content
 | 
			
		||||
MENU_LINK_CONTENT
 | 
			
		||||
        ,
 | 
			
		||||
        'menu' => <<<MENU_UI
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    menu: menu_ui
 | 
			
		||||
  7:
 | 
			
		||||
    menu: menu_ui
 | 
			
		||||
MENU_UI
 | 
			
		||||
        ,
 | 
			
		||||
      ],
 | 
			
		||||
      'field_plugins' => [],
 | 
			
		||||
      'migrations' => [
 | 
			
		||||
        'system' => [
 | 
			
		||||
          'source_module' => 'menu',
 | 
			
		||||
          'destination_module' => 'system',
 | 
			
		||||
        ],
 | 
			
		||||
        'menu_ui' => [
 | 
			
		||||
          'source_module' => 'menu',
 | 
			
		||||
          'destination_module' => 'menu_ui',
 | 
			
		||||
        ],
 | 
			
		||||
        'menu_link_content' => [
 | 
			
		||||
          'source_module' => 'menu',
 | 
			
		||||
          'destination_module' => 'menu_link_content',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'source_system_data' => [
 | 
			
		||||
        'module' => [
 | 
			
		||||
          'menu' => [
 | 
			
		||||
            'name' => 'menu',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'system' => [
 | 
			
		||||
            'name' => 'system',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
 | 
			
		||||
      'expected_7' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'expected_6' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
          'content' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test menu migration with menu_link_content uninstalled.
 | 
			
		||||
    $tests[2] = $tests[1];
 | 
			
		||||
    unset($tests[2]['modules_to_enable']['menu_link_content']);
 | 
			
		||||
    unset($tests[2]['files']['menu_link_content']);
 | 
			
		||||
    unset($tests[2]['migrations']['menu_link_content']);
 | 
			
		||||
    $tests[2]['expected_7'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        'system' => '',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[2]['expected_6'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'content' => '',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test menu migration with menu_ui uninstalled.
 | 
			
		||||
    $tests[3] = $tests[1];
 | 
			
		||||
    unset($tests[3]['modules_to_enable']['menu_ui']);
 | 
			
		||||
    unset($tests[3]['migrations']['menu_ui']);
 | 
			
		||||
    $tests[3]['expected_7'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        'system' => '',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[3]['expected_6'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'menu' => 'menu_link_content, menu_ui, system',
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'content' => '',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test an i18n migration with all three required destination modules
 | 
			
		||||
    // enabled.
 | 
			
		||||
    $tests[4] = [
 | 
			
		||||
      'modules_to_enable' => [
 | 
			
		||||
        'block' => [],
 | 
			
		||||
        'block_content' => [],
 | 
			
		||||
        'content_translation' => [],
 | 
			
		||||
        'system' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'files' => [
 | 
			
		||||
        'system' => <<<SYSTEM
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    i18nblocks:
 | 
			
		||||
      - block
 | 
			
		||||
      - block_content
 | 
			
		||||
      - content_translation
 | 
			
		||||
  7:
 | 
			
		||||
    i18nblocks:
 | 
			
		||||
      - block
 | 
			
		||||
      - block_content
 | 
			
		||||
      - content_translation
 | 
			
		||||
SYSTEM
 | 
			
		||||
        ,
 | 
			
		||||
        'block' => <<<BLOCK
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    block: block
 | 
			
		||||
  7:
 | 
			
		||||
    block: block
 | 
			
		||||
BLOCK
 | 
			
		||||
        ,
 | 
			
		||||
        'block_content' => <<<BLOCK_CONTENT
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    block: block_content
 | 
			
		||||
  7:
 | 
			
		||||
    block: block_content
 | 
			
		||||
BLOCK_CONTENT
 | 
			
		||||
        ,
 | 
			
		||||
      ],
 | 
			
		||||
      'field_plugins' => [],
 | 
			
		||||
      'migrations' => [
 | 
			
		||||
        'block' => [
 | 
			
		||||
          'source_module' => 'block',
 | 
			
		||||
          'destination_module' => 'block',
 | 
			
		||||
        ],
 | 
			
		||||
        'block_content' => [
 | 
			
		||||
          'source_module' => 'block',
 | 
			
		||||
          'destination_module' => 'block_content',
 | 
			
		||||
        ],
 | 
			
		||||
        'i18nblocks' => [
 | 
			
		||||
          'source_module' => 'i18nblocks',
 | 
			
		||||
          'destination_module' => 'content_translation',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'source_system_data' => [
 | 
			
		||||
        'module' => [
 | 
			
		||||
          'block' => [
 | 
			
		||||
            'name' => 'block',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'i18nblocks' => [
 | 
			
		||||
            'name' => 'i18nblocks',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'system' => [
 | 
			
		||||
            'name' => 'system',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
 | 
			
		||||
      'expected_7' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'block' => 'block, block_content',
 | 
			
		||||
          'i18nblocks' => 'block, block_content, content_translation',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'expected_6' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
          'content' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'block' => 'block, block_content',
 | 
			
		||||
          'i18nblocks' => 'block, block_content, content_translation',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Test i18n_block  migration with block uninstalled.
 | 
			
		||||
    $tests[5] = $tests[4];
 | 
			
		||||
    unset($tests[5]['modules_to_enable']['block']);
 | 
			
		||||
    unset($tests[5]['files']['block']);
 | 
			
		||||
    unset($tests[5]['migrations']['block']);
 | 
			
		||||
    $tests[5]['expected_7'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'i18nblocks' => 'block, block_content, content_translation',
 | 
			
		||||
      ],
 | 
			
		||||
      MigrationState::FINISHED => [
 | 
			
		||||
        'block' => 'block_content',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[5]['expected_6'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'content' => '',
 | 
			
		||||
        'i18nblocks' => 'block, block_content, content_translation',
 | 
			
		||||
      ],
 | 
			
		||||
      MigrationState::FINISHED => [
 | 
			
		||||
        'block' => 'block_content',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Tests modules that don't require an upgrade path.
 | 
			
		||||
    $tests[6] = [
 | 
			
		||||
      'modules_to_enable' => [
 | 
			
		||||
        'system' => [],
 | 
			
		||||
        'content_translation' => [],
 | 
			
		||||
      ],
 | 
			
		||||
      'files' => [
 | 
			
		||||
        'system' => <<<SYSTEM
 | 
			
		||||
finished:
 | 
			
		||||
  6:
 | 
			
		||||
    help: core
 | 
			
		||||
    i18ncontent: content_translation
 | 
			
		||||
  7:
 | 
			
		||||
    help: core
 | 
			
		||||
    i18ncontent: content_translation
 | 
			
		||||
SYSTEM
 | 
			
		||||
        ,
 | 
			
		||||
      ],
 | 
			
		||||
      'field_plugins' => [],
 | 
			
		||||
      'migrations' => [],
 | 
			
		||||
      'source_system_data' => [
 | 
			
		||||
        'module' => [
 | 
			
		||||
          'system' => [
 | 
			
		||||
            'name' => 'system',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'help' => [
 | 
			
		||||
            'name' => 'help',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
          'i18ncontent' => [
 | 
			
		||||
            'name' => 'i18ncontent',
 | 
			
		||||
            'status' => TRUE,
 | 
			
		||||
          ],
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
 | 
			
		||||
      'expected_7' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'help' => 'core',
 | 
			
		||||
          'i18ncontent' => 'content_translation',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
      'expected_6' => [
 | 
			
		||||
        MigrationState::NOT_FINISHED => [
 | 
			
		||||
          'system' => '',
 | 
			
		||||
          'content' => '',
 | 
			
		||||
        ],
 | 
			
		||||
        MigrationState::FINISHED => [
 | 
			
		||||
          'help' => 'core',
 | 
			
		||||
          'i18ncontent' => 'content_translation',
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    $tests[7] = $tests[6];
 | 
			
		||||
    unset($tests[7]['modules_to_enable']['content_translation']);
 | 
			
		||||
    $tests[7]['expected_7'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'i18ncontent' => 'content_translation',
 | 
			
		||||
      ],
 | 
			
		||||
      MigrationState::FINISHED => [
 | 
			
		||||
        'help' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
    $tests[7]['expected_6'] = [
 | 
			
		||||
      MigrationState::NOT_FINISHED => [
 | 
			
		||||
        'system' => '',
 | 
			
		||||
        'content' => '',
 | 
			
		||||
        'i18ncontent' => 'content_translation',
 | 
			
		||||
      ],
 | 
			
		||||
      MigrationState::FINISHED => [
 | 
			
		||||
        'help' => 'core',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return $tests;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,218 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit\source;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Database\Connection;
 | 
			
		||||
use Drupal\Tests\migrate\Unit\MigrateTestCase;
 | 
			
		||||
use Drupal\migrate\Exception\RequirementsException;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @coversDefaultClass \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class DrupalSqlBaseTest extends MigrateTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Define bare minimum migration configuration.
 | 
			
		||||
   *
 | 
			
		||||
   * @var string[]
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationConfiguration = [
 | 
			
		||||
    'id' => 'DrupalSqlBase',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The DrupalSqlBase object.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase
 | 
			
		||||
   */
 | 
			
		||||
  protected $base;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The plugin definition.
 | 
			
		||||
   *
 | 
			
		||||
   * @var array
 | 
			
		||||
   */
 | 
			
		||||
  protected $pluginDefinition = [];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Mock StateInterface.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \PHPUnit\Framework\MockObject\MockObject
 | 
			
		||||
   */
 | 
			
		||||
  protected $state;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Mock entity type manager.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \PHPUnit\Framework\MockObject\MockObject
 | 
			
		||||
   */
 | 
			
		||||
  protected $entityTypeManager;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Minimum database contents needed to test DrupalSqlBase.
 | 
			
		||||
   *
 | 
			
		||||
   * @var string[]
 | 
			
		||||
   */
 | 
			
		||||
  protected $databaseContents = [
 | 
			
		||||
    'system' => [
 | 
			
		||||
      [
 | 
			
		||||
        'filename' => 'sites/all/modules/module1',
 | 
			
		||||
        'name' => 'module1',
 | 
			
		||||
        'type' => 'module',
 | 
			
		||||
        'status' => 0,
 | 
			
		||||
        'schema_version' => -1,
 | 
			
		||||
      ],
 | 
			
		||||
    ],
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
    $this->pluginDefinition['requirements_met'] = TRUE;
 | 
			
		||||
    $this->pluginDefinition['source_module'] = 'module1';
 | 
			
		||||
    $this->state = $this->createMock('Drupal\Core\State\StateInterface');
 | 
			
		||||
    $this->entityTypeManager = $this->createMock('Drupal\Core\Entity\EntityTypeManagerInterface');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @covers ::checkRequirements
 | 
			
		||||
   */
 | 
			
		||||
  public function testSourceProviderNotActive(): void {
 | 
			
		||||
    $plugin = new TestDrupalSqlBase([], 'placeholder_id', $this->pluginDefinition, $this->getMigration(), $this->state, $this->entityTypeManager);
 | 
			
		||||
    $plugin->setDatabase($this->getDatabase($this->databaseContents));
 | 
			
		||||
    $this->expectException(RequirementsException::class);
 | 
			
		||||
    $this->expectExceptionMessage('The module module1 is not enabled in the source site.');
 | 
			
		||||
    try {
 | 
			
		||||
      $plugin->checkRequirements();
 | 
			
		||||
    }
 | 
			
		||||
    catch (RequirementsException $e) {
 | 
			
		||||
      // Ensure requirements are set on the exception.
 | 
			
		||||
      $this->assertEquals(['source_module' => 'module1'], $e->getRequirements());
 | 
			
		||||
      // Re-throw so PHPUnit can assert the exception.
 | 
			
		||||
      throw $e;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @covers ::checkRequirements
 | 
			
		||||
   */
 | 
			
		||||
  public function testSourceDatabaseError(): void {
 | 
			
		||||
    $plugin = new TestDrupalSqlBase([], 'test', $this->pluginDefinition, $this->getMigration(), $this->state, $this->entityTypeManager);
 | 
			
		||||
    $this->expectException(RequirementsException::class);
 | 
			
		||||
    $this->expectExceptionMessage('No database connection configured for source plugin test');
 | 
			
		||||
    $plugin->checkRequirements();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @covers ::checkRequirements
 | 
			
		||||
   *
 | 
			
		||||
   * @param bool $success
 | 
			
		||||
   *   True if this test will not throw an exception.
 | 
			
		||||
   * @param null|string $minimum_version
 | 
			
		||||
   *   The minimum version declared in the configuration of a source plugin.
 | 
			
		||||
   * @param string $schema_version
 | 
			
		||||
   *   The schema version for the source module declared in a source plugin.
 | 
			
		||||
   *
 | 
			
		||||
   * @dataProvider providerMinimumVersion
 | 
			
		||||
   */
 | 
			
		||||
  public function testMinimumVersion($success, $minimum_version, $schema_version): void {
 | 
			
		||||
    $this->pluginDefinition['minimum_version'] = $minimum_version;
 | 
			
		||||
    $this->databaseContents['system'][0]['status'] = 1;
 | 
			
		||||
    $this->databaseContents['system'][0]['schema_version'] = $schema_version;
 | 
			
		||||
    $plugin = new TestDrupalSqlBase([], 'test', $this->pluginDefinition, $this->getMigration(), $this->state, $this->entityTypeManager);
 | 
			
		||||
    $plugin->setDatabase($this->getDatabase($this->databaseContents));
 | 
			
		||||
    $this->assertSame([], $plugin->fields());
 | 
			
		||||
 | 
			
		||||
    if (!$success) {
 | 
			
		||||
      $this->expectException(RequirementsException::class);
 | 
			
		||||
      $this->expectExceptionMessage("Required minimum version $minimum_version");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $plugin->checkRequirements();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Provides data for testMinimumVersion.
 | 
			
		||||
   */
 | 
			
		||||
  public static function providerMinimumVersion() {
 | 
			
		||||
    return [
 | 
			
		||||
      'minimum less than schema' => [
 | 
			
		||||
        TRUE,
 | 
			
		||||
        '7000',
 | 
			
		||||
        '7001',
 | 
			
		||||
      ],
 | 
			
		||||
      'same version' => [
 | 
			
		||||
        TRUE,
 | 
			
		||||
        '7001',
 | 
			
		||||
        '7001',
 | 
			
		||||
      ],
 | 
			
		||||
      'minimum greater than schema' => [
 | 
			
		||||
        FALSE,
 | 
			
		||||
        '7005',
 | 
			
		||||
        '7001',
 | 
			
		||||
      ],
 | 
			
		||||
      'schema version 0' => [
 | 
			
		||||
        FALSE,
 | 
			
		||||
        '7000',
 | 
			
		||||
        '0',
 | 
			
		||||
      ],
 | 
			
		||||
      'schema version -1' => [
 | 
			
		||||
        FALSE,
 | 
			
		||||
        '7000',
 | 
			
		||||
        '-1',
 | 
			
		||||
      ],
 | 
			
		||||
      'minimum not set' => [
 | 
			
		||||
        TRUE,
 | 
			
		||||
        NULL,
 | 
			
		||||
        '-1',
 | 
			
		||||
      ],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extends the DrupalSqlBase abstract class.
 | 
			
		||||
 */
 | 
			
		||||
class TestDrupalSqlBase extends DrupalSqlBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function fields() {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function query() {
 | 
			
		||||
    throw new \RuntimeException(__METHOD__ . " not implemented for " . __CLASS__);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tweaks DrupalSqlBase to set a new database connection for tests.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Database\Connection $database
 | 
			
		||||
   *   The new connection to use.
 | 
			
		||||
   *
 | 
			
		||||
   * @see \Drupal\Tests\migrate\Unit\MigrateSourceSqlTestCase
 | 
			
		||||
   */
 | 
			
		||||
  public function setDatabase(Connection $database): void {
 | 
			
		||||
    $this->database = $database;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getIds() {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,229 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit\source\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\Tests\migrate\Unit\MigrateTestCase;
 | 
			
		||||
 | 
			
		||||
// cspell:ignore throttleable
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests the D6 SQL base class.
 | 
			
		||||
 *
 | 
			
		||||
 * @group migrate_drupal
 | 
			
		||||
 */
 | 
			
		||||
class Drupal6SqlBaseTest extends MigrateTestCase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Define bare minimum migration configuration.
 | 
			
		||||
   *
 | 
			
		||||
   * @var string[]
 | 
			
		||||
   */
 | 
			
		||||
  protected $migrationConfiguration = [
 | 
			
		||||
    'id' => 'Drupal6SqlBase',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The DrupalSqlBase object.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase
 | 
			
		||||
   */
 | 
			
		||||
  protected $base;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Minimum database contents needed to test Drupal6SqlBase.
 | 
			
		||||
   *
 | 
			
		||||
   * @var string[]
 | 
			
		||||
   */
 | 
			
		||||
  protected $databaseContents = [
 | 
			
		||||
    'system' => [
 | 
			
		||||
      [
 | 
			
		||||
        'filename' => 'sites/all/modules/module1',
 | 
			
		||||
        'name' => 'module1',
 | 
			
		||||
        'type' => 'module',
 | 
			
		||||
        'status' => 1,
 | 
			
		||||
        'schema_version' => -1,
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'filename' => 'sites/all/modules/module2',
 | 
			
		||||
        'name' => 'module2',
 | 
			
		||||
        'type' => 'module',
 | 
			
		||||
        'status' => 0,
 | 
			
		||||
        'schema_version' => 7201,
 | 
			
		||||
      ],
 | 
			
		||||
      [
 | 
			
		||||
        'filename' => 'sites/all/modules/test2',
 | 
			
		||||
        'name' => 'test2',
 | 
			
		||||
        'type' => 'theme',
 | 
			
		||||
        'status' => 1,
 | 
			
		||||
        'schema_version' => -1,
 | 
			
		||||
      ],
 | 
			
		||||
    ],
 | 
			
		||||
    'variable' => [
 | 
			
		||||
      [
 | 
			
		||||
        'name' => 'my_variable',
 | 
			
		||||
        'value' => 'b:1;',
 | 
			
		||||
      ],
 | 
			
		||||
    ],
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  protected function setUp(): void {
 | 
			
		||||
    parent::setUp();
 | 
			
		||||
 | 
			
		||||
    $plugin = 'placeholder_id';
 | 
			
		||||
    /** @var \Drupal\Core\State\StateInterface $state */
 | 
			
		||||
    $state = $this->createMock('Drupal\Core\State\StateInterface');
 | 
			
		||||
    /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
 | 
			
		||||
    $entity_type_manager = $this->createMock('Drupal\Core\Entity\EntityTypeManagerInterface');
 | 
			
		||||
    $this->base = new TestDrupal6SqlBase($this->migrationConfiguration, $plugin, [], $this->getMigration(), $state, $entity_type_manager);
 | 
			
		||||
    $this->base->setDatabase($this->getDatabase($this->databaseContents));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests for Drupal6SqlBase::getSystemData().
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetSystemData(): void {
 | 
			
		||||
    $system_data = $this->base->getSystemData();
 | 
			
		||||
    // Should be 1 theme and 2 modules.
 | 
			
		||||
    $this->assertCount(1, $system_data['theme']);
 | 
			
		||||
    $this->assertCount(2, $system_data['module']);
 | 
			
		||||
 | 
			
		||||
    // Calling again should be identical.
 | 
			
		||||
    $this->assertSame($system_data, $this->base->getSystemData());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests for Drupal6SqlBase::moduleExists().
 | 
			
		||||
   */
 | 
			
		||||
  public function testDrupal6ModuleExists(): void {
 | 
			
		||||
    // This module should exist.
 | 
			
		||||
    $this->assertTrue($this->base->moduleExistsWrapper('module1'));
 | 
			
		||||
 | 
			
		||||
    // These modules should not exist.
 | 
			
		||||
    $this->assertFalse($this->base->moduleExistsWrapper('module2'));
 | 
			
		||||
    $this->assertFalse($this->base->moduleExistsWrapper('module3'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests for Drupal6SqlBase::getModuleSchemaVersion().
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetModuleSchemaVersion(): void {
 | 
			
		||||
    // Non-existent module.
 | 
			
		||||
    $this->assertFalse($this->base->getModuleSchemaVersionWrapper('module3'));
 | 
			
		||||
 | 
			
		||||
    // Disabled module should still return schema version.
 | 
			
		||||
    $this->assertEquals(7201, $this->base->getModuleSchemaVersionWrapper('module2'));
 | 
			
		||||
 | 
			
		||||
    // Enabled module.
 | 
			
		||||
    $this->assertEquals(-1, $this->base->getModuleSchemaVersionWrapper('module1'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests for Drupal6SqlBase::variableGet().
 | 
			
		||||
   */
 | 
			
		||||
  public function testVariableGet(): void {
 | 
			
		||||
    // Test default value.
 | 
			
		||||
    $this->assertEquals('my_default', $this->base->variableGetWrapper('non_existent_variable', 'my_default'));
 | 
			
		||||
 | 
			
		||||
    // Test non-default.
 | 
			
		||||
    $this->assertTrue($this->base->variableGetWrapper('my_variable', FALSE));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\migrate_drupal\Unit\source\d6;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Database\Connection;
 | 
			
		||||
use Drupal\Core\Extension\ModuleHandlerInterface;
 | 
			
		||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extends the Drupal6SqlBase abstract class.
 | 
			
		||||
 */
 | 
			
		||||
class TestDrupal6SqlBase extends DrupalSqlBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function fields() {
 | 
			
		||||
    return [
 | 
			
		||||
      'filename' => 'The path of the primary file for this item.',
 | 
			
		||||
      'name' => 'The name of the item; e.g. node.',
 | 
			
		||||
      'type' => 'The type of the item, either module, theme, or theme_engine.',
 | 
			
		||||
      'owner' => "A theme's 'parent'. Can be either a theme or an engine.",
 | 
			
		||||
      'status' => 'Boolean indicating whether or not this item is enabled.',
 | 
			
		||||
      'throttle' => 'Boolean indicating whether this item is disabled when the throttle.module disables throttleable items.',
 | 
			
		||||
      'bootstrap' => "Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted).",
 | 
			
		||||
      'schema_version' => "The module's database schema version number.",
 | 
			
		||||
      'weight' => "The order in which this module's hooks should be invoked.",
 | 
			
		||||
      'info' => "A serialized array containing information from the module's .info file.",
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function query() {
 | 
			
		||||
    $query = $this->database
 | 
			
		||||
      ->select('system', 's')
 | 
			
		||||
      ->fields('s', ['filename', 'name', 'schema_version']);
 | 
			
		||||
    return $query;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tweaks Drupal6SqlBase to set a new database connection for tests.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Database\Connection $database
 | 
			
		||||
   *   The new connection to use.
 | 
			
		||||
   *
 | 
			
		||||
   * @see \Drupal\Tests\migrate\Unit\MigrateSqlTestCase
 | 
			
		||||
   */
 | 
			
		||||
  public function setDatabase(Connection $database): void {
 | 
			
		||||
    $this->database = $database;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tweaks Drupal6SqlBase to set a new module handler for tests.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
 | 
			
		||||
   *   The new module handler to use.
 | 
			
		||||
   *
 | 
			
		||||
   * @see \Drupal\Tests\migrate\Unit\MigrateSqlTestCase
 | 
			
		||||
   */
 | 
			
		||||
  public function setModuleHandler(ModuleHandlerInterface $module_handler): void {
 | 
			
		||||
    $this->moduleHandler = $module_handler;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Wrapper method to test protected method moduleExists().
 | 
			
		||||
   */
 | 
			
		||||
  public function moduleExistsWrapper($module) {
 | 
			
		||||
    return parent::moduleExists($module);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Wrapper method to test protected method getModuleSchemaVersion().
 | 
			
		||||
   */
 | 
			
		||||
  public function getModuleSchemaVersionWrapper($module) {
 | 
			
		||||
    return parent::getModuleSchemaVersion($module);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Wrapper method to test protected method variableGet().
 | 
			
		||||
   */
 | 
			
		||||
  public function variableGetWrapper($name, $default) {
 | 
			
		||||
    return parent::variableGet($name, $default);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public function getIds() {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user