diff --git a/api/composer.json b/api/composer.json index dcd9eebc06..6fc2a164da 100644 --- a/api/composer.json +++ b/api/composer.json @@ -10,7 +10,7 @@ "cweagans/composer-patches": "1.7.3", "doctrine/doctrine-bundle": "2.12.0", "doctrine/doctrine-migrations-bundle": "3.3.1", - "doctrine/orm": "2.19.6", + "doctrine/orm": "3.2.0", "exercise/htmlpurifier-bundle": "5.0", "friendsofsymfony/http-cache": "3.0.0", "friendsofsymfony/http-cache-bundle": "3.0.1", @@ -52,7 +52,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "3.59.3", - "hautelook/alice-bundle": "2.13.0", + "hautelook/alice-bundle": "2.14.0", "justinrainbow/json-schema": "5.3.0", "php-coveralls/php-coveralls": "2.7.0", "phpspec/prophecy-phpunit": "2.2", diff --git a/api/composer.lock b/api/composer.lock index 87c3353b50..43115ac2b9 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "19fb87a03e69ed84c290b70f666abf0c", + "content-hash": "79608af6ca4c01fc6b228a56919642f2", "packages": [ { "name": "api-platform/core", @@ -1565,61 +1565,48 @@ }, { "name": "doctrine/orm", - "version": "2.19.6", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073" + "reference": "37946d3a21ddf837c0d84f8156ee60a92102e332" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", - "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073", + "url": "https://api.github.com/repos/doctrine/orm/zipball/37946d3a21ddf837c0d84f8156ee60a92102e332", + "reference": "37946d3a21ddf837c0d84f8156ee60a92102e332", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.1", - "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2 || ^3", - "doctrine/persistence": "^2.4 || ^3", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1", "ext-ctype": "*", - "php": "^7.1 || ^8.0", + "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.13 || >= 3.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.3.9 || ^7.0" }, "require-dev": { - "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^12.0", - "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.11.1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "doctrine/coding-standard": "^12.0", + "phpbench/phpbench": "^1.0", + "phpstan/phpstan": "1.11.1", + "phpunit/phpunit": "^10.4.0", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "4.30.0 || 5.24.0" + "symfony/cache": "^5.4 || ^6.2 || ^7.0", + "vimeo/psalm": "5.24.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", - "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "bin/doctrine" - ], "type": "library", "autoload": { "psr-4": { @@ -1660,9 +1647,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.6" + "source": "https://github.com/doctrine/orm/tree/3.2.0" }, - "time": "2024-06-26T17:24:40+00:00" + "time": "2024-05-23T14:27:52+00:00" }, { "name": "doctrine/persistence", @@ -2243,6 +2230,7 @@ "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", "doctrine/orm": "to use the extensions with the ORM" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -11276,35 +11264,35 @@ }, { "name": "hautelook/alice-bundle", - "version": "2.13.0", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/theofidry/AliceBundle.git", - "reference": "7b8cf62973853ec406ecb27f3b90b91a1b525a05" + "reference": "9b648956ffe4c39318dc61cbe8c2a7e209e9ab58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/AliceBundle/zipball/7b8cf62973853ec406ecb27f3b90b91a1b525a05", - "reference": "7b8cf62973853ec406ecb27f3b90b91a1b525a05", + "url": "https://api.github.com/repos/theofidry/AliceBundle/zipball/9b648956ffe4c39318dc61cbe8c2a7e209e9ab58", + "reference": "9b648956ffe4c39318dc61cbe8c2a7e209e9ab58", "shasum": "" }, "require": { - "doctrine/data-fixtures": "^1.5", - "doctrine/doctrine-bundle": "^2.5", - "doctrine/orm": "^2.10.0", - "doctrine/persistence": "^2.2 || ^3.0", + "doctrine/data-fixtures": "^1.7", + "doctrine/doctrine-bundle": "^2.11.3", + "doctrine/orm": "^3.1", + "doctrine/persistence": "^3.3.1", "php": "^8.2", "psr/log": "^1.0 || ^2.0 || ^3.0", "symfony/finder": "^6.4 || ^7.0", "symfony/framework-bundle": "^6.4 || ^7.0", - "theofidry/alice-data-fixtures": "^1.5" + "theofidry/alice-data-fixtures": "^1.7" }, "require-dev": { "monolog/monolog": "^3.5", - "phpspec/prophecy": "^1.7", + "phpspec/prophecy": "^1.14.0", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^6.4 || ^7.0" + "phpunit/phpunit": "^9.6.17", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0" }, "type": "symfony-bundle", "extra": { @@ -11344,9 +11332,9 @@ ], "support": { "issues": "https://github.com/theofidry/AliceBundle/issues", - "source": "https://github.com/theofidry/AliceBundle/tree/2.13.0" + "source": "https://github.com/theofidry/AliceBundle/tree/2.14.0" }, - "time": "2023-12-03T23:53:29+00:00" + "time": "2024-03-08T19:55:04+00:00" }, { "name": "justinrainbow/json-schema", diff --git a/api/src/HttpCache/PurgeHttpCacheListener.php b/api/src/HttpCache/PurgeHttpCacheListener.php index b204d4a852..b803c1b52b 100644 --- a/api/src/HttpCache/PurgeHttpCacheListener.php +++ b/api/src/HttpCache/PurgeHttpCacheListener.php @@ -31,7 +31,7 @@ use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Event\PreUpdateEventArgs; use Doctrine\ORM\Mapping\AssociationMapping; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\PersistentCollection; use FOS\HttpCacheBundle\CacheManager; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; @@ -51,7 +51,7 @@ public function __construct(private readonly IriConverterInterface|LegacyIriConv */ public function preUpdate(PreUpdateEventArgs $eventArgs): void { $changeSet = $eventArgs->getEntityChangeSet(); - $objectManager = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager() : $eventArgs->getEntityManager(); + $objectManager = $eventArgs->getObjectManager(); $associationMappings = $objectManager->getClassMetadata(ClassUtils::getClass($eventArgs->getObject()))->getAssociationMappings(); foreach ($changeSet as $key => $value) { @@ -74,7 +74,12 @@ public function preUpdate(PreUpdateEventArgs $eventArgs): void { */ public function onFlush(OnFlushEventArgs $eventArgs): void { /** @var EntityManagerInterface */ - $em = method_exists($eventArgs, 'getObjectManager') ? $eventArgs->getObjectManager() : $eventArgs->getEntityManager(); + $em = $eventArgs->getObjectManager(); + + if (!$em instanceof EntityManagerInterface) { + return; + } + $uow = $em->getUnitOfWork(); foreach ($uow->getScheduledEntityInsertions() as $entity) { @@ -116,7 +121,7 @@ public function postFlush(): void { private function addTagsForManyToManyRelations($collection, $entities) { $associationMapping = $collection->getMapping(); - if (ClassMetadataInfo::MANY_TO_MANY !== $associationMapping['type']) { + if (ClassMetadata::MANY_TO_MANY !== $associationMapping['type']) { return; } @@ -220,15 +225,7 @@ private function gatherRelationTags(EntityManagerInterface $em, object $entity): $associationMappings = $em->getClassMetadata(ClassUtils::getClass($entity))->getAssociationMappings(); foreach ($associationMappings as $property => $associationMapping) { - // @phpstan-ignore-next-line - if (class_exists(AssociationMapping::class) && $associationMapping instanceof AssociationMapping && ($associationMapping->targetEntity ?? null) && !$this->resourceClassResolver->isResourceClass($associationMapping->targetEntity)) { - return; - } - - // @phpstan-ignore-next-line - if (\is_array($associationMapping) - && \array_key_exists('targetEntity', $associationMapping) - && !$this->resourceClassResolver->isResourceClass($associationMapping['targetEntity'])) { + if ($associationMapping instanceof AssociationMapping && ($associationMapping->targetEntity ?? null) && !$this->resourceClassResolver->isResourceClass($associationMapping->targetEntity)) { return; } diff --git a/api/src/Repository/UserRepository.php b/api/src/Repository/UserRepository.php index 6be84d88e1..0829c2a014 100644 --- a/api/src/Repository/UserRepository.php +++ b/api/src/Repository/UserRepository.php @@ -32,8 +32,8 @@ public function upgradePassword(PasswordAuthenticatedUserInterface $user, string } $user->password = $newHashedPassword; - $this->_em->persist($user); - $this->_em->flush(); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); } /** @@ -41,7 +41,7 @@ public function upgradePassword(PasswordAuthenticatedUserInterface $user, string * @throws NoResultException */ public function loadUserByIdentifier(string $identifier): ?User { - $queryBuilder = $this->_em->createQueryBuilder(); + $queryBuilder = $this->getEntityManager()->createQueryBuilder(); $queryBuilder->select('user'); $queryBuilder->from(User::class, 'user'); $queryBuilder->join('user.profile', 'profile'); diff --git a/api/src/Serializer/Normalizer/RelatedCollectionLinkNormalizer.php b/api/src/Serializer/Normalizer/RelatedCollectionLinkNormalizer.php index 10b5701b6c..b7435e0d88 100644 --- a/api/src/Serializer/Normalizer/RelatedCollectionLinkNormalizer.php +++ b/api/src/Serializer/Normalizer/RelatedCollectionLinkNormalizer.php @@ -15,9 +15,11 @@ use App\Metadata\Resource\OperationHelper; use App\Util\ClassInfoTrait; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\AssociationMapping; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\InverseSideMapping; use Doctrine\ORM\Mapping\MappingException; -use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\OwningSideMapping; use Rize\UriTemplate; use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; @@ -155,8 +157,8 @@ public function getRelatedCollectionHref($object, $rel, array $context = []): st try { $classMetadata = $this->getClassMetadata($resourceClass); - if (!$classMetadata instanceof ClassMetadataInfo) { - throw new \RuntimeException("The class metadata for {$resourceClass} must be an instance of ClassMetadataInfo."); + if (!$classMetadata instanceof ClassMetadata) { + throw new \RuntimeException("The class metadata for {$resourceClass} must be an instance of ClassMetadata."); } $relationMetadata = $classMetadata->getAssociationMapping($rel); @@ -164,10 +166,8 @@ public function getRelatedCollectionHref($object, $rel, array $context = []): st throw new UnsupportedRelationException($resourceClass.'#'.$rel.' is not a Doctrine association. Embedding non-Doctrine collections is currently not implemented.'); } - $relatedResourceClass = $relationMetadata['targetEntity']; - - $relatedFilterName = $relationMetadata['mappedBy']; - $relatedFilterName ??= $relationMetadata['inversedBy']; + $relatedResourceClass = $relationMetadata->targetEntity; + $relatedFilterName = $this->getRelatedProperty($relationMetadata); if (empty($relatedResourceClass) || empty($relatedFilterName)) { throw new UnsupportedRelationException('The '.$resourceClass.'#'.$rel.' relation does not have both a targetEntity and a mappedBy or inversedBy property'); @@ -251,4 +251,16 @@ private function exactSearchFilterExists(string $resourceClass, mixed $propertyN && 'exact' === $filterDescription[$propertyName]['strategy']; })); } + + private function getRelatedProperty(AssociationMapping $mapping): ?string { + if ($mapping instanceof InverseSideMapping) { + return $mapping->mappedBy ?? null; + } + + if ($mapping instanceof OwningSideMapping) { + return $mapping->inversedBy ?? null; + } + + return null; + } } diff --git a/api/src/Util/IdGenerator.php b/api/src/Util/IdGenerator.php index a45db9d0e2..8ae71587ed 100644 --- a/api/src/Util/IdGenerator.php +++ b/api/src/Util/IdGenerator.php @@ -2,7 +2,7 @@ namespace App\Util; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Id\AbstractIdGenerator; class IdGenerator extends AbstractIdGenerator { @@ -10,7 +10,7 @@ public static function generateRandomHexString(int $length): string { return bin2hex(random_bytes($length / 2)); } - public function generate(EntityManager $em, $entity): string { + public function generateId(EntityManagerInterface $em, ?object $entity): mixed { return IdGenerator::generateRandomHexString(12); } } diff --git a/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php b/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php index b250fef235..9379bd627f 100644 --- a/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php +++ b/api/tests/Metadata/Resource/Factory/UriTemplateFactoryTest.php @@ -2,8 +2,8 @@ namespace App\Tests\Metadata\Resource\Factory; -use ApiPlatform\Api\FilterInterface; use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\FilterInterface; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\IriConverterInterface; diff --git a/api/tests/Serializer/Normalizer/RelatedCollectionLinkNormalizerTest.php b/api/tests/Serializer/Normalizer/RelatedCollectionLinkNormalizerTest.php index 164c4987ab..6b1587a03b 100644 --- a/api/tests/Serializer/Normalizer/RelatedCollectionLinkNormalizerTest.php +++ b/api/tests/Serializer/Normalizer/RelatedCollectionLinkNormalizerTest.php @@ -2,10 +2,10 @@ namespace App\Tests\Serializer\Normalizer; -use ApiPlatform\Api\FilterInterface; use ApiPlatform\Doctrine\Orm\Filter\DateFilter; use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\FilterInterface; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\IriConverterInterface; @@ -18,6 +18,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\Mapping\OneToManyAssociationMapping; use Doctrine\Persistence\ManagerRegistry; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -159,7 +160,13 @@ public function testNormalizeReplacesLinkArrayWithSingleFilteredCollectionLink() $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); + $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); $this->mockGeneratedRoute(); @@ -231,7 +238,12 @@ public function testNormalizeReplacesSerializedNameLinkArray() { $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockGeneratedRoute(); // when @@ -252,7 +264,12 @@ public function testNormalizeDoesntReplaceWhenFilterDoesntApplyToMappedProperty( $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->mockRelatedFilterDescription(['some_other_property' => ['strategy' => 'exact']]); $this->mockGeneratedRoute(); @@ -269,7 +286,12 @@ public function testNormalizeDoesntReplaceWhenEmptyFiltersArray() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata(['filters' => []]); $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); $this->mockGeneratedRoute(); @@ -286,7 +308,12 @@ public function testNormalizeDoesntReplaceWhenNoFilters() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata([]); $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); $this->mockGeneratedRoute(); @@ -298,23 +325,6 @@ public function testNormalizeDoesntReplaceWhenNoFilters() { $this->shouldNotReplaceChildren($result); } - public function testNormalizeDoesntReplaceWhenTargetEntityIsMissing() { - // given - $resource = new ParentEntity(); - $this->mockDecoratedNormalizer(); - $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => null, 'mappedBy' => 'parent']); - $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); - $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); - $this->mockGeneratedRoute(); - - // when - $result = $this->normalizer->normalize($resource, null, ['resource_class' => ParentEntity::class]); - - // then - $this->shouldNotReplaceChildren($result); - } - public function testNormalizeDoesntReplaceWhenNotADoctrineAssociation() { // given $resource = new ParentEntity(); @@ -342,7 +352,11 @@ public function testNormalizeDoesntReplaceWhenMappedByIsMissing() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => null, 'inversedBy' => null]); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->mockRelatedFilterDescription(['parent' => ['strategy' => 'exact']]); $this->mockGeneratedRoute(); @@ -359,7 +373,12 @@ public function testNormalizeDoesntReplaceWhenFilterDoesntExistInContainer() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->filterInstance = null; $this->mockGeneratedRoute(); @@ -376,7 +395,12 @@ public function testNormalizeDoesntReplaceWhenFilterIsNotSearchFilter() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $this->mockRelatedResourceMetadata(['filters' => ['attribute_filter_something_something']]); $this->filterInstance = new DateFilter($this->managerRegistryMock, null, ['filters' => ['attribute_filter_something_something']]); $this->mockGeneratedRoute(); @@ -393,7 +417,12 @@ public function testNormalizeDoesntReplaceWhenMissingGetCollectionOperation() { $resource = new ParentEntity(); $this->mockDecoratedNormalizer(); $this->mockNameConverter(); - $this->mockAssociationMetadata(['targetEntity' => Child::class, 'mappedBy' => 'parent']); + $this->mockAssociationMetadata(OneToManyAssociationMapping::fromMappingArray([ + 'targetEntity' => Child::class, + 'mappedBy' => 'parent', + 'fieldName' => 'children', + 'sourceEntity' => ParentEntity::class, + ])); $metadataCollection = new ResourceMetadataCollection('Dummy'); $metadataCollection->append((new ApiResource())->withOperations(new Operations([new Get()]))); diff --git a/api/tests/Util/CamelPascalNamingStrategyTest.php b/api/tests/Util/CamelPascalNamingStrategyTest.php index 84cb01a92c..f5b58c8ab1 100644 --- a/api/tests/Util/CamelPascalNamingStrategyTest.php +++ b/api/tests/Util/CamelPascalNamingStrategyTest.php @@ -41,7 +41,7 @@ public function testPropertyToColumnName(string $input, string $output) { $strategy = new CamelPascalNamingStrategy(); // when - $result = $strategy->propertyToColumnName($input); + $result = $strategy->propertyToColumnName($input, ''); // then $this->assertEquals($output, $result);