From 807e561dd7eb8cf608ed2f77c291ed0a4abd364f Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Thu, 2 Oct 2014 13:46:18 +0200
Subject: [PATCH] Issue #2332751 by tstoeckler, benjy: Added Allow to limit the
 nodes to migrate by node type.

---
 .../config/schema/migrate.source.schema.yml   |  20 ++
 .../src/Plugin/migrate/source/d6/Node.php     |   4 +
 .../src/Unit/source/d6/NodeByNodeTypeTest.php | 131 +++++++
 .../source/d6/NodeRevisionByNodeTypeTest.php  | 338 ++++++++++++++++++
 .../src/Unit/source/d6/NodeRevisionTest.php   |  19 +-
 .../tests/src/Unit/source/d6/NodeTest.php     |  17 -
 .../tests/src/Unit/source/d6/TestNode.php     |  37 ++
 .../src/Unit/source/d6/TestNodeRevision.php   |  37 ++
 8 files changed, 568 insertions(+), 35 deletions(-)
 create mode 100644 core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeByNodeTypeTest.php
 create mode 100644 core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
 create mode 100644 core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNode.php
 create mode 100644 core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNodeRevision.php

diff --git a/core/modules/migrate/config/schema/migrate.source.schema.yml b/core/modules/migrate/config/schema/migrate.source.schema.yml
index 97cab991c062..35e8df025b98 100644
--- a/core/modules/migrate/config/schema/migrate.source.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.source.schema.yml
@@ -186,6 +186,26 @@ migrate.source.d6_node_type:
       type: migrate_entity_constant
       label: 'Constants'
 
+migrate.source.d6_node:
+  type: migrate_source
+  label: 'Drupal 6 node'
+  mapping:
+    node_type:
+      # The node type can be specified both as a string ID of a node type or an
+      # array of node type IDs, so there is no way to consistently parse this.
+      type: ignore
+      label: 'Node type'
+
+migrate.source.d6_node_revision:
+  type: migrate_source
+  label: 'Drupal 6 node'
+  mapping:
+    node_type:
+      # The node type can be specified both as a string ID of a node type or an
+      # array of node type IDs, so there is no way to consistently parse this.
+      type: ignore
+      label: 'Node type'
+
 migrate.source.d6_upload_instance:
   type: migrate_source
   label: 'Drupal 6 upload form display'
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Node.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Node.php
index 8e3e5585329f..bdfa637dd636 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Node.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Node.php
@@ -56,6 +56,10 @@ public function query() {
       ));
     $query->innerJoin('node', 'n', static::JOIN);
 
