Skip to content

Commit 1d5f020

Browse files
authored
Merge pull request #2751 from antograssiot/filter-name-converter
Add support for name converter in filters
2 parents 0888bf3 + 74692f2 commit 1d5f020

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1491
-412
lines changed

features/bootstrap/DoctrineContext.php

Lines changed: 123 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositeLabel as CompositeLabelDocument;
1818
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositePrimitiveItem as CompositePrimitiveItemDocument;
1919
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\CompositeRelation as CompositeRelationDocument;
20+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\ConvertedBoolean as ConvertedBoolDocument;
21+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\ConvertedDate as ConvertedDateDocument;
22+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\ConvertedInteger as ConvertedIntegerDocument;
23+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\ConvertedString as ConvertedStringDocument;
2024
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Customer as CustomerDocument;
2125
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\Dummy as DummyDocument;
2226
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Document\DummyAggregateOffer as DummyAggregateOfferDocument;
@@ -62,6 +66,10 @@
6266
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositePrimitiveItem;
6367
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation;
6468
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Container;
69+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedBoolean;
70+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedDate;
71+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedInteger;
72+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\ConvertedString;
6573
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Customer;
6674
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
6775
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyAggregateOffer;
@@ -164,6 +172,7 @@ public function thereAreDummyObjects(int $nb)
164172
$dummy->setAlias('Alias #'.($nb - $i));
165173
$dummy->setDummy('SomeDummyTest'.$i);
166174
$dummy->setDescription($descriptions[($i - 1) % 2]);
175+
$dummy->nameConverted = 'Converted '.$i;
167176

168177
$this->manager->persist($dummy);
169178
}
@@ -257,6 +266,7 @@ public function thereAreDummyPropertyObjects(int $nb)
257266
foreach (['foo', 'bar', 'baz'] as $property) {
258267
$dummyProperty->{$property} = $dummyGroup->{$property} = ucfirst($property).' #'.$i;
259268
}
269+
$dummyProperty->nameConverted = "NameConverted #$i";
260270

261271
$dummyProperty->group = $dummyGroup;
262272

@@ -657,6 +667,66 @@ public function thereAreDummyObjectsWithDummyDateAndEmbeddedDummy(int $nb)
657667
$this->manager->flush();
658668
}
659669

670+
/**
671+
* @Given there are :nb convertedDate objects
672+
*/
673+
public function thereAreconvertedDateObjectsWith(int $nb)
674+
{
675+
for ($i = 1; $i <= $nb; ++$i) {
676+
$convertedDate = $this->buildConvertedDate();
677+
$convertedDate->nameConverted = new \DateTime(sprintf('2015-04-%d', $i), new \DateTimeZone('UTC'));
678+
679+
$this->manager->persist($convertedDate);
680+
}
681+
682+
$this->manager->flush();
683+
}
684+
685+
/**
686+
* @Given there are :nb convertedString objects
687+
*/
688+
public function thereAreconvertedStringObjectsWith(int $nb)
689+
{
690+
for ($i = 1; $i <= $nb; ++$i) {
691+
$convertedString = $this->buildConvertedString();
692+
$convertedString->nameConverted = ($i % 2) ? "name#$i" : null;
693+
694+
$this->manager->persist($convertedString);
695+
}
696+
697+
$this->manager->flush();
698+
}
699+
700+
/**
701+
* @Given there are :nb convertedBoolean objects
702+
*/
703+
public function thereAreconvertedBooleanObjectsWith(int $nb)
704+
{
705+
for ($i = 1; $i <= $nb; ++$i) {
706+
$convertedBoolean = $this->buildConvertedBoolean();
707+
$convertedBoolean->nameConverted = (bool) ($i % 2);
708+
709+
$this->manager->persist($convertedBoolean);
710+
}
711+
712+
$this->manager->flush();
713+
}
714+
715+
/**
716+
* @Given there are :nb convertedInteger objects
717+
*/
718+
public function thereAreconvertedIntegerObjectsWith(int $nb)
719+
{
720+
for ($i = 1; $i <= $nb; ++$i) {
721+
$convertedInteger = $this->buildConvertedInteger();
722+
$convertedInteger->nameConverted = $i;
723+
724+
$this->manager->persist($convertedInteger);
725+
}
726+
727+
$this->manager->flush();
728+
}
729+
660730
/**
661731
* @Given there are :nb dummy objects with dummyPrice
662732
*/
@@ -1264,6 +1334,35 @@ public function thereAreNbDummyDtoCustom($nb)
12641334
$this->manager->clear();
12651335
}
12661336

