Chris@0: 'Node ID', Chris@0: ]; Chris@0: Chris@0: /** Chris@0: * The test values. Chris@0: * Chris@0: * @var array Chris@0: */ Chris@0: protected $testValues = [ Chris@0: 'nid' => 1, Chris@0: 'title' => 'node 1', Chris@0: ]; Chris@0: Chris@0: /** Chris@18: * Test source properties for testing get and getMultiple. Chris@18: * Chris@18: * @var array Chris@18: */ Chris@18: protected $testGetSourceProperties = [ Chris@18: 'source_key_1' => 'source_value_1', Chris@18: 'source_key_2' => 'source_value_2', Chris@18: '@source_key_3' => 'source_value_3', Chris@18: 'shared_key_1' => 'source_shared_value_1', Chris@18: '@shared_key_2' => 'source_shared_value_2', Chris@18: '@@@@shared_key_3' => 'source_shared_value_3', Chris@18: ]; Chris@18: Chris@18: /** Chris@18: * Test source keys for testing get and getMultiple. Chris@18: * Chris@18: * @var array Chris@18: */ Chris@18: protected $testGetSourceIds = [ Chris@18: 'source_key_1' => [], Chris@18: ]; Chris@18: Chris@18: /** Chris@18: * Test destination properties for testing get and getMultiple. Chris@18: * Chris@18: * @var array Chris@18: */ Chris@18: protected $testGetDestinationProperties = [ Chris@18: 'destination_key_1' => 'destination_value_1', Chris@18: 'destination_key_2' => 'destination_value_2', Chris@18: '@destination_key_3' => 'destination_value_3', Chris@18: 'shared_key_1' => 'destination_shared_value_1', Chris@18: '@shared_key_2' => 'destination_shared_value_2', Chris@18: '@@@@shared_key_3' => 'destination_shared_value_3', Chris@18: ]; Chris@18: Chris@18: /** Chris@0: * The test hash. Chris@0: * Chris@0: * @var string Chris@0: */ Chris@0: protected $testHash = '85795d4cde4a2425868b812cc88052ecd14fc912e7b9b4de45780f66750e8b1e'; Chris@0: Chris@0: /** Chris@0: * The test hash after changing title value to 'new title'. Chris@0: * Chris@0: * @var string Chris@0: */ Chris@0: protected $testHashMod = '9476aab0b62b3f47342cc6530441432e5612dcba7ca84115bbab5cceaca1ecb3'; Chris@0: Chris@0: /** Chris@0: * Tests object creation: empty. Chris@0: */ Chris@0: public function testRowWithoutData() { Chris@0: $row = new Row(); Chris@0: $this->assertSame([], $row->getSource(), 'Empty row'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests object creation: basic. Chris@0: */ Chris@0: public function testRowWithBasicData() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $this->assertSame($this->testValues, $row->getSource(), 'Row with data, simple id.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests object creation: multiple source IDs. Chris@0: */ Chris@0: public function testRowWithMultipleSourceIds() { Chris@0: $multi_source_ids = $this->testSourceIds + ['vid' => 'Node revision']; Chris@0: $multi_source_ids_values = $this->testValues + ['vid' => 1]; Chris@0: $row = new Row($multi_source_ids_values, $multi_source_ids); Chris@0: $this->assertSame($multi_source_ids_values, $row->getSource(), 'Row with data, multifield id.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests object creation: invalid values. Chris@0: */ Chris@0: public function testRowWithInvalidData() { Chris@0: $invalid_values = [ Chris@0: 'title' => 'node X', Chris@0: ]; Chris@0: $this->setExpectedException(\Exception::class); Chris@0: $row = new Row($invalid_values, $this->testSourceIds); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests source immutability after freeze. Chris@0: */ Chris@0: public function testSourceFreeze() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHash, $row->getHash(), 'Correct hash.'); Chris@0: $row->setSourceProperty('title', 'new title'); Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHashMod, $row->getHash(), 'Hash changed correctly.'); Chris@0: $row->freezeSource(); Chris@0: $this->setExpectedException(\Exception::class); Chris@0: $row->setSourceProperty('title', 'new title'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests setting on a frozen row. Chris@0: */ Chris@0: public function testSetFrozenRow() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $row->freezeSource(); Chris@0: $this->setExpectedException(\Exception::class, "The source is frozen and can't be changed any more"); Chris@0: $row->setSourceProperty('title', 'new title'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests hashing. Chris@0: */ Chris@0: public function testHashing() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $this->assertSame('', $row->getHash(), 'No hash at creation'); Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHash, $row->getHash(), 'Correct hash.'); Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHash, $row->getHash(), 'Correct hash even doing it twice.'); Chris@0: Chris@0: // Set the map to needs update. Chris@0: $test_id_map = [ Chris@0: 'original_hash' => '', Chris@0: 'hash' => '', Chris@0: 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, Chris@0: ]; Chris@0: $row->setIdMap($test_id_map); Chris@0: $this->assertTrue($row->needsUpdate()); Chris@0: Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHash, $row->getHash(), 'Correct hash even if id_mpa have changed.'); Chris@0: $row->setSourceProperty('title', 'new title'); Chris@0: $row->rehash(); Chris@0: $this->assertSame($this->testHashMod, $row->getHash(), 'Hash changed correctly.'); Chris@0: // Check hash calculation algorithm. Chris@0: $hash = hash('sha256', serialize($row->getSource())); Chris@0: $this->assertSame($hash, $row->getHash()); Chris@0: // Check length of generated hash used for mapping schema. Chris@0: $this->assertSame(64, strlen($row->getHash())); Chris@0: Chris@0: // Set the map to successfully imported. Chris@0: $test_id_map = [ Chris@0: 'original_hash' => '', Chris@0: 'hash' => '', Chris@0: 'source_row_status' => MigrateIdMapInterface::STATUS_IMPORTED, Chris@0: ]; Chris@0: $row->setIdMap($test_id_map); Chris@0: $this->assertFalse($row->needsUpdate()); Chris@0: Chris@0: // Set the same hash value and ensure it was not changed. Chris@0: $random = $this->randomMachineName(); Chris@0: $test_id_map = [ Chris@0: 'original_hash' => $random, Chris@0: 'hash' => $random, Chris@0: 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, Chris@0: ]; Chris@0: $row->setIdMap($test_id_map); Chris@0: $this->assertFalse($row->changed()); Chris@0: Chris@0: // Set different has values to ensure it is marked as changed. Chris@0: $test_id_map = [ Chris@0: 'original_hash' => $this->randomMachineName(), Chris@0: 'hash' => $this->randomMachineName(), Chris@0: 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, Chris@0: ]; Chris@0: $row->setIdMap($test_id_map); Chris@0: $this->assertTrue($row->changed()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests getting/setting the ID Map. Chris@0: * Chris@0: * @covers ::setIdMap Chris@0: * @covers ::getIdMap Chris@0: */ Chris@0: public function testGetSetIdMap() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $test_id_map = [ Chris@0: 'original_hash' => '', Chris@0: 'hash' => '', Chris@0: 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, Chris@0: ]; Chris@0: $row->setIdMap($test_id_map); Chris@0: $this->assertEquals($test_id_map, $row->getIdMap()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests the source ID. Chris@0: */ Chris@0: public function testSourceIdValues() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $this->assertSame(['nid' => $this->testValues['nid']], $row->getSourceIdValues()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests the multiple source IDs. Chris@0: */ Chris@0: public function testMultipleSourceIdValues() { Chris@0: // Set values in same order as ids. Chris@0: $multi_source_ids = $this->testSourceIds + [ Chris@0: 'vid' => 'Node revision', Chris@0: 'type' => 'Node type', Chris@0: 'langcode' => 'Node language', Chris@0: ]; Chris@0: $multi_source_ids_values = $this->testValues + [ Chris@0: 'vid' => 1, Chris@0: 'type' => 'page', Chris@0: 'langcode' => 'en', Chris@0: ]; Chris@0: $row = new Row($multi_source_ids_values, $multi_source_ids); Chris@0: $this->assertSame(array_keys($multi_source_ids), array_keys($row->getSourceIdValues())); Chris@0: Chris@0: // Set values in different order. Chris@0: $multi_source_ids = $this->testSourceIds + [ Chris@0: 'vid' => 'Node revision', Chris@0: 'type' => 'Node type', Chris@0: 'langcode' => 'Node language', Chris@0: ]; Chris@0: $multi_source_ids_values = $this->testValues + [ Chris@0: 'langcode' => 'en', Chris@0: 'type' => 'page', Chris@0: 'vid' => 1, Chris@0: ]; Chris@0: $row = new Row($multi_source_ids_values, $multi_source_ids); Chris@0: $this->assertSame(array_keys($multi_source_ids), array_keys($row->getSourceIdValues())); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests getting the source property. Chris@0: * Chris@0: * @covers ::getSourceProperty Chris@0: */ Chris@0: public function testGetSourceProperty() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $this->assertSame($this->testValues['nid'], $row->getSourceProperty('nid')); Chris@0: $this->assertSame($this->testValues['title'], $row->getSourceProperty('title')); Chris@0: $this->assertNull($row->getSourceProperty('non_existing')); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests setting and getting the destination. Chris@0: */ Chris@0: public function testDestination() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: $this->assertEmpty($row->getDestination()); Chris@0: $this->assertFalse($row->hasDestinationProperty('nid')); Chris@0: Chris@0: // Set a destination. Chris@0: $row->setDestinationProperty('nid', 2); Chris@0: $this->assertTrue($row->hasDestinationProperty('nid')); Chris@0: $this->assertEquals(['nid' => 2], $row->getDestination()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests setting/getting multiple destination IDs. Chris@0: */ Chris@0: public function testMultipleDestination() { Chris@0: $row = new Row($this->testValues, $this->testSourceIds); Chris@0: // Set some deep nested values. Chris@0: $row->setDestinationProperty('image/alt', 'alt text'); Chris@0: $row->setDestinationProperty('image/fid', 3); Chris@0: Chris@0: $this->assertTrue($row->hasDestinationProperty('image')); Chris@0: $this->assertFalse($row->hasDestinationProperty('alt')); Chris@0: $this->assertFalse($row->hasDestinationProperty('fid')); Chris@0: Chris@0: $destination = $row->getDestination(); Chris@0: $this->assertEquals('alt text', $destination['image']['alt']); Chris@0: $this->assertEquals(3, $destination['image']['fid']); Chris@0: $this->assertEquals('alt text', $row->getDestinationProperty('image/alt')); Chris@0: $this->assertEquals(3, $row->getDestinationProperty('image/fid')); Chris@0: } Chris@0: Chris@18: /** Chris@18: * Test getting source and destination properties. Chris@18: * Chris@18: * @param string $key Chris@18: * The key to look up. Chris@18: * @param string $expected_value Chris@18: * The expected value. Chris@18: * Chris@18: * @dataProvider getDataProvider Chris@18: * @covers ::get Chris@18: */ Chris@18: public function testGet($key, $expected_value) { Chris@18: $row = $this->createRowWithDestinationProperties($this->testGetSourceProperties, $this->testGetSourceIds, $this->testGetDestinationProperties); Chris@18: $this->assertSame($expected_value, $row->get($key)); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Data Provider for testGet. Chris@18: * Chris@18: * @return array Chris@18: * The keys and expected values. Chris@18: */ Chris@18: public function getDataProvider() { Chris@18: return [ Chris@18: ['source_key_1', 'source_value_1'], Chris@18: ['source_key_2', 'source_value_2'], Chris@18: ['@@source_key_3', 'source_value_3'], Chris@18: ['shared_key_1', 'source_shared_value_1'], Chris@18: ['@@shared_key_2', 'source_shared_value_2'], Chris@18: ['@@@@@@@@shared_key_3', 'source_shared_value_3'], Chris@18: ['@destination_key_1', 'destination_value_1'], Chris@18: ['@destination_key_2', 'destination_value_2'], Chris@18: ['@@@destination_key_3', 'destination_value_3'], Chris@18: ['@shared_key_1', 'destination_shared_value_1'], Chris@18: ['@@@shared_key_2', 'destination_shared_value_2'], Chris@18: ['@@@@@@@@@shared_key_3', 'destination_shared_value_3'], Chris@18: ['destination_key_1', NULL], Chris@18: ['@shared_key_2', NULL], Chris@18: ['@source_key_1', NULL], Chris@18: ['random_source_key', NULL], Chris@18: ['@random_destination_key', NULL], Chris@18: ]; Chris@18: } Chris@18: Chris@18: /** Chris@18: * Test getting multiple source and destination properties. Chris@18: * Chris@18: * @param array $keys Chris@18: * An array of keys to look up. Chris@18: * @param array $expected_values Chris@18: * An array of expected values. Chris@18: * Chris@18: * @covers::getMultiple Chris@18: * @dataProvider getMultipleDataProvider Chris@18: */ Chris@18: public function testGetMultiple(array $keys, array $expected_values) { Chris@18: $row = $this->createRowWithDestinationProperties($this->testGetSourceProperties, $this->testGetSourceIds, $this->testGetDestinationProperties); Chris@18: $this->assertArrayEquals(array_combine($keys, $expected_values), $row->getMultiple($keys)); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Data Provider for testGetMultiple. Chris@18: * Chris@18: * @return array Chris@18: * The keys and expected values. Chris@18: */ Chris@18: public function getMultipleDataProvider() { Chris@18: return [ Chris@18: 'Single Key' => [ Chris@18: 'keys' => ['source_key_1'], Chris@18: 'values' => ['source_value_1'], Chris@18: ], Chris@18: 'All Source Keys' => [ Chris@18: 'keys' => [ Chris@18: 'source_key_1', Chris@18: 'source_key_2', Chris@18: '@@source_key_3', Chris@18: ], Chris@18: 'values' => [ Chris@18: 'source_value_1', Chris@18: 'source_value_2', Chris@18: 'source_value_3', Chris@18: ], Chris@18: ], Chris@18: 'All Destination Keys' => [ Chris@18: 'keys' => [ Chris@18: '@destination_key_1', Chris@18: '@destination_key_2', Chris@18: '@@@destination_key_3', Chris@18: ], Chris@18: 'values' => [ Chris@18: 'destination_value_1', Chris@18: 'destination_value_2', Chris@18: 'destination_value_3', Chris@18: ], Chris@18: ], Chris@18: 'Mix of keys including non-existant' => [ Chris@18: 'keys' => [ Chris@18: 'shared_key_1', Chris@18: '@shared_key_1', Chris@18: '@@shared_key_2', Chris@18: '@@@shared_key_2', Chris@18: '@@@@@@@@@shared_key_3', Chris@18: 'non_existant_source_key', Chris@18: '@non_existant_destination_key', Chris@18: ], Chris@18: 'values' => [ Chris@18: 'source_shared_value_1', Chris@18: 'destination_shared_value_1', Chris@18: 'source_shared_value_2', Chris@18: 'destination_shared_value_2', Chris@18: 'destination_shared_value_3', Chris@18: NULL, Chris@18: NULL, Chris@18: ], Chris@18: ], Chris@18: ]; Chris@18: } Chris@18: Chris@18: /** Chris@18: * Create a row and load it with destination properties. Chris@18: * Chris@18: * @param array $source_properties Chris@18: * The source property array. Chris@18: * @param array $source_ids Chris@18: * The source ids array. Chris@18: * @param array $destination_properties Chris@18: * The destination properties to load. Chris@18: * @param bool $is_stub Chris@18: * Whether this row is a stub row, defaults to FALSE. Chris@18: * Chris@18: * @return \Drupal\migrate\Row Chris@18: * The row, populated with destination properties. Chris@18: */ Chris@18: protected function createRowWithDestinationProperties(array $source_properties, array $source_ids, array $destination_properties, $is_stub = FALSE) { Chris@18: $row = new Row($source_properties, $source_ids, $is_stub); Chris@18: foreach ($destination_properties as $key => $property) { Chris@18: $row->setDestinationProperty($key, $property); Chris@18: } Chris@18: return $row; Chris@18: } Chris@18: Chris@0: }