From 68501b8bb68b01730fa1a67082ab1ad79bc27407 Mon Sep 17 00:00:00 2001 From: divine <48183131+divine@users.noreply.github.com> Date: Thu, 5 May 2022 03:50:37 +0300 Subject: [PATCH 1/4] feat: add not equal range filter Co-Authored-By: Samuel Chiriluta <3427855+samuel4x4@users.noreply.github.com> --- .../Common/Filter/RangeFilterInterface.php | 1 + .../Common/Filter/RangeFilterTrait.php | 3 +- src/Doctrine/Odm/Filter/RangeFilter.php | 9 ++ src/Doctrine/Orm/Filter/RangeFilter.php | 11 +++ .../Common/Filter/RangeFilterTestTrait.php | 16 ++++ tests/Doctrine/Odm/Filter/RangeFilterTest.php | 94 +++++++++++++++++++ tests/Doctrine/Orm/Filter/RangeFilterTest.php | 66 +++++++++++++ 7 files changed, 199 insertions(+), 1 deletion(-) diff --git a/src/Doctrine/Common/Filter/RangeFilterInterface.php b/src/Doctrine/Common/Filter/RangeFilterInterface.php index 2ea0db988b3..6abdcbf19fd 100644 --- a/src/Doctrine/Common/Filter/RangeFilterInterface.php +++ b/src/Doctrine/Common/Filter/RangeFilterInterface.php @@ -26,4 +26,5 @@ interface RangeFilterInterface public const PARAMETER_GREATER_THAN_OR_EQUAL = 'gte'; public const PARAMETER_LESS_THAN = 'lt'; public const PARAMETER_LESS_THAN_OR_EQUAL = 'lte'; + public const PARAMETER_NOT_EQUAL = 'ne'; } diff --git a/src/Doctrine/Common/Filter/RangeFilterTrait.php b/src/Doctrine/Common/Filter/RangeFilterTrait.php index 007d59f0db6..a8fa2fd78aa 100644 --- a/src/Doctrine/Common/Filter/RangeFilterTrait.php +++ b/src/Doctrine/Common/Filter/RangeFilterTrait.php @@ -49,6 +49,7 @@ public function getDescription(string $resourceClass): array $description += $this->getFilterDescription($property, self::PARAMETER_GREATER_THAN_OR_EQUAL); $description += $this->getFilterDescription($property, self::PARAMETER_LESS_THAN); $description += $this->getFilterDescription($property, self::PARAMETER_LESS_THAN_OR_EQUAL); + $description += $this->getFilterDescription($property, self::PARAMETER_NOT_EQUAL); } return $description; @@ -78,7 +79,7 @@ protected function getFilterDescription(string $fieldName, string $operator): ar private function normalizeValues(array $values, string $property): ?array { - $operators = [self::PARAMETER_BETWEEN, self::PARAMETER_GREATER_THAN, self::PARAMETER_GREATER_THAN_OR_EQUAL, self::PARAMETER_LESS_THAN, self::PARAMETER_LESS_THAN_OR_EQUAL]; + $operators = [self::PARAMETER_BETWEEN, self::PARAMETER_GREATER_THAN, self::PARAMETER_GREATER_THAN_OR_EQUAL, self::PARAMETER_LESS_THAN, self::PARAMETER_LESS_THAN_OR_EQUAL, self::PARAMETER_NOT_EQUAL]; foreach ($values as $operator => $value) { if (!\in_array($operator, $operators, true)) { diff --git a/src/Doctrine/Odm/Filter/RangeFilter.php b/src/Doctrine/Odm/Filter/RangeFilter.php index 9dbcf22318d..5f3cf344e2c 100644 --- a/src/Doctrine/Odm/Filter/RangeFilter.php +++ b/src/Doctrine/Odm/Filter/RangeFilter.php @@ -122,6 +122,15 @@ protected function addMatch(Builder $aggregationBuilder, string $field, string $ $aggregationBuilder->match()->field($matchField)->lte($value); + break; + case self::PARAMETER_NOT_EQUAL: + $value = $this->normalizeValue($value, $operator); + if (null === $value) { + return; + } + + $aggregationBuilder->match()->field($matchField)->notEqual($value); + break; } } diff --git a/src/Doctrine/Orm/Filter/RangeFilter.php b/src/Doctrine/Orm/Filter/RangeFilter.php index edd5b95afb0..de2740ca605 100644 --- a/src/Doctrine/Orm/Filter/RangeFilter.php +++ b/src/Doctrine/Orm/Filter/RangeFilter.php @@ -144,6 +144,17 @@ protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterf ->andWhere(sprintf('%s.%s <= :%s', $alias, $field, $valueParameter)) ->setParameter($valueParameter, $value); + break; + case self::PARAMETER_NOT_EQUAL: + $value = $this->normalizeValue($value, $operator); + if (null === $value) { + return; + } + + $queryBuilder + ->andWhere(sprintf('%s.%s <> :%s', $alias, $field, $valueParameter)) + ->setParameter($valueParameter, $value); + break; } } diff --git a/tests/Doctrine/Common/Filter/RangeFilterTestTrait.php b/tests/Doctrine/Common/Filter/RangeFilterTestTrait.php index 3940b4cabe7..911a845ca0d 100644 --- a/tests/Doctrine/Common/Filter/RangeFilterTestTrait.php +++ b/tests/Doctrine/Common/Filter/RangeFilterTestTrait.php @@ -134,6 +134,22 @@ private function provideApplyTestArguments(): array ], ], ], + 'ne' => [ + null, + [ + 'dummyPrice' => [ + 'ne' => '9.99', + ], + ], + ], + 'ne (non-numeric)' => [ + null, + [ + 'dummyPrice' => [ + 'ne' => '127.0.0.1', + ], + ], + ], ]; } } diff --git a/tests/Doctrine/Odm/Filter/RangeFilterTest.php b/tests/Doctrine/Odm/Filter/RangeFilterTest.php index 012afc82b83..67b0feca216 100644 --- a/tests/Doctrine/Odm/Filter/RangeFilterTest.php +++ b/tests/Doctrine/Odm/Filter/RangeFilterTest.php @@ -60,6 +60,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'id[ne]' => [ + 'property' => 'id', + 'type' => 'string', + 'required' => false, + ], 'name[between]' => [ 'property' => 'name', 'type' => 'string', @@ -85,6 +90,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'name[ne]' => [ + 'property' => 'name', + 'type' => 'string', + 'required' => false, + ], 'alias[between]' => [ 'property' => 'alias', 'type' => 'string', @@ -110,6 +120,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'alias[ne]' => [ + 'property' => 'alias', + 'type' => 'string', + 'required' => false, + ], 'description[between]' => [ 'property' => 'description', 'type' => 'string', @@ -135,6 +150,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'description[ne]' => [ + 'property' => 'description', + 'type' => 'string', + 'required' => false, + ], 'dummy[between]' => [ 'property' => 'dummy', 'type' => 'string', @@ -160,6 +180,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummy[ne]' => [ + 'property' => 'dummy', + 'type' => 'string', + 'required' => false, + ], 'dummyDate[between]' => [ 'property' => 'dummyDate', 'type' => 'string', @@ -185,6 +210,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyDate[ne]' => [ + 'property' => 'dummyDate', + 'type' => 'string', + 'required' => false, + ], 'dummyFloat[between]' => [ 'property' => 'dummyFloat', 'type' => 'string', @@ -210,6 +240,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyFloat[ne]' => [ + 'property' => 'dummyFloat', + 'type' => 'string', + 'required' => false, + ], 'dummyPrice[between]' => [ 'property' => 'dummyPrice', 'type' => 'string', @@ -235,6 +270,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyPrice[ne]' => [ + 'property' => 'dummyPrice', + 'type' => 'string', + 'required' => false, + ], 'jsonData[between]' => [ 'property' => 'jsonData', 'type' => 'string', @@ -260,6 +300,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'jsonData[ne]' => [ + 'property' => 'jsonData', + 'type' => 'string', + 'required' => false, + ], 'arrayData[between]' => [ 'property' => 'arrayData', 'type' => 'string', @@ -285,6 +330,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'arrayData[ne]' => [ + 'property' => 'arrayData', + 'type' => 'string', + 'required' => false, + ], 'nameConverted[between]' => [ 'property' => 'nameConverted', 'type' => 'string', @@ -310,6 +360,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'nameConverted[ne]' => [ + 'property' => 'nameConverted', + 'type' => 'string', + 'required' => false, + ], 'dummyBoolean[between]' => [ 'property' => 'dummyBoolean', 'type' => 'string', @@ -335,6 +390,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyBoolean[ne]' => [ + 'property' => 'dummyBoolean', + 'type' => 'string', + 'required' => false, + ], 'relatedDummy[between]' => [ 'property' => 'relatedDummy', 'type' => 'string', @@ -360,6 +420,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'relatedDummy[ne]' => [ + 'property' => 'relatedDummy', + 'type' => 'string', + 'required' => false, + ], 'relatedDummies[between]' => [ 'property' => 'relatedDummies', 'type' => 'string', @@ -385,6 +450,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'relatedDummies[ne]' => [ + 'property' => 'relatedDummies', + 'type' => 'string', + 'required' => false, + ], 'relatedOwnedDummy[between]' => [ 'property' => 'relatedOwnedDummy', 'type' => 'string', @@ -410,6 +480,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'relatedOwnedDummy[ne]' => [ + 'property' => 'relatedOwnedDummy', + 'type' => 'string', + 'required' => false, + ], 'relatedOwningDummy[between]' => [ 'property' => 'relatedOwningDummy', 'type' => 'string', @@ -435,6 +510,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'relatedOwningDummy[ne]' => [ + 'property' => 'relatedOwningDummy', + 'type' => 'string', + 'required' => false, + ], ], $filter->getDescription($this->resourceClass)); } @@ -547,6 +627,20 @@ public function provideApplyTestData(): array ], ], ], + 'ne' => [ + [ + [ + '$match' => [ + 'dummyPrice' => [ + '$notEqual' => 9.99, + ], + ], + ], + ], + ], + 'ne (non-numeric)' => [ + [], + ], ] ); } diff --git a/tests/Doctrine/Orm/Filter/RangeFilterTest.php b/tests/Doctrine/Orm/Filter/RangeFilterTest.php index 718c7b00ef4..d47c7d40457 100644 --- a/tests/Doctrine/Orm/Filter/RangeFilterTest.php +++ b/tests/Doctrine/Orm/Filter/RangeFilterTest.php @@ -57,6 +57,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'id[ne]' => [ + 'property' => 'id', + 'type' => 'string', + 'required' => false, + ], 'name[between]' => [ 'property' => 'name', 'type' => 'string', @@ -82,6 +87,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'name[ne]' => [ + 'property' => 'name', + 'type' => 'string', + 'required' => false, + ], 'alias[between]' => [ 'property' => 'alias', 'type' => 'string', @@ -107,6 +117,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'alias[ne]' => [ + 'property' => 'alias', + 'type' => 'string', + 'required' => false, + ], 'description[between]' => [ 'property' => 'description', 'type' => 'string', @@ -132,6 +147,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'description[ne]' => [ + 'property' => 'description', + 'type' => 'string', + 'required' => false, + ], 'dummy[between]' => [ 'property' => 'dummy', 'type' => 'string', @@ -157,6 +177,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummy[ne]' => [ + 'property' => 'dummy', + 'type' => 'string', + 'required' => false, + ], 'dummyDate[between]' => [ 'property' => 'dummyDate', 'type' => 'string', @@ -182,6 +207,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyDate[ne]' => [ + 'property' => 'dummyDate', + 'type' => 'string', + 'required' => false, + ], 'dummyFloat[between]' => [ 'property' => 'dummyFloat', 'type' => 'string', @@ -207,6 +237,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyFloat[ne]' => [ + 'property' => 'dummyFloat', + 'type' => 'string', + 'required' => false, + ], 'dummyPrice[between]' => [ 'property' => 'dummyPrice', 'type' => 'string', @@ -232,6 +267,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyPrice[ne]' => [ + 'property' => 'dummyPrice', + 'type' => 'string', + 'required' => false, + ], 'jsonData[between]' => [ 'property' => 'jsonData', 'type' => 'string', @@ -257,6 +297,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'jsonData[ne]' => [ + 'property' => 'jsonData', + 'type' => 'string', + 'required' => false, + ], 'arrayData[between]' => [ 'property' => 'arrayData', 'type' => 'string', @@ -282,6 +327,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'arrayData[ne]' => [ + 'property' => 'arrayData', + 'type' => 'string', + 'required' => false, + ], 'nameConverted[between]' => [ 'property' => 'nameConverted', 'type' => 'string', @@ -307,6 +357,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'nameConverted[ne]' => [ + 'property' => 'nameConverted', + 'type' => 'string', + 'required' => false, + ], 'dummyBoolean[between]' => [ 'property' => 'dummyBoolean', 'type' => 'string', @@ -332,6 +387,11 @@ public function testGetDescriptionDefaultFields() 'type' => 'string', 'required' => false, ], + 'dummyBoolean[ne]' => [ + 'property' => 'dummyBoolean', + 'type' => 'string', + 'required' => false, + ], ], $filter->getDescription($this->resourceClass)); } @@ -382,6 +442,12 @@ public function provideApplyTestData(): array 'lte + gte' => [ sprintf('SELECT o FROM %s o WHERE o.dummyPrice >= :dummyPrice_p1 AND o.dummyPrice <= :dummyPrice_p2', Dummy::class), ], + 'ne' => [ + sprintf('SELECT o FROM %s o WHERE o.dummyPrice <> :dummyPrice_p1', Dummy::class), + ], + 'ne (non-numeric)' => [ + sprintf('SELECT o FROM %s o', Dummy::class), + ], ] ); } From 808a68dfa9724d6e72240b9dde52853d5a475d2b Mon Sep 17 00:00:00 2001 From: divine <48183131+divine@users.noreply.github.com> Date: Thu, 5 May 2022 04:08:10 +0300 Subject: [PATCH 2/4] fix: behat test --- features/doctrine/numeric_filter.feature | 2 +- features/doctrine/order_filter.feature | 2 +- features/doctrine/range_filter.feature | 2 +- tests/Doctrine/Odm/Filter/RangeFilterTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/doctrine/numeric_filter.feature b/features/doctrine/numeric_filter.feature index ec449ae0be7..ff5c7f602d1 100644 --- a/features/doctrine/numeric_filter.feature +++ b/features/doctrine/numeric_filter.feature @@ -193,7 +193,7 @@ Feature: Numeric filter on collections "@type": {"pattern": "^IriTemplateMapping$"}, "variable": { "oneOf": [ - {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte)?\\])?$"}, + {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte|ne)?\\])?$"}, {"pattern": "^order\\[name_converted\\]$"} ] }, diff --git a/features/doctrine/order_filter.feature b/features/doctrine/order_filter.feature index 285f8557906..9c757134355 100644 --- a/features/doctrine/order_filter.feature +++ b/features/doctrine/order_filter.feature @@ -964,7 +964,7 @@ Feature: Order filter on collections "variable": { "oneOf": [ {"pattern": "^order\\[name_converted\\]$"}, - {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte)?\\])?$"} + {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte|ne)?\\])?$"} ] }, "property": {"pattern": "^name_converted$"}, diff --git a/features/doctrine/range_filter.feature b/features/doctrine/range_filter.feature index 9a9ec12d074..abfe96ac8de 100644 --- a/features/doctrine/range_filter.feature +++ b/features/doctrine/range_filter.feature @@ -481,7 +481,7 @@ Feature: Range filter on collections "@type": {"pattern": "^IriTemplateMapping$"}, "variable": { "oneOf": [ - {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte)?\\])?$"}, + {"pattern": "^name_converted(\\[(between|gt|gte|lt|lte|ne)?\\])?$"}, {"pattern": "^order\\[name_converted\\]$"} ] }, diff --git a/tests/Doctrine/Odm/Filter/RangeFilterTest.php b/tests/Doctrine/Odm/Filter/RangeFilterTest.php index 67b0feca216..5ab6db14150 100644 --- a/tests/Doctrine/Odm/Filter/RangeFilterTest.php +++ b/tests/Doctrine/Odm/Filter/RangeFilterTest.php @@ -632,7 +632,7 @@ public function provideApplyTestData(): array [ '$match' => [ 'dummyPrice' => [ - '$notEqual' => 9.99, + '$ne' => 9.99, ], ], ], From c35b006a203872b4d6a72b2ff56c2d907a3467f5 Mon Sep 17 00:00:00 2001 From: divine <48183131+divine@users.noreply.github.com> Date: Thu, 5 May 2022 04:33:59 +0300 Subject: [PATCH 3/4] fix: more behat tests --- features/doctrine/numeric_filter.feature | 4 ++-- features/doctrine/order_filter.feature | 4 ++-- features/doctrine/range_filter.feature | 6 +++--- features/main/crud.feature | 14 +++++++++++++- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/features/doctrine/numeric_filter.feature b/features/doctrine/numeric_filter.feature index ff5c7f602d1..abecb20160e 100644 --- a/features/doctrine/numeric_filter.feature +++ b/features/doctrine/numeric_filter.feature @@ -203,8 +203,8 @@ Feature: Numeric filter on collections "required": ["@type", "variable", "property", "required"], "additionalProperties": false }, - "minItems": 8, - "maxItems": 8, + "minItems": 9, + "maxItems": 9, "uniqueItems": true } }, diff --git a/features/doctrine/order_filter.feature b/features/doctrine/order_filter.feature index 9c757134355..25443022282 100644 --- a/features/doctrine/order_filter.feature +++ b/features/doctrine/order_filter.feature @@ -973,8 +973,8 @@ Feature: Order filter on collections "required": ["@type", "variable", "property", "required"], "additionalProperties": false }, - "minItems": 8, - "maxItems": 8, + "minItems": 9, + "maxItems": 9, "uniqueItems": true } }, diff --git a/features/doctrine/range_filter.feature b/features/doctrine/range_filter.feature index abfe96ac8de..b5e79f4f625 100644 --- a/features/doctrine/range_filter.feature +++ b/features/doctrine/range_filter.feature @@ -471,7 +471,7 @@ Feature: Range filter on collections "type": "object", "properties": { "@type": {"pattern": "^hydra:IriTemplate$"}, - "hydra:template": {"pattern": "^/converted_integers\\{\\?.*name_converted\\[between\\],name_converted\\[gt\\],name_converted\\[gte\\],name_converted\\[lt\\],name_converted\\[lte\\].*\\}$"}, + "hydra:template": {"pattern": "^/converted_integers\\{\\?.*name_converted\\[between\\],name_converted\\[gt\\],name_converted\\[gte\\],name_converted\\[lt\\],name_converted\\[lte\\],name_converted\\[ne\\].*\\}$"}, "hydra:variableRepresentation": {"pattern": "^BasicRepresentation$"}, "hydra:mapping": { "type": "array", @@ -491,8 +491,8 @@ Feature: Range filter on collections "required": ["@type", "variable", "property", "required"], "additionalProperties": false }, - "minItems": 8, - "maxItems": 8, + "minItems": 9, + "maxItems": 9, "uniqueItems": true } }, diff --git a/features/main/crud.feature b/features/main/crud.feature index eb829488659..65c855ccd11 100644 --- a/features/main/crud.feature +++ b/features/main/crud.feature @@ -144,7 +144,7 @@ Feature: Create-Retrieve-Update-Delete "hydra:totalItems": 1, "hydra:search": { "@type": "hydra:IriTemplate", - "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],exists[relatedDummies],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[]}", + "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],exists[relatedDummies],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],dummyFloat[ne],dummyPrice[between],dummyPrice[gt],dummyPrice[gte],dummyPrice[lt],dummyPrice[lte],dummyPrice[ne],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[]}", "hydra:variableRepresentation": "BasicRepresentation", "hydra:mapping": [ { @@ -333,6 +333,12 @@ Feature: Create-Retrieve-Update-Delete "property": "dummyFloat", "required": false }, + { + "@type": "IriTemplateMapping", + "variable": "dummyFloat[ne]", + "property": "dummyFloat", + "required": false + }, { "@type": "IriTemplateMapping", "variable": "dummyPrice[between]", @@ -363,6 +369,12 @@ Feature: Create-Retrieve-Update-Delete "property": "dummyPrice", "required": false }, + { + "@type": "IriTemplateMapping", + "variable": "dummyPrice[ne]", + "property": "dummyPrice", + "required": false + }, { "@type": "IriTemplateMapping", "variable": "id", From f566882fc01126684bb7f48dc971ed48cb33d8cf Mon Sep 17 00:00:00 2001 From: divine <48183131+divine@users.noreply.github.com> Date: Thu, 5 May 2022 05:43:38 +0300 Subject: [PATCH 4/4] feat: add not equal range filter test --- features/doctrine/range_filter.feature | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/features/doctrine/range_filter.feature b/features/doctrine/range_filter.feature index b5e79f4f625..2e3ccce8b1b 100644 --- a/features/doctrine/range_filter.feature +++ b/features/doctrine/range_filter.feature @@ -396,6 +396,49 @@ Feature: Range filter on collections } """ + Scenario: Filter for entities by range (not equal to) + When I send a "GET" request to "/dummies?dummyPrice[ne]=12.99" + Then the response status code should be 200 + And the response should be in JSON + And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8" + And the JSON should be valid according to this schema: + """ + { + "type": "object", + "properties": { + "@context": {"pattern": "^/contexts/Dummy$"}, + "@id": {"pattern": "^/dummies$"}, + "@type": {"pattern": "^hydra:Collection$"}, + "hydra:member": { + "type": "array", + "items": { + "type": "object", + "properties": { + "@id": { + "oneOf": [ + {"pattern": "^/dummies/1$"}, + {"pattern": "^/dummies/3$"}, + {"pattern": "^/dummies/4$"} + ] + } + } + }, + "minItems": 3, + "maxItems": 3, + "uniqueItems": true + }, + "hydra:totalItems": {"type": "number", "minimum": 22, "maximum": 22}, + "hydra:view": { + "type": "object", + "properties": { + "@id": {"pattern": "^/dummies\\?dummyPrice%5Bne%5D=12.99"}, + "@type": {"pattern": "^hydra:PartialCollectionView$"} + } + } + } + } + """ + Scenario: Filter for entities within an impossible range When I send a "GET" request to "/dummies?dummyPrice[gt]=19.99" Then the response status code should be 200