diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/IdConflictTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/IdConflictTestBase.php index af131515a3..adaae9f0ef 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/IdConflictTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/IdConflictTestBase.php @@ -2,11 +2,167 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional; -/** - * Class IdConflictTestBase - * - * @package \Drupal\Tests\migrate_drupal_ui\Functional - */ -class IdConflictTestBase { + use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait; + + /** + * Provides a base class for testing the review step of the Upgrade form. + * + * When using this test class, enable translation modules. + */ +abstract class IdConflictTestBase extends MigrateUpgradeTestBase { + + use CreateTestContentEntitiesTrait; + + /** + * An array suitable for drupalPostForm(). + * + * @var array + */ + protected $edits = []; + + /** + * {@inheritdoc} + */ + public static $modules = ['migrate_drupal_ui']; + + /** + * Tests the migrate upgrade review form. + * + * The upgrade review form displays a list of modules that will be upgraded + * and a list of modules that will not be upgraded. This test is to ensure + * that the review page works correctly for all contributed Drupal 6 and + * Drupal 7 modules that have moved to core, e.g. Views, and for modules that + * were in Drupal 6 or Drupal 7 core but are not in Drupal 8 core, e.g. + * Overlay. + * + * To do this all modules in the source fixtures are enabled, except test and + * example modules. This means that we can test that the modules that do not + * need any migrations, such as Overlay, since there will be no available + * migrations which declare those modules as their source_module. It is + * assumed that the test fixtures include all modules that have moved to or + * dropped from core. + * + * The upgrade review form will also display errors for each migration that + * does not have a source_module definition. That function is not tested here. + * + * @see \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase + */ + public function testIdConflictPage() { + $this->prepare(); + // Start the upgrade process. + $this->drupalGet('/upgrade'); + $this->drupalPostForm(NULL, [], t('Continue')); + $this->drupalPostForm(NULL, $this->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); + + // Check there are no errors when a module does not have any migrations and + // does not need any. Test with a module that is was in both Drupal 6 and + // Drupal 7 core. + $module = 'help'; + $query = $this->sourceDatabase->delete('system'); + $query->condition('type', 'module'); + $query->condition('name', $module); + $query->execute(); + + // Start the upgrade process. + $this->drupalGet('/upgrade'); + $this->drupalPostForm(NULL, [], t('Continue')); + $this->drupalPostForm(NULL, $this->edits, t('Review upgrade')); + $this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.')); + + // Test the upgrade paths. First remove the module from the available paths + // list. + $available_paths = $this->getAvailablePaths(); + $available_paths = array_diff($available_paths, [$module]); + $missing_paths = $this->getMissingPaths(); + $this->assertUpgradePaths($session, $available_paths, $missing_paths); + } + + /** + * Performs preparation for the form tests. + * + * This is not done in setup because setup executes before the source database + * is loaded. + */ + public function prepare() { + $connection_options = $this->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; + } + $this->edits = $this->translatePostValues($edit); + + // Enable all modules in the source except test and example modules, but + // include simpletest. + /** @var \Drupal\Core\Database\Query\SelectInterface $update */ + $update = $this->sourceDatabase->update('system') + ->fields(['status' => 1]) + ->condition('type', 'module'); + $and = $update->andConditionGroup() + ->condition('name', '%test%', 'NOT LIKE') + ->condition('name', '%example%', 'NOT LIKE'); + $conditions = $update->orConditionGroup(); + $conditions->condition($and); + $conditions->condition('name', 'simpletest'); + $update->condition($conditions); + $update->execute(); + + // Create entries for D8 test modules. + $insert = $this->sourceDatabase->insert('system') + ->fields([ + 'filename' => 'migrate_status_active_test', + 'name' => 'migrate_status_active_test', + 'type' => 'module', + 'status' => 1, + ]); + $insert->execute(); + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + return []; + } + + /** + * {@inheritdoc} + */ + protected function getEntityCountsIncremental() { + return []; + } } + diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php index b664cc4a82..b49c6510f9 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/IdConflictTest.php @@ -2,11 +2,191 @@ namespace Drupal\Tests\migrate_drupal_ui\Functional\d6; -/** - * Class IdConflictTest - * - * @package \Drupal\Tests\migrate_drupal_ui\Functional\d6 - */ -class IdConflictTest { + use Drupal\node\Entity\Node; + use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase; + + /** + * Tests Drupal 6 Id Conflict page. + * + * The test method is provided by the MigrateUpgradeTestBase class. + * + * @group migrate_drupal_ui + * + * @group legacy + */ +class IdConflictTest extends MigrateUpgradeExecuteTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = [ + 'language', + 'content_translation', + 'config_translation', + 'migrate_drupal_ui', + 'telephone', + 'aggregator', + 'book', + 'forum', + 'statistics', + 'migration_provider_test', + // Required for translation migrations. + 'migrate_drupal_multilingual', + 'node_migrate_master', + ]; + + /** + * The entity storage for node. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $nodeStorage; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php'); + } + + /** + * {@inheritdoc} + */ + protected function getSourceBasePath() { + return __DIR__ . '/files'; + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() {} + + /** + * {@inheritdoc} + */ + protected function getEntityCountsIncremental() {} + + /** + * {@inheritdoc} + */ + protected function getAvailablePaths() {} + + /** + * {@inheritdoc} + */ + protected function getMissingPaths() {} + + /** + * Executes all steps of migrations upgrade. + */ + public function testMigrateUpgradeExecute() { + $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')); + $session->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.'); + $session->fieldExists('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')); + $session->pageTextContains('Resolve all issues below to continue the upgrade.'); + + $this->drupalPostForm(NULL, $edits, t('Review upgrade')); + // Ensure we get errors about missing modules. + $session->pageTextContains(t('Resolve all issues below to continue the upgrade.')); + $session->pageTextContains(t('The no_source_module plugin must define the source_module property.')); + + // Uninstall the module causing the missing module error messages. + $this->container->get('module_installer')->uninstall(['migration_provider_test'], TRUE); + + // Test the file sources. + $this->drupalGet('/upgrade'); + $this->drupalPostForm(NULL, [], t('Continue')); + if ($version == 6) { + $paths['d6_source_base_path'] = DRUPAL_ROOT . '/wrong-path'; + } + else { + $paths['source_base_path'] = 'https://example.com/wrong-path'; + $paths['source_private_file_path'] = DRUPAL_ROOT . '/wrong-path'; + } + $this->drupalPostForm(NULL, $paths + $edits, t('Review upgrade')); + if ($version == 6) { + $session->responseContains('Failed to read from Files directory.'); + } + else { + $session->responseContains('Failed to read from Public files directory.'); + $session->responseContains('Failed to read from Private files directory.'); + } + + // 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')); + $entity_types = [ + 'block_content', + 'menu_link_content', + 'file', + 'taxonomy_term', + 'user', + 'comment', + 'node', + ]; + $this->assertIdConflict($session, $entity_types); + } + + /** + * Tests that follow-up migrations have been run successfully. + */ + protected function assertFollowUpMigrationResults() { + $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); + } } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php index 1ba800ee9a..f1542ebe90 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php @@ -38,11 +38,23 @@ class Upgrade6Test extends MigrateUpgradeExecuteTestBase { 'node_migrate_master', ]; + /** + * The entity storage for node. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $nodeStorage; + /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); + + $this->nodeStorage = $this->container->get('entity_type.manager') + ->getStorage('node'); + $this->nodeStorage->delete($this->nodeStorage->loadMultiple()); + $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php'); } diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php index c85a258e4b..03bc9f211b 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php @@ -40,11 +40,22 @@ class Upgrade7Test extends MigrateUpgradeExecuteTestBase { 'node_migrate_master', ]; + /** + * The entity storage for node. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $nodeStorage; + /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); + $this->nodeStorage = $this->container->get('entity_type.manager') + ->getStorage('node'); + $this->nodeStorage->delete($this->nodeStorage->loadMultiple()); + $this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php'); } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeMasterTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeMasterTest.php index 198fd28503..133b7ded03 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeMasterTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeMasterTest.php @@ -45,14 +45,16 @@ protected function setUp() { // Create content. $this->createContent(); + $this->nodeStorage = $this->container->get('entity_type.manager') + ->getStorage('node'); + $this->nodeStorage->delete($this->nodeStorage->loadMultiple()); + $this->installSchema('file', ['file_usage']); $this->executeMigrations([ 'language', 'd6_language_content_settings', 'd6_node_master', ]); - $this->nodeStorage = $this->container->get('entity_type.manager') - ->getStorage('node'); } /** diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeMasterTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeMasterTest.php index 9595b83a36..dd16a5aaf0 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeMasterTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeMasterTest.php @@ -61,6 +61,10 @@ protected function setUp() { // Create content. $this->createContent(); + $this->nodeStorage = $this->container->get('entity_type.manager') + ->getStorage('node'); + $this->nodeStorage->delete($this->nodeStorage->loadMultiple()); + $this->migrateUsers(); $this->migrateFields(); $this->executeMigrations([