Skip to content

Commit

Permalink
Merge b606f9d into 21145c7
Browse files Browse the repository at this point in the history
  • Loading branch information
fherbin committed Feb 5, 2020
2 parents 21145c7 + b606f9d commit fa339e6
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,9 @@ protected function getAttributeValue($object, $attribute, $format = null, array
$this->resourceClassResolver->isResourceClass($className)
) {
if (!is_iterable($attributeValue)) {
if (null === $attributeValue && $type->isNullable()) {
return null;
}
throw new UnexpectedValueException('Unexpected non-iterable value for to-many relation.');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

/**
* @ApiResource
*/
class DummyTableNonDoctrineInheritance
{
/**
* @var int The id
*
* @Groups({"default"})
*/
public $id;

/**
* @var string The dummy name
*
* @Groups({"default"})
*/
public $name;

/**
* @var DummyTableNonDoctrineInheritanceRelated
*/
public $parent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

/**
* @ApiResource(
* attributes={
* "normalization_context"={"groups"={"default"}},
* "denormalization_context"={"groups"={"default"}}
* }
* )
*/
class DummyTableNonDoctrineInheritanceRelated
{
/**
* @var int The id
*
* @Groups({"default"})
*/
public $id;

/**
* @var DummyTableNonDoctrineInheritance[]|null
*
* @Groups({"default"})
*/
public $children;
}
129 changes: 129 additions & 0 deletions tests/Serializer/AbstractItemNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyForAdditionalFieldsInput;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritance;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableInheritanceChild;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableNonDoctrineInheritance;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyTableNonDoctrineInheritanceRelated;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
use Doctrine\Common\Collections\ArrayCollection;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -1125,4 +1127,131 @@ public function testNormalizationWithDataTransformer()

$propertyAccessorProphecy->setValue($actualDummy, 'name', 'Dummy')->shouldHaveBeenCalled();
}

public function testNullableToManyRelationProperty()
{
$dummy = new DummyTableNonDoctrineInheritanceRelated();

$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
$propertyNameCollectionFactoryProphecy->create(DummyTableNonDoctrineInheritanceRelated::class, [])->willReturn(
new PropertyNameCollection(['children'])
)->shouldBeCalled();

$propertyMetadata = new PropertyMetadata(
new Type(Type::BUILTIN_TYPE_ARRAY, true, DummyTableNonDoctrineInheritance::class, true,
new Type(Type::BUILTIN_TYPE_INT),
new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyTableNonDoctrineInheritance::class)
),
'',
true
);

$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
$propertyMetadataFactoryProphecy
->create(DummyTableNonDoctrineInheritanceRelated::class, 'children', [])
->willReturn($propertyMetadata)->shouldBeCalled();

$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
$iriConverterProphecy->getIriFromItem($dummy)->willReturn('/dummies/1')->shouldBeCalled();

$propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class);
$propertyAccessorProphecy->getValue($dummy, 'children')->willReturn(null)->shouldBeCalled();

$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$resourceClassResolverProphecy->getResourceClass($dummy, DummyTableNonDoctrineInheritanceRelated::class)
->willReturn(DummyTableNonDoctrineInheritanceRelated::class)->shouldBeCalled();
$resourceClassResolverProphecy->isResourceClass(DummyTableNonDoctrineInheritance::class)->willReturn(true)->shouldBeCalled();

$serializerProphecy = $this->prophesize(SerializerInterface::class);
$serializerProphecy->willImplement(NormalizerInterface::class);

$normalizer = $this->getMockForAbstractClass(
AbstractItemNormalizer::class,
[
$propertyNameCollectionFactoryProphecy->reveal(),
$propertyMetadataFactoryProphecy->reveal(),
$iriConverterProphecy->reveal(),
$resourceClassResolverProphecy->reveal(),
$propertyAccessorProphecy->reveal(),
null,
null,
null,
false,
[],
[],
null,
false,
]
);
$normalizer->setSerializer($serializerProphecy->reveal());
$this->assertEquals(
['children' => null],
$normalizer->normalize($dummy, null, ['resource_class' => DummyTableNonDoctrineInheritanceRelated::class, 'resources' => []])
);
}

public function testNotNullableToManyRelationProperty()
{
$dummy = new DummyTableNonDoctrineInheritanceRelated();

$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
$propertyNameCollectionFactoryProphecy->create(DummyTableNonDoctrineInheritanceRelated::class, [])->willReturn(
new PropertyNameCollection(['children'])
)->shouldBeCalled();

$propertyMetadata = new PropertyMetadata(
new Type(Type::BUILTIN_TYPE_ARRAY, false, DummyTableNonDoctrineInheritance::class, true,
new Type(Type::BUILTIN_TYPE_INT),
new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyTableNonDoctrineInheritance::class)
),
'',
true
);

$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
$propertyMetadataFactoryProphecy
->create(DummyTableNonDoctrineInheritanceRelated::class, 'children', [])
->willReturn($propertyMetadata)->shouldBeCalled();

$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
$iriConverterProphecy->getIriFromItem($dummy)->willReturn('/dummies/1')->shouldBeCalled();

$propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class);
$propertyAccessorProphecy->getValue($dummy, 'children')->willReturn(null)->shouldBeCalled();

$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
$resourceClassResolverProphecy->getResourceClass($dummy, DummyTableNonDoctrineInheritanceRelated::class)
->willReturn(DummyTableNonDoctrineInheritanceRelated::class)->shouldBeCalled();
$resourceClassResolverProphecy->isResourceClass(DummyTableNonDoctrineInheritance::class)->willReturn(true)->shouldBeCalled();

$serializerProphecy = $this->prophesize(SerializerInterface::class);
$serializerProphecy->willImplement(NormalizerInterface::class);

$normalizer = $this->getMockForAbstractClass(
AbstractItemNormalizer::class,
[
$propertyNameCollectionFactoryProphecy->reveal(),
$propertyMetadataFactoryProphecy->reveal(),
$iriConverterProphecy->reveal(),
$resourceClassResolverProphecy->reveal(),
$propertyAccessorProphecy->reveal(),
null,
null,
null,
false,
[],
[],
null,
false,
]
);
$normalizer->setSerializer($serializerProphecy->reveal());

$this->expectException(UnexpectedValueException::class);
$normalizer->normalize(
$dummy,
null,
['resource_class' => DummyTableNonDoctrineInheritanceRelated::class, 'resources' => []]
);
}
}

0 comments on commit fa339e6

Please sign in to comment.