+    if (isset($this->configuration['node_type'])) {
+      $query->condition('type', $this->configuration['node_type']);
+    }
+
     return $query;
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeByNodeTypeTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeByNodeTypeTest.php
new file mode 100644
index 000000000000..cb0b671c679d
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeByNodeTypeTest.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\NodeByNodeTypeTest.
+ */
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d6;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D6 node source plugin with 'node_type' configuration.
+ *
+ * @group migrate_drupal
+ */
+class NodeByNodeTypeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\Node';
+
+  // The fake Migration configuration entity.
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    // Leave it empty for now.
+    'idlist' => array(),
+    // The fake configuration for the source.
+    'source' => array(
+      'plugin' => 'd6_node',
+      'node_type' => 'page',
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      // Node fields.
+      'nid' => 1,
+      'vid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'title' => 'node title 1',
+      'uid' => 1,
+      'status' => 1,
+      'timestamp' => 1279051598,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'body' => 'body for node 1',
+      'teaser' => 'teaser for node 1',
+      'format' => 1,
+      'log' => 'log message 1',
+    ),
+    array(
+      // Node fields.
+      'nid' => 2,
+      'vid' => 2,
+      'type' => 'page',
+      'language' => 'en',
+      'title' => 'node title 2',
+      'uid' => 1,
+      'status' => 1,
+      'timestamp' => 1279290908,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'body' => 'body for node 2',
+      'teaser' => 'teaser for node 2',
+      'format' => 1,
+      'log' => 'log message 2',
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $database_contents = $this->expectedResults;
+
+    $database_contents[] = array(
+      // Node fields.
+      'nid' => 5,
+      'vid' => 5,
+      'type' => 'article',
+      'language' => 'en',
+      'title' => 'node title 5',
+      'uid' => 1,
+      'status' => 1,
+      'timestamp' => 1279290908,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'body' => 'body for node 5',
+      'teaser' => 'body for node 5',
+      'format' => 1,
+      'log' => 'log message 3',
+    );
+
+    // Add another row with an article node and make sure it is not migrated.
+
+    foreach ($database_contents as $k => $row) {
+      foreach (array('nid', 'vid', 'title', 'uid', 'body', 'teaser', 'format', 'timestamp', 'log') as $i => $field) {
+        $this->databaseContents['node_revisions'][$k][$field] = $row[$field];
+        // Keep nid and vid.
+        if ($i > 1) {
+          unset($row[$field]);
+        }
+      }
+      $this->databaseContents['node'][$k] = $row;
+    }
+
+    parent::setUp();
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
new file mode 100644
index 000000000000..9abbd632cbc7
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
@@ -0,0 +1,338 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\NodeRevisionByNodeTypeTest.
+ */
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d6;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D6 node revision source plugin.
+ *
+ * @group migrate_drupal
+ */
+class NodeRevisionByNodeTypeTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\NodeRevision';
+
+  // The fake Migration configuration entity.
+  protected $migrationConfiguration = array(
+    'id' => 'test',
+    // Leave it empty for now.
+    'idlist' => array(),
+    // The fake configuration for the source.
+    'source' => array(
+      'plugin' => 'd6_node_revision',
+      'node_type' => 'page',
+    ),
+    'sourceIds' => array(
+      'vid' => array(
+        'alias' => 'v',
+      ),
+    ),
+    'destinationIds' => array(
+      'vid' => array(
+        // This is where the field schema would go.
+      ),
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      // Node fields.
+      'nid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 1,
+      'uid' => 1,
+      'title' => 'title for revision 1 (node 1)',
+      'body' => 'body for revision 1 (node 1)',
+      'teaser' => 'teaser for revision 1 (node 1)',
+      'log' => 'log for revision 1 (node 1)',
+      'format' => 1,
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
+      'nid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 3,
+      'uid' => 1,
+      'title' => 'title for revision 3 (node 1)',
+      'body' => 'body for revision 3 (node 1)',
+      'teaser' => 'teaser for revision 3 (node 1)',
+      'log' => 'log for revision 3 (node 1)',
+      'format' => 1,
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
+      'nid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 4,
+      'uid' => 1,
+      'title' => 'title for revision 4 (node 1)',
+      'body' => 'body for revision 4 (node 1)',
+      'teaser' => 'teaser for revision 4 (node 1)',
+      'log' => 'log for revision 4 (node 1)',
+      'format' => 1,
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+  );
+
+  protected $fields = array(
+    'field_test_one' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_one',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_one',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 0,
+        'db_storage' => 1,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+    ),
+    'field_test_two' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_two',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_two',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 1,
+        'db_storage' => 0,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+
+      // Multi field values.
+      'values' => array(
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 2,
+          'nid' => 2,
+          'field_test_two_value' => 'test field node 2',
+          'delta' => 0,
+        ),
+      ),
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $database_contents = $this->expectedResults;
+
+    $database_contents[] = array(
+      // Node fields.
+      'nid' => 2,
+      'type' => 'article',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 2,
+      'uid' => 1,
+      'title' => 'title for revision 2 (node 2)',
+      'body' => 'body for revision 2 (node 2)',
+      'teaser' => 'teaser for revision 2 (node 2)',
+      'log' => 'log for revision 2 (node 2)',
+      'format' => 1,
+      'field_test_two' => array(
+        'test field node 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 2',
+      ),
+    );
+
+    foreach ($database_contents as $k => $row) {
+      $this->databaseContents['node_revisions'][$k]['nid'] = $row['nid'];
+      $this->databaseContents['node_revisions'][$k]['vid'] = $row['vid'];
+      $this->databaseContents['node_revisions'][$k]['uid'] = $row['uid'];
+      $this->databaseContents['node_revisions'][$k]['title'] = $row['title'];
+      $this->databaseContents['node_revisions'][$k]['body'] = $row['body'];
+      $this->databaseContents['node_revisions'][$k]['teaser'] = $row['teaser'];
+      $this->databaseContents['node_revisions'][$k]['format'] = $row['format'];
+      $this->databaseContents['node_revisions'][$k]['log'] = $row['log'];
+
+      unset($row['body']);
+      unset($row['teaser']);
+      unset($row['format']);
+      unset($row['log']);
+
+      //$this->databaseContents['node'][$k] = $row;
+      $this->databaseContents['node'][$row['nid']] = $row;
+
+      // Add the column field storage data.
+      $table = 'content_type_' . $row['type'];
+      foreach ($row['fields'] as $field_name => $value) {
+        $this->databaseContents[$table][$k][$field_name . "_value"] = $value;
+        $this->databaseContents[$table][$k]['vid'] = $row['vid'];
+        $this->databaseContents[$table][$k]['nid'] = $row['nid'];
+      }
+      // Unset from results.
+      unset($row['fields']);
+      unset($this->expectedResults[$k]['fields']);
+    }
+
+    // Setup field tables.
+    foreach ($this->fields as $field) {
+      $cnf = $field['content_node_field'];
+      $this->databaseContents['content_node_field'][] = $cnf;
+      $this->databaseContents['content_node_field_instance'][] = $field['content_node_field_instance'];
+
+      // If it's a multi-field then setup a new table.
+      if ($cnf['multiple']) {
+        foreach ($field['values'] as $value) {
+          $this->databaseContents['content_' . $cnf['field_name']][] = $value;
+        }
+      }
+    }
+
+    parent::setUp();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function testRetrieval() {
+    // @todo: Fix this as per https://www.drupal.org/node/2299795
+    $this->markTestIncomplete('FakeSelect does not support multiple source identifiers, can not test.');
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
index a83c70daa233..d9b17b1529bf 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
@@ -25,9 +25,7 @@ class NodeRevisionTest extends MigrateSqlSourceTestCase {
     'idlist' => array(),
     // The fake configuration for the source.
     'source' => array(
-      'node_type' => 'page',
       'plugin' => 'd6_node_revision',
-      'bundle' => 'page',
     ),
     'sourceIds' => array(
       'vid' => array(
@@ -143,7 +141,7 @@ class NodeRevisionTest extends MigrateSqlSourceTestCase {
     array(
       // Node fields.
       'nid' => 2,
-      'type' => 'page',
+      'type' => 'article',
       'language' => 'en',
       'status' => 1,
       'created' => 1279290908,
@@ -334,18 +332,3 @@ public function testRetrieval() {
   }
 
 }
-
-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\d6\NodeRevision;
-
-class TestNodeRevision extends NodeRevision {
-  public function setDatabase(Connection $database) {
-    $this->database = $database;
-  }
-  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
-  }
-}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeTest.php
index 20715cafdbca..81e84cde377f 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeTest.php
@@ -25,7 +25,6 @@ class NodeTest extends MigrateSqlSourceTestCase {
     'idlist' => array(),
     // The fake configuration for the source.
     'source' => array(
-      'bundle' => 'page',
       'plugin' => 'd6_node',
     ),
   );
@@ -124,19 +123,3 @@ protected function setUp() {
   }
 
 }
-
-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\d6\Node;
-
-class TestNode extends Node {
-  protected $cckSchemaCorrect = true;
-  public function setDatabase(Connection $database) {
-    $this->database = $database;
-  }
-  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
-  }
-}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNode.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNode.php
new file mode 100644
index 000000000000..471416e6c7b2
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNode.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\TestNode.
+ */
+
+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\d6\Node;
+
+/**
+ * Provides a node source plugin used for unit testing.
+ */
+class TestNode extends Node {
+
+  /**
+   * Sets the database connection for this source plugin.
+   *
+   * @param \Drupal\Core\Database\Connection $database
+   */
+  public function setDatabase(Connection $database) {
+    $this->database = $database;
+  }
+
+  /**
+   * Sets the module handler for this source plugin.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   */
+  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNodeRevision.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNodeRevision.php
new file mode 100644
index 000000000000..77e5ac6d46aa
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/TestNodeRevision.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\TestNodeRevision.
+ */
+
+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\d6\NodeRevision;
+
+/**
+ * Provides a node revision source plugin used for unit testing.
+ */
+class TestNodeRevision extends NodeRevision {
+
+  /**
+   * Sets the database connection for this source plugin.
+   *
+   * @param \Drupal\Core\Database\Connection $database
+   */
+  public function setDatabase(Connection $database) {
+    $this->database = $database;
+  }
+
+  /**
+   * Sets the module handler for this source plugin.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   */
+  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+}
-- 
GitLab