Skip to content

Commit 5784c52

Browse files
committed
test: add tests for "allow to output null links" in Hal\Serializer\ItemNormalizerTest
1 parent b16e729 commit 5784c52

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

tests/Hal/Serializer/ItemNormalizerTest.php

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2121
use ApiPlatform\Metadata\Property\PropertyNameCollection;
2222
use ApiPlatform\Metadata\ResourceClassResolverInterface;
23+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue4372\RelatedEntity;
2324
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5452\ActivableInterface;
2425
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5452\Author;
2526
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue5452\Book;
@@ -28,6 +29,7 @@
2829
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy;
2930
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MaxDepthDummy;
3031
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
32+
use PHPUnit\Framework\Attributes\DataProvider;
3133
use PHPUnit\Framework\TestCase;
3234
use Prophecy\Argument;
3335
use Prophecy\PhpUnit\ProphecyTrait;
@@ -420,4 +422,147 @@ public function testMaxDepth(): void
420422

421423
$this->assertEquals($expected, $normalizer->normalize($level1, ItemNormalizer::FORMAT, [ObjectNormalizer::ENABLE_MAX_DEPTH => true]));
422424
}
425+
426+
#[DataProvider('getSkipNullToOneRelationCases')]
427+
public function testSkipNullToOneRelation($context, $expected)
428+
{
429+
$dummy = new Dummy();
430+
$dummy->setAlias(null);
431+
$dummy->relatedDummy = null;
432+
433+
$propertyNameCollection = new PropertyNameCollection(['alias', 'relatedDummy']);
434+
$propertyNameCollectionFactory = $this->createMock(PropertyNameCollectionFactoryInterface::class);
435+
$propertyNameCollectionFactory->method('create')->willReturn($propertyNameCollection);
436+
437+
$propertyMetadataFactory = $this->createMock(PropertyMetadataFactoryInterface::class);
438+
$propertyMetadataFactory->method('create')->willReturnCallback(function ($resourceClass, $propertyName, $groups) {
439+
if ('alias' == $propertyName) {
440+
return (new ApiProperty())->withNativeType(Type::string())->withDescription('')->withReadable(true);
441+
}
442+
if ('relatedDummy' == $propertyName) {
443+
return (new ApiProperty())->withNativeType(Type::object(RelatedDummy::class))->withDescription('')->withReadable(true)->withWritable(false)->withReadableLink(true);
444+
}
445+
});
446+
447+
$iriConverter = $this->createMock(IriConverterInterface::class);
448+
$iriConverter->method('getIriFromResource')->willReturn('/dummies/1');
449+
450+
$resourceClassResolver = $this->createMock(ResourceClassResolverInterface::class);
451+
$resourceClassResolver->method('getResourceClass')->willReturnCallback(function ($resource) {
452+
if ($resource instanceof Dummy) {
453+
return Dummy::class;
454+
}
455+
if (null == $resource) {
456+
return RelatedDummy::class;
457+
}
458+
});
459+
$resourceClassResolver->method('isResourceClass')->willReturn(true);
460+
461+
/**
462+
* @var SerializerInterface&NormalizerInterface $serializer
463+
*/
464+
$serializer = $this->createMockForIntersectionOfInterfaces([SerializerInterface::class, NormalizerInterface::class]);
465+
$serializer->method('normalize')->with(null, null, self::anything())->willReturn(null);
466+
467+
$nameConverter = self::createMock(NameConverterInterface::class);
468+
$nameConverter->method('normalize')->willReturnCallback(function ($propertyName) {
469+
if ('alias' == $propertyName) {
470+
return 'alias';
471+
}
472+
if ('relatedDummy' == $propertyName) {
473+
return 'related_dummy';
474+
}
475+
});
476+
477+
$normalizer = new ItemNormalizer(
478+
propertyNameCollectionFactory: $propertyNameCollectionFactory,
479+
propertyMetadataFactory: $propertyMetadataFactory,
480+
iriConverter: $iriConverter,
481+
resourceClassResolver: $resourceClassResolver,
482+
propertyAccessor: null,
483+
nameConverter: $nameConverter,
484+
classMetadataFactory: null,
485+
defaultContext: [],
486+
resourceMetadataCollectionFactory: null,
487+
resourceAccessChecker: null,
488+
tagCollector: null,
489+
);
490+
$normalizer->setSerializer($serializer);
491+
492+
self::assertThat($expected, self::equalTo($normalizer->normalize($dummy, null, $context)));
493+
}
494+
495+
public static function getSkipNullToOneRelationCases()
496+
{
497+
yield [
498+
['skip_null_to_one_relations' => true],
499+
[
500+
'_links' => [
501+
'self' => [
502+
'href' => '/dummies/1',
503+
],
504+
],
505+
'alias' => null,
506+
],
507+
];
508+
509+
yield [
510+
['skip_null_to_one_relations' => false],
511+
[
512+
'_links' => [
513+
'self' => [
514+
'href' => '/dummies/1',
515+
],
516+
'related_dummy' => null,
517+
],
518+
'alias' => null,
519+
]];
520+
}
521+
522+
/**
523+
* @return string|void
524+
*/
525+
private static function convertPropertyNames($propertyName)
526+
{
527+
if ('relatedEntity' == $propertyName) {
528+
return 'related_entity';
529+
}
530+
if ('relatedEmbeddedEntity' == $propertyName) {
531+
return 'related_embedded_entity';
532+
}
533+
if ('collection' == $propertyName) {
534+
return 'collection';
535+
}
536+
if ('relatedEntity2' == $propertyName) {
537+
return 'related_entity2';
538+
}
539+
if ('relatedEmbeddedEntity2' == $propertyName) {
540+
return 'related_embedded_entity2';
541+
}
542+
543+
return $propertyName;
544+
}
545+
546+
/**
547+
* @return ApiProperty|void
548+
*/
549+
private static function createPropertyMetadata($propertyName)
550+
{
551+
$relatedPropertyMeta = (new ApiProperty())->withNativeType(Type::object(RelatedEntity::class))->withDescription('')->withReadable(true)->withWritable(false)->withReadableLink(true);
552+
if ('relatedEntity' == $propertyName) {
553+
return $relatedPropertyMeta;
554+
}
555+
if ('relatedEmbeddedEntity' == $propertyName) {
556+
return $relatedPropertyMeta;
557+
}
558+
if ('relatedEntity2' == $propertyName) {
559+
return $relatedPropertyMeta;
560+
}
561+
562+
if ('relatedEmbeddedEntity2' == $propertyName) {
563+
return $relatedPropertyMeta;
564+
}
565+
566+
return (new ApiProperty())->withNativeType(Type::string())->withDescription('')->withReadable(true);
567+
}
423568
}

0 commit comments

Comments
 (0)