1337+
/**
1338+
* @Given there is a order with same customer and receiver
1339+
*/
1340+
public function testEagerLoadingNotDuplicateRelation()
1341+
{
1342+
$customer = $this->isOrm() ? new Customer() : new CustomerDocument();
1343+
$customer->name = 'customer_name';
1344+
1345+
$address1 = $this->isOrm() ? new Address() : new AddressDocument();
1346+
$address1->name = 'foo';
1347+
$address2 = $this->isOrm() ? new Address() : new AddressDocument();
1348+
$address2->name = 'bar';
1349+
1350+
$order = $this->isOrm() ? new Order() : new OrderDocument();
1351+
$order->recipient = $customer;
1352+
$order->customer = $customer;
1353+
1354+
$customer->addresses->add($address1);
1355+
$customer->addresses->add($address2);
1356+
1357+
$this->manager->persist($address1);
1358+
$this->manager->persist($address2);
1359+
$this->manager->persist($customer);
1360+
$this->manager->persist($order);
1361+
1362+
$this->manager->flush();
1363+
$this->manager->clear();
1364+
}
1365+
12671366
private function isOrm(): bool
12681367
{
12691368
return null !== $this->schemaTool;
@@ -1579,31 +1678,34 @@ private function buildThirdLevel()
15791678
}
15801679

15811680
/**
1582-
* @Given there is a order with same customer and receiver
1681+
* @return ConvertedDate|ConvertedDateDocument
15831682
*/
1584-
public function testEagerLoadingNotDuplicateRelation()
1683+
private function buildConvertedDate()
15851684
{
1586-
$customer = $this->isOrm() ? new Customer() : new CustomerDocument();
1587-
$customer->name = 'customer_name';
1588-
1589-
$address1 = $this->isOrm() ? new Address() : new AddressDocument();
1590-
$address1->name = 'foo';
1591-
$address2 = $this->isOrm() ? new Address() : new AddressDocument();
1592-
$address2->name = 'bar';
1593-
1594-
$order = $this->isOrm() ? new Order() : new OrderDocument();
1595-
$order->recipient = $customer;
1596-
$order->customer = $customer;
1685+
return $this->isOrm() ? new ConvertedDate() : new ConvertedDateDocument();
1686+
}
15971687

1598-
$customer->addresses->add($address1);
1599-
$customer->addresses->add($address2);
1688+
/**
1689+
* @return ConvertedBoolean|ConvertedBoolDocument
1690+
*/
1691+
private function buildConvertedBoolean()
1692+
{
1693+
return $this->isOrm() ? new ConvertedBoolean() : new ConvertedBoolDocument();
1694+
}
16001695

1601-
$this->manager->persist($address1);
1602-
$this->manager->persist($address2);
1603-
$this->manager->persist($customer);
1604-
$this->manager->persist($order);
1696+
/**
1697+
* @return ConvertedInteger|ConvertedIntegerDocument
1698+
*/
1699+
private function buildConvertedInteger()
1700+
{
1701+
return $this->isOrm() ? new ConvertedInteger() : new ConvertedIntegerDocument();
1702+
}
16051703

1606-
$this->manager->flush();
1607-
$this->manager->clear();
1704+
/**
1705+
* @return ConvertedString|ConvertedStringDocument
1706+
*/
1707+
private function buildConvertedString()
1708+
{
1709+
return $this->isOrm() ? new ConvertedString() : new ConvertedStringDocument();
16081710
}
16091711
}

