3 namespace Drupal\Tests\migrate_drupal\Kernel\d6;
5 use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
6 use Drupal\migrate\Audit\AuditResult;
7 use Drupal\migrate\Audit\IdAuditor;
8 use Drupal\node\Entity\Node;
9 use Drupal\node\Entity\NodeType;
10 use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
11 use Drupal\Tests\migrate_drupal\Traits\CreateTestContentEntitiesTrait;
14 * Tests the migration auditor for ID conflicts.
16 * @group migrate_drupal
18 class MigrateDrupal6AuditIdsTest extends MigrateDrupal6TestBase {
20 use FileSystemModuleDiscoveryDataProviderTrait;
21 use CreateTestContentEntitiesTrait;
22 use ContentModerationTestTrait;
27 protected function setUp() {
28 // Enable all modules.
29 self::$modules = array_keys($this->coreModuleListDataProvider());
32 // Install required entity schemas.
33 $this->installEntitySchemas();
35 // Install required schemas.
36 $this->installSchema('book', ['book']);
37 $this->installSchema('dblog', ['watchdog']);
38 $this->installSchema('forum', ['forum_index']);
39 $this->installSchema('node', ['node_access']);
40 $this->installSchema('search', ['search_dataset']);
41 $this->installSchema('system', ['sequences']);
42 $this->installSchema('tracker', ['tracker_node', 'tracker_user']);
44 // Enable content moderation for nodes of type page.
45 $this->installEntitySchema('content_moderation_state');
46 $this->installConfig('content_moderation');
47 NodeType::create(['type' => 'page'])->save();
48 $workflow = $this->createEditorialWorkflow();
49 $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
54 * Tests multiple migrations to the same destination with no ID conflicts.
56 public function testMultipleMigrationWithoutIdConflicts() {
57 // Create a node of type page.
58 $node = Node::create(['type' => 'page', 'title' => 'foo']);
59 $node->moderation_state->value = 'published';
62 // Insert data in the d6_node:page migration mapping table to simulate a
63 // previously migrated node.
64 $id_map = $this->getMigration('d6_node:page')->getIdMap();
65 $table_name = $id_map->mapTableName();
66 $id_map->getDatabase()->insert($table_name)
68 'source_ids_hash' => 1,
74 // Audit the IDs of the d6_node migrations for the page & article node type.
75 // There should be no conflicts since the highest destination ID should be
76 // equal to the highest migrated ID, as found in the aggregated mapping
77 // tables of the two node migrations.
79 $this->getMigration('d6_node:page'),
80 $this->getMigration('d6_node:article'),
83 $results = (new IdAuditor())->auditMultiple($migrations);
84 /** @var \Drupal\migrate\Audit\AuditResult $result */
85 foreach ($results as $result) {
86 $this->assertInstanceOf(AuditResult::class, $result);
87 $this->assertTrue($result->passed());
92 * Tests all migrations with no ID conflicts.
94 public function testAllMigrationsWithNoIdConflicts() {
95 $migrations = $this->container
96 ->get('plugin.manager.migration')
97 ->createInstancesByTag('Drupal 6');
99 // Audit all Drupal 6 migrations that support it. There should be no
100 // conflicts since no content has been created.
101 $results = (new IdAuditor())->auditMultiple($migrations);
102 /** @var \Drupal\migrate\Audit\AuditResult $result */
103 foreach ($results as $result) {
104 $this->assertInstanceOf(AuditResult::class, $result);
105 $this->assertTrue($result->passed());
110 * Tests all migrations with ID conflicts.
112 public function testAllMigrationsWithIdConflicts() {
113 // Get all Drupal 6 migrations.
114 $migrations = $this->container
115 ->get('plugin.manager.migration')
116 ->createInstancesByTag('Drupal 6');
119 $this->createContent();
121 // Audit the IDs of all migrations. There should be conflicts since content
123 $conflicts = array_map(
124 function (AuditResult $result) {
125 return $result->passed() ? NULL : $result->getMigration()->getBaseId();
127 (new IdAuditor())->auditMultiple($migrations)
131 'd6_aggregator_feed',
132 'd6_aggregator_item',
140 'd6_term_node_revision',
142 'node_translation_menu_links',
144 $this->assertEmpty(array_diff(array_filter($conflicts), $expected));
148 * Tests draft revisions ID conflicts.
150 public function testDraftRevisionIdConflicts() {
151 // Create a published node of type page.
152 $node = Node::create(['type' => 'page', 'title' => 'foo']);
153 $node->moderation_state->value = 'published';
156 // Create a draft revision.
157 $node->moderation_state->value = 'draft';
158 $node->setNewRevision(TRUE);
161 // Insert data in the d6_node_revision:page migration mapping table to
162 // simulate a previously migrated node revision.
163 $id_map = $this->getMigration('d6_node_revision:page')->getIdMap();
164 $table_name = $id_map->mapTableName();
165 $id_map->getDatabase()->insert($table_name)
167 'source_ids_hash' => 1,
173 // Audit the IDs of the d6_node_revision migration. There should be
174 // conflicts since a draft revision has been created.
175 /** @var \Drupal\migrate\Audit\AuditResult $result */
176 $result = (new IdAuditor())->audit($this->getMigration('d6_node_revision:page'));
177 $this->assertInstanceOf(AuditResult::class, $result);
178 $this->assertFalse($result->passed());
182 * Tests ID conflicts for inaccessible nodes.
184 public function testNodeGrantsIdConflicts() {
185 // Enable the node_test module to restrict access to page nodes.
186 $this->enableModules(['node_test']);
188 // Create a published node of type page.
189 $node = Node::create(['type' => 'page', 'title' => 'foo']);
190 $node->moderation_state->value = 'published';
193 // Audit the IDs of the d6_node migration. There should be conflicts
194 // even though the new node is not accessible.
195 /** @var \Drupal\migrate\Audit\AuditResult $result */
196 $result = (new IdAuditor())->audit($this->getMigration('d6_node:page'));
197 $this->assertInstanceOf(AuditResult::class, $result);
198 $this->assertFalse($result->passed());