3 namespace Drupal\Tests\migrate\Kernel;
5 use Drupal\migrate\MigrateExecutable;
6 use Drupal\migrate\Plugin\MigrateIdMapInterface;
7 use Drupal\migrate\Row;
8 use Drupal\taxonomy\Entity\Term;
9 use Drupal\taxonomy\Entity\Vocabulary;
12 * Tests rolling back of imports.
16 class MigrateRollbackTest extends MigrateTestBase {
23 public static $modules = ['field', 'taxonomy', 'text'];
28 protected function setUp() {
30 $this->installEntitySchema('taxonomy_vocabulary');
31 $this->installEntitySchema('taxonomy_term');
32 $this->installConfig(['taxonomy']);
36 * Tests rolling back configuration and content entities.
38 public function testRollback() {
39 // We use vocabularies to demonstrate importing and rolling back
40 // configuration entities.
41 $vocabulary_data_rows = [
42 ['id' => '1', 'name' => 'categories', 'weight' => '2'],
43 ['id' => '2', 'name' => 'tags', 'weight' => '1'],
45 $ids = ['id' => ['type' => 'integer']];
47 'id' => 'vocabularies',
48 'migration_tags' => ['Import and rollback test'],
50 'plugin' => 'embedded_data',
51 'data_rows' => $vocabulary_data_rows,
59 'destination' => ['plugin' => 'entity:taxonomy_vocabulary'],
62 $vocabulary_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
63 $vocabulary_id_map = $vocabulary_migration->getIdMap();
65 $this->assertTrue($vocabulary_migration->getDestinationPlugin()->supportsRollback());
67 // Import and validate vocabulary config entities were created.
68 $vocabulary_executable = new MigrateExecutable($vocabulary_migration, $this);
69 $vocabulary_executable->import();
70 foreach ($vocabulary_data_rows as $row) {
71 /** @var Vocabulary $vocabulary */
72 $vocabulary = Vocabulary::load($row['id']);
73 $this->assertTrue($vocabulary);
74 $map_row = $vocabulary_id_map->getRowBySource(['id' => $row['id']]);
75 $this->assertNotNull($map_row['destid1']);
78 // We use taxonomy terms to demonstrate importing and rolling back content
81 ['id' => '1', 'vocab' => '1', 'name' => 'music'],
82 ['id' => '2', 'vocab' => '2', 'name' => 'Bach'],
83 ['id' => '3', 'vocab' => '2', 'name' => 'Beethoven'],
85 $ids = ['id' => ['type' => 'integer']];
88 'migration_tags' => ['Import and rollback test'],
90 'plugin' => 'embedded_data',
91 'data_rows' => $term_data_rows,
99 'destination' => ['plugin' => 'entity:taxonomy_term'],
100 'migration_dependencies' => ['required' => ['vocabularies']],
103 $term_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
104 $term_id_map = $term_migration->getIdMap();
106 $this->assertTrue($term_migration->getDestinationPlugin()->supportsRollback());
108 // Pre-create a term, to make sure it isn't deleted on rollback.
109 $preserved_term_ids[] = 1;
110 $new_term = Term::create(['tid' => 1, 'vid' => 1, 'name' => 'music']);
113 // Import and validate term entities were created.
114 $term_executable = new MigrateExecutable($term_migration, $this);
115 $term_executable->import();
116 // Also explicitly mark one row to be preserved on rollback.
117 $preserved_term_ids[] = 2;
118 $map_row = $term_id_map->getRowBySource(['id' => 2]);
119 $dummy_row = new Row(['id' => 2], $ids);
120 $term_id_map->saveIdMapping($dummy_row, [$map_row['destid1']],
121 $map_row['source_row_status'], MigrateIdMapInterface::ROLLBACK_PRESERVE);
123 foreach ($term_data_rows as $row) {
124 /** @var Term $term */
125 $term = Term::load($row['id']);
126 $this->assertTrue($term);
127 $map_row = $term_id_map->getRowBySource(['id' => $row['id']]);
128 $this->assertNotNull($map_row['destid1']);
131 // Add a failed row to test if this can be rolled back without errors.
132 $this->mockFailure($term_migration, ['id' => '4', 'vocab' => '2', 'name' => 'FAIL']);
134 // Rollback and verify the entities are gone.
135 $term_executable->rollback();
136 foreach ($term_data_rows as $row) {
137 $term = Term::load($row['id']);
138 if (in_array($row['id'], $preserved_term_ids)) {
139 $this->assertNotNull($term);
142 $this->assertNull($term);
144 $map_row = $term_id_map->getRowBySource(['id' => $row['id']]);
145 $this->assertFalse($map_row);
147 $vocabulary_executable->rollback();
148 foreach ($vocabulary_data_rows as $row) {
149 $term = Vocabulary::load($row['id']);
150 $this->assertNull($term);
151 $map_row = $vocabulary_id_map->getRowBySource(['id' => $row['id']]);
152 $this->assertFalse($map_row);
155 // Test that simple configuration is not rollbackable.
156 $term_setting_rows = [
157 ['id' => 1, 'override_selector' => '0', 'terms_per_page_admin' => '10'],
159 $ids = ['id' => ['type' => 'integer']];
161 'id' => 'taxonomy_settings',
162 'migration_tags' => ['Import and rollback test'],
164 'plugin' => 'embedded_data',
165 'data_rows' => $term_setting_rows,
169 'override_selector' => 'override_selector',
170 'terms_per_page_admin' => 'terms_per_page_admin',
173 'plugin' => 'config',
174 'config_name' => 'taxonomy.settings',
176 'migration_dependencies' => ['required' => ['vocabularies']],
179 $settings_migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
180 $this->assertFalse($settings_migration->getDestinationPlugin()->supportsRollback());