features/doctrine/boolean_filter.feature

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,3 +448,78 @@ Feature: Boolean filter on collections
448448
}
449449
"""
450450
And the JSON node "hydra:totalItems" should be equal to 25
451+
452+
@createSchema
453+
Scenario: Get collection filtered using a name converter
454+
Given there are 5 convertedBoolean objects
455+
When I send a "GET" request to "/converted_booleans?name_converted=false"
456+
Then the response status code should be 200
457+
And the response should be in JSON
458+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
459+
And the JSON should be valid according to this schema:
460+
"""
461+
{
462+
"type": "object",
463+
"properties": {
464+
"@context": {"pattern": "^/contexts/ConvertedBoolean"},
465+
"@id": {"pattern": "^/converted_booleans"},
466+
"@type": {"pattern": "^hydra:Collection$"},
467+
"hydra:member": {
468+
"type": "array",
469+
"items": {
470+
"type": "object",
471+
"properties": {
472+
"@id": {"pattern": "^/converted_booleans/(2|4)$"},
473+
"@type": {"pattern": "^ConvertedBoolean"},
474+
"name_converted": {"type": "boolean"},
475+
"id": {"type": "integer", "minimum":2, "maximum": 4}
476+
},
477+
"required": ["@id", "@type", "name_converted", "id"],
478+
"additionalProperties": false
479+
},
480+
"minItems": 2,
481+
"maxItems": 2,
482+
"uniqueItems": true
483+
},
484+
"hydra:totalItems": {"type": "integer", "minimum": 2, "maximum": 2},
485+
"hydra:view": {
486+
"type": "object",
487+
"properties": {
488+
"@id": {"pattern": "^/converted_booleans\\?name_converted=false"},
489+
"@type": {"pattern": "^hydra:PartialCollectionView$"}
490+
},
491+
"required": ["@id", "@type"],
492+
"additionalProperties": false
493+
},
494+
"hydra:search": {
495+
"type": "object",
496+
"properties": {
497+
"@type": {"pattern": "^hydra:IriTemplate$"},
498+
"hydra:template": {"pattern": "^/converted_booleans\\{\\?name_converted\\}$"},
499+
"hydra:variableRepresentation": {"pattern": "^BasicRepresentation$"},
500+
"hydra:mapping": {
501+
"type": "array",
502+
"items": {
503+
"type": "object",
504+
"properties": {
505+
"@type": {"pattern": "^IriTemplateMapping$"},
506+
"variable": {"pattern": "^name_converted$"},
507+
"property": {"pattern": "^name_converted$"},
508+
"required": {"type": "boolean"}
509+
},
510+
"required": ["@type", "variable", "property", "required"],
511+
"additionalProperties": false
512+
},
513+
"minItems": 1,
514+
"maxItems": 1,
515+
"uniqueItems": true
516+
}
517+
},
518+
"additionalProperties": false,
519+
"required": ["@type", "hydra:template", "hydra:variableRepresentation", "hydra:mapping"]
520+
},
521+
"additionalProperties": false,
522+
"required": ["@context", "@id", "@type", "hydra:member", "hydra:totalItems", "hydra:view", "hydra:search"]
523+
}
524+
}
525+
"""

features/doctrine/date_filter.feature

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ Feature: Date filter on collections
413413
},
414414
"hydra:search": {
415415
"@type": "hydra:IriTemplate",
416-
"hydra:template": "/dummies{?dummyBoolean,relatedDummy.embeddedDummy.dummyBoolean,dummyDate[before],dummyDate[strictly_before],dummyDate[after],dummyDate[strictly_after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[strictly_before],relatedDummy.dummyDate[after],relatedDummy.dummyDate[strictly_after],exists[alias],exists[description],exists[relatedDummy.name],exists[dummyBoolean],exists[relatedDummy],dummyFloat,dummyFloat[],dummyPrice,dummyPrice[],order[id],order[name],order[description],order[relatedDummy.name],order[relatedDummy.symfony],order[dummyDate],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name,relatedDummy.thirdLevel.level,relatedDummy.thirdLevel.level[],relatedDummy.thirdLevel.fourthLevel.level,relatedDummy.thirdLevel.fourthLevel.level[],relatedDummy.thirdLevel.badFourthLevel.level,relatedDummy.thirdLevel.badFourthLevel.level[],relatedDummy.thirdLevel.fourthLevel.badThirdLevel.level,relatedDummy.thirdLevel.fourthLevel.badThirdLevel.level[],properties[]}",
416+
"hydra:template": "/dummies{?dummyBoolean,relatedDummy.embeddedDummy.dummyBoolean,dummyDate[before],dummyDate[strictly_before],dummyDate[after],dummyDate[strictly_after],relatedDummy.dummyDate[before],relatedDummy.dummyDate[strictly_before],relatedDummy.dummyDate[after],relatedDummy.dummyDate[strictly_after],exists[alias],exists[description],exists[relatedDummy.name],exists[dummyBoolean],exists[relatedDummy],dummyFloat,dummyFloat[],dummyPrice,dummyPrice[],order[id],order[name],order[description],order[relatedDummy.name],order[relatedDummy.symfony],order[dummyDate],dummyFloat[between],dummyFloat[gt],dummyFloat[gte],dummyFloat[lt],dummyFloat[lte],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],id,id[],name,alias,description,relatedDummy.name,relatedDummy.name[],relatedDummies,relatedDummies[],dummy,relatedDummies.name,relatedDummy.thirdLevel.level,relatedDummy.thirdLevel.level[],relatedDummy.thirdLevel.fourthLevel.level,relatedDummy.thirdLevel.fourthLevel.level[],relatedDummy.thirdLevel.badFourthLevel.level,relatedDummy.thirdLevel.badFourthLevel.level[],relatedDummy.thirdLevel.fourthLevel.badThirdLevel.level,relatedDummy.thirdLevel.fourthLevel.badThirdLevel.level[],name_converted,properties[]}",
417417
"hydra:variableRepresentation": "BasicRepresentation",
418418
"hydra:mapping": [
419419
{
@@ -740,6 +740,12 @@ Feature: Date filter on collections
740740
"property": "relatedDummy.thirdLevel.fourthLevel.badThirdLevel.level",
741741
"required": false
742742
},
743+
{
744+
"@type": "IriTemplateMapping",
745+
"variable": "name_converted",
746+
"property": "name_converted",
747+
"required": false
748+
},
743749
{
744750
"@type": "IriTemplateMapping",
745751
"variable": "properties[]",
@@ -1102,3 +1108,78 @@ Feature: Date filter on collections
11021108
}
11031109
}
11041110
"""
1111+
1112+
@createSchema
1113+
Scenario: Get collection filtered using a name converter
1114+
Given there are 30 convertedDate objects
1115+
When I send a "GET" request to "/converted_dates?name_converted[strictly_after]=2015-04-28"
1116+
Then the response status code should be 200
1117+
And the response should be in JSON
1118+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
1119+
And the JSON should be valid according to this schema:
1120+
"""
1121+
{
1122+
"type": "object",
1123+
"properties": {
1124+
"@context": {"pattern": "^/contexts/ConvertedDate"},
1125+
"@id": {"pattern": "^/converted_dates"},
1126+
"@type": {"pattern": "^hydra:Collection$"},
1127+
"hydra:member": {
1128+
"type": "array",
1129+
"items": {
1130+
"type": "object",
1131+
"properties": {
1132+
"@id": {"pattern": "^/converted_dates/(29|30)$"},
1133+
"@type": {"pattern": "^ConvertedDate"},
1134+
"name_converted": {"type": "string"},
1135+
"id": {"type": "integer", "minimum":29, "maximum": 30}
1136+
},
1137+
"required": ["@id", "@type", "name_converted", "id"],
1138+
"additionalProperties": false
1139+
},
1140+
"minItems": 2,
1141+
"maxItems": 2,
1142+
"uniqueItems": true
1143+
},
1144+
"hydra:totalItems": {"type": "integer", "minimum": 2, "maximum": 2},
1145+
"hydra:view": {
1146+
"type": "object",
1147+
"properties": {
1148+
"@id": {"pattern": "^/converted_dates\\?name_converted%5Bstrictly_after%5D=2015\\-04\\-28$"},
1149+
"@type": {"pattern": "^hydra:PartialCollectionView$"}
1150+
},
1151+
"required": ["@id", "@type"],
1152+
"additionalProperties": false
1153+
},
1154+
"hydra:search": {
1155+
"type": "object",
1156+
"properties": {
1157+
"@type": {"pattern": "^hydra:IriTemplate$"},
1158+
"hydra:template": {"pattern": "^/converted_dates\\{\\?.*name_converted\\[before\\],name_converted\\[strictly_before\\],name_converted\\[after\\],name_converted\\[strictly_after\\].*\\}$"},
1159+
"hydra:variableRepresentation": {"pattern": "^BasicRepresentation$"},
1160+
"hydra:mapping": {
1161+
"type": "array",
1162+
"items": {
1163+
"type": "object",
1164+
"properties": {
1165+
"@type": {"pattern": "^IriTemplateMapping$"},
1166+
"variable": {"pattern": "^name_converted(\\[(strictly_)?(before|after)\\])$"},
1167+
"property": {"pattern": "^name_converted$"},
1168+
"required": {"type": "boolean"}
1169+
},
1170+
"required": ["@type", "variable", "property", "required"],
1171+
"additionalProperties": false
1172+
},
1173+
"minItems": 4,
1174+
"maxItems": 4,
1175+
"uniqueItems": true
1176+
}
1177+
},
1178+
"additionalProperties": false,
1179+
"required": ["@type", "hydra:template", "hydra:variableRepresentation", "hydra:mapping"]
1180+
},
1181+
"additionalProperties": false,
1182+
"required": ["@context", "@id", "@type", "hydra:member", "hydra:totalItems", "hydra:view", "hydra:search"]
1183+
}
1184+
}
1185+
"""

0 commit comments

Comments
 (0)