diff --git a/composer.json b/composer.json index 3cdec06..b57149d 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,6 @@ "symfony/serializer": "^5.4|^6.0|^7.0" }, "require-dev": { - "devedge/sami-github": "^1.0.6", "keboola/coding-standard": "^15.0.1", "keboola/php-temp": "^2.0.1", "phpstan/phpstan": "^1.12.24", diff --git a/src/Manifest/ManifestManager/Options/OutTable/ManifestOptions.php b/src/Manifest/ManifestManager/Options/OutTable/ManifestOptions.php index 8b2708f..fde6a69 100644 --- a/src/Manifest/ManifestManager/Options/OutTable/ManifestOptions.php +++ b/src/Manifest/ManifestManager/Options/OutTable/ManifestOptions.php @@ -16,8 +16,24 @@ class ManifestOptions { - private const ALLOWED_MANIFEST_TYPES = [self::MANIFEST_TYPE_OUTPUT]; public const MANIFEST_TYPE_OUTPUT = 'output'; + public const MANIFEST_TYPE_INPUT = 'input'; + public const MANIFEST_TYPE_OUT = 'out'; + public const MANIFEST_TYPE_IN = 'in'; + + private const ALLOWED_MANIFEST_TYPES = [ + self::MANIFEST_TYPE_OUTPUT, + self::MANIFEST_TYPE_INPUT, + self::MANIFEST_TYPE_OUT, + self::MANIFEST_TYPE_IN, + ]; + + // The Python SDK writes the stage value ("in"/"out") into manifest_type, while the canonical + // values are "input"/"output". Accept the stage aliases and normalize them to the canonical form. + private const MANIFEST_TYPE_NORMALIZATION_MAP = [ + self::MANIFEST_TYPE_OUT => self::MANIFEST_TYPE_OUTPUT, + self::MANIFEST_TYPE_IN => self::MANIFEST_TYPE_INPUT, + ]; private ?string $destination = null; private ?bool $incremental = null; @@ -158,7 +174,7 @@ public function setManifestType(string $manifestType): ManifestOptions )); } - $this->manifestType = $manifestType; + $this->manifestType = self::MANIFEST_TYPE_NORMALIZATION_MAP[$manifestType] ?? $manifestType; return $this; } diff --git a/tests/Manifest/ManifestManager/Options/OutTableManifestOptionsTest.php b/tests/Manifest/ManifestManager/Options/OutTableManifestOptionsTest.php index 239b619..12fbabc 100644 --- a/tests/Manifest/ManifestManager/Options/OutTableManifestOptionsTest.php +++ b/tests/Manifest/ManifestManager/Options/OutTableManifestOptionsTest.php @@ -159,6 +159,80 @@ public function provideOptions(): array ]; } + public function testFromArrayWithPythonSdkManifestType(): void + { + $options = ManifestOptions::fromArray([ + 'delimiter' => ',', + 'enclosure' => '"', + 'manifest_type' => 'out', + 'schema' => [ + [ + 'name' => 'id', + 'nullable' => true, + 'primary_key' => false, + ], + ], + ]); + + $this->assertSame(ManifestOptions::MANIFEST_TYPE_OUTPUT, $options->getManifestType()); + + $array = $options->toArray(false); + $this->assertSame('output', $array['manifest_type']); + } + + public function testSetManifestTypeOutIsNormalized(): void + { + $options = (new ManifestOptions())->setManifestType('out'); + $this->assertSame(ManifestOptions::MANIFEST_TYPE_OUTPUT, $options->getManifestType()); + } + + public function testFromArrayWithPythonSdkInputManifestType(): void + { + $options = ManifestOptions::fromArray([ + 'delimiter' => ',', + 'enclosure' => '"', + 'manifest_type' => 'in', + 'schema' => [ + [ + 'name' => 'id', + 'nullable' => true, + 'primary_key' => false, + ], + ], + ]); + + $this->assertSame(ManifestOptions::MANIFEST_TYPE_INPUT, $options->getManifestType()); + + $array = $options->toArray(false); + $this->assertSame('input', $array['manifest_type']); + } + + public function testSetManifestTypeInIsNormalized(): void + { + $options = (new ManifestOptions())->setManifestType('in'); + $this->assertSame(ManifestOptions::MANIFEST_TYPE_INPUT, $options->getManifestType()); + } + + public function testSetManifestTypeCanonicalValuesArePreserved(): void + { + $this->assertSame( + ManifestOptions::MANIFEST_TYPE_OUTPUT, + (new ManifestOptions())->setManifestType('output')->getManifestType(), + ); + $this->assertSame( + ManifestOptions::MANIFEST_TYPE_INPUT, + (new ManifestOptions())->setManifestType('input')->getManifestType(), + ); + } + + public function testSetManifestTypeRejectsUnknownValue(): void + { + $this->expectException(OptionsValidationException::class); + $this->expectExceptionMessage('Manifest type "invalid" is not allowed'); + + (new ManifestOptions())->setManifestType('invalid'); + } + /** @dataProvider validNamesProvider */ public function testManifestOptionsSchemaValidNames(string $name): void {