data_pipelines-1.x-dev/tests/src/Kernel/DatasetPipelineBaseTest.php
tests/src/Kernel/DatasetPipelineBaseTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\data_pipelines\Kernel;
use Drupal\Core\TypedData\MapDataDefinition;
use Drupal\Core\TypedData\Plugin\DataType\StringData;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\data_pipelines\DatasetData;
use Drupal\data_pipelines\DatasetPipelineBase;
use Drupal\data_pipelines\Entity\Dataset;
use Prophecy\Argument;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* Defines a test for DatasetPipelineBase.
*
* @group data_pipelines
* @covers \Drupal\data_pipelines\DatasetPipelineBase
* @covers \Drupal\data_pipelines\Entity\Dataset::validate
* @covers \Drupal\data_pipelines\Plugin\DataType\DatasetData
* @covers \Drupal\data_pipelines\Plugin\Validation\Constraint\ItemCountValidator
*/
class DatasetPipelineBaseTest extends DatasetKernelTestBase {
/**
* Tests validation on a valid CSV.
*/
public function testValidationValidCsv() {
$file = $this->getTestFile(dirname(__DIR__, 1) . '/fixtures/test-pipeline-1.csv');
$dataset = Dataset::create([
'source' => 'csv:file',
'destinations' => [$this->createTestMemoryDestination()],
'name' => $this->randomMachineName(),
'machine_name' => mb_strtolower($this->randomMachineName()),
'pipeline' => 'test_pipeline_1',
'csv_file' => $file,
]);
$this->assertTrue($dataset->hasValidation());
$this->assertEmpty($dataset->validate());
}
/**
* Tests has validation method.
*
* @covers \Drupal\data_pipelines\Entity\Dataset::hasValidation
* @covers \Drupal\data_pipelines\DatasetPipelineBase::hasValidation
*/
public function testHasValidation(): void {
$file = $this->getTestFile(dirname(__DIR__, 1) . '/fixtures/test-pipeline-1.csv');
$dataset = Dataset::create([
'source' => 'csv:file',
'destinations' => [$this->createTestMemoryDestination()],
'name' => $this->randomMachineName(),
'machine_name' => mb_strtolower($this->randomMachineName()),
'pipeline' => 'pipeline_with_no_validation',
'csv_file' => $file,
]);
$this->assertFalse($dataset->hasValidation());
}
/**
* Tests validation on a valid JSON file.
*/
public function testValidationValidJson() {
$file = $this->getTestFile(dirname(__DIR__, 1) . '/fixtures/test-pipeline-1.json');
$dataset = Dataset::create([
'source' => 'json:file',
'destinations' => [$this->createTestMemoryDestination()],
'name' => $this->randomMachineName(),
'machine_name' => mb_strtolower($this->randomMachineName()),
'pipeline' => 'test_pipeline_1',
'json_file' => $file,
]);
$this->assertEmpty($dataset->validate());
}
/**
* Tests validation on an invalid CSV.
*/
public function testValidationInvalidCsv() {
// @todo remove this once Drupal 9 is not supported anymore.
$d10 = version_compare(\Drupal::VERSION, '10', '>');
$file = $this->getTestFile(dirname(__DIR__, 1) . '/fixtures/test-pipeline-1-invalid.csv');
$dataset = Dataset::create([
'source' => 'csv:file',
'destinations' => [$this->createTestMemoryDestination()],
'name' => $this->randomMachineName(),
'machine_name' => mb_strtolower($this->randomMachineName()),
'pipeline' => 'test_pipeline_1',
'csv_file' => $file,
]);
iterator_to_array($dataset->getDataIterator());
$result = $dataset->getLogs();
// Symfony 4 and Symfony 5 has different violation count.
// @todo update this once Drupal 9 is not supported anymore.
$this->assertCount($d10 ? 3 : 2, $result);
$violation = $result[0];
$this->assertEquals('Validation error in row 1: Firstname should be at least 3 characters', $violation);
$violation = $result[1];
$this->assertEquals('Validation error in row 2: Firstname is required', $violation);
// Symfony 4 and Symfony 5 has different violation count.
// @todo update this once Drupal 9 is not supported anymore.
if ($d10) {
$violation = $result[2];
$this->assertEquals('Validation error in row 2: Firstname should be at least 3 characters', $violation);
}
}
/**
* Tests validation on an invalid JSON file.
*/
public function testValidationInvalidJson() {
// @todo remove this once Drupal 9 is not supported anymore.
$d10 = version_compare(\Drupal::VERSION, '10', '>');
$file = $this->getTestFile(dirname(__DIR__, 1) . '/fixtures/test-pipeline-1-invalid.json');
$dataset = Dataset::create([
'source' => 'json:file',
'destinations' => [$this->createTestMemoryDestination()],
'pipeline' => 'test_pipeline_1',
'name' => $this->randomMachineName(),
'machine_name' => mb_strtolower($this->randomMachineName()),
'json_file' => $file,
]);
iterator_to_array($dataset->getDataIterator());
$result = $dataset->getLogs();
// Symfony 4 and Symfony 5 has different violation count.
// @todo update this once Drupal 9 is not supported anymore.
$this->assertCount($d10 ? 4 : 3, $result);
$violation = $result[0];
$this->assertEquals('Validation error in row 1: Firstname should be at least 3 characters', $violation);
$violation = $result[1];
$this->assertEquals('Validation error in row 2: Firstname is required', $violation);
// Symfony 4 and Symfony 5 has different violation count.
// @todo update this once Drupal 9 is not supported anymore.
if ($d10) {
$violation = $result[2];
$this->assertEquals('Validation error in row 2: Firstname should be at least 3 characters', $violation);
}
// Symfony 4 and Symfony 5 has different violation count.
// @todo update this once Drupal 9 is not supported anymore.
$violation = $result[$d10 ? 3 : 2];
$this->assertEquals('Validation error in row 3: All records should have 3 values', $violation);
}
/**
* Ensure the typed data created during validation is cached per pipeline.
*/
public function testTypedDataCaching(): void {
$dataset_data = new DatasetData([
'foo' => 'bar',
]);
$string_data = $this->prophesize(StringData::class);
$string_data->validate()->willReturn(new ConstraintViolationList());
$typed_data_manager = $this->prophesize(TypedDataManager::class);
$typed_data_manager->create(Argument::type(MapDataDefinition::class), $dataset_data, 'test_pipeline_1')->shouldBeCalled()->willReturn($string_data->reveal());
$this->container->set('typed_data_manager', $typed_data_manager->reveal());
$data_pipeline = DatasetPipelineBase::create($this->container, [], 'test_pipeline_1', [
'validations' => [
'field' => [
'foo' => [
new NotBlank(),
],
],
'record' => [],
],
]);
$data_pipeline->validate($dataset_data);
}
}
