|
15 | 15 |
|
16 | 16 | use ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer; |
17 | 17 | use ApiPlatform\Elasticsearch\Tests\Fixtures\Foo; |
| 18 | +use ApiPlatform\Elasticsearch\Tests\Fixtures\IntegerIdentified; |
| 19 | +use ApiPlatform\Metadata\ApiProperty; |
18 | 20 | use ApiPlatform\Metadata\ApiResource; |
19 | 21 | use ApiPlatform\Metadata\Get; |
20 | 22 | use ApiPlatform\Metadata\Operations; |
| 23 | +use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface; |
21 | 24 | use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; |
22 | 25 | use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; |
23 | 26 | use PHPUnit\Framework\TestCase; |
24 | 27 | use Prophecy\PhpUnit\ProphecyTrait; |
| 28 | +use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; |
25 | 29 | use Symfony\Component\Serializer\Exception\LogicException; |
26 | 30 | use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; |
27 | 31 | use Symfony\Component\Serializer\Normalizer\NormalizerInterface; |
| 32 | +use Symfony\Component\TypeInfo\Type; |
28 | 33 |
|
29 | 34 | final class DocumentNormalizerTest extends TestCase |
30 | 35 | { |
@@ -85,6 +90,41 @@ public function testDenormalize(): void |
85 | 90 | self::assertEquals($expectedFoo, $normalizer->denormalize($document, Foo::class, DocumentNormalizer::FORMAT)); |
86 | 91 | } |
87 | 92 |
|
| 93 | + public function testDenormalizeCoercesIdentifierToDeclaredType(): void |
| 94 | + { |
| 95 | + $document = [ |
| 96 | + '_index' => 'test', |
| 97 | + '_type' => '_doc', |
| 98 | + '_id' => '1', |
| 99 | + '_version' => 1, |
| 100 | + 'found' => true, |
| 101 | + '_source' => [ |
| 102 | + 'name' => 'Caroline', |
| 103 | + ], |
| 104 | + ]; |
| 105 | + |
| 106 | + $resourceMetadataFactory = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class); |
| 107 | + $resourceMetadataFactory->create(IntegerIdentified::class)->willReturn(new ResourceMetadataCollection(IntegerIdentified::class, [(new ApiResource())->withOperations(new Operations([new Get()]))])); |
| 108 | + |
| 109 | + $propertyMetadataFactory = $this->prophesize(PropertyMetadataFactoryInterface::class); |
| 110 | + $propertyMetadataFactory->create(IntegerIdentified::class, 'id')->willReturn((new ApiProperty())->withNativeType(Type::nullable(Type::int()))); |
| 111 | + |
| 112 | + // property_info is wired in production (elasticsearch.php), which makes the inner |
| 113 | + // ObjectNormalizer enforce the declared "int" type on the id property: a raw string |
| 114 | + // "_id" would be rejected. |
| 115 | + $normalizer = new DocumentNormalizer( |
| 116 | + $resourceMetadataFactory->reveal(), |
| 117 | + propertyTypeExtractor: new ReflectionExtractor(), |
| 118 | + propertyMetadataFactory: $propertyMetadataFactory->reveal(), |
| 119 | + ); |
| 120 | + |
| 121 | + $item = $normalizer->denormalize($document, IntegerIdentified::class, DocumentNormalizer::FORMAT); |
| 122 | + |
| 123 | + self::assertInstanceOf(IntegerIdentified::class, $item); |
| 124 | + self::assertSame(1, $item->id); |
| 125 | + self::assertSame('Caroline', $item->name); |
| 126 | + } |
| 127 | + |
88 | 128 | public function testSupportsNormalization(): void |
89 | 129 | { |
90 | 130 | $itemNormalizer = new DocumentNormalizer($this->prophesize(ResourceMetadataCollectionFactoryInterface::class)->reveal()); |
|
0 commit comments