Newer
Older
<?php
Dries Buytaert
committed
namespace Drupal\Tests\migrate\Unit\process;
@trigger_error('The ' . __NAMESPACE__ . '\DedupeEntityTest is deprecated in
Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MakeUniqueEntityFieldTest', E_USER_DEPRECATED);
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\migrate\Plugin\migrate\process\DedupeEntity;
Alex Pott
committed
use Drupal\Component\Utility\Unicode;
/**
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\DedupeEntity
* @group migrate
*/
class DedupeEntityTest extends MigrateProcessTestCase {
/**
* The mock entity query.
*
* @var \Drupal\Core\Entity\Query\QueryInterface
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $entityQuery;
/**
* The mocked entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityTypeManager;
/**
* The migration configuration, initialized to set the ID to test.
*
* @var array
*/
protected $migrationConfiguration = [
'id' => 'test',
];
/**
* {@inheritdoc}
*/
Dries Buytaert
committed
protected function setUp() {
$this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface')
->disableOriginalConstructor()
->getMock();
$this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
$storage = $this->getMock(EntityStorageInterface::class);
$storage->expects($this->any())
->method('getQuery')
->willReturn($this->entityQuery);
$this->entityTypeManager->expects($this->any())
->method('getStorage')
->with('test_entity_type')
->willReturn($storage);
parent::setUp();
}
/**
* Tests entity based deduplication based on providerTestDedupe() values.
*
* @dataProvider providerTestDedupe
*/
Alex Pott
committed
public function testDedupe($count, $postfix = '', $start = NULL, $length = NULL) {
$configuration = [
'entity_type' => 'test_entity_type',
'field' => 'test_field',
];
if ($postfix) {
$configuration['postfix'] = $postfix;
}
Alex Pott
committed
$configuration['start'] = isset($start) ? $start : NULL;
$configuration['length'] = isset($length) ? $length : NULL;
$plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager);
$this->entityQueryExpects($count);
Alex Pott
committed
$value = $this->randomMachineName(32);
Alex Pott
committed
$actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty');
$expected = Unicode::substr($value, $start, $length);
$expected .= $count ? $postfix . $count : '';
$this->assertSame($expected, $actual);
}
/**
* Tests that invalid start position throws an exception.
*/
public function testDedupeEntityInvalidStart() {
$configuration = [
Alex Pott
committed
'entity_type' => 'test_entity_type',
'field' => 'test_field',
'start' => 'foobar',
];
$plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager);
Alex Pott
committed
$this->setExpectedException('Drupal\migrate\MigrateException', 'The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.');
$plugin->transform('test_start', $this->migrateExecutable, $this->row, 'testproperty');
}
/**
* Tests that invalid length option throws an exception.
*/
public function testDedupeEntityInvalidLength() {
$configuration = [
Alex Pott
committed
'entity_type' => 'test_entity_type',
'field' => 'test_field',
'length' => 'foobar',
];
$plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager);
Alex Pott
committed
$this->setExpectedException('Drupal\migrate\MigrateException', 'The character length configuration key should be an integer. Omit this key to capture the entire string.');
$plugin->transform('test_length', $this->migrateExecutable, $this->row, 'testproperty');
}
/**
* Data provider for testDedupe().
*/
public function providerTestDedupe() {
return [
Alex Pott
committed
// Tests no duplication.
[0],
Alex Pott
committed
// Tests no duplication and start position.
[0, NULL, 10],
Alex Pott
committed
// Tests no duplication, start position, and length.
[0, NULL, 5, 10],
Alex Pott
committed
// Tests no duplication and length.
[0, NULL, NULL, 10],
Alex Pott
committed
// Tests duplication.
[3],
Alex Pott
committed
// Tests duplication and start position.
[3, NULL, 10],
Alex Pott
committed
// Tests duplication, start position, and length.
[3, NULL, 5, 10],
Alex Pott
committed
// Tests duplication and length.
[3, NULL, NULL, 10],
Alex Pott
committed
// Tests no duplication and postfix.
[0, '_'],
Alex Pott
committed
// Tests no duplication, postfix, and start position.
[0, '_', 5],
Alex Pott
committed
// Tests no duplication, postfix, start position, and length.
[0, '_', 5, 10],
Alex Pott
committed
// Tests no duplication, postfix, and length.
[0, '_', NULL, 10],
Alex Pott
committed
// Tests duplication and postfix.
[2, '_'],
Alex Pott
committed
// Tests duplication, postfix, and start position.
[2, '_', 5],
Alex Pott
committed
// Tests duplication, postfix, start position, and length.
[2, '_', 5, 10],
Alex Pott
committed
// Tests duplication, postfix, and length.
[2, '_', NULL, 10],
];
}
/**
* Helper function to add expectations to the mock entity query object.
*
* @param int $count
* The number of deduplications to be set up.
*/
protected function entityQueryExpects($count) {
$this->entityQuery->expects($this->exactly($count + 1))
->method('condition')
->will($this->returnValue($this->entityQuery));
$this->entityQuery->expects($this->exactly($count + 1))
->method('count')
->will($this->returnValue($this->entityQuery));
$this->entityQuery->expects($this->exactly($count + 1))
->method('execute')
->will($this->returnCallback(function () use (&$count) { return $count--;}));
}
/**
* Test deduplicating only migrated entities.
*/
public function testDedupeMigrated() {
$configuration = [
'entity_type' => 'test_entity_type',
'field' => 'test_field',
'migrated' => TRUE,
];
$plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Setup the entityQuery used in DedupeEntity::exists. The map, $map, is
// an array consisting of the four input parameters to the query condition
// method and then the query to return. Both 'forum' and
// 'test_vocab' are existing entities. There is no 'test_vocab1'.
$map = [];
foreach (['forums', 'test_vocab', 'test_vocab1'] as $id) {
$query = $this->prophesize(QueryInterface::class);
$query->willBeConstructedWith([]);
$query->execute()->willReturn($id === 'test_vocab1' ? [] : [$id]);
$map[] = ['test_field', $id, NULL, NULL, $query->reveal()];
}
$this->entityQuery
->method('condition')
->will($this->returnValueMap($map));
// Entity 'forums' is pre-existing, entity 'test_vocab' was migrated.
$this->idMap
->method('lookupSourceID')
->will($this->returnValueMap([
[['test_field' => 'forums'], FALSE],
[['test_field' => 'test_vocab'], ['source_id' => 42]],
]));
// Existing entity 'forums' was not migrated, it should not be deduplicated.
$actual = $plugin->transform('forums', $this->migrateExecutable, $this->row, 'testproperty');
$this->assertEquals('forums', $actual, 'Pre-existing name is re-used');
// Entity 'test_vocab' was migrated, should be deduplicated.
$actual = $plugin->transform('test_vocab', $this->migrateExecutable, $this->row, 'testproperty');
$this->assertEquals('test_vocab1', $actual, 'Migrated name is deduplicated');
}