View source  
  <?php
namespace Drupal\Tests\migrate_plus\Kernel\Plugin\migrate_plus\data_parser;
use Drupal\KernelTests\KernelTestBase;
use Drupal\migrate\MigrateException;
class SimpleXmlTest extends KernelTestBase {
  
  protected static $modules = [
    'migrate',
    'migrate_plus',
  ];
  
  protected $path;
  
  protected $pluginManager;
  
  protected $configuration;
  
  protected $expected;
  
  protected function setUp() : void {
    parent::setUp();
    $this->path = $this->container
      ->get('module_handler')
      ->getModule('migrate_plus')
      ->getPath();
    $this->pluginManager = $this->container
      ->get('plugin.manager.migrate_plus.data_parser');
    $this->configuration = [
      'plugin' => 'url',
      'data_fetcher_plugin' => 'file',
      'data_parser_plugin' => 'simple_xml',
      'destination' => 'node',
      'urls' => [],
      'ids' => [
        'id' => [
          'type' => 'integer',
        ],
      ],
      'fields' => [
        [
          'name' => 'id',
          'label' => 'Id',
          'selector' => '@id',
        ],
        [
          'name' => 'values',
          'label' => 'Values',
          'selector' => 'values',
        ],
      ],
      'item_selector' => '/items/item',
    ];
    $this->expected = [
      [
        'Value 1',
        'Value 2',
      ],
      [
        'Value 1 (single)',
      ],
    ];
  }
  
  public function testReduceSingleValue() : void {
    $url = $this->path . '/tests/data/simple_xml_reduce_single_value.xml';
    $this->configuration['urls'][0] = $url;
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $this
      ->assertResults($this->expected, $parser);
  }
  
  public function testReadNonStandardXmlWhitespace() : void {
    $url = $this->path . '/tests/data/simple_xml_invalid_multi_whitespace.xml';
    $this->configuration['urls'][0] = $url;
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $this
      ->assertResults($this->expected, $parser);
  }
  
  public function testReadNonStandardXml2() : void {
    $url = $this->path . '/tests/data/simple_xml_invalid_single_line.xml';
    $this->configuration['urls'][0] = $url;
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $this
      ->assertResults($this->expected, $parser);
  }
  
  public function testReadBrokenXmlMissingTag() : void {
    $url = $this->path . '/tests/data/simple_xml_broken_missing_tag.xml';
    $this->configuration['urls'][0] = $url;
    $this
      ->expectException(MigrateException::class);
    
    $this
      ->expectExceptionMessageMatches('/^Fatal Error 7[0-9]/');
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $parser
      ->next();
  }
  
  public function testReadBrokenXmlTagMismatch() : void {
    $url = $this->path . '/tests/data/simple_xml_broken_tag_mismatch.xml';
    $this->configuration['urls'][0] = $url;
    $this
      ->expectException(MigrateException::class);
    $this
      ->expectExceptionMessageMatches('/^Fatal Error 76/');
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $parser
      ->next();
  }
  
  public function testReadNonXml() : void {
    $url = $this->path . '/tests/data/simple_xml_non_xml.xml';
    $this->configuration['urls'][0] = $url;
    $this
      ->expectException(MigrateException::class);
    $this
      ->expectExceptionMessageMatches('/^Fatal Error 46/');
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $parser
      ->next();
  }
  
  public function testReadNonExistingXml() : void {
    $url = $this->path . '/tests/data/simple_xml_non_existing.xml';
    $this->configuration['urls'][0] = $url;
    $this
      ->expectException(MigrateException::class);
    $this
      ->expectExceptionMessage('file parser plugin: could not retrieve data from');
    $parser = $this->pluginManager
      ->createInstance('simple_xml', $this->configuration);
    $parser
      ->next();
  }
  
  protected function assertResults($expected, \Traversable $parser) {
    $data = [];
    foreach ($parser as $item) {
      $values = [];
      foreach ($item['values'] as $value) {
        $values[] = (string) $value;
      }
      $data[] = $values;
    }
    $this
      ->assertEquals($expected, $data);
  }
}