Unverified Commit 02f1c210 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3086238 by quietone, alexpott, heddn, larowlan, benjifisher, dinarcon:...

Issue #3086238 by quietone, alexpott, heddn, larowlan, benjifisher, dinarcon: getHighestId() should not fail when there is a destination id with type string
parent 267186a6
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -971,14 +971,11 @@ protected function getMigrationPluginManager() {
   * {@inheritdoc}
   */
  public function getHighestId() {
    array_filter(
      $this->migration->getDestinationPlugin()->getIds(),
      function (array $id) {
        if ($id['type'] !== 'integer') {
          throw new \LogicException('Cannot determine the highest migrated ID without an integer ID column');
        }
      }
    );
    // Ensure that at the ID an integer.
    $keys = $this->migration->getDestinationPlugin()->getIds();
    if (reset($keys)['type'] !== 'integer') {
      throw new \LogicException('To determine the highest migrated ID the first ID must be an integer');
    };

    // List of mapping tables to look in for the highest ID.
    $map_tables = [
+133 −0
Original line number Diff line number Diff line
@@ -1071,4 +1071,137 @@ public function testMapTableCreation() {
    $this->assertTrue($this->database->schema()->tableExists($message_table_name));
  }

  /**
   * Tests getHighestId method.
   *
   * @param array $destination_ids
   *   Array of destination ids.
   * @param array $rows
   *   Array of map table rows.
   * @param int $expected
   *   Expected highest id value.
   *
   * @dataProvider getHighestIdDataProvider
   */
  public function testGetHighestId(array $destination_ids, array $rows, $expected) {
    $this->database = $this->getDatabase([]);
    $this->sourceIds = $destination_ids;
    $this->destinationIds = $destination_ids;
    $db_keys = [];
    $dest_id_count = count($destination_ids);
    for ($i = 1; $i <= $dest_id_count; $i++) {
      $db_keys[$i] = "sourceid$i";
    }
    for ($i = 1; $i <= $dest_id_count; $i++) {
      $db_keys[] = "destid$i";
    }
    $id_map = $this->getIdMap();
    foreach ($rows as $row) {
      $values = array_combine($db_keys, $row);
      $source_values = array_slice($row, 0, $dest_id_count);
      $values['source_ids_hash'] = $id_map->getSourceIdsHash($source_values);
      $this->saveMap($values);
    }

    $actual = $id_map->getHighestId();
    $this->assertSame($expected, $actual);
  }

  /**
   * Data provider for getHighestId().
   *
   * Scenarios to test:
   * - Destination ID type integer.
   * - Destination ID types integer and string.
   *
   * @return array
   *   An array of data values.
   */
  public function getHighestIdDataProvider() {
    return [
      'Destination ID type integer' => [
        'dest_ids' => [
          'nid' => [
            'type' => 'integer',
          ],
        ],
        'rows' => [
          [1, 2],
          [2, 1],
          [4, 3],
          [9, 5],
        ],
        'expected' => 5,
      ],
      'Destination ID types integer and string' => [
        'dest_ids' => [
          'nid' => [
            'type' => 'integer',
          ],
          'vid' => [
            'type' => 'integer',
          ],
          'language' => [
            'type' => 'string',
          ],
        ],
        'rows' => [
          [1, 1, 'en', 1, 6, 'en'],
          [1, 4, 'fr', 1, 6, 'fr'],
          [1, 6, 'de', 1, 6, 'de'],
          [2, 8, 'en', 2, 8, 'en'],
        ],
        'expected' => 2,
      ],
    ];
  }

  /**
   * Tests getHighestId method with invalid data.
   *
   * @param array $destination_ids
   *   Array of destination ids.
   *
   * @dataProvider getHighestIdInvalidDataProvider
   */
  public function testGetHighestIdInvalid(array $destination_ids) {
    $this->expectException(\LogicException::class);
    $this->expectExceptionMessage('To determine the highest migrated ID the first ID must be an integer');
    $this->destinationIds = $destination_ids;
    $id_map = $this->getIdMap();
    $id_map->getHighestId();
  }

  /**
   * Data provider for testGetHighestIdInvalid().
   *
   * Scenarios to test:
   * - Destination ID type string.
   * - Destination ID types int (not integer) and string.
   *
   * @return array
   *   An array of data values.
   */
  public function getHighestIdInvalidDataProvider() {
    return [
      'Destination ID type string' => [
        'ids' => [
          'language' => [
            'type' => 'string',
          ],
        ],
      ],
      'Destination ID types int (not integer) and string' => [
        'ids' => [
          'nid' => [
            'type' => 'int',
          ],
          'language' => [
            'type' => 'string',
          ],
        ],
      ],
    ];
  }

}