diff --git a/features/doctrine/range_filter.feature b/features/doctrine/range_filter.feature index 847857aeec6..9a9ec12d074 100644 --- a/features/doctrine/range_filter.feature +++ b/features/doctrine/range_filter.feature @@ -60,6 +60,51 @@ Feature: Range filter on collections } """ + @createSchema + Scenario: Get collection filtered by range (between the same values) + Given there are 30 dummy objects with dummyPrice + When I send a "GET" request to "/dummies?dummyPrice[between]=12.99..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/2$"}, + {"pattern": "^/dummies/6$"}, + {"pattern": "^/dummies/10$"} + ] + } + } + }, + "minItems": 3, + "maxItems": 3, + "uniqueItems": true + }, + "hydra:totalItems": {"type": "number", "minimum": 8, "maximum": 8}, + "hydra:view": { + "type": "object", + "properties": { + "@id": {"pattern": "^/dummies\\?dummyPrice%5Bbetween%5D=12.99..12.99"}, + "@type": {"pattern": "^hydra:PartialCollectionView$"} + } + } + } + } + """ + Scenario: Filter by range (between) with invalid format When I send a "GET" request to "/dummies?dummyPrice[between]=9.99..12.99..15.99" Then the response status code should be 200 diff --git a/src/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilter.php b/src/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilter.php index 132ca27f603..05b08692bec 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilter.php +++ b/src/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilter.php @@ -78,6 +78,11 @@ protected function addMatch(Builder $aggregationBuilder, string $field, string $ return; } + if ($rangeValue[0] === $rangeValue[1]) { + $aggregationBuilder->match()->field($matchField)->equals($rangeValue[0]); + return; + } + $aggregationBuilder->match()->field($matchField)->gte($rangeValue[0])->lte($rangeValue[1]); break; diff --git a/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php b/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php index 44e4614a03c..816cc2e3e1b 100644 --- a/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php +++ b/src/Bridge/Doctrine/Orm/Filter/RangeFilter.php @@ -85,6 +85,13 @@ protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterf return; } + if ($rangeValue[0] === $rangeValue[1]) { + $queryBuilder + ->andWhere(sprintf('%s.%s = :%s', $alias, $field, $valueParameter)) + ->setParameter($valueParameter, $rangeValue[0]); + return; + } + $queryBuilder ->andWhere(sprintf('%1$s.%2$s BETWEEN :%3$s_1 AND :%3$s_2', $alias, $field, $valueParameter)) ->setParameter(sprintf('%s_1', $valueParameter), $rangeValue[0]) diff --git a/tests/Bridge/Doctrine/Common/Filter/RangeFilterTestTrait.php b/tests/Bridge/Doctrine/Common/Filter/RangeFilterTestTrait.php index b7b43a312eb..73bab437ff9 100644 --- a/tests/Bridge/Doctrine/Common/Filter/RangeFilterTestTrait.php +++ b/tests/Bridge/Doctrine/Common/Filter/RangeFilterTestTrait.php @@ -29,6 +29,14 @@ private function provideApplyTestArguments(): array ], ], ], + 'between (same values)' => [ + null, + [ + 'dummyPrice' => [ + 'between' => '9.99..9.99', + ], + ], + ], 'between (too many operands)' => [ null, [ diff --git a/tests/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilterTest.php b/tests/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilterTest.php index 57c1d102e34..31fb18bf5ce 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilterTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/Filter/RangeFilterTest.php @@ -453,6 +453,15 @@ public function provideApplyTestData(): array ], ], ], + 'between (same values)' => [ + [ + [ + '$match' => [ + 'dummyPrice' => 9.99, + ], + ], + ], + ], 'between (too many operands)' => [ [], ], diff --git a/tests/Bridge/Doctrine/Orm/Filter/RangeFilterTest.php b/tests/Bridge/Doctrine/Orm/Filter/RangeFilterTest.php index 5c9af911412..178b379ecdb 100644 --- a/tests/Bridge/Doctrine/Orm/Filter/RangeFilterTest.php +++ b/tests/Bridge/Doctrine/Orm/Filter/RangeFilterTest.php @@ -343,6 +343,9 @@ public function provideApplyTestData(): array 'between' => [ sprintf('SELECT o FROM %s o WHERE o.dummyPrice BETWEEN :dummyPrice_p1_1 AND :dummyPrice_p1_2', Dummy::class), ], + 'between (same values)' => [ + sprintf('SELECT o FROM %s o WHERE o.dummyPrice = :dummyPrice_p1', Dummy::class), + ], 'between (too many operands)' => [ sprintf('SELECT o FROM %s o', Dummy::class), ],