27557d18af8c164c996b24046c60bae56699eacc
[yaffs-website] / web / core / modules / migrate / tests / src / Unit / process / MakeUniqueEntityFieldTest.php
1 <?php
2
3 namespace Drupal\Tests\migrate\Unit\process;
4
5 use Drupal\Core\Entity\EntityStorageInterface;
6 use Drupal\Core\Entity\EntityTypeManagerInterface;
7 use Drupal\Core\Entity\Query\QueryInterface;
8 use Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField;
9 use Drupal\Component\Utility\Unicode;
10
11 /**
12  * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField
13  * @group migrate
14  */
15 class MakeUniqueEntityFieldTest extends MigrateProcessTestCase {
16
17   /**
18    * The mock entity query.
19    *
20    * @var \Drupal\Core\Entity\Query\QueryInterface|\Drupal\Core\Entity\Query\QueryFactory
21    */
22   protected $entityQuery;
23
24   /**
25    * The mocked entity type manager.
26    *
27    * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
28    */
29   protected $entityTypeManager;
30
31   /**
32    * The migration configuration, initialized to set the ID to test.
33    *
34    * @var array
35    */
36   protected $migrationConfiguration = [
37     'id' => 'test',
38   ];
39
40   /**
41    * {@inheritdoc}
42    */
43   protected function setUp() {
44     $this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface')
45       ->disableOriginalConstructor()
46       ->getMock();
47     $this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
48
49     $storage = $this->getMock(EntityStorageInterface::class);
50     $storage->expects($this->any())
51       ->method('getQuery')
52       ->willReturn($this->entityQuery);
53     $this->entityTypeManager->expects($this->any())
54       ->method('getStorage')
55       ->with('test_entity_type')
56       ->willReturn($storage);
57     parent::setUp();
58   }
59
60   /**
61    * Tests making an entity field value unique.
62    *
63    * @dataProvider providerTestMakeUniqueEntityField
64    */
65   public function testMakeUniqueEntityField($count, $postfix = '', $start = NULL, $length = NULL) {
66     $configuration = [
67       'entity_type' => 'test_entity_type',
68       'field' => 'test_field',
69     ];
70     if ($postfix) {
71       $configuration['postfix'] = $postfix;
72     }
73     $configuration['start'] = isset($start) ? $start : NULL;
74     $configuration['length'] = isset($length) ? $length : NULL;
75     $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager);
76     $this->entityQueryExpects($count);
77     $value = $this->randomMachineName(32);
78     $actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty');
79     $expected = Unicode::substr($value, $start, $length);
80     $expected .= $count ? $postfix . $count : '';
81     $this->assertSame($expected, $actual);
82   }
83
84   /**
85    * Tests that invalid start position throws an exception.
86    */
87   public function testMakeUniqueEntityFieldEntityInvalidStart() {
88     $configuration = [
89       'entity_type' => 'test_entity_type',
90       'field' => 'test_field',
91       'start' => 'foobar',
92     ];
93     $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager);
94     $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.');
95     $plugin->transform('test_start', $this->migrateExecutable, $this->row, 'testproperty');
96   }
97
98   /**
99    * Tests that invalid length option throws an exception.
100    */
101   public function testMakeUniqueEntityFieldEntityInvalidLength() {
102     $configuration = [
103       'entity_type' => 'test_entity_type',
104       'field' => 'test_field',
105       'length' => 'foobar',
106     ];
107     $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager);
108     $this->setExpectedException('Drupal\migrate\MigrateException', 'The character length configuration key should be an integer. Omit this key to capture the entire string.');
109     $plugin->transform('test_length', $this->migrateExecutable, $this->row, 'testproperty');
110   }
111
112   /**
113    * Data provider for testMakeUniqueEntityField().
114    */
115   public function providerTestMakeUniqueEntityField() {
116     return [
117       // Tests no duplication.
118       [0],
119       // Tests no duplication and start position.
120       [0, NULL, 10],
121       // Tests no duplication, start position, and length.
122       [0, NULL, 5, 10],
123       // Tests no duplication and length.
124       [0, NULL, NULL, 10],
125       // Tests duplication.
126       [3],
127       // Tests duplication and start position.
128       [3, NULL, 10],
129       // Tests duplication, start position, and length.
130       [3, NULL, 5, 10],
131       // Tests duplication and length.
132       [3, NULL, NULL, 10],
133       // Tests no duplication and postfix.
134       [0, '_'],
135       // Tests no duplication, postfix, and start position.
136       [0, '_', 5],
137       // Tests no duplication, postfix, start position, and length.
138       [0, '_', 5, 10],
139       // Tests no duplication, postfix, and length.
140       [0, '_', NULL, 10],
141       // Tests duplication and postfix.
142       [2, '_'],
143       // Tests duplication, postfix, and start position.
144       [2, '_', 5],
145       // Tests duplication, postfix, start position, and length.
146       [2, '_', 5, 10],
147       // Tests duplication, postfix, and length.
148       [2, '_', NULL, 10],
149     ];
150   }
151
152   /**
153    * Helper function to add expectations to the mock entity query object.
154    *
155    * @param int $count
156    *   The number of unique values to be set up.
157    */
158   protected function entityQueryExpects($count) {
159     $this->entityQuery->expects($this->exactly($count + 1))
160       ->method('condition')
161       ->will($this->returnValue($this->entityQuery));
162     $this->entityQuery->expects($this->exactly($count + 1))
163       ->method('count')
164       ->will($this->returnValue($this->entityQuery));
165     $this->entityQuery->expects($this->exactly($count + 1))
166       ->method('execute')
167       ->will($this->returnCallback(function () use (&$count) {
168         return $count--;
169       }));
170   }
171
172   /**
173    * Tests making an entity field value unique only for migrated entities.
174    */
175   public function testMakeUniqueEntityFieldMigrated() {
176     $configuration = [
177       'entity_type' => 'test_entity_type',
178       'field' => 'test_field',
179       'migrated' => TRUE,
180     ];
181     $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager);
182
183     // Setup the entityQuery used in MakeUniqueEntityFieldEntity::exists. The
184     // map, $map, is an array consisting of the four input parameters to the
185     // query condition method and then the query to return. Both 'forum' and
186     // 'test_vocab' are existing entities. There is no 'test_vocab1'.
187     $map = [];
188     foreach (['forums', 'test_vocab', 'test_vocab1'] as $id) {
189       $query = $this->prophesize(QueryInterface::class);
190       $query->willBeConstructedWith([]);
191       $query->execute()->willReturn($id === 'test_vocab1' ? [] : [$id]);
192       $map[] = ['test_field', $id, NULL, NULL, $query->reveal()];
193     }
194     $this->entityQuery
195       ->method('condition')
196       ->will($this->returnValueMap($map));
197
198     // Entity 'forums' is pre-existing, entity 'test_vocab' was migrated.
199     $this->idMap
200       ->method('lookupSourceID')
201       ->will($this->returnValueMap([
202         [['test_field' => 'forums'], FALSE],
203         [['test_field' => 'test_vocab'], ['source_id' => 42]],
204       ]));
205
206     // Existing entity 'forums' was not migrated, value should not be unique.
207     $actual = $plugin->transform('forums', $this->migrateExecutable, $this->row, 'testproperty');
208     $this->assertEquals('forums', $actual, 'Pre-existing name is re-used');
209
210     // Entity 'test_vocab' was migrated, value should be unique.
211     $actual = $plugin->transform('test_vocab', $this->migrateExecutable, $this->row, 'testproperty');
212     $this->assertEquals('test_vocab1', $actual, 'Migrated name is deduplicated');
213   }
214
215 }