diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php index 19a8b24777..1b4aaa35e3 100644 --- a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php +++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php @@ -70,11 +70,11 @@ public function testProvidersExist() { public function testFieldProvidersExist() { $expected_mappings = [ 'userreference' => [ - 'source_module' => 'user_reference', + 'source_module' => 'userreference', 'destination_module' => 'core', ], 'nodereference' => [ - 'source_module' => 'node_reference', + 'source_module' => 'nodereference', 'destination_module' => 'core', ], 'optionwidgets' => [ diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php index d3205a6029..e8c2dd5e6d 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php @@ -11,7 +11,7 @@ * type_map = { * "nodereference" = "entity_reference", * }, - * source_module = "node_reference", + * source_module = "nodereference", * destination_module = "core", * ) */ diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php index b52b44603c..b42d94cba3 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php @@ -11,7 +11,7 @@ * type_map = { * "userreference" = "entity_reference", * }, - * source_module = "user_reference", + * source_module = "userreference", * destination_module = "core", * ) */ diff --git a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php index 898a8a5568..375f8af26e 100644 --- a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php +++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php @@ -69,6 +69,101 @@ class MigrateUpgradeForm extends ConfirmFormBase { protected $moduleHandler; /** + * List of extensions that do not need an upgrade path. + * + * This property is an array where the keys are the version of Drupal from + * which we are upgrading and the values are arrays of extensions that do not + * need an upgrade path. + * + * @var array[] + */ + protected $noUpgradePaths = [ + '6' => [ + 'blog', + 'blogapi', + 'calendarsignup', + 'color', + 'content_copy', + 'content_multigroup', + 'content_permissions', + 'date_api', + 'date_locale', + 'date_php4', + 'date_popup', + 'date_repeat', + 'date_timezone', + 'date_tools', + 'datepicker', + 'ddblock', + 'fieldgroup', + 'filefield_meta', + 'help', + 'i18n', + 'i18nstrings', + 'imageapi', + 'imageapi_gd', + 'imageapi_imagemagick', + 'imagecache_ui', + 'jquery_ui', + 'nodeaccess', + 'number', + 'openid', + 'php', + 'ping', + 'poll', + 'throttle', + 'tracker', + 'translation', + 'trigger', + 'variable', + 'variable_admin', + 'views_export', + 'views_ui', + ], + '7' => [ + 'blog', + 'book', + 'bulk_export', + 'contextual', + 'ctools', + 'ctools_access_ruleset', + 'ctools_ajax_sample', + 'ctools_custom_content', + 'dashboard', + 'date_all_day', + 'date_api', + 'date_context', + 'date_migrate', + 'date_popup', + 'date_repeat', + 'date_repeat_field', + 'date_tools', + 'date_views', + 'entity', + 'entity_feature', + 'entity_token', + 'field_ui', + 'help', + 'openid', + 'overlay', + 'page_manager', + 'php', + 'poll', + 'search_embedded_form', + 'search_extra_type', + 'search_node_tags', + 'simpletest', + 'stylizer', + 'term_depth', + 'toolbar', + 'translation', + 'trigger', + 'views_content', + 'views_ui', + ], + ]; + + /** * Constructs the MigrateUpgradeForm. * * @param \Drupal\Core\State\StateInterface $state @@ -160,6 +255,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) { public function buildOverviewForm(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Upgrade'); + // Add the no upgrade path array to the form state so it can be altered. + $form_state->set('no_upgrade_paths', $this->noUpgradePaths); + if ($date_performed = $this->state->get('migrate_drupal_ui.performed')) { // @todo Add back support for rollbacks and incremental migrations. // https://www.drupal.org/node/2687843 @@ -269,7 +367,7 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) '#type' => 'radios', '#default_value' => 7, '#title' => $this->t('Drupal version of the source site'), - '#options' => [6 => $this->t('Drupal 6'), 7 => $this->t('Drupal 7')], + '#options' => ['6' => $this->t('Drupal 6'), '7' => $this->t('Drupal 7')], '#required' => TRUE, ]; @@ -332,7 +430,7 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) '#description' => $this->t('To import files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'), '#states' => [ 'visible' => [ - ':input[name="version"]' => ['value' => 6], + ':input[name="version"]' => ['value' => '6'], ], ], ]; @@ -343,7 +441,7 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) '#description' => $this->t('To import public files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'), '#states' => [ 'visible' => [ - ':input[name="version"]' => ['value' => 7], + ':input[name="version"]' => ['value' => '7'], ], ], ]; @@ -355,7 +453,7 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) '#description' => $this->t('To import private files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot).'), '#states' => [ 'visible' => [ - ':input[name="version"]' => ['value' => 7], + ':input[name="version"]' => ['value' => '7'], ], ], ]; @@ -404,11 +502,11 @@ public function validateCredentialForm(array &$form, FormStateInterface $form_st try { $connection = $this->getConnection($database); - $version = $this->getLegacyDrupalVersion($connection); + $version = (string) $this->getLegacyDrupalVersion($connection); if (!$version) { $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database does not contain a recognizable Drupal version.')); } - elseif ($version != $form_state->getValue('version')) { + elseif ($version !== (string) $form_state->getValue('version')) { $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database is Drupal version @version but version @selected was selected.', [ '@version' => $version, '@selected' => $form_state->getValue('version'), @@ -431,7 +529,7 @@ public function validateCredentialForm(array &$form, FormStateInterface $form_st // Store the retrieved migration IDs in form storage. $form_state->set('version', $version); $form_state->set('migrations', $migration_array); - if ($version == 6) { + if ($version === '6') { $form_state->set('source_base_path', $form_state->getValue('d6_source_base_path')); } else { @@ -661,9 +759,23 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { // Get the source_module and destination_module from the field plugins. $definitions = $this->fieldPluginManager->getDefinitions(); foreach ($definitions as $definition) { - $source_module = $definition['source_module']; - $destination_module = $definition['destination_module']; - $table_data[$source_module][$destination_module][$definition['id']] = $definition['id']; + if (in_array($version, $definition['core'])) { + $source_module = $definition['source_module']; + $destination_module = $definition['destination_module']; + $table_data[$source_module][$destination_module][$definition['id']] = $definition['id']; + } + } + + // Fetch the system data at the first opportunity. + $system_data = $form_state->get('system_data'); + + // Add source_module and destination_module for modules that do not need an + // upgrade path and are enabled on the source site. + $no_upgrade_paths = $form_state->get('no_upgrade_paths'); + foreach ($no_upgrade_paths[$version] as $extension) { + if ($system_data['module'][$extension]['status']) { + $table_data[$extension]['core'][$extension] = $extension; + } } // Sort the table by source module names and within that destination @@ -673,8 +785,6 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { ksort($table_data[$source_module]); } - // Fetch the system data at the first opportunity. - $system_data = $form_state->get('system_data'); // Remove core profiles from the system data. foreach (['standard', 'minimal'] as $profile) { unset($system_data['module'][$profile]); diff --git a/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.info.yml b/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.info.yml new file mode 100644 index 0000000000..c6b66cdb34 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.info.yml @@ -0,0 +1,6 @@ +name: 'Upgrade form alter test' +type: module +description: 'Tests that contrib modules can alter the upgrade form.' +package: Testing +version: VERSION +core: 8.x diff --git a/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.module b/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.module new file mode 100644 index 0000000000..8855721dc3 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/upgrade_form_alter_test/upgrade_form_alter_test.module @@ -0,0 +1,18 @@ +get('no_upgrade_paths'); + $no_upgrade_paths['6'][] = 'event'; + $no_upgrade_paths['7'][] = 'book'; + $form_state->set('no_upgrade_paths', $no_upgrade_paths); +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php similarity index 60% copy from core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php copy to core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php index 98c05aaef4..e6ef1e3d15 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php @@ -2,35 +2,19 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional; -use Drupal\Core\Database\Database; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate_drupal\MigrationConfigurationTrait; -use Drupal\Tests\BrowserTestBase; use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait; /** * Provides a base class for testing migration upgrades in the UI. */ -abstract class MigrateUpgradeTestBase extends BrowserTestBase { +abstract class MigrateUpgradeExecuteTestBase extends MigrateUpgradeTestBase { use MigrationConfigurationTrait; use CreateTestContentEntitiesTrait; /** - * Use the Standard profile to test help implementations of many core modules. - * - * @var string - */ - protected $profile = 'standard'; - - /** - * The source database connection. - * - * @var \Drupal\Core\Database\Connection - */ - protected $sourceDatabase; - - /** * Modules to enable. * * @var array @@ -45,6 +29,7 @@ 'forum', 'statistics', 'migration_provider_test', + 'upgrade_form_alter_test', ]; /** @@ -52,74 +37,15 @@ */ protected function setUp() { parent::setUp(); - $this->createMigrationConnection(); - $this->sourceDatabase = Database::getConnection('default', 'migrate_drupal_ui'); - - // Log in as user 1. Migrations in the UI can only be performed as user 1. - $this->drupalLogin($this->rootUser); // Create content. $this->createContent(); } /** - * 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 (substr($path, -3) == '.gz') { - $path = 'compress.zlib://' . $path; - } - require $path; - - Database::setActiveConnection($default_db); - } - - /** - * Changes the database connection to the prefixed one. - * - * @todo Remove when we don't use global. https://www.drupal.org/node/2552791 - */ - protected function createMigrationConnection() { - $connection_info = Database::getConnectionInfo('default')['default']; - if ($connection_info['driver'] === 'sqlite') { - // Create database file in the test site's public file directory so that - // \Drupal\simpletest\TestBase::restoreEnvironment() will delete this once - // the test is complete. - $file = $this->publicFilesDirectory . '/' . $this->testId . '-migrate.db.sqlite'; - touch($file); - $connection_info['database'] = $file; - $connection_info['prefix'] = ''; - } - else { - $prefix = is_array($connection_info['prefix']) ? $connection_info['prefix']['default'] : $connection_info['prefix']; - // Simpletest uses fixed length prefixes. Create a new prefix for the - // source database. Adding to the end of the prefix ensures that - // \Drupal\simpletest\TestBase::restoreEnvironment() will remove the - // additional tables. - $connection_info['prefix'] = $prefix . '0'; - } - - Database::addConnectionInfo('migrate_drupal_ui', 'default', $connection_info); - } - - /** - * {@inheritdoc} - */ - protected function tearDown() { - Database::removeConnection('migrate_drupal_ui'); - parent::tearDown(); - } - - /** * Executes all steps of migrations upgrade. */ - public function testMigrateUpgrade() { + public function testMigrateUpgradeExecute() { $connection_options = $this->sourceDatabase->getConnectionOptions(); $this->drupalGet('/upgrade'); $session = $this->assertSession(); @@ -197,26 +123,17 @@ public function testMigrateUpgrade() { $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.')); $session->statusCodeEquals(200); $session->pageTextContains('Upgrade analysis report'); - // Ensure there are no errors about the missing modules from the test module. + // Ensure there are no errors about missing modules from the test module. $session->pageTextNotContains(t('Source module not found for migration_provider_no_annotation.')); $session->pageTextNotContains(t('Source module not found for migration_provider_test.')); $session->pageTextNotContains(t('Destination module not found for migration_provider_test')); // Ensure there are no errors about any other missing migration providers. $session->pageTextNotContains(t('module not found')); - // Test the available migration paths. - $all_available = $this->getAvailablePaths(); - foreach ($all_available as $available) { - $session->elementExists('xpath', "//span[contains(@class, 'checked') and text() = '$available']"); - $session->elementNotExists('xpath', "//span[contains(@class, 'warning') and text() = '$available']"); - } - - // Test the missing migration paths. - $all_missing = $this->getMissingPaths(); - foreach ($all_missing as $missing) { - $session->elementExists('xpath', "//span[contains(@class, 'warning') and text() = '$missing']"); - $session->elementNotExists('xpath', "//span[contains(@class, 'checked') and text() = '$missing']"); - } + // Test the upgrade paths. + $available_paths = $this->getAvailablePaths(); + $missing_paths = $this->getMissingPaths(); + $this->assertUpgradePaths($session, $available_paths, $missing_paths); $this->drupalPostForm(NULL, [], t('Perform upgrade')); $this->assertText(t('Congratulations, you upgraded Drupal!')); @@ -261,58 +178,4 @@ public function testMigrateUpgrade() { \Drupal::service('module_installer')->install(['book']); } - /** - * Transforms a nested array into a flat array suitable for BrowserTestBase::drupalPostForm(). - * - * @param array $values - * A multi-dimensional form values array to convert. - * - * @return array - * The flattened $edit array suitable for BrowserTestBase::drupalPostForm(). - */ - protected function translatePostValues(array $values) { - $edit = []; - // The easiest and most straightforward way to translate values suitable for - // BrowserTestBase::drupalPostForm() is to actually build the POST data string - // and convert the resulting key/value pairs back into a flat array. - $query = http_build_query($values); - foreach (explode('&', $query) as $item) { - list($key, $value) = explode('=', $item); - $edit[urldecode($key)] = urldecode($value); - } - return $edit; - } - - /** - * Gets the source base path for the concrete test. - * - * @return string - * The source base path. - */ - abstract protected function getSourceBasePath(); - - /** - * Gets the expected number of entities per entity type after migration. - * - * @return int[] - * An array of expected counts keyed by entity type ID. - */ - abstract protected function getEntityCounts(); - - /** - * Gets the available upgrade paths. - * - * @return string[] - * An array of available upgrade paths. - */ - abstract protected function getAvailablePaths(); - - /** - * Gets the missing upgrade paths. - * - * @return string[] - * An array of missing upgrade paths. - */ - abstract protected function getMissingPaths(); - } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php new file mode 100644 index 0000000000..d158de68bf --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php @@ -0,0 +1,125 @@ +sourceDatabase->getConnectionOptions(); + $driver = $connection_options['driver']; + $connection_options['prefix'] = $connection_options['prefix']['default']; + + // Use the driver connection form to get the correct options out of the + // database settings. This supports all of the databases we test against. + $drivers = drupal_get_database_types(); + $form = $drivers[$driver]->getFormOptions($connection_options); + $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); + $version = $this->getLegacyDrupalVersion($this->sourceDatabase); + $edit = [ + $driver => $connection_options, + 'source_private_file_path' => $this->getSourceBasePath(), + 'version' => $version, + ]; + if ($version == 6) { + $edit['d6_source_base_path'] = $this->getSourceBasePath(); + } + else { + $edit['source_base_path'] = $this->getSourceBasePath(); + } + if (count($drivers) !== 1) { + $edit['driver'] = $driver; + } + $edits = $this->translatePostValues($edit); + + // Enable all modules in the source. + $this->sourceDatabase->update('system') + ->fields(['status' => 1]) + ->condition('type', 'module') + ->condition('name', '%test%', 'NOT LIKE') + ->condition('name', '%example%', 'NOT LIKE') + ->execute(); + $this->sourceDatabase->update('system') + ->fields(['status' => 1]) + ->condition('type', 'module') + ->condition('name', 'simpletest') + ->execute(); + + // Start the upgrade process. + $this->drupalGet('/upgrade'); + $this->drupalPostForm(NULL, [], t('Continue')); + $this->drupalPostForm(NULL, $edits, t('Review upgrade')); + $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.')); + + // Ensure there are no errors about missing modules from the test module. + $session = $this->assertSession(); + $session->pageTextNotContains(t('Source module not found for migration_provider_no_annotation.')); + $session->pageTextNotContains(t('Source module not found for migration_provider_test.')); + $session->pageTextNotContains(t('Destination module not found for migration_provider_test')); + // Ensure there are no errors about any other missing migration providers. + $session->pageTextNotContains(t('module not found')); + + // Test the upgrade paths. + $available_paths = $this->getAvailablePaths(); + $missing_paths = $this->getMissingPaths(); + $this->assertUpgradePaths($session, $available_paths, $missing_paths); + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + return []; + } + +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php index 98c05aaef4..2ad7629b43 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional; use Drupal\Core\Database\Database; -use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate_drupal\MigrationConfigurationTrait; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait; @@ -31,23 +30,6 @@ protected $sourceDatabase; /** - * Modules to enable. - * - * @var array - */ - public static $modules = [ - 'language', - 'content_translation', - 'migrate_drupal_ui', - 'telephone', - 'aggregator', - 'book', - 'forum', - 'statistics', - 'migration_provider_test', - ]; - - /** * {@inheritdoc} */ protected function setUp() { @@ -57,9 +39,6 @@ protected function setUp() { // Log in as user 1. Migrations in the UI can only be performed as user 1. $this->drupalLogin($this->rootUser); - - // Create content. - $this->createContent(); } /** @@ -117,151 +96,6 @@ protected function tearDown() { } /** - * Executes all steps of migrations upgrade. - */ - public function testMigrateUpgrade() { - $connection_options = $this->sourceDatabase->getConnectionOptions(); - $this->drupalGet('/upgrade'); - $session = $this->assertSession(); - $session->responseContains('Upgrade a site by importing its files and the data from its database into a clean and empty new install of Drupal 8.'); - - $this->drupalPostForm(NULL, [], t('Continue')); - $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); - $this->assertFieldByName('mysql[host]'); - - $driver = $connection_options['driver']; - $connection_options['prefix'] = $connection_options['prefix']['default']; - - // Use the driver connection form to get the correct options out of the - // database settings. This supports all of the databases we test against. - $drivers = drupal_get_database_types(); - $form = $drivers[$driver]->getFormOptions($connection_options); - $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); - $version = $this->getLegacyDrupalVersion($this->sourceDatabase); - $edit = [ - $driver => $connection_options, - 'source_private_file_path' => $this->getSourceBasePath(), - 'version' => $version, - ]; - if ($version == 6) { - $edit['d6_source_base_path'] = $this->getSourceBasePath(); - } - else { - $edit['source_base_path'] = $this->getSourceBasePath(); - } - if (count($drivers) !== 1) { - $edit['driver'] = $driver; - } - $edits = $this->translatePostValues($edit); - - // Ensure submitting the form with invalid database credentials gives us a - // nice warning. - $this->drupalPostForm(NULL, [$driver . '[database]' => 'wrong'] + $edits, t('Review upgrade')); - $this->assertText('Resolve the issue below to continue the upgrade.'); - - $this->drupalPostForm(NULL, $edits, t('Review upgrade')); - $session->pageTextContains('WARNING: Content may be overwritten on your new site.'); - $session->pageTextContains('There is conflicting content of these types:'); - $session->pageTextContains('aggregator feed entities'); - $session->pageTextContains('aggregator feed item entities'); - $session->pageTextContains('custom block entities'); - $session->pageTextContains('custom menu link entities'); - $session->pageTextContains('file entities'); - $session->pageTextContains('taxonomy term entities'); - $session->pageTextContains('user entities'); - $session->pageTextContains('comments'); - $session->pageTextContains('content item revisions'); - $session->pageTextContains('content items'); - $session->pageTextContains('There is translated content of these types:'); - $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.')); - $this->assertResponse(200); - $this->assertText('Upgrade analysis report'); - // Ensure we get errors about missing modules. - $session->pageTextContains(t('Source module not found for migration_provider_no_annotation.')); - $session->pageTextContains(t('Source module not found for migration_provider_test.')); - $session->pageTextContains(t('Destination module not found for migration_provider_test')); - - // Uninstall the module causing the missing module error messages. - $this->container->get('module_installer')->uninstall(['migration_provider_test'], TRUE); - - // Restart the upgrade process. - $this->drupalGet('/upgrade'); - $session->responseContains('Upgrade a site by importing its files and the data from its database into a clean and empty new install of Drupal 8.'); - - $this->drupalPostForm(NULL, [], t('Continue')); - $session->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.'); - $session->fieldExists('mysql[host]'); - - $this->drupalPostForm(NULL, $edits, t('Review upgrade')); - $session->pageTextContains('WARNING: Content may be overwritten on your new site.'); - $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.')); - $session->statusCodeEquals(200); - $session->pageTextContains('Upgrade analysis report'); - // Ensure there are no errors about the missing modules from the test module. - $session->pageTextNotContains(t('Source module not found for migration_provider_no_annotation.')); - $session->pageTextNotContains(t('Source module not found for migration_provider_test.')); - $session->pageTextNotContains(t('Destination module not found for migration_provider_test')); - // Ensure there are no errors about any other missing migration providers. - $session->pageTextNotContains(t('module not found')); - - // Test the available migration paths. - $all_available = $this->getAvailablePaths(); - foreach ($all_available as $available) { - $session->elementExists('xpath', "//span[contains(@class, 'checked') and text() = '$available']"); - $session->elementNotExists('xpath', "//span[contains(@class, 'warning') and text() = '$available']"); - } - - // Test the missing migration paths. - $all_missing = $this->getMissingPaths(); - foreach ($all_missing as $missing) { - $session->elementExists('xpath', "//span[contains(@class, 'warning') and text() = '$missing']"); - $session->elementNotExists('xpath', "//span[contains(@class, 'checked') and text() = '$missing']"); - } - - $this->drupalPostForm(NULL, [], t('Perform upgrade')); - $this->assertText(t('Congratulations, you upgraded Drupal!')); - - // Have to reset all the statics after migration to ensure entities are - // loadable. - $this->resetAll(); - - $expected_counts = $this->getEntityCounts(); - foreach (array_keys(\Drupal::entityTypeManager() - ->getDefinitions()) as $entity_type) { - $real_count = \Drupal::entityQuery($entity_type)->count()->execute(); - $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; - $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count."); - } - - $plugin_manager = \Drupal::service('plugin.manager.migration'); - /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */ - $all_migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version); - foreach ($all_migrations as $migration) { - $id_map = $migration->getIdMap(); - foreach ($id_map as $source_id => $map) { - // Convert $source_id into a keyless array so that - // \Drupal\migrate\Plugin\migrate\id_map\Sql::getSourceHash() works as - // expected. - $source_id_values = array_values(unserialize($source_id)); - $row = $id_map->getRowBySource($source_id_values); - $destination = serialize($id_map->currentDestination()); - $message = "Migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; - // A completed migration should have maps with - // MigrateIdMapInterface::STATUS_IGNORED or - // MigrateIdMapInterface::STATUS_IMPORTED. - if ($row['source_row_status'] == MigrateIdMapInterface::STATUS_FAILED || $row['source_row_status'] == MigrateIdMapInterface::STATUS_NEEDS_UPDATE) { - $this->fail($message); - } - else { - $this->pass($message); - } - } - } - \Drupal::service('module_installer')->install(['forum']); - \Drupal::service('module_installer')->install(['book']); - } - - /** * Transforms a nested array into a flat array suitable for BrowserTestBase::drupalPostForm(). * * @param array $values @@ -284,6 +118,33 @@ protected function translatePostValues(array $values) { } /** + * Tests the displayed upgrade paths. + * + * @param $session + * @param $available_paths + * An array of modules that will be upgraded. + * @param $missing_paths + * An array of modules that will not be upgraded. + */ + protected function assertUpgradePaths($session, $available_paths, $missing_paths) { + // Test the available migration paths. + foreach ($available_paths as $available) { + $session->elementExists('xpath', "//span[contains(@class, 'checked') and text() = '$available']"); + $session->elementNotExists('xpath', "//span[contains(@class, 'warning') and text() = '$available']"); + } + + // Test the missing migration paths. + foreach ($missing_paths as $missing) { + $session->elementExists('xpath', "//span[contains(@class, 'warning') and text() = '$missing']"); + $session->elementNotExists('xpath', "//span[contains(@class, 'checked') and text() = '$missing']"); + } + + // Test the total count of missing and available paths. + $session->elementsCount('xpath', "//span[contains(@class, 'upgrade-analysis-report__status-icon--warning')]", count($missing_paths)); + $session->elementsCount('xpath', "//span[contains(@class, 'upgrade-analysis-report__status-icon--checked')]", count($available_paths)); + } + + /** * Gets the source base path for the concrete test. * * @return string diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php new file mode 100644 index 0000000000..7432288a65 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php @@ -0,0 +1,127 @@ +loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php'); + } + + /** + * {@inheritdoc} + */ + protected function getAvailablePaths() { + return [ + 'aggregator', + 'block', + 'book', + 'color', + 'comment', + 'contact', + 'content', + 'date', + 'dblog', + 'email', + 'filefield', + 'filter', + 'forum', + 'i18ntaxonomy', + 'imagecache', + 'imagefield', + 'language', + 'link', + 'locale', + 'menu', + 'node', + 'nodereference', + 'optionwidgets', + 'path', + 'profile', + 'search', + 'statistics', + 'syslog', + 'system', + 'taxonomy', + 'text', + 'update', + 'upload', + 'user', + 'userreference', + // Modules that have no upgrade path. + 'blog', + 'blogapi', + 'calendarsignup', + 'content_copy', + 'content_multigroup', + 'content_permissions', + 'date_api', + 'date_locale', + 'date_php4', + 'date_popup', + 'date_repeat', + 'date_timezone', + 'date_tools', + 'datepicker', + 'ddblock', + 'fieldgroup', + 'filefield_meta', + 'help', + 'i18n', + 'i18nstrings', + 'imageapi', + 'imageapi_gd', + 'imageapi_imagemagick', + 'imagecache_ui', + 'jquery_ui', + 'nodeaccess', + 'number', + 'openid', + 'php', + 'ping', + 'poll', + 'throttle', + 'tracker', + 'translation', + 'trigger', + 'variable', + 'variable_admin', + 'views_export', + 'views_ui', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getMissingPaths() { + return [ + 'devel', + 'devel_generate', + 'devel_node_access', + 'event', + 'i18nblocks', + 'i18ncck', + 'i18ncontent', + 'i18nmenu', + 'i18npoll', + 'i18nprofile', + 'i18nsync', + 'i18nviews', + 'phone', + 'views', + ]; + } + +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php index 432b7036d7..215dd88dd9 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php @@ -2,17 +2,17 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional\d6; -use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase; +use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase; use Drupal\user\Entity\User; /** * Tests Drupal 6 upgrade using the migrate UI. * - * The test method is provided by the MigrateUpgradeTestBase class. + * The test method is provided by the MigrateUpgradeTest class. * * @group migrate_drupal_ui */ -class MigrateUpgrade6Test extends MigrateUpgradeTestBase { +class MigrateUpgrade6Test extends MigrateUpgradeExecuteTestBase { /** * {@inheritdoc} @@ -93,34 +93,43 @@ protected function getAvailablePaths() { 'date', 'dblog', 'email', - 'entityreference', - 'file', 'filefield', 'filter', + 'forum', 'i18ntaxonomy', - 'image', 'imagecache', 'imagefield', + 'language', 'link', - 'list', - 'menu', 'locale', + 'menu', 'node', - 'node_reference', - 'number', - 'options', + 'nodereference', 'optionwidgets', 'path', - 'phone', 'profile', 'search', + 'statistics', 'system', 'taxonomy', 'text', - 'translation', 'upload', 'user', - 'user_reference', + 'userreference', + // Modules that have no upgrade path. + 'date_api', + 'date_timezone', + 'i18n', + 'i18nstrings', + 'imageapi', + 'number', + 'php', + 'profile', + 'variable_admin', + // To test that contrib modules can alter this list, Event is added here + // by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). + 'event', ]; } @@ -129,27 +138,24 @@ protected function getAvailablePaths() { */ protected function getMissingPaths() { return [ - 'date_api', - 'date_timezone', - 'event', - 'i18n', + // To test that contrib modules can alter this list, Event is removed from + // here by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). 'i18nblocks', 'i18ncck', 'i18ncontent', 'i18nmenu', + // This module is in the missing path list because it is installed on the + // source site but it is not installed on the destination site. 'i18nprofile', - 'i18nstrings', - 'imageapi', - 'php', - 'variable_admin', ]; } /** * Executes all steps of migrations upgrade. */ - public function testMigrateUpgrade() { - parent::testMigrateUpgrade(); + public function testMigrateUpgradeExecute() { + parent::testMigrateUpgradeExecute(); // Ensure migrated users can log in. $user = User::load(2); diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php new file mode 100644 index 0000000000..9452c31cf1 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php @@ -0,0 +1,119 @@ +loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php'); + } + + /** + * {@inheritdoc} + */ + protected function getAvailablePaths() { + return [ + 'aggregator', + 'block', + 'comment', + 'contact', + 'date', + 'dblog', + 'email', + 'field', + 'field_sql_storage', + 'file', + 'filter', + 'forum', + 'image', + 'language', + 'link', + 'list', + 'locale', + 'menu', + 'node', + 'number', + 'options', + 'path', + 'phone', + 'profile', + 'search', + 'shortcut', + 'statistics', + 'syslog', + 'system', + 'taxonomy', + 'text', + 'tracker', + 'update', + 'user', + // Modules that have no upgrade path. + 'blog', + 'book', + 'bulk_export', + 'contextual', + 'ctools', + 'ctools_access_ruleset', + 'ctools_ajax_sample', + 'ctools_custom_content', + 'dashboard', + 'date_all_day', + 'date_api', + 'date_context', + 'date_migrate', + 'date_popup', + 'date_repeat', + 'date_repeat_field', + 'date_tools', + 'date_views', + 'entity', + 'entity_feature', + 'entity_token', + 'entityreference', + 'field_ui', + 'help', + 'openid', + 'overlay', + 'page_manager', + 'php', + 'poll', + 'search_embedded_form', + 'search_extra_type', + 'search_node_tags', + 'simpletest', + 'stylizer', + 'term_depth', + 'translation', + 'toolbar', + 'trigger', + 'views_content', + 'views_ui', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getMissingPaths() { + return [ + // To test that contrib modules can alter this list, Book is removed from + // here by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). + 'color', + 'rdf', + 'views', + ]; + } + +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php index 21210dde76..5ab7143453 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php @@ -2,17 +2,17 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional\d7; -use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase; +use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase; use Drupal\user\Entity\User; /** * Tests Drupal 7 upgrade using the migrate UI. * - * The test method is provided by the MigrateUpgradeTestBase class. + * The test method is provided by the MigrateUpgradeTest class. * * @group migrate_drupal_ui */ -class MigrateUpgrade7Test extends MigrateUpgradeTestBase { +class MigrateUpgrade7Test extends MigrateUpgradeExecuteTestBase { /** * {@inheritdoc} @@ -90,6 +90,10 @@ protected function getAvailablePaths() { return [ 'aggregator', 'block', + // To test that contrib modules can alter this list, Book is added here + // by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). + 'book', 'comment', 'contact', 'date', @@ -99,20 +103,17 @@ protected function getAvailablePaths() { 'field', 'field_sql_storage', 'file', - 'filefield', 'filter', 'forum', 'image', - 'imagefield', + 'language', 'link', 'list', 'locale', 'menu', 'node', - 'node_reference', 'number', 'options', - 'optionwidgets', 'path', 'phone', 'search', @@ -121,9 +122,22 @@ protected function getAvailablePaths() { 'system', 'taxonomy', 'text', - 'translation', 'user', - 'user_reference', + // Modules that have no upgrade path. + 'blog', + 'contextual', + 'date_api', + 'entity', + 'field_ui', + 'help', + 'php', + 'simpletest', + 'toolbar', + 'trigger', + // To test that contrib modules can alter this list, Book is added here + // by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). + 'book', ]; } @@ -132,21 +146,15 @@ protected function getAvailablePaths() { */ protected function getMissingPaths() { return [ - 'blog', - 'book', + // To test that contrib modules can alter this list, Book is removed from + // here by a hook_form_alter(). + // @see upgrade_form_alter_test_form_migrate_drupal_ui_form_alter(). 'color', - 'contextual', - 'date_api', - 'entity', - 'field_ui', - 'help', - 'php', 'rdf', - 'simpletest', + // These modules are in the missing path list because they are installed + // on the source site but they are not installed on the destination site. 'syslog', - 'toolbar', 'tracker', - 'trigger', 'update', ]; } @@ -154,8 +162,8 @@ protected function getMissingPaths() { /** * Executes all steps of migrations upgrade. */ - public function testMigrateUpgrade() { - parent::testMigrateUpgrade(); + public function testMigrateUpgradeExecute() { + parent::testMigrateUpgradeExecute(); // Ensure migrated users can log in. $user = User::load(2); diff --git a/core/modules/node/migrations/d6_node_translation.yml b/core/modules/node/migrations/d6_node_translation.yml index 4bf36da736..88d79dd9b4 100644 --- a/core/modules/node/migrations/d6_node_translation.yml +++ b/core/modules/node/migrations/d6_node_translation.yml @@ -6,7 +6,6 @@ deriver: Drupal\node\Plugin\migrate\D6NodeDeriver source: plugin: d6_node translations: true - source_module: translation process: # If you are using this file to build a custom migration consider removing # the nid field to allow incremental migrations. diff --git a/core/modules/node/migrations/d7_node_translation.yml b/core/modules/node/migrations/d7_node_translation.yml index 856f34505e..69217b971f 100644 --- a/core/modules/node/migrations/d7_node_translation.yml +++ b/core/modules/node/migrations/d7_node_translation.yml @@ -7,7 +7,6 @@ deriver: Drupal\node\Plugin\migrate\D7NodeDeriver source: plugin: d7_node translations: true - source_module: translation process: # If you are using this file to build a custom migration consider removing # the nid field to allow incremental migrations.