'test', ]; /** * {@inheritdoc} */ 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 */ public function testDedupe($count, $postfix = '', $start = NULL, $length = NULL) { $configuration = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', ]; if ($postfix) { $configuration['postfix'] = $postfix; } $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); $value = $this->randomMachineName(32); $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 = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', 'start' => 'foobar', ]; $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); $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 = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', 'length' => 'foobar', ]; $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); $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 [ // Tests no duplication. [0], // Tests no duplication and start position. [0, NULL, 10], // Tests no duplication, start position, and length. [0, NULL, 5, 10], // Tests no duplication and length. [0, NULL, NULL, 10], // Tests duplication. [3], // Tests duplication and start position. [3, NULL, 10], // Tests duplication, start position, and length. [3, NULL, 5, 10], // Tests duplication and length. [3, NULL, NULL, 10], // Tests no duplication and postfix. [0, '_'], // Tests no duplication, postfix, and start position. [0, '_', 5], // Tests no duplication, postfix, start position, and length. [0, '_', 5, 10], // Tests no duplication, postfix, and length. [0, '_', NULL, 10], // Tests duplication and postfix. [2, '_'], // Tests duplication, postfix, and start position. [2, '_', 5], // Tests duplication, postfix, start position, and length. [2, '_', 5, 10], // 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); // 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'); } }