View source
<?php
namespace Drupal\Tests\smart_sql_idmap\Unit\Plugin\migrate\id_map;
use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Database\Driver\sqlite\Connection;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Plugin\MigrateIdMapInterface;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
use Drupal\migrate\Row;
use Drupal\Tests\migrate\Unit\MigrateSqlIdMapTest;
use Drupal\Tests\smart_sql_idmap\Unit\TestSmartSqlIdMap;
use PHPUnit\Framework\ExpectationFailedException;
class SmartSqlTest extends MigrateSqlIdMapTest {
protected $migrationConfiguration = [
'id' => 'smart_sql_idmap_test',
];
protected $expectedMapTableName = 'm_map_smart_sql_idmap_test';
protected $expectedPrefixedMapTableName = 'm_map_smart_sql_idmap_test';
protected $expectedMessageTableName = 'm_message_smart_sql_idmap_test';
protected function saveMap(array $map) {
$table = $this
->getIdMap()
->mapTableName();
$schema = $this->database
->schema();
if ($schema
->tableExists($table)) {
foreach (array_keys($map) as $field) {
if (!$schema
->fieldExists($table, $field)) {
$schema
->addField($table, $field, [
'type' => 'text',
]);
}
}
}
else {
$schema
->createTable($table, $this
->createSchemaFromRow($map));
}
$this->database
->insert($table)
->fields($map)
->execute();
}
protected function getIdMap() {
$migration = $this
->getMigration();
$plugin = $this
->createMock('Drupal\\migrate\\Plugin\\MigrateSourceInterface');
$plugin
->method('getIds')
->willReturn($this->sourceIds);
$migration
->method('getSourcePlugin')
->willReturn($plugin);
$plugin = $this
->createMock('Drupal\\migrate\\Plugin\\MigrateDestinationInterface');
$plugin
->method('getIds')
->willReturn($this->destinationIds);
$migration
->method('getDestinationPlugin')
->willReturn($plugin);
$event_dispatcher = $this
->createMock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface');
$migration_plugin_manager = $this
->createMock(MigrationPluginManagerInterface::class);
$base_plugin_id = substr($migration
->id(), 0, strpos($migration
->id(), PluginBase::DERIVATIVE_SEPARATOR));
if ($base_plugin_id) {
$migration_plugin_manager
->expects($this
->any())
->method('getDefinitions')
->willReturn([]);
}
$id_map = new TestSmartSqlIdMap($this->database, $migration_plugin_manager, [], 'smart_sql', [], $migration, $event_dispatcher);
$migration
->method('getIdMap')
->willReturn($id_map);
return $id_map;
}
public function testSaveIdMapping() {
$source = [
'source_id_property' => 'source_value',
];
$row = new Row($source, [
'source_id_property' => [],
]);
$id_map = $this
->getIdMap();
$id_map
->saveIdMapping($row, [
'destination_id_property' => 2,
]);
$expected_result = [
[
'sourceid1' => 'source_value',
'source_ids_hash' => $this
->getIdMap()
->getSourceIdsHash($source),
'destid1' => 2,
] + $this
->idMapDefaults(),
];
$this
->queryResultTest($this
->getIdMapContents(), $expected_result);
$source = [
'source_id_property' => 'source_value_1',
];
$row = new Row($source, [
'source_id_property' => [],
]);
$id_map
->saveIdMapping($row, [
'destination_id_property' => 3,
]);
$expected_result[] = [
'sourceid1' => 'source_value_1',
'source_ids_hash' => $this
->getIdMap()
->getSourceIdsHash($source),
'destid1' => 3,
] + $this
->idMapDefaults();
$this
->queryResultTest($this
->getIdMapContents(), $expected_result);
$id_map
->saveIdMapping($row, [
'destination_id_property' => 4,
]);
$expected_result[1]['destid1'] = 4;
$this
->queryResultTest($this
->getIdMapContents(), $expected_result);
}
public function testGetRowsNeedingUpdate() {
$id_map = $this
->getIdMap();
$row_statuses = [
MigrateIdMapInterface::STATUS_IMPORTED,
MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
MigrateIdMapInterface::STATUS_IGNORED,
MigrateIdMapInterface::STATUS_FAILED,
];
foreach ($row_statuses as $status) {
$source = [
'source_id_property' => 'source_value_' . $status,
];
$row = new Row($source, [
'source_id_property' => [],
]);
$destination = [
'destination_id_property' => 'destination_value_' . $status,
];
$id_map
->saveIdMapping($row, $destination, $status);
$expected_results[] = [
'sourceid1' => 'source_value_' . $status,
'source_ids_hash' => $this
->getIdMap()
->getSourceIdsHash($source),
'destid1' => 'destination_value_' . $status,
'source_row_status' => $status,
'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
'hash' => '',
];
if ($status == MigrateIdMapInterface::STATUS_IMPORTED) {
$rows_needing_update = $id_map
->getRowsNeedingUpdate(1);
$this
->assertCount(0, $rows_needing_update);
}
}
$this
->queryResultTest($this
->getIdMapContents(), $expected_results);
$row_needing_update = $id_map
->getRowsNeedingUpdate(1);
$this
->assertCount(1, $row_needing_update);
$source_id = $expected_results[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]['sourceid1'];
$test_row = $id_map
->getRowBySource([
'source_id_property' => $source_id,
]);
$this
->assertSame($test_row, (array) $row_needing_update[0]);
$source = [
'source_id_property' => 'source_value_multiple',
];
$row = new Row($source, [
'source_id_property' => [],
]);
$destination = [
'destination_id_property' => 'destination_value_multiple',
];
$id_map
->saveIdMapping($row, $destination, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
$rows_needing_update = $id_map
->getRowsNeedingUpdate(2);
$this
->assertCount(2, $rows_needing_update);
}
public function testLookupDestinationIds() {
$id_map = $this
->setupRows([
'nid',
], [
'nid',
], [
[
1,
101,
],
[
2,
102,
],
[
3,
103,
],
]);
$this
->assertEquals([], $id_map
->lookupDestinationIds([]));
$this
->assertEquals([
[
101,
],
], $id_map
->lookupDestinationIds([
1,
]));
$this
->assertEquals([
[
102,
],
], $id_map
->lookupDestinationIds([
2,
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
99,
]));
$this
->assertEquals([
[
101,
],
], $id_map
->lookupDestinationIds([
'nid' => 1,
]));
$this
->assertEquals([
[
102,
],
], $id_map
->lookupDestinationIds([
'nid' => 2,
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
'nid' => 99,
]));
$id_map = $this
->setupRows([
'nid',
'language',
], [
'nid',
'langcode',
], [
[
1,
'en',
101,
'en',
],
[
1,
'fr',
101,
'fr',
],
[
1,
'de',
101,
'de',
],
[
2,
'en',
102,
'en',
],
]);
$this
->assertEquals([], $id_map
->lookupDestinationIds([]));
$this
->assertEquals([
[
101,
'en',
],
], $id_map
->lookupDestinationIds([
1,
'en',
]));
$this
->assertEquals([
[
101,
'fr',
],
], $id_map
->lookupDestinationIds([
1,
'fr',
]));
$this
->assertEquals([
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
2,
'en',
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
2,
'fr',
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
99,
'en',
]));
$this
->assertEquals([
[
101,
'en',
],
], $id_map
->lookupDestinationIds([
'nid' => 1,
'language' => 'en',
]));
$this
->assertEquals([
[
101,
'fr',
],
], $id_map
->lookupDestinationIds([
'nid' => 1,
'language' => 'fr',
]));
$this
->assertEquals([
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
'nid' => 2,
'language' => 'en',
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
'nid' => 2,
'language' => 'fr',
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
'nid' => 99,
'language' => 'en',
]));
$this
->assertEquals([
[
101,
'en',
],
[
101,
'fr',
],
[
101,
'de',
],
], $id_map
->lookupDestinationIds([
1,
]));
$this
->assertEquals([
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
2,
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
99,
]));
$this
->assertEquals([
[
101,
'en',
],
[
101,
'fr',
],
[
101,
'de',
],
], $id_map
->lookupDestinationIds([
'nid' => 1,
]));
$this
->assertEquals([
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
'nid' => 2,
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
'nid' => 99,
]));
$this
->assertEquals([
[
101,
'en',
],
[
101,
'fr',
],
[
101,
'de',
],
], $id_map
->lookupDestinationIds([
'nid' => 1,
'language' => NULL,
]));
$this
->assertEquals([
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
'nid' => 2,
'language' => NULL,
]));
$this
->assertEquals([
[
101,
'en',
],
[
102,
'en',
],
], $id_map
->lookupDestinationIds([
'language' => 'en',
]));
$this
->assertEquals([
[
101,
'fr',
],
], $id_map
->lookupDestinationIds([
'language' => 'fr',
]));
$this
->assertEquals([], $id_map
->lookupDestinationIds([
'language' => 'zh',
]));
try {
$id_map
->lookupDestinationIds([
1,
2,
3,
]);
$this
->fail('Too many source IDs should throw');
} catch (MigrateException $e) {
$this
->assertEquals("Extra unknown items for map {$this->expectedMapTableName} in source IDs: array (\n 0 => 3,\n)", $e
->getMessage());
}
try {
$id_map
->lookupDestinationIds([
'nid' => 1,
'aaa' => '2',
]);
$this
->fail('Unknown source ID key should throw');
} catch (MigrateException $e) {
$this
->assertEquals("Extra unknown items for map {$this->expectedMapTableName} in source IDs: array (\n 'aaa' => '2',\n)", $e
->getMessage());
}
$id_map
->getDatabase()
->update($id_map
->mapTableName())
->condition('sourceid1', 1)
->condition('sourceid2', 'en')
->fields([
TestSmartSqlIdMap::SOURCE_IDS_HASH => uniqid(),
])
->execute();
$this
->assertNotEquals([
[
101,
'en',
],
], $id_map
->lookupDestinationIds([
1,
'en',
]));
}
public function testSetUpdate() {
$id_map = $this
->getIdMap();
$row_statuses = [
MigrateIdMapInterface::STATUS_IMPORTED,
MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
MigrateIdMapInterface::STATUS_IGNORED,
MigrateIdMapInterface::STATUS_FAILED,
];
foreach ($row_statuses as $status) {
$source = [
'source_id_property' => 'source_value_' . $status,
];
$row = new Row($source, [
'source_id_property' => [],
]);
$destination = [
'destination_id_property' => 'destination_value_' . $status,
];
$id_map
->saveIdMapping($row, $destination, $status);
$expected_results[] = [
'sourceid1' => 'source_value_' . $status,
'source_ids_hash' => $this
->getIdMap()
->getSourceIdsHash($source),
'destid1' => 'destination_value_' . $status,
'source_row_status' => $status,
'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
'hash' => '',
];
}
$this
->queryResultTest($this
->getIdMapContents(), $expected_results);
foreach ($row_statuses as $status) {
$id_map
->setUpdate([
'source_id_property' => 'source_value_' . $status,
]);
}
foreach ($expected_results as $key => $value) {
$expected_results[$key]['source_row_status'] = MigrateIdMapInterface::STATUS_NEEDS_UPDATE;
}
$this
->queryResultTest($this
->getIdMapContents(), $expected_results);
try {
$id_map
->setUpdate([]);
$this
->assertFalse(FALSE, 'MigrateException not thrown, when source identifiers were provided to update.');
} catch (MigrateException $e) {
$this
->assertTrue(TRUE, "MigrateException thrown, when source identifiers were not provided to update.");
}
}
public function testPrepareUpdate() {
$id_map = $this
->getIdMap();
$row_statuses = [
MigrateIdMapInterface::STATUS_IMPORTED,
MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
MigrateIdMapInterface::STATUS_IGNORED,
MigrateIdMapInterface::STATUS_FAILED,
];
foreach ($row_statuses as $status) {
$source = [
'source_id_property' => 'source_value_' . $status,
];
$row = new Row($source, [
'source_id_property' => [],
]);
$destination = [
'destination_id_property' => 'destination_value_' . $status,
];
$id_map
->saveIdMapping($row, $destination, $status);
$expected_results[] = [
'sourceid1' => 'source_value_' . $status,
'destid1' => 'destination_value_' . $status,
'source_row_status' => $status,
'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
'hash' => '',
];
}
$this
->queryResultTest($this
->getIdMapContents(), $expected_results);
$id_map
->prepareUpdate();
foreach ($expected_results as $key => $value) {
$expected_results[$key]['source_row_status'] = MigrateIdMapInterface::STATUS_NEEDS_UPDATE;
}
$this
->queryResultTest($this
->getIdMapContents(), $expected_results);
}
public function testGetQualifiedMapTablePrefix() {
$connection_options = [
'database' => ':memory:',
'prefix' => 'prefix',
];
$pdo = Connection::open($connection_options);
$this->database = new Connection($pdo, $connection_options);
$qualified_map_table = $this
->getIdMap()
->getQualifiedMapTableName();
$this
->assertEquals("prefix.{$this->expectedPrefixedMapTableName}", $qualified_map_table);
}
private function getIdMapContents() {
$result = $this->database
->select($this
->getIdMap()
->getQualifiedMapTableName(), 't')
->fields('t')
->execute();
$contents = [];
foreach ($result as $row) {
$contents[] = (array) $row;
}
return $contents;
}
public function testMapTableCreation() {
$id_map = $this
->getIdMap();
$map_table_name = $id_map
->mapTableName();
$message_table_name = $id_map
->messageTableName();
$this
->assertEquals($this->expectedMapTableName, $map_table_name);
$this
->assertEquals($this->expectedMessageTableName, $message_table_name);
$this
->assertFalse($this->database
->schema()
->tableExists($map_table_name));
$this
->assertFalse($this->database
->schema()
->tableExists($message_table_name));
$id_map
->getDatabase();
$this
->assertTrue($this->database
->schema()
->tableExists($map_table_name));
$this
->assertTrue($this->database
->schema()
->tableExists($message_table_name));
}
public function testGetRowByDestination() {
try {
parent::testGetRowByDestination();
} catch (ExpectationFailedException $exception) {
$message_is_about_actual_array_is_not_false = preg_match('/^Failed asserting that Array .*/', $exception
->getMessage()) && preg_match('/.* is false\\.$/', $exception
->getMessage()) || preg_match('/^Failed asserting that an array is empty.$/', $exception
->getMessage());
if (!$message_is_about_actual_array_is_not_false) {
throw $exception;
}
}
$id_map = $this
->getIdMap();
$missing_result_row = $id_map
->getRowByDestination([
'destination_id_property' => 'invalid_destination_id_property',
]);
$this
->assertIsArray($missing_result_row);
$invalid_result_row = $id_map
->getRowByDestination([
'invalid_destination_key' => 'invalid_destination_id_property',
]);
$this
->assertIsArray($invalid_result_row);
}
}