Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0
This commit is contained in:
parent
2f563ab520
commit
f1c8716f57
1732 changed files with 52334 additions and 11780 deletions
|
@ -0,0 +1,9 @@
|
|||
langcode: en
|
||||
status: true
|
||||
name: High Water import node
|
||||
type: high_water_import_node
|
||||
description: ''
|
||||
help: ''
|
||||
new_revision: false
|
||||
preview_mode: 1
|
||||
display_submitted: true
|
|
@ -0,0 +1,7 @@
|
|||
type: module
|
||||
name: Migrate SQL Source test
|
||||
description: 'Provides a database table and records for SQL import testing.'
|
||||
package: Testing
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- migrate
|
|
@ -0,0 +1,16 @@
|
|||
id: high_water_test
|
||||
label: High water test.
|
||||
source:
|
||||
plugin: high_water_test
|
||||
high_water_property:
|
||||
name: changed
|
||||
destination:
|
||||
plugin: entity:node
|
||||
migration_tags:
|
||||
test: test
|
||||
process:
|
||||
changed: changed
|
||||
title: title
|
||||
type:
|
||||
plugin: default_value
|
||||
default_value: high_water_import_node
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\migrate_sql_test\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
|
||||
/**
|
||||
* Source plugin for migration high water tests.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "high_water_test"
|
||||
* )
|
||||
*/
|
||||
class HighWaterTest extends SqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this
|
||||
->select('high_water_node', 'm')
|
||||
->fields('m', array_keys($this->fields()));
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'id' => $this->t('Id'),
|
||||
'title' => $this->t('Title'),
|
||||
'changed' => $this->t('Changed'),
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return [
|
||||
'id' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
177
core/modules/migrate/tests/src/Kernel/HighWaterTest.php
Normal file
177
core/modules/migrate/tests/src/Kernel/HighWaterTest.php
Normal file
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
/**
|
||||
* Tests migration high water property.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class HighWaterTest extends MigrateTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'system',
|
||||
'user',
|
||||
'node',
|
||||
'migrate',
|
||||
'migrate_sql_test',
|
||||
'field',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create source test table.
|
||||
$this->sourceDatabase->schema()->createTable('high_water_node', [
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'description' => 'Serial',
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
],
|
||||
'changed' => [
|
||||
'description' => 'Highwater',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
],
|
||||
'title' => [
|
||||
'description' => 'Title',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
],
|
||||
],
|
||||
'primary key' => [
|
||||
'id',
|
||||
],
|
||||
'description' => 'Contains nodes to import',
|
||||
]);
|
||||
|
||||
// Add 3 items to source table.
|
||||
$this->sourceDatabase->insert('high_water_node')
|
||||
->fields([
|
||||
'title',
|
||||
'changed',
|
||||
])
|
||||
->values([
|
||||
'title' => 'Item 1',
|
||||
'changed' => 1,
|
||||
])
|
||||
->values([
|
||||
'title' => 'Item 2',
|
||||
'changed' => 2,
|
||||
])
|
||||
->values([
|
||||
'title' => 'Item 3',
|
||||
'changed' => 3,
|
||||
])
|
||||
->execute();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('node', 'node_access');
|
||||
|
||||
$this->executeMigration('high_water_test');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests high water property of SqlBase.
|
||||
*/
|
||||
public function testHighWater() {
|
||||
// Assert all of the nodes have been imported.
|
||||
$this->assertNodeExists('Item 1');
|
||||
$this->assertNodeExists('Item 2');
|
||||
$this->assertNodeExists('Item 3');
|
||||
|
||||
// Update Item 1 setting its high_water_property to value that is below
|
||||
// current high water mark.
|
||||
$this->sourceDatabase->update('high_water_node')
|
||||
->fields([
|
||||
'title' => 'Item 1 updated',
|
||||
'changed' => 2,
|
||||
])
|
||||
->condition('title', 'Item 1')
|
||||
->execute();
|
||||
|
||||
// Update Item 2 setting its high_water_property to value equal to
|
||||
// current high water mark.
|
||||
$this->sourceDatabase->update('high_water_node')
|
||||
->fields([
|
||||
'title' => 'Item 2 updated',
|
||||
'changed' => 3,
|
||||
])
|
||||
->condition('title', 'Item 2')
|
||||
->execute();
|
||||
|
||||
// Update Item 3 setting its high_water_property to value that is above
|
||||
// current high water mark.
|
||||
$this->sourceDatabase->update('high_water_node')
|
||||
->fields([
|
||||
'title' => 'Item 3 updated',
|
||||
'changed' => 4,
|
||||
])
|
||||
->condition('title', 'Item 3')
|
||||
->execute();
|
||||
|
||||
// Execute migration again.
|
||||
$this->executeMigration('high_water_test');
|
||||
|
||||
// Item with lower highwater should not be updated.
|
||||
$this->assertNodeExists('Item 1');
|
||||
$this->assertNodeDoesNotExist('Item 1 updated');
|
||||
|
||||
// Item with equal highwater should not be updated.
|
||||
$this->assertNodeExists('Item 2');
|
||||
$this->assertNodeDoesNotExist('Item 2 updated');
|
||||
|
||||
// Item with greater highwater should be updated.
|
||||
$this->assertNodeExists('Item 3 updated');
|
||||
$this->assertNodeDoesNotExist('Item 3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that node with given title exists.
|
||||
*
|
||||
* @param string $title
|
||||
* Title of the node.
|
||||
*/
|
||||
protected function assertNodeExists($title) {
|
||||
self::assertTrue($this->nodeExists($title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that node with given title does not exist.
|
||||
*
|
||||
* @param string $title
|
||||
* Title of the node.
|
||||
*/
|
||||
protected function assertNodeDoesNotExist($title) {
|
||||
self::assertFalse($this->nodeExists($title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if node with given title exists.
|
||||
*
|
||||
* @param string $title
|
||||
* Title of the node.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function nodeExists($title) {
|
||||
$query = \Drupal::entityQuery('node');
|
||||
$result = $query
|
||||
->condition('title', $title)
|
||||
->range(0, 1)
|
||||
->execute();
|
||||
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
}
|
180
core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php
Normal file
180
core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php
Normal file
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Base class for tests of Migrate source plugins.
|
||||
*/
|
||||
abstract class MigrateSourceTestBase extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['migrate'];
|
||||
|
||||
/**
|
||||
* The mocked migration.
|
||||
*
|
||||
* @var MigrationInterface|\Prophecy\Prophecy\ObjectProphecy
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* The source plugin under test.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrateSourceInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* The data provider.
|
||||
*
|
||||
* @see \Drupal\Tests\migrate\Kernel\MigrateSourceTestBase::testSource
|
||||
*
|
||||
* @return array
|
||||
* Array of data sets to test, each of which is a numerically indexed array
|
||||
* with the following elements:
|
||||
* - An array of source data, which can be optionally processed and set up
|
||||
* by subclasses.
|
||||
* - An array of expected result rows.
|
||||
* - (optional) The number of result rows the plugin under test is expected
|
||||
* to return. If this is not a numeric value, the plugin will not be
|
||||
* counted.
|
||||
* - (optional) Array of configuration options for the plugin under test.
|
||||
*/
|
||||
abstract public function providerSource();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a mock migration. This will be injected into the source plugin
|
||||
// under test.
|
||||
$this->migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
$this->migration->id()->willReturn(
|
||||
$this->randomMachineName(16)
|
||||
);
|
||||
// Prophesize a useless ID map plugin and an empty set of destination IDs.
|
||||
// Calling code can override these prophecies later and set up different
|
||||
// behaviors.
|
||||
$this->migration->getIdMap()->willReturn(
|
||||
$this->prophesize(MigrateIdMapInterface::class)->reveal()
|
||||
);
|
||||
$this->migration->getDestinationIds()->willReturn([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the plugin to be tested by reading the class @covers annotation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPluginClass() {
|
||||
$annotations = $this->getAnnotations();
|
||||
|
||||
if (isset($annotations['class']['covers'])) {
|
||||
return $annotations['class']['covers'][0];
|
||||
}
|
||||
else {
|
||||
$this->fail('No plugin class was specified');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates the source plugin under test.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The source plugin configuration.
|
||||
*
|
||||
* @return \Drupal\migrate\Plugin\MigrateSourceInterface|object
|
||||
* The fully configured source plugin.
|
||||
*/
|
||||
protected function getPlugin(array $configuration) {
|
||||
// Only create the plugin once per test.
|
||||
if ($this->plugin) {
|
||||
return $this->plugin;
|
||||
}
|
||||
|
||||
$class = ltrim($this->getPluginClass(), '\\');
|
||||
|
||||
/** @var \Drupal\migrate\Plugin\MigratePluginManager $plugin_manager */
|
||||
$plugin_manager = $this->container->get('plugin.manager.migrate.source');
|
||||
|
||||
foreach ($plugin_manager->getDefinitions() as $id => $definition) {
|
||||
if (ltrim($definition['class'], '\\') == $class) {
|
||||
$this->plugin = $plugin_manager
|
||||
->createInstance($id, $configuration, $this->migration->reveal());
|
||||
|
||||
$this->migration
|
||||
->getSourcePlugin()
|
||||
->willReturn($this->plugin);
|
||||
|
||||
return $this->plugin;
|
||||
}
|
||||
}
|
||||
$this->fail('No plugin found for class ' . $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the source plugin against a particular data set.
|
||||
*
|
||||
* @param array $source_data
|
||||
* The source data that the source plugin will read.
|
||||
* @param array $expected_data
|
||||
* The result rows the source plugin is expected to return.
|
||||
* @param mixed $expected_count
|
||||
* (optional) How many rows the source plugin is expected to return.
|
||||
* Defaults to count($expected_data). If set to a non-null, non-numeric
|
||||
* value (like FALSE or 'nope'), the source plugin will not be counted.
|
||||
* @param array $configuration
|
||||
* (optional) Configuration for the source plugin.
|
||||
*
|
||||
* @dataProvider providerSource
|
||||
*/
|
||||
public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = []) {
|
||||
$plugin = $this->getPlugin($configuration);
|
||||
|
||||
// All source plugins must define IDs.
|
||||
$this->assertNotEmpty($plugin->getIds());
|
||||
|
||||
if (is_null($expected_count)) {
|
||||
$expected_count = count($expected_data);
|
||||
}
|
||||
// If an expected count was given, assert it only if the plugin is
|
||||
// countable.
|
||||
if (is_numeric($expected_count)) {
|
||||
$this->assertInstanceOf('\Countable', $plugin);
|
||||
$this->assertCount($expected_count, $plugin);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
/** @var \Drupal\migrate\Row $row */
|
||||
foreach ($plugin as $row) {
|
||||
$this->assertInstanceOf(Row::class, $row);
|
||||
|
||||
$expected = $expected_data[$i++];
|
||||
$actual = $row->getSource();
|
||||
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertArrayHasKey($key, $actual);
|
||||
|
||||
if (is_array($value)) {
|
||||
ksort($value);
|
||||
ksort($actual[$key]);
|
||||
$this->assertEquals($value, $actual[$key]);
|
||||
}
|
||||
else {
|
||||
$this->assertSame((string) $value, (string) $actual[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\Core\Database\Driver\sqlite\Connection;
|
||||
|
||||
/**
|
||||
* Base class for tests of Migrate source plugins that use a database.
|
||||
*/
|
||||
abstract class MigrateSqlSourceTestBase extends MigrateSourceTestBase {
|
||||
|
||||
/**
|
||||
* Builds an in-memory SQLite database from a set of source data.
|
||||
*
|
||||
* @param array $source_data
|
||||
* The source data, keyed by table name. Each table is an array containing
|
||||
* the rows in that table.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Driver\sqlite\Connection
|
||||
* The SQLite database connection.
|
||||
*/
|
||||
protected function getDatabase(array $source_data) {
|
||||
// Create an in-memory SQLite database. Plugins can interact with it like
|
||||
// any other database, and it will cease to exist when the connection is
|
||||
// closed.
|
||||
$connection_options = ['database' => ':memory:'];
|
||||
$pdo = Connection::open($connection_options);
|
||||
$connection = new Connection($pdo, $connection_options);
|
||||
|
||||
// Create the tables and fill them with data.
|
||||
foreach ($source_data as $table => $rows) {
|
||||
// Use the biggest row to build the table schema.
|
||||
$counts = array_map('count', $rows);
|
||||
asort($counts);
|
||||
end($counts);
|
||||
$pilot = $rows[key($counts)];
|
||||
|
||||
$connection->schema()
|
||||
->createTable($table, [
|
||||
// SQLite uses loose affinity typing, so it's OK for every field to
|
||||
// be a text field.
|
||||
'fields' => array_map(function() { return ['type' => 'text']; }, $pilot),
|
||||
]);
|
||||
|
||||
$fields = array_keys($pilot);
|
||||
$insert = $connection->insert($table)->fields($fields);
|
||||
array_walk($rows, [$insert, 'values']);
|
||||
$insert->execute();
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the source plugin against a particular data set.
|
||||
*
|
||||
* @param array $source_data
|
||||
* The source data that the plugin will read. See getDatabase() for the
|
||||
* expected format.
|
||||
* @param array $expected_data
|
||||
* The result rows the plugin is expected to return.
|
||||
* @param int $expected_count
|
||||
* (optional) How many rows the source plugin is expected to return.
|
||||
* @param array $configuration
|
||||
* (optional) Configuration for the source plugin.
|
||||
*
|
||||
* @dataProvider providerSource
|
||||
*
|
||||
* @requires extension pdo_sqlite
|
||||
*/
|
||||
public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = []) {
|
||||
$plugin = $this->getPlugin($configuration);
|
||||
|
||||
// Since we don't yet inject the database connection, we need to use a
|
||||
// reflection hack to set it in the plugin instance.
|
||||
$reflector = new \ReflectionObject($plugin);
|
||||
$property = $reflector->getProperty('database');
|
||||
$property->setAccessible(TRUE);
|
||||
$property->setValue($plugin, $this->getDatabase($source_data));
|
||||
|
||||
parent::testSource($source_data, $expected_data, $expected_count, $configuration);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,8 @@ use Drupal\KernelTests\KernelTestBase;
|
|||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateMessageInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\Migration;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
|
@ -136,6 +138,16 @@ abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageI
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a migration's configuration before executing it.
|
||||
*
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration to execute.
|
||||
*/
|
||||
protected function prepareMigration(MigrationInterface $migration) {
|
||||
// Default implementation for test classes not requiring modification.
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a single migration.
|
||||
*
|
||||
|
@ -152,6 +164,8 @@ abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageI
|
|||
if ($this instanceof MigrateDumpAlterInterface) {
|
||||
static::migrateDumpAlter($this);
|
||||
}
|
||||
|
||||
$this->prepareMigration($this->migration);
|
||||
(new MigrateExecutable($this->migration, $this))->import();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ class MigrationTest extends KernelTestBase {
|
|||
$this->assertEqual('entity:entity_view_mode', $migration->getDestinationPlugin()->getPluginId());
|
||||
|
||||
// Test the source plugin is invalidated.
|
||||
$migration->set('source', ['plugin' => 'd6_field']);
|
||||
$this->assertEqual('d6_field', $migration->getSourcePlugin()->getPluginId());
|
||||
$migration->set('source', ['plugin' => 'embedded_data', 'data_rows' => [], 'ids' => []]);
|
||||
$this->assertEqual('embedded_data', $migration->getSourcePlugin()->getPluginId());
|
||||
|
||||
// Test the destination plugin is invalidated.
|
||||
$migration->set('destination', ['plugin' => 'null']);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel\Plugin;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the migration plugin manager.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\MigratePluginManager
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrationPluginConfigurationTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'migrate',
|
||||
'migrate_drupal',
|
||||
// Test with a simple migration.
|
||||
'ban',
|
||||
];
|
||||
|
||||
/**
|
||||
* Test merging configuration into a plugin through the plugin manager.
|
||||
*
|
||||
* @dataProvider mergeProvider
|
||||
*/
|
||||
public function testConfigurationMerge($configuration, $expected) {
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
|
||||
$migration = $this->container->get('plugin.manager.migration')->createInstance('d7_blocked_ips', $configuration);
|
||||
$source_configuration = $migration->getSourceConfiguration();
|
||||
$this->assertEquals($expected, $source_configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide configuration data for testing.
|
||||
*/
|
||||
public function mergeProvider() {
|
||||
return [
|
||||
// Tests adding new configuration to a migration.
|
||||
[
|
||||
// New configuration.
|
||||
[
|
||||
'source' => [
|
||||
'constants' => [
|
||||
'added_setting' => 'Ban them all!',
|
||||
],
|
||||
],
|
||||
],
|
||||
// Expected final source configuration.
|
||||
[
|
||||
'plugin' => 'd7_blocked_ips',
|
||||
'constants' => [
|
||||
'added_setting' => 'Ban them all!',
|
||||
],
|
||||
],
|
||||
],
|
||||
// Tests overriding pre-existing configuration in a migration.
|
||||
[
|
||||
// New configuration.
|
||||
[
|
||||
'source' => [
|
||||
'plugin' => 'a_different_plugin',
|
||||
],
|
||||
],
|
||||
// Expected final source configuration.
|
||||
[
|
||||
'plugin' => 'a_different_plugin',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel\Plugin;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the migration plugin manager.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\MigratePluginManager
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrationPluginListTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'migrate',
|
||||
// Test with all modules containing Drupal migrations.
|
||||
'action',
|
||||
'aggregator',
|
||||
'ban',
|
||||
'block',
|
||||
'block_content',
|
||||
'book',
|
||||
'comment',
|
||||
'contact',
|
||||
'dblog',
|
||||
'field',
|
||||
'file',
|
||||
'filter',
|
||||
'forum',
|
||||
'image',
|
||||
'language',
|
||||
'locale',
|
||||
'menu_link_content',
|
||||
'menu_ui',
|
||||
'node',
|
||||
'path',
|
||||
'search',
|
||||
'shortcut',
|
||||
'simpletest',
|
||||
'statistics',
|
||||
'syslog',
|
||||
'system',
|
||||
'taxonomy',
|
||||
'text',
|
||||
'tracker',
|
||||
'update',
|
||||
'user',
|
||||
];
|
||||
|
||||
/**
|
||||
* @covers ::getDefinitions
|
||||
*/
|
||||
public function testGetDefinitions() {
|
||||
// Make sure retrieving all the core migration plugins does not throw any
|
||||
// errors.
|
||||
$migration_plugins = $this->container->get('plugin.manager.migration')->getDefinitions();
|
||||
// All the plugins provided by core depend on migrate_drupal.
|
||||
$this->assertEmpty($migration_plugins);
|
||||
|
||||
// Enable a module that provides migrations that do not depend on
|
||||
// migrate_drupal.
|
||||
$this->enableModules(['migrate_external_translated_test']);
|
||||
$migration_plugins = $this->container->get('plugin.manager.migration')->getDefinitions();
|
||||
// All the plugins provided by migrate_external_translated_test do not
|
||||
// depend on migrate_drupal.
|
||||
$this::assertArrayHasKey('external_translated_test_node', $migration_plugins);
|
||||
$this::assertArrayHasKey('external_translated_test_node_translation', $migration_plugins);
|
||||
|
||||
// Disable the test module and the list should be empty again.
|
||||
$this->disableModules(['migrate_external_translated_test']);
|
||||
$migration_plugins = $this->container->get('plugin.manager.migration')->getDefinitions();
|
||||
// All the plugins provided by core depend on migrate_drupal.
|
||||
$this->assertEmpty($migration_plugins);
|
||||
|
||||
// Enable migrate_drupal to test that the plugins can now be discovered.
|
||||
$this->enableModules(['migrate_drupal']);
|
||||
// Set up a migrate database connection so that plugin discovery works.
|
||||
// Clone the current connection and replace the current prefix.
|
||||
$connection_info = Database::getConnectionInfo('migrate');
|
||||
if ($connection_info) {
|
||||
Database::renameConnection('migrate', 'simpletest_original_migrate');
|
||||
}
|
||||
$connection_info = Database::getConnectionInfo('default');
|
||||
foreach ($connection_info as $target => $value) {
|
||||
$prefix = is_array($value['prefix']) ? $value['prefix']['default'] : $value['prefix'];
|
||||
// Simpletest uses 7 character prefixes at most so this can't cause
|
||||
// collisions.
|
||||
$connection_info[$target]['prefix']['default'] = $prefix . '0';
|
||||
|
||||
// Add the original simpletest prefix so SQLite can attach its database.
|
||||
// @see \Drupal\Core\Database\Driver\sqlite\Connection::init()
|
||||
$connection_info[$target]['prefix'][$value['prefix']['default']] = $value['prefix']['default'];
|
||||
}
|
||||
Database::addConnectionInfo('migrate', 'default', $connection_info['default']);
|
||||
|
||||
$migration_plugins = $this->container->get('plugin.manager.migration')->getDefinitions();
|
||||
// All the plugins provided by core depend on migrate_drupal.
|
||||
$this->assertNotEmpty($migration_plugins);
|
||||
}
|
||||
|
||||
}
|
|
@ -33,10 +33,27 @@ class MigrationTest extends KernelTestBase {
|
|||
* @covers ::getMigrationDependencies
|
||||
*/
|
||||
public function testGetMigrationDependencies() {
|
||||
$migration = \Drupal::service('plugin.manager.migration')->createStubMigration([
|
||||
'migration_dependencies' => NULL
|
||||
]);
|
||||
$this->assertNotEmpty($migration->getMigrationDependencies(), 'Migration dependencies is not empty');
|
||||
$plugin_manager = \Drupal::service('plugin.manager.migration');
|
||||
$plugin_definition = [
|
||||
'process' => [
|
||||
'f1' => 'bar',
|
||||
'f2' => [
|
||||
'plugin' => 'migration',
|
||||
'migration' => 'm1'
|
||||
],
|
||||
'f3' => [
|
||||
'plugin' => 'iterator',
|
||||
'process' => [
|
||||
'target_id' => [
|
||||
'plugin' => 'migration',
|
||||
'migration' => 'm2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
$migration = $plugin_manager->createStubMigration($plugin_definition);
|
||||
$this->assertSame(['required' => [], 'optional' => ['m1', 'm2']], $migration->getMigrationDependencies());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
183
core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
Normal file
183
core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel\process;
|
||||
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
||||
use Drupal\KernelTests\Core\File\FileTestBase;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Plugin\migrate\process\FileCopy;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Tests the copy_file process plugin.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class CopyFileTest extends FileTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* The file system service.
|
||||
*
|
||||
* @var \Drupal\Core\File\FileSystemInterface
|
||||
*/
|
||||
protected $fileSystem;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->fileSystem = $this->container->get('file_system');
|
||||
$this->container->get('stream_wrapper_manager')->registerWrapper('temporary', 'Drupal\Core\StreamWrapper\TemporaryStream', StreamWrapperInterface::LOCAL_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test successful imports/copies.
|
||||
*/
|
||||
public function testSuccessfulCopies() {
|
||||
$file = $this->createUri(NULL, NULL, 'temporary');
|
||||
$file_absolute = $this->fileSystem->realpath($file);
|
||||
$data_sets = [
|
||||
// Test a local to local copy.
|
||||
[
|
||||
$this->root . '/core/modules/simpletest/files/image-test.jpg',
|
||||
'public://file1.jpg'
|
||||
],
|
||||
// Test a temporary file using an absolute path.
|
||||
[
|
||||
$file_absolute,
|
||||
'temporary://test.jpg'
|
||||
],
|
||||
// Test a temporary file using a relative path.
|
||||
[
|
||||
$file_absolute,
|
||||
'temporary://core/modules/simpletest/files/test.jpg'
|
||||
],
|
||||
];
|
||||
foreach ($data_sets as $data) {
|
||||
list($source_path, $destination_path) = $data;
|
||||
$actual_destination = $this->doImport($source_path, $destination_path);
|
||||
$message = sprintf('File %s exists', $destination_path);
|
||||
$this->assertFileExists($destination_path, $message);
|
||||
// Make sure we didn't accidentally do a move.
|
||||
$this->assertFileExists($source_path, $message);
|
||||
$this->assertSame($actual_destination, $destination_path, 'The import returned the copied filename.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test successful file reuse.
|
||||
*/
|
||||
public function testSuccessfulReuse() {
|
||||
$source_path = $this->root . '/core/modules/simpletest/files/image-test.jpg';
|
||||
$destination_path = 'public://file1.jpg';
|
||||
$file_reuse = file_unmanaged_copy($source_path, $destination_path);
|
||||
$timestamp = (new \SplFileInfo($file_reuse))->getMTime();
|
||||
$this->assertInternalType('int', $timestamp);
|
||||
|
||||
// We need to make sure the modified timestamp on the file is sooner than
|
||||
// the attempted migration.
|
||||
sleep(1);
|
||||
$configuration = ['reuse' => TRUE];
|
||||
$this->doImport($source_path, $destination_path, $configuration);
|
||||
clearstatcache(TRUE, $destination_path);
|
||||
$modified_timestamp = (new \SplFileInfo($destination_path))->getMTime();
|
||||
$this->assertEquals($timestamp, $modified_timestamp);
|
||||
|
||||
$configuration = ['reuse' => FALSE];
|
||||
$this->doImport($source_path, $destination_path, $configuration);
|
||||
clearstatcache(TRUE, $destination_path);
|
||||
$modified_timestamp = (new \SplFileInfo($destination_path))->getMTime();
|
||||
$this->assertGreaterThan($timestamp, $modified_timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test successful moves.
|
||||
*/
|
||||
public function testSuccessfulMoves() {
|
||||
$file_1 = $this->createUri(NULL, NULL, 'temporary');
|
||||
$file_1_absolute = $this->fileSystem->realpath($file_1);
|
||||
$file_2 = $this->createUri(NULL, NULL, 'temporary');
|
||||
$file_2_absolute = $this->fileSystem->realpath($file_2);
|
||||
$local_file = $this->createUri(NULL, NULL, 'public');
|
||||
$data_sets = [
|
||||
// Test a local to local copy.
|
||||
[
|
||||
$local_file,
|
||||
'public://file1.jpg'
|
||||
],
|
||||
// Test a temporary file using an absolute path.
|
||||
[
|
||||
$file_1_absolute,
|
||||
'temporary://test.jpg'
|
||||
],
|
||||
// Test a temporary file using a relative path.
|
||||
[
|
||||
$file_2_absolute,
|
||||
'temporary://core/modules/simpletest/files/test.jpg'
|
||||
],
|
||||
];
|
||||
foreach ($data_sets as $data) {
|
||||
list($source_path, $destination_path) = $data;
|
||||
$actual_destination = $this->doImport($source_path, $destination_path, ['move' => TRUE]);
|
||||
$message = sprintf('File %s exists', $destination_path);
|
||||
$this->assertFileExists($destination_path, $message);
|
||||
$message = sprintf('File %s does not exist', $source_path);
|
||||
$this->assertFileNotExists($source_path, $message);
|
||||
$this->assertSame($actual_destination, $destination_path, 'The importer returned the moved filename.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that non-existent files throw an exception.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateException
|
||||
*
|
||||
* @expectedExceptionMessage File '/non/existent/file' does not exist
|
||||
*/
|
||||
public function testNonExistentSourceFile() {
|
||||
$source = '/non/existent/file';
|
||||
$this->doImport($source, 'public://wontmatter.jpg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 'rename' overwrite mode.
|
||||
*/
|
||||
public function testRenameFile() {
|
||||
$source = $this->createUri(NULL, NULL, 'temporary');
|
||||
$destination = $this->createUri('foo.txt', NULL, 'public');
|
||||
$expected_destination = 'public://foo_0.txt';
|
||||
$actual_destination = $this->doImport($source, $destination, ['rename' => TRUE]);
|
||||
$this->assertFileExists($expected_destination, 'File was renamed on import');
|
||||
$this->assertSame($actual_destination, $expected_destination, 'The importer returned the renamed filename.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Do an import using the destination.
|
||||
*
|
||||
* @param string $source_path
|
||||
* Source path to copy from.
|
||||
* @param string $destination_path
|
||||
* The destination path to copy to.
|
||||
* @param array $configuration
|
||||
* Process plugin configuration settings.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateException
|
||||
*/
|
||||
protected function doImport($source_path, $destination_path, $configuration = []) {
|
||||
$plugin = FileCopy::create($this->container, $configuration, 'file_copy', []);
|
||||
$executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
|
||||
$row = new Row([], []);
|
||||
|
||||
$result = $plugin->transform([$source_path, $destination_path], $executable, $row, 'foobaz');
|
||||
|
||||
// Return the imported file Uri.
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
44
core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php
Normal file
44
core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\EventBase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\EventBase
|
||||
* @group migrate
|
||||
*/
|
||||
class EventBaseTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* Test getMigration method.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::getMigration
|
||||
*/
|
||||
public function testGetMigration() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface')->reveal();
|
||||
$row = $this->prophesize('\Drupal\migrate\Row')->reveal();
|
||||
$event = new EventBase($migration, $message_service, $row, [1, 2, 3]);
|
||||
$this->assertSame($migration, $event->getMigration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test logging a message.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::logMessage
|
||||
*/
|
||||
public function testLogMessage() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface');
|
||||
$event = new EventBase($migration, $message_service->reveal());
|
||||
// Assert that the intended calls to the services happen.
|
||||
$message_service->display('status message', 'status')->shouldBeCalledTimes(1);
|
||||
$event->logMessage('status message');
|
||||
$message_service->display('warning message', 'warning')->shouldBeCalledTimes(1);
|
||||
$event->logMessage('warning message', 'warning');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\MigrateImportEvent;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\MigrateImportEvent
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrateImportEventTest extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* Test getMigration method.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::getMigration
|
||||
*/
|
||||
public function testGetMigration() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface')->reveal();
|
||||
$event = new MigrateImportEvent($migration, $message_service);
|
||||
$this->assertSame($migration, $event->getMigration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test logging a message.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::logMessage
|
||||
*/
|
||||
public function testLogMessage() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface');
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface');
|
||||
$event = new MigrateImportEvent($migration->reveal(), $message_service->reveal());
|
||||
// Assert that the intended calls to the services happen.
|
||||
$message_service->display('status message', 'status')->shouldBeCalledTimes(1);
|
||||
$event->logMessage('status message');
|
||||
$message_service->display('warning message', 'warning')->shouldBeCalledTimes(1);
|
||||
$event->logMessage('warning message', 'warning');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\MigratePostRowSaveEvent;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\MigratePostRowSaveEvent
|
||||
* @group migrate
|
||||
*/
|
||||
class MigratePostRowSaveEventTest extends EventBaseTest {
|
||||
|
||||
/**
|
||||
* Test getDestinationIdValues method.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::getDestinationIdValues
|
||||
*/
|
||||
public function testGetDestinationIdValues() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface')->reveal();
|
||||
$row = $this->prophesize('\Drupal\migrate\Row')->reveal();
|
||||
$event = new MigratePostRowSaveEvent($migration, $message_service, $row, [1, 2, 3]);
|
||||
$this->assertSame([1, 2, 3], $event->getDestinationIdValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getRow method.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::getRow
|
||||
*/
|
||||
public function testGetRow() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface');
|
||||
$row = $this->prophesize('\Drupal\migrate\Row')->reveal();
|
||||
$event = new MigratePostRowSaveEvent($migration, $message_service->reveal(), $row, [1, 2, 3]);
|
||||
$this->assertSame($row, $event->getRow());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\MigratePreRowSaveEvent;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\MigratePreRowSaveEvent
|
||||
* @group migrate
|
||||
*/
|
||||
class MigratePreRowSaveEventTest extends EventBaseTest {
|
||||
|
||||
/**
|
||||
* Test getRow method.
|
||||
*
|
||||
* @covers ::__construct
|
||||
* @covers ::getRow
|
||||
*/
|
||||
public function testGetRow() {
|
||||
$migration = $this->prophesize('\Drupal\migrate\Plugin\MigrationInterface')->reveal();
|
||||
$message_service = $this->prophesize('\Drupal\migrate\MigrateMessageInterface')->reveal();
|
||||
$row = $this->prophesize('\Drupal\migrate\Row')->reveal();
|
||||
$event = new MigratePreRowSaveEvent($migration, $message_service, $row);
|
||||
$this->assertSame($row, $event->getRow());
|
||||
}
|
||||
|
||||
}
|
|
@ -114,9 +114,9 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
->with($row, array('test'))
|
||||
->will($this->returnValue(array('id' => 'test')));
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->will($this->returnValue($destination));
|
||||
->willReturn($destination);
|
||||
|
||||
$this->assertSame(MigrationInterface::RESULT_COMPLETED, $this->executable->import());
|
||||
}
|
||||
|
@ -156,9 +156,9 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
->with($row, array('test'))
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->will($this->returnValue($destination));
|
||||
->willReturn($destination);
|
||||
|
||||
$this->idMap->expects($this->never())
|
||||
->method('saveIdMapping');
|
||||
|
@ -196,9 +196,9 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
->with($row, array('test'))
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->will($this->returnValue($destination));
|
||||
->willReturn($destination);
|
||||
|
||||
$this->idMap->expects($this->once())
|
||||
->method('saveIdMapping')
|
||||
|
@ -256,9 +256,9 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
->with($row, array('test'))
|
||||
->will($this->throwException(new MigrateException($exception_message)));
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->will($this->returnValue($destination));
|
||||
->willReturn($destination);
|
||||
|
||||
$this->idMap->expects($this->once())
|
||||
->method('saveIdMapping')
|
||||
|
@ -306,7 +306,7 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
$destination->expects($this->never())
|
||||
->method('import');
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->willReturn($destination);
|
||||
|
||||
|
@ -354,9 +354,9 @@ class MigrateExecutableTest extends MigrateTestCase {
|
|||
->with($row, array('test'))
|
||||
->will($this->throwException(new \Exception($exception_message)));
|
||||
|
||||
$this->migration->expects($this->once())
|
||||
$this->migration
|
||||
->method('getDestinationPlugin')
|
||||
->will($this->returnValue($destination));
|
||||
->willReturn($destination);
|
||||
|
||||
$this->idMap->expects($this->once())
|
||||
->method('saveIdMapping')
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace Drupal\Tests\migrate\Unit;
|
|||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
|
||||
|
@ -75,7 +77,21 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
* @return \Drupal\migrate\Plugin\MigrateSourceInterface
|
||||
* A mocked source plugin.
|
||||
*/
|
||||
protected function getSource($configuration = [], $migrate_config = [], $status = MigrateIdMapInterface::STATUS_NEEDS_UPDATE) {
|
||||
protected function getSource($configuration = [], $migrate_config = [], $status = MigrateIdMapInterface::STATUS_NEEDS_UPDATE, $high_water_value = NULL) {
|
||||
$container = new ContainerBuilder();
|
||||
\Drupal::setContainer($container);
|
||||
|
||||
$key_value = $this->getMock(KeyValueStoreInterface::class);
|
||||
|
||||
$key_value_factory = $this->getMock(KeyValueFactoryInterface::class);
|
||||
$key_value_factory
|
||||
->method('get')
|
||||
->with('migrate:high_water')
|
||||
->willReturn($key_value);
|
||||
$container->set('keyvalue', $key_value_factory);
|
||||
|
||||
$container->set('cache.migrate', $this->getMock(CacheBackendInterface::class));
|
||||
|
||||
$this->migrationConfiguration = $this->defaultMigrationConfiguration + $migrate_config;
|
||||
$this->migration = parent::getMigration();
|
||||
$this->executable = $this->getMigrateExecutable($this->migration);
|
||||
|
@ -90,47 +106,45 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
->willReturn($id_map_array);
|
||||
|
||||
$constructor_args = [$configuration, 'd6_action', [], $this->migration];
|
||||
$methods = ['getModuleHandler', 'fields', 'getIds', '__toString', 'getIterator', 'prepareRow', 'initializeIterator', 'calculateDependencies'];
|
||||
$source_plugin = $this->getMock('\Drupal\migrate\Plugin\migrate\source\SourcePluginBase', $methods, $constructor_args);
|
||||
$methods = ['getModuleHandler', 'fields', 'getIds', '__toString', 'prepareRow', 'initializeIterator'];
|
||||
$source_plugin = $this->getMock(SourcePluginBase::class, $methods, $constructor_args);
|
||||
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('fields')
|
||||
->willReturn([]);
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('getIds')
|
||||
->willReturn([]);
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('__toString')
|
||||
->willReturn('');
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('prepareRow')
|
||||
->willReturn(empty($migrate_config['prepare_row_false']));
|
||||
|
||||
$rows = [$this->row];
|
||||
if (isset($configuration['high_water_property']) && isset($high_water_value)) {
|
||||
$property = $configuration['high_water_property']['name'];
|
||||
$rows = array_filter($rows, function (array $row) use ($property, $high_water_value) {
|
||||
return $row[$property] >= $high_water_value;
|
||||
});
|
||||
}
|
||||
$iterator = new \ArrayIterator($rows);
|
||||
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('initializeIterator')
|
||||
->willReturn([]);
|
||||
$iterator = new \ArrayIterator([$this->row]);
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('getIterator')
|
||||
->willReturn($iterator);
|
||||
|
||||
$module_handler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
|
||||
$module_handler = $this->getMock(ModuleHandlerInterface::class);
|
||||
$source_plugin
|
||||
->expects($this->any())
|
||||
->method('getModuleHandler')
|
||||
->willReturn($module_handler);
|
||||
|
||||
$this->migration
|
||||
->expects($this->any())
|
||||
->method('getSourcePlugin')
|
||||
->willReturn($source_plugin);
|
||||
|
||||
return $this->migration->getSourcePlugin();
|
||||
return $source_plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,9 +152,8 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
* @expectedException \Drupal\migrate\MigrateException
|
||||
*/
|
||||
public function testHighwaterTrackChangesIncompatible() {
|
||||
$source_config = ['track_changes' => TRUE];
|
||||
$migration_config = ['highWaterProperty' => ['name' => 'something']];
|
||||
$this->getSource($source_config, $migration_config);
|
||||
$source_config = ['track_changes' => TRUE, 'high_water_property' => ['name' => 'something']];
|
||||
$this->getSource($source_config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,9 +181,20 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
// Test the skip argument.
|
||||
$source = $this->getSource(['skip_count' => TRUE]);
|
||||
$this->assertEquals(-1, $source->count());
|
||||
|
||||
$this->migrationConfiguration['id'] = 'test_migration';
|
||||
$migration = $this->getMigration();
|
||||
$source = new StubSourceGeneratorPlugin([], '', [], $migration);
|
||||
|
||||
// Test the skipCount property's default value.
|
||||
$this->assertEquals(-1, $source->count());
|
||||
|
||||
// Test the count value using a generator.
|
||||
$source = new StubSourceGeneratorPlugin(['skip_count' => FALSE], '', [], $migration);
|
||||
$this->assertEquals(3, $source->count());
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Test that the key can be set for the count cache.
|
||||
*
|
||||
* @covers ::count
|
||||
|
@ -219,14 +243,12 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
* Test that an outdated highwater mark does not cause a row to be imported.
|
||||
*/
|
||||
public function testOutdatedHighwater() {
|
||||
|
||||
$source = $this->getSource([], [], MigrateIdMapInterface::STATUS_IMPORTED);
|
||||
|
||||
// Set the originalHighwater to something higher than our timestamp.
|
||||
$this->migration
|
||||
->expects($this->any())
|
||||
->method('getHighwater')
|
||||
->willReturn($this->row['timestamp'] + 1);
|
||||
$configuration = [
|
||||
'high_water_property' => [
|
||||
'name' => 'timestamp',
|
||||
],
|
||||
];
|
||||
$source = $this->getSource($configuration, [], MigrateIdMapInterface::STATUS_IMPORTED, $this->row['timestamp'] + 1);
|
||||
|
||||
// The current highwater mark is now higher than the row timestamp so no row
|
||||
// is expected.
|
||||
|
@ -240,13 +262,17 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
* @throws \Exception
|
||||
*/
|
||||
public function testNewHighwater() {
|
||||
|
||||
$configuration = [
|
||||
'high_water_property' => [
|
||||
'name' => 'timestamp',
|
||||
],
|
||||
];
|
||||
// Set a highwater property field for source. Now we should have a row
|
||||
// because the row timestamp is greater than the current highwater mark.
|
||||
$source = $this->getSource([], ['highWaterProperty' => ['name' => 'timestamp']], MigrateIdMapInterface::STATUS_IMPORTED);
|
||||
$source = $this->getSource($configuration, [], MigrateIdMapInterface::STATUS_IMPORTED, $this->row['timestamp'] - 1);
|
||||
|
||||
$source->rewind();
|
||||
$this->assertTrue(is_a($source->current(), 'Drupal\migrate\Row'), 'Incoming row timestamp is greater than current highwater mark so we have a row.');
|
||||
$this->assertInstanceOf(Row::class, $source->current(), 'Incoming row timestamp is greater than current highwater mark so we have a row.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,6 +413,21 @@ class MigrateSourceTest extends MigrateTestCase {
|
|||
$this->assertFalse($source->prepareRow($row));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cacheCounts, skipCount, trackChanges preserve their default
|
||||
* values.
|
||||
*/
|
||||
public function testDefaultPropertiesValues() {
|
||||
$this->migrationConfiguration['id'] = 'test_migration';
|
||||
$migration = $this->getMigration();
|
||||
$source = new StubSourceGeneratorPlugin([], '', [], $migration);
|
||||
|
||||
// Test the default value of the skipCount Value;
|
||||
$this->assertTrue($source->getSkipCount());
|
||||
$this->assertTrue($source->getCacheCounts());
|
||||
$this->assertTrue($source->getTrackChanges());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a mock executable for the test.
|
||||
*
|
||||
|
@ -450,3 +491,61 @@ class StubSourcePlugin extends SourcePluginBase {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stubbed source plugin with a generator as iterator. Also it overwrites the
|
||||
* $skipCount, $cacheCounts and $trackChanges properties.
|
||||
*/
|
||||
class StubSourceGeneratorPlugin extends StubSourcePlugin {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $skipCount = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $cacheCounts = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $trackChanges = TRUE;
|
||||
|
||||
/**
|
||||
* Return the skipCount value.
|
||||
*/
|
||||
public function getSkipCount() {
|
||||
return $this->skipCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the cacheCounts value.
|
||||
*/
|
||||
public function getCacheCounts() {
|
||||
return $this->cacheCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trackChanges value.
|
||||
*/
|
||||
public function getTrackChanges() {
|
||||
return $this->trackChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$data = [
|
||||
['title' => 'foo'],
|
||||
['title' => 'bar'],
|
||||
['title' => 'iggy'],
|
||||
];
|
||||
foreach ($data as $row) {
|
||||
yield $row;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,9 +3,16 @@
|
|||
namespace Drupal\Tests\migrate\Unit;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\DependencyInjection\ContainerNotInitializedException;
|
||||
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
|
||||
|
||||
/**
|
||||
* Base class for Migrate module source unit tests.
|
||||
*
|
||||
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase instead.
|
||||
*/
|
||||
abstract class MigrateSqlSourceTestCase extends MigrateTestCase {
|
||||
|
||||
|
@ -44,9 +51,9 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase {
|
|||
* Once the migration is run, we save a mark of the migrated sources, so the
|
||||
* migration can run again and update only new sources or changed sources.
|
||||
*
|
||||
* @var string
|
||||
* @var mixed
|
||||
*/
|
||||
const ORIGINAL_HIGH_WATER = '';
|
||||
const ORIGINAL_HIGH_WATER = NULL;
|
||||
|
||||
/**
|
||||
* Expected results after the source parsing.
|
||||
|
@ -77,6 +84,27 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase {
|
|||
$state = $this->getMock('Drupal\Core\State\StateInterface');
|
||||
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
|
||||
// Mock a key-value store to return high-water values.
|
||||
$key_value = $this->getMock(KeyValueStoreInterface::class);
|
||||
|
||||
// SourcePluginBase does not yet support full dependency injection so we
|
||||
// need to make sure that \Drupal::keyValue() works as expected by mocking
|
||||
// the keyvalue service.
|
||||
$key_value_factory = $this->getMock(KeyValueFactoryInterface::class);
|
||||
$key_value_factory
|
||||
->method('get')
|
||||
->with('migrate:high_water')
|
||||
->willReturn($key_value);
|
||||
|
||||
try {
|
||||
$container = \Drupal::getContainer();
|
||||
}
|
||||
catch (ContainerNotInitializedException $e) {
|
||||
$container = new ContainerBuilder();
|
||||
}
|
||||
$container->set('keyvalue', $key_value_factory);
|
||||
\Drupal::setContainer($container);
|
||||
|
||||
$migration = $this->getMigration();
|
||||
$migration->expects($this->any())
|
||||
->method('getHighWater')
|
||||
|
|
|
@ -80,7 +80,7 @@ abstract class MigrateTestCase extends UnitTestCase {
|
|||
|
||||
$migration->method('getHighWaterProperty')
|
||||
->willReturnCallback(function () use ($configuration) {
|
||||
return isset($configuration['highWaterProperty']) ? $configuration['highWaterProperty'] : '';
|
||||
return isset($configuration['high_water_property']) ? $configuration['high_water_property'] : '';
|
||||
});
|
||||
|
||||
$migration->method('set')
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\migrate\Unit\MigrationStorageTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit;
|
||||
|
||||
use Drupal\Component\Uuid\UuidInterface;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\Query\QueryFactoryInterface;
|
||||
use Drupal\Core\Entity\Query\QueryInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\migrate\MigrationStorage;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\MigrationStorage
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrationStorageTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The migration storage.
|
||||
*
|
||||
* @var \Drupal\Tests\migrate\Unit\TestMigrationStorage
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* The storage query.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Query\QueryInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->query = $this->getMock(QueryInterface::class);
|
||||
$this->query->method('condition')
|
||||
->willReturnSelf();
|
||||
|
||||
$query_factory = $this->getMock(QueryFactoryInterface::class);
|
||||
$query_factory->method('get')
|
||||
->willReturn($this->query);
|
||||
|
||||
$this->storage = new TestMigrationStorage(
|
||||
$this->getMock(EntityTypeInterface::class),
|
||||
$this->getMock(ConfigFactoryInterface::class),
|
||||
$this->getMock(UuidInterface::class),
|
||||
$this->getMock(LanguageManagerInterface::class),
|
||||
$query_factory
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getVariantIds() when variants exist.
|
||||
*
|
||||
* @covers ::getVariantIds
|
||||
*/
|
||||
public function testGetVariantIdsWithVariants() {
|
||||
$this->query->method('execute')
|
||||
->willReturn(['d6_node__page', 'd6_node__article']);
|
||||
|
||||
$ids = $this->storage->getVariantIds(['d6_node:*', 'd6_user']);
|
||||
$this->assertSame(['d6_node__page', 'd6_node__article', 'd6_user'], $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getVariantIds() when no variants exist.
|
||||
*
|
||||
* @covers ::getVariantIds
|
||||
*/
|
||||
public function testGetVariantIdsNoVariants() {
|
||||
$this->query->method('execute')
|
||||
->willReturn([]);
|
||||
|
||||
$ids = $this->storage->getVariantIds(['d6_node:*', 'd6_user']);
|
||||
$this->assertSame(['d6_user'], $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests getVariantIds().
|
||||
*
|
||||
* This tests getVariantIds() when no variants exist and there are no static
|
||||
* (non-variant) dependencies.
|
||||
*
|
||||
* @covers ::getVariantIds
|
||||
*/
|
||||
public function testGetVariantIdsNoVariantsOrStaticDependencies() {
|
||||
$this->query->method('execute')
|
||||
->willReturn([]);
|
||||
|
||||
$ids = $this->storage->getVariantIds(['d6_node:*', 'd6_node_revision:*']);
|
||||
$this->assertSame([], $ids);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test version of \Drupal\migrate\MigrationStorage.
|
||||
*
|
||||
* This class exposes protected methods for testing.
|
||||
*/
|
||||
class TestMigrationStorage extends MigrationStorage {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVariantIds(array $ids) {
|
||||
return parent::getVariantIds($ids);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\migrate\Unit\process\GetTest.
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\process\UrlEncode;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateMessage;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\migrate\Unit\MigrateTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\UrlEncode
|
||||
* @group file
|
||||
*/
|
||||
class UrlEncodeTest extends MigrateTestCase {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $migrationConfiguration = [
|
||||
'id' => 'test',
|
||||
];
|
||||
|
||||
/**
|
||||
* The data provider for testing URL encoding scenarios.
|
||||
*
|
||||
* @return array
|
||||
* An array of URLs to test.
|
||||
*/
|
||||
public function urlDataProvider() {
|
||||
return array(
|
||||
'A URL with no characters requiring encoding' => array('http://example.com/normal_url.html', 'http://example.com/normal_url.html'),
|
||||
'The definitive use case - encoding spaces in URLs' => array('http://example.com/url with spaces.html', 'http://example.com/url%20with%20spaces.html'),
|
||||
'Definitive use case 2 - spaces in directories' => array('http://example.com/dir with spaces/foo.html', 'http://example.com/dir%20with%20spaces/foo.html'),
|
||||
'Local filespecs without spaces should not be transformed' => array('/tmp/normal.txt', '/tmp/normal.txt'),
|
||||
'Local filespecs with spaces should not be transformed' => array('/tmp/with spaces.txt', '/tmp/with spaces.txt'),
|
||||
'Make sure URL characters (:, ?, &) are not encoded but others are.' => array('https://example.com/?a=b@c&d=e+f%', 'https://example.com/?a%3Db%40c&d%3De%2Bf%25'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cover various encoding scenarios.
|
||||
* @dataProvider urlDataProvider
|
||||
*/
|
||||
public function testUrls($input, $output) {
|
||||
$this->assertEquals($output, $this->doTransform($input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the urlencode process plugin over the given value.
|
||||
*
|
||||
* @param string $value
|
||||
* URL to be encoded.
|
||||
*
|
||||
* @return string
|
||||
* Encoded URL.
|
||||
*/
|
||||
protected function doTransform($value) {
|
||||
$executable = new MigrateExecutable($this->getMigration(), new MigrateMessage());
|
||||
$row = new Row([], []);
|
||||
|
||||
return (new UrlEncode([], 'urlencode', []))
|
||||
->transform($value, $executable, $row, 'foobaz');
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue