Skip to content

Commit 603ad01

Browse files
authored
Merge pull request #950 from soyuka/reproduce-attempt-944
Fix #944 - allows to filter by relation by keeping EagerLoading enabled
2 parents b092dd0 + 495ea9e commit 603ad01

File tree

16 files changed

+647
-27
lines changed

16 files changed

+647
-27
lines changed

features/bootstrap/FeatureContext.php

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeLabel;
1414
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation;
1515
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
16+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCar;
17+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyCarColor;
18+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyFriend;
1619
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\FileConfigDummy;
1720
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
21+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedToDummyFriend;
1822
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelationEmbedder;
1923
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\UuidIdentifierDummy;
2024
use Behat\Behat\Context\Context;
@@ -135,18 +139,21 @@ public function thereIsDummyObjectsWithRelatedDummy($nb)
135139
}
136140

137141
/**
138-
* @Given there is :nb dummy objects with relatedDummies
142+
* @Given there is :nb dummy objects having each :nbrelated relatedDummies
139143
*/
140-
public function thereIsDummyObjectsWithRelatedDummies($nb)
144+
public function thereIsDummyObjectsWithRelatedDummies($nb, $nbrelated)
141145
{
142146
for ($i = 1; $i <= $nb; ++$i) {
143-
$relatedDummy = new RelatedDummy();
144-
$relatedDummy->setName('RelatedDummy #'.$i);
145-
146147
$dummy = new Dummy();
147148
$dummy->setName('Dummy #'.$i);
148149
$dummy->setAlias('Alias #'.($nb - $i));
149-
$dummy->addRelatedDummy($relatedDummy);
150+
151+
for ($j = 1; $j <= $nbrelated; ++$j) {
152+
$relatedDummy = new RelatedDummy();
153+
$relatedDummy->setName('RelatedDummy'.$j.$i);
154+
$this->manager->persist($relatedDummy);
155+
$dummy->addRelatedDummy($relatedDummy);
156+
}
150157

151158
$this->manager->persist($relatedDummy);
152159
$this->manager->persist($dummy);
@@ -319,4 +326,60 @@ public function thereIsAFileConfigDummyObject()
319326
$this->manager->persist($fileConfigDummy);
320327
$this->manager->flush();
321328
}
329+
330+
/**
331+
* @Given there is a DummyCar entity with related colors
332+
*/
333+
public function thereIsAFooEntityWithRelatedBars()
334+
{
335+
$foo = new DummyCar();
336+
$this->manager->persist($foo);
337+
338+
$bar1 = new DummyCarColor();
339+
$bar1->setProp('red');
340+
$bar1->setCar($foo);
341+
$this->manager->persist($bar1);
342+
343+
$bar2 = new DummyCarColor();
344+
$bar2->setProp('blue');
345+
$bar2->setCar($foo);
346+
$this->manager->persist($bar2);
347+
348+
$foo->setColors([$bar1, $bar2]);
349+
$this->manager->persist($foo);
350+
351+
$this->manager->flush();
352+
}
353+
354+
/**
355+
* @Given there is a RelatedDummy with :nb friends
356+
*/
357+
public function thereIsARelatedDummyWithFriends($nb)
358+
{
359+
$relatedDummy = new RelatedDummy();
360+
$relatedDummy->setName('RelatedDummy with friends');
361+
$this->manager->persist($relatedDummy);
362+
363+
for ($i = 1; $i <= $nb; ++$i) {
364+
$friend = new DummyFriend();
365+
$friend->setName('Friend-'.$i);
366+
367+
$this->manager->persist($friend);
368+
369+
$relation = new RelatedToDummyFriend();
370+
$relation->setName('Relation-'.$i);
371+
$relation->setDummyFriend($friend);
372+
$relation->setRelatedDummy($relatedDummy);
373+
374+
$relatedDummy->addRelatedToDummyFriend($relation);
375+
376+
$this->manager->persist($relation);
377+
}
378+
379+
$relatedDummy2 = new RelatedDummy();
380+
$relatedDummy2->setName('RelatedDummy without friends');
381+
$this->manager->persist($relatedDummy2);
382+
383+
$this->manager->flush();
384+
}
322385
}

features/doctrine/date_filter.feature

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,18 +395,18 @@ Feature: Date filter on collections
395395
And the JSON should be equal to:
396396
"""
397397
{
398-
"@context": "\/contexts\/Dummy",
399-
"@id": "\/dummies",
398+
"@context": "/contexts/Dummy",
399+
"@id": "/dummies",
400400
"@type": "hydra:Collection",
401401
"hydra:member": [],
402402
"hydra:totalItems": 0,
403403
"hydra:view": {
404-
"@id": "\/dummies?relatedDummy.dummyDate%5Bafter%5D=2015-04-28",
404+
"@id": "/dummies?relatedDummy.dummyDate%5Bafter%5D=2015-04-28",
405405
"@type": "hydra:PartialCollectionView"
406406
},
407407
"hydra:search": {
408408
"@type": "hydra:IriTemplate",
409-
"hydra:template": "\/dummies{?id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,order[id],order[name],order[relatedDummy.symfony],dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyBoolean,dummyFloat,dummyPrice}",
409+
"hydra:template": "/dummies{?id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name,order[id],order[name],order[relatedDummy.symfony],dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyBoolean,dummyFloat,dummyPrice}",
410410
"hydra:variableRepresentation": "BasicRepresentation",
411411
"hydra:mapping": [
412412
{
@@ -469,6 +469,12 @@ Feature: Date filter on collections
469469
"property": "dummy",
470470
"required": false
471471
},
472+
{
473+
"@type": "IriTemplateMapping",
474+
"variable": "relatedDummies.name",
475+
"property": "relatedDummies.name",
476+
"required": false
477+
},
472478
{
473479
"@type": "IriTemplateMapping",
474480
"variable": "order[id]",

features/doctrine/search_filter.feature

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,66 @@ Feature: Search filter on collections
44
I need to search for collections properties
55

66
@createSchema
7+
@dropSchema
8+
Scenario: Test ManyToMany with filter on join table
9+
Given there is a RelatedDummy with 4 friends
10+
When I add "Accept" header equal to "application/hal+json"
11+
And I send a "GET" request to "/related_dummies?relatedToDummyFriend.dummyFriend=/dummy_friends/4"
12+
Then the response status code should be 200
13+
And the JSON node "_embedded.item" should have 1 element
14+
And the JSON node "_embedded.item[0]._links.relatedToDummyFriend" should have 4 elements
15+
And the JSON node "_embedded.item[0]._embedded.relatedToDummyFriend" should have 4 elements
16+
17+
@createSchema
18+
Scenario: Test #944
19+
Given there is a DummyCar entity with related colors
20+
When I send a "GET" request to "/dummy_cars?colors.prop=red"
21+
Then the response status code should be 200
22+
And the JSON should be equal to:
23+
"""
24+
{
25+
"@context": "/contexts/DummyCar",
26+
"@id": "/dummy_cars",
27+
"@type": "hydra:Collection",
28+
"hydra:member": [
29+
{
30+
"@id": "/dummy_cars/1",
31+
"@type": "DummyCar",
32+
"colors": [
33+
{
34+
"@id": "/dummy_car_colors/1",
35+
"@type": "DummyCarColor",
36+
"prop": "red"
37+
},
38+
{
39+
"@id": "/dummy_car_colors/2",
40+
"@type": "DummyCarColor",
41+
"prop": "blue"
42+
}
43+
]
44+
}
45+
],
46+
"hydra:totalItems": 1,
47+
"hydra:view": {
48+
"@id": "/dummy_cars?colors.prop=red",
49+
"@type": "hydra:PartialCollectionView"
50+
},
51+
"hydra:search": {
52+
"@type": "hydra:IriTemplate",
53+
"hydra:template": "/dummy_cars{?colors.prop}",
54+
"hydra:variableRepresentation": "BasicRepresentation",
55+
"hydra:mapping": [
56+
{
57+
"@type": "IriTemplateMapping",
58+
"variable": "colors.prop",
59+
"property": "colors.prop",
60+
"required": false
61+
}
62+
]
63+
}
64+
}
65+
"""
66+
767
Scenario: Search collection by name (partial)
868
Given there is "30" dummy objects
969
When I send a "GET" request to "/dummies?name=my"
@@ -45,7 +105,6 @@ Feature: Search filter on collections
45105
"""
46106

47107
Scenario: Search collection by name (partial case insensitive)
48-
Given there is "30" dummy objects
49108
When I send a "GET" request to "/dummies?dummy=somedummytest1"
50109
Then the response status code should be 200
51110
And the response should be in JSON
@@ -179,3 +238,17 @@ Feature: Search filter on collections
179238
}
180239
}
181240
"""
241+
242+
@createSchema
243+
@dropSchema
244+
Scenario: Search related collection by name
245+
Given there is 3 dummy objects having each 3 relatedDummies
246+
When I add "Accept" header equal to "application/hal+json"
247+
And I send a "GET" request to "/dummies?relatedDummies.name=RelatedDummy1"
248+
Then the response status code should be 200
249+
And the response should be in JSON
250+
And the JSON node "_embedded.item" should have 3 elements
251+
And the JSON node "_embedded.item[0]._links.relatedDummies" should have 3 elements
252+
And the JSON node "_embedded.item[1]._links.relatedDummies" should have 3 elements
253+
And the JSON node "_embedded.item[2]._links.relatedDummies" should have 3 elements
254+

features/main/crud.feature

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Feature: Create-Retrieve-Update-Delete
123123
"hydra:totalItems": 1,
124124
"hydra:search": {
125125
"@type": "hydra:IriTemplate",
126-
"hydra:template": "/dummies{?id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,order[id],order[name],order[relatedDummy.symfony],dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyBoolean,dummyFloat,dummyPrice}",
126+
"hydra:template": "/dummies{?id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name,order[id],order[name],order[relatedDummy.symfony],dummyDate[before],dummyDate[after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[after],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyBoolean,dummyFloat,dummyPrice}",
127127
"hydra:variableRepresentation": "BasicRepresentation",
128128
"hydra:mapping": [
129129
{
@@ -186,6 +186,12 @@ Feature: Create-Retrieve-Update-Delete
186186
"property": "dummy",
187187
"required": false
188188
},
189+
{
190+
"@type": "IriTemplateMapping",
191+
"variable": "relatedDummies.name",
192+
"property": "relatedDummies.name",
193+
"required": false
194+
},
189195
{
190196
"@type": "IriTemplateMapping",
191197
"variable": "order[id]",

features/main/relation.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ Feature: Relations support
6060
"@context": "/contexts/RelatedDummy",
6161
"@id": "/related_dummies/1",
6262
"@type": "https://schema.org/Product",
63+
"id": 1,
6364
"name": null,
65+
"symfony": "symfony",
6466
"dummyDate": null,
6567
"thirdLevel": "/third_levels/1",
66-
"relatedToDummyFriend": null,
68+
"relatedToDummyFriend": [],
6769
"dummyBoolean": null,
68-
"id": 1,
69-
"symfony": "symfony",
7070
"age": null
7171
}
7272
"""

0 commit comments

Comments
 (0)