From b996b8bcd477d1b009eb799512652ef1f0272888 Mon Sep 17 00:00:00 2001 From: Sergii Lifinskyi Date: Thu, 23 Jul 2026 17:15:22 +0300 Subject: [PATCH 1/2] Add regression test for nullable enum header conversion --- .../Unit/Handler/HeaderConversionTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/Ecotone/tests/Messaging/Unit/Handler/HeaderConversionTest.php b/packages/Ecotone/tests/Messaging/Unit/Handler/HeaderConversionTest.php index b39f68741..c84cc63a0 100644 --- a/packages/Ecotone/tests/Messaging/Unit/Handler/HeaderConversionTest.php +++ b/packages/Ecotone/tests/Messaging/Unit/Handler/HeaderConversionTest.php @@ -5,9 +5,11 @@ namespace Test\Ecotone\Messaging\Unit\Handler; use Ecotone\Lite\EcotoneLite; +use Ecotone\Messaging\Attribute\Parameter\Header; use Ecotone\Messaging\Channel\SimpleMessageChannelBuilder; use Ecotone\Messaging\Config\ServiceConfiguration; use Ecotone\Messaging\Conversion\MediaType; +use Ecotone\Modelling\Attribute\CommandHandler; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Ramsey\Uuid\Uuid; @@ -104,6 +106,31 @@ public function test_using_fallback_conversion_to_json(ServiceConfiguration $ser ); } + public function test_converting_scalar_header_to_nullable_enum(): void + { + $handler = new class () { + public ?DeliveryMethod $deliveryMethod = null; + + #[CommandHandler('withNullableEnumConversion', endpointId: 'withNullableEnumConversionEndpoint')] + public function handle( + #[Header('deliveryMethod')] ?DeliveryMethod $deliveryMethod = null + ): void { + $this->deliveryMethod = $deliveryMethod; + } + }; + + $ecotoneLite = EcotoneLite::bootstrapFlowTesting( + [$handler::class], + [$handler], + ); + + $ecotoneLite->sendCommandWithRoutingKey('withNullableEnumConversion', metadata: [ + 'deliveryMethod' => DeliveryMethod::Email->value, + ]); + + self::assertSame(DeliveryMethod::Email, $handler->deliveryMethod); + } + /** * This will change nothing, as it's used for payload, not header conversion. * However to be sure that it's not affecting header conversion, it's part of the test scenario @@ -120,3 +147,8 @@ public static function differentDefaultSerializations(): iterable ]; } } + +enum DeliveryMethod: string +{ + case Email = 'email'; +} From d93deedee362e35eb8c4090ff04e53da8202309d Mon Sep 17 00:00:00 2001 From: Sergii Lifinskyi Date: Thu, 23 Jul 2026 17:15:44 +0300 Subject: [PATCH 2/2] Fix nullable enum header conversion --- .../Conversion/ScalarToEnum/ScalarToEnumConverter.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/Ecotone/src/Messaging/Conversion/ScalarToEnum/ScalarToEnumConverter.php b/packages/Ecotone/src/Messaging/Conversion/ScalarToEnum/ScalarToEnumConverter.php index c6d94a100..fc9e5d7f2 100644 --- a/packages/Ecotone/src/Messaging/Conversion/ScalarToEnum/ScalarToEnumConverter.php +++ b/packages/Ecotone/src/Messaging/Conversion/ScalarToEnum/ScalarToEnumConverter.php @@ -19,6 +19,10 @@ class ScalarToEnumConverter implements Converter */ public function convert($source, Type $sourceType, MediaType $sourceMediaType, Type $targetType, MediaType $targetMediaType) { + if ($targetType instanceof Type\UnionType) { + $targetType = $targetType->withoutNull(); + } + $ref = new ReflectionEnum($targetType->toString()); if ($ref->isBacked()) {