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