@@ -138,6 +138,7 @@ public function testGetSubresource()
138138 $ this ->assertIdentifierManagerMethodCalls ($ managerProphecy );
139139
140140 $ classMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
141+ $ classMetadataProphecy ->hasAssociation ('relatedDummies ' )->willReturn (true )->shouldBeCalled ();
141142 $ classMetadataProphecy ->getAssociationMapping ('relatedDummies ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_MANY ]);
142143
143144 $ managerProphecy ->getClassMetadata (Dummy::class)->shouldBeCalled ()->willReturn ($ classMetadataProphecy ->reveal ());
@@ -195,6 +196,7 @@ public function testGetSubSubresourceItem()
195196 $ qb ->getDQL ()->shouldBeCalled ()->willReturn ($ dummyDQL );
196197
197198 $ classMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
199+ $ classMetadataProphecy ->hasAssociation ('relatedDummies ' )->willReturn (true )->shouldBeCalled ();
198200 $ classMetadataProphecy ->getAssociationMapping ('relatedDummies ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_MANY ]);
199201
200202 $ dummyManagerProphecy = $ this ->prophesize (EntityManager::class);
@@ -220,6 +222,7 @@ public function testGetSubSubresourceItem()
220222 $ rqb ->expr ()->shouldBeCalled ()->willReturn ($ relatedExpProphecy ->reveal ());
221223
222224 $ rClassMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
225+ $ rClassMetadataProphecy ->hasAssociation ('thirdLevel ' )->shouldBeCalled ()->willReturn (true );
223226 $ rClassMetadataProphecy ->getAssociationMapping ('thirdLevel ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_ONE ]);
224227
225228 $ rDummyManagerProphecy = $ this ->prophesize (EntityManager::class);
@@ -279,6 +282,7 @@ public function testQueryResultExtension()
279282 $ this ->assertIdentifierManagerMethodCalls ($ managerProphecy );
280283
281284 $ classMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
285+ $ classMetadataProphecy ->hasAssociation ('relatedDummies ' )->willReturn (true )->shouldBeCalled ();
282286 $ classMetadataProphecy ->getAssociationMapping ('relatedDummies ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_MANY ]);
283287
284288 $ managerProphecy ->getClassMetadata (Dummy::class)->shouldBeCalled ()->willReturn ($ classMetadataProphecy ->reveal ());
@@ -384,6 +388,7 @@ public function testGetSubSubresourceItemLegacy()
384388 $ classMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
385389 $ classMetadataProphecy ->getIdentifier ()->shouldBeCalled ()->willReturn ($ identifiers );
386390 $ classMetadataProphecy ->getTypeOfField ('id ' )->shouldBeCalled ()->willReturn ('integer ' );
391+ $ classMetadataProphecy ->hasAssociation ('relatedDummies ' )->willReturn (true )->shouldBeCalled ();
387392 $ classMetadataProphecy ->getAssociationMapping ('relatedDummies ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_MANY ]);
388393
389394 $ dummyManagerProphecy = $ this ->prophesize (EntityManager::class);
@@ -411,6 +416,7 @@ public function testGetSubSubresourceItemLegacy()
411416 $ rClassMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
412417 $ rClassMetadataProphecy ->getIdentifier ()->shouldBeCalled ()->willReturn ($ identifiers );
413418 $ rClassMetadataProphecy ->getTypeOfField ('id ' )->shouldBeCalled ()->willReturn ('integer ' );
419+ $ rClassMetadataProphecy ->hasAssociation ('thirdLevel ' )->shouldBeCalled ()->willReturn (true );
414420 $ rClassMetadataProphecy ->getAssociationMapping ('thirdLevel ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_ONE ]);
415421
416422 $ rDummyManagerProphecy = $ this ->prophesize (EntityManager::class);
@@ -449,4 +455,92 @@ public function testGetSubSubresourceItemLegacy()
449455
450456 $ this ->assertEquals ($ result , $ dataProvider ->getSubresource (ThirdLevel::class, ['id ' => 1 , 'relatedDummies ' => 1 ], $ context ));
451457 }
458+
459+ public function testGetSubresourceCollectionItem ()
460+ {
461+ $ managerRegistryProphecy = $ this ->prophesize (ManagerRegistry::class);
462+ $ identifiers = ['id ' ];
463+ $ funcProphecy = $ this ->prophesize (Func::class);
464+ $ func = $ funcProphecy ->reveal ();
465+
466+ // First manager (Dummy)
467+ $ dummyDQL = 'dql ' ;
468+
469+ $ qb = $ this ->prophesize (QueryBuilder::class);
470+ $ qb ->select ('relatedDummies_a3 ' )->shouldBeCalled ()->willReturn ($ qb );
471+ $ qb ->from (Dummy::class, 'id_a2 ' )->shouldBeCalled ()->willReturn ($ qb );
472+ $ qb ->innerJoin ('id_a2.relatedDummies ' , 'relatedDummies_a3 ' )->shouldBeCalled ()->willReturn ($ qb );
473+ $ qb ->andWhere ('id_a2.id = :id_p2 ' )->shouldBeCalled ()->willReturn ($ qb );
474+
475+ $ dummyFunc = new Func ('in ' , ['any ' ]);
476+
477+ $ dummyExpProphecy = $ this ->prophesize (Expr::class);
478+ $ dummyExpProphecy ->in ('relatedDummies_a1 ' , $ dummyDQL )->willReturn ($ dummyFunc )->shouldBeCalled ();
479+
480+ $ qb ->expr ()->shouldBeCalled ()->willReturn ($ dummyExpProphecy ->reveal ());
481+
482+ $ qb ->getDQL ()->shouldBeCalled ()->willReturn ($ dummyDQL );
483+
484+ $ classMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
485+ $ classMetadataProphecy ->hasAssociation ('relatedDummies ' )->willReturn (true )->shouldBeCalled ();
486+ $ classMetadataProphecy ->getAssociationMapping ('relatedDummies ' )->shouldBeCalled ()->willReturn (['type ' => ClassMetadata::MANY_TO_MANY ]);
487+
488+ $ dummyManagerProphecy = $ this ->prophesize (EntityManager::class);
489+ $ dummyManagerProphecy ->createQueryBuilder ()->shouldBeCalled ()->willReturn ($ qb ->reveal ());
490+ $ dummyManagerProphecy ->getClassMetadata (Dummy::class)->shouldBeCalled ()->willReturn ($ classMetadataProphecy ->reveal ());
491+ $ this ->assertIdentifierManagerMethodCalls ($ dummyManagerProphecy );
492+
493+ $ managerRegistryProphecy ->getManagerForClass (Dummy::class)->shouldBeCalled ()->willReturn ($ dummyManagerProphecy ->reveal ());
494+
495+ // Second manager (RelatedDummy)
496+ $ relatedDQL = 'relateddql ' ;
497+
498+ $ rqb = $ this ->prophesize (QueryBuilder::class);
499+ $ rqb ->select ('relatedDummies_a1 ' )->shouldBeCalled ()->willReturn ($ rqb );
500+ $ rqb ->from (RelatedDummy::class, 'relatedDummies_a1 ' )->shouldBeCalled ()->willReturn ($ rqb );
501+ $ rqb ->andWhere ('relatedDummies_a1.id = :id_p1 ' )->shouldBeCalled ()->willReturn ($ rqb );
502+ $ rqb ->andWhere ($ dummyFunc )->shouldBeCalled ()->willReturn ($ rqb );
503+ $ rqb ->getDQL ()->shouldBeCalled ()->willReturn ($ relatedDQL );
504+
505+ $ relatedExpProphecy = $ this ->prophesize (Expr::class);
506+ $ relatedExpProphecy ->in ('o ' , $ relatedDQL )->willReturn ($ func )->shouldBeCalled ();
507+
508+ $ rqb ->expr ()->shouldBeCalled ()->willReturn ($ relatedExpProphecy ->reveal ());
509+
510+ $ rClassMetadataProphecy = $ this ->prophesize (ClassMetadata::class);
511+ $ rClassMetadataProphecy ->hasAssociation ('id ' )->shouldBeCalled ()->willReturn (false );
512+ $ rClassMetadataProphecy ->isIdentifier ('id ' )->shouldBeCalled ()->willReturn (true );
513+
514+ $ rDummyManagerProphecy = $ this ->prophesize (EntityManager::class);
515+ $ rDummyManagerProphecy ->createQueryBuilder ()->shouldBeCalled ()->willReturn ($ rqb ->reveal ());
516+ $ rDummyManagerProphecy ->getClassMetadata (RelatedDummy::class)->shouldBeCalled ()->willReturn ($ rClassMetadataProphecy ->reveal ());
517+ $ this ->assertIdentifierManagerMethodCalls ($ rDummyManagerProphecy );
518+
519+ $ managerRegistryProphecy ->getManagerForClass (RelatedDummy::class)->shouldBeCalled ()->willReturn ($ rDummyManagerProphecy ->reveal ());
520+
521+ $ result = new \StdClass ();
522+ $ queryProphecy = $ this ->prophesize (AbstractQuery::class);
523+ $ queryProphecy ->getOneOrNullResult ()->shouldBeCalled ()->willReturn ($ result );
524+
525+ $ queryBuilder = $ this ->prophesize (QueryBuilder::class);
526+
527+ $ queryBuilder ->andWhere ($ func )->shouldBeCalled ()->willReturn ($ queryBuilder );
528+
529+ $ queryBuilder ->getQuery ()->shouldBeCalled ()->willReturn ($ queryProphecy ->reveal ());
530+ $ queryBuilder ->setParameter ('id_p1 ' , 2 )->shouldBeCalled ()->willReturn ($ queryBuilder );
531+ $ queryBuilder ->setParameter ('id_p2 ' , 1 )->shouldBeCalled ()->willReturn ($ queryBuilder );
532+
533+ $ repositoryProphecy = $ this ->prophesize (EntityRepository::class);
534+ $ repositoryProphecy ->createQueryBuilder ('o ' )->shouldBeCalled ()->willReturn ($ queryBuilder ->reveal ());
535+
536+ $ rDummyManagerProphecy ->getRepository (RelatedDummy::class)->shouldBeCalled ()->willReturn ($ repositoryProphecy ->reveal ());
537+
538+ list ($ propertyNameCollectionFactory , $ propertyMetadataFactory ) = $ this ->getMetadataProphecies ([Dummy::class => $ identifiers , RelatedDummy::class => $ identifiers ]);
539+
540+ $ dataProvider = new SubresourceDataProvider ($ managerRegistryProphecy ->reveal (), $ propertyNameCollectionFactory , $ propertyMetadataFactory );
541+
542+ $ context = ['property ' => 'id ' , 'identifiers ' => [['id ' , Dummy::class, true ], ['relatedDummies ' , RelatedDummy::class, true ]], 'collection ' => false , ChainIdentifierDenormalizer::HAS_IDENTIFIER_DENORMALIZER => true ];
543+
544+ $ this ->assertEquals ($ result , $ dataProvider ->getSubresource (RelatedDummy::class, ['id ' => ['id ' => 1 ], 'relatedDummies ' => ['id ' => 2 ]], $ context ));
545+ }
452546}
0 commit comments