diff --git a/src/Elasticsearch/Tests/Filter/MatchFilterTest.php b/src/Elasticsearch/Tests/Filter/MatchFilterTest.php index b03b40b6764..114f5fe77f5 100644 --- a/src/Elasticsearch/Tests/Filter/MatchFilterTest.php +++ b/src/Elasticsearch/Tests/Filter/MatchFilterTest.php @@ -87,7 +87,7 @@ public function testApply(): void ); } - public function testApplyWithNestedProperty(): void + public function testApplyWithNestedArrayProperty(): void { $fooType = new Type(Type::BUILTIN_TYPE_ARRAY, false, Foo::class, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class)); $barType = new Type(Type::BUILTIN_TYPE_STRING); @@ -119,6 +119,38 @@ public function testApplyWithNestedProperty(): void ); } + public function testApplyWithNestedObjectProperty(): void + { + $fooType = new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class); + $barType = new Type(Type::BUILTIN_TYPE_STRING); + + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); + $propertyMetadataFactoryProphecy->create(Foo::class, 'foo')->willReturn((new ApiProperty())->withBuiltinTypes([$fooType]))->shouldBeCalled(); + $propertyMetadataFactoryProphecy->create(Foo::class, 'bar')->willReturn((new ApiProperty())->withBuiltinTypes([$barType]))->shouldBeCalled(); + + $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); + $resourceClassResolverProphecy->isResourceClass(Foo::class)->willReturn(true)->shouldBeCalled(); + + $nameConverterProphecy = $this->prophesize(NameConverterInterface::class); + $nameConverterProphecy->normalize('foo.bar', Foo::class, null, Argument::type('array'))->willReturn('foo.bar')->shouldBeCalled(); + $nameConverterProphecy->normalize('foo', Foo::class, null, Argument::type('array'))->willReturn('foo')->shouldBeCalled(); + + $matchFilter = new MatchFilter( + $this->prophesize(PropertyNameCollectionFactoryInterface::class)->reveal(), + $propertyMetadataFactoryProphecy->reveal(), + $resourceClassResolverProphecy->reveal(), + $this->prophesize(IriConverterInterface::class)->reveal(), + $this->prophesize(PropertyAccessorInterface::class)->reveal(), + $nameConverterProphecy->reveal(), + ['foo.bar' => null] + ); + + self::assertSame( + ['bool' => ['must' => [['nested' => ['path' => 'foo', 'query' => ['match' => ['foo.bar' => 'Krupicka']]]]]]], + $matchFilter->apply([], Foo::class, null, ['filters' => ['foo.bar' => 'Krupicka']]) + ); + } + public function testApplyWithInvalidFilters(): void { $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); diff --git a/src/Elasticsearch/Tests/Filter/TermFilterTest.php b/src/Elasticsearch/Tests/Filter/TermFilterTest.php index a73abe96b4a..34c713e042a 100644 --- a/src/Elasticsearch/Tests/Filter/TermFilterTest.php +++ b/src/Elasticsearch/Tests/Filter/TermFilterTest.php @@ -87,7 +87,7 @@ public function testApply(): void ); } - public function testApplyWithNestedProperty(): void + public function testApplyWithNestedArrayProperty(): void { $fooType = new Type(Type::BUILTIN_TYPE_ARRAY, false, Foo::class, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class)); $barType = new Type(Type::BUILTIN_TYPE_STRING); @@ -119,6 +119,38 @@ public function testApplyWithNestedProperty(): void ); } + public function testApplyWithNestedObjectProperty(): void + { + $fooType = new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class); + $barType = new Type(Type::BUILTIN_TYPE_STRING); + + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); + $propertyMetadataFactoryProphecy->create(Foo::class, 'foo')->willReturn((new ApiProperty())->withBuiltinTypes([$fooType]))->shouldBeCalled(); + $propertyMetadataFactoryProphecy->create(Foo::class, 'bar')->willReturn((new ApiProperty())->withBuiltinTypes([$barType]))->shouldBeCalled(); + + $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); + $resourceClassResolverProphecy->isResourceClass(Foo::class)->willReturn(true)->shouldBeCalled(); + + $nameConverterProphecy = $this->prophesize(NameConverterInterface::class); + $nameConverterProphecy->normalize('foo.bar', Foo::class, null, Argument::type('array'))->willReturn('foo.bar')->shouldBeCalled(); + $nameConverterProphecy->normalize('foo', Foo::class, null, Argument::type('array'))->willReturn('foo')->shouldBeCalled(); + + $termFilter = new TermFilter( + $this->prophesize(PropertyNameCollectionFactoryInterface::class)->reveal(), + $propertyMetadataFactoryProphecy->reveal(), + $resourceClassResolverProphecy->reveal(), + $this->prophesize(IriConverterInterface::class)->reveal(), + $this->prophesize(PropertyAccessorInterface::class)->reveal(), + $nameConverterProphecy->reveal(), + ['foo.bar' => null] + ); + + self::assertSame( + ['bool' => ['must' => [['nested' => ['path' => 'foo', 'query' => ['term' => ['foo.bar' => 'Krupicka']]]]]]], + $termFilter->apply([], Foo::class, null, ['filters' => ['foo.bar' => 'Krupicka']]) + ); + } + public function testApplyWithInvalidFilters(): void { $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); diff --git a/src/Elasticsearch/Tests/Util/FieldDatatypeTraitTest.php b/src/Elasticsearch/Tests/Util/FieldDatatypeTraitTest.php index 4979c983e31..452f59cc1f5 100644 --- a/src/Elasticsearch/Tests/Util/FieldDatatypeTraitTest.php +++ b/src/Elasticsearch/Tests/Util/FieldDatatypeTraitTest.php @@ -32,6 +32,16 @@ public function testGetNestedFieldPath(): void $fieldDatatype = $this->getValidFieldDatatype(); self::assertSame('foo.bar', $fieldDatatype->getNestedFieldPath(Foo::class, 'foo.bar.baz')); + self::assertSame('foo', $fieldDatatype->getNestedFieldPath(Foo::class, 'foo.baz')); + self::assertNull($fieldDatatype->getNestedFieldPath(Foo::class, 'baz')); + } + + public function testGetNestedFieldInNestedCollection(): void + { + $fieldDatatype = $this->getValidFieldDatatype(); + + self::assertSame('bar.foo', $fieldDatatype->getNestedFieldPath(Foo::class, 'bar.foo.baz')); + self::assertSame('bar', $fieldDatatype->getNestedFieldPath(Foo::class, 'bar.foo')); self::assertNull($fieldDatatype->getNestedFieldPath(Foo::class, 'baz')); } @@ -72,6 +82,7 @@ public function testIsNestedField(): void $fieldDatatype = $this->getValidFieldDatatype(); self::assertTrue($fieldDatatype->isNestedField(Foo::class, 'foo.bar.baz')); + self::assertTrue($fieldDatatype->isNestedField(Foo::class, 'foo.baz')); self::assertFalse($fieldDatatype->isNestedField(Foo::class, 'baz')); } @@ -79,10 +90,12 @@ private function getValidFieldDatatype() { $fooType = new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class); $barType = new Type(Type::BUILTIN_TYPE_ARRAY, false, Foo::class, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, Foo::class)); + $bazType = new Type(Type::BUILTIN_TYPE_STRING, false, Foo::class); $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); $propertyMetadataFactoryProphecy->create(Foo::class, 'foo')->willReturn((new ApiProperty())->withBuiltinTypes([$fooType]))->shouldBeCalled(); $propertyMetadataFactoryProphecy->create(Foo::class, 'bar')->willReturn((new ApiProperty())->withBuiltinTypes([$barType]))->shouldBeCalled(); + $propertyMetadataFactoryProphecy->create(Foo::class, 'baz')->willReturn((new ApiProperty())->withBuiltinTypes([$bazType])); $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); $resourceClassResolverProphecy->isResourceClass(Foo::class)->willReturn(true)->shouldBeCalled(); diff --git a/src/Elasticsearch/Util/FieldDatatypeTrait.php b/src/Elasticsearch/Util/FieldDatatypeTrait.php index b4a238e148d..d139d74f311 100644 --- a/src/Elasticsearch/Util/FieldDatatypeTrait.php +++ b/src/Elasticsearch/Util/FieldDatatypeTrait.php @@ -69,7 +69,7 @@ private function getNestedFieldPath(string $resourceClass, string $property): ?s ) { $nestedPath = $this->getNestedFieldPath($nextResourceClass, implode('.', $properties)); - return null === $nestedPath ? $nestedPath : "$currentProperty.$nestedPath"; + return null === $nestedPath ? $currentProperty : "$currentProperty.$nestedPath"; } if ( @@ -78,7 +78,9 @@ private function getNestedFieldPath(string $resourceClass, string $property): ?s && null !== ($className = $type->getClassName()) && $this->resourceClassResolver->isResourceClass($className) ) { - return $currentProperty; + $nestedPath = $this->getNestedFieldPath($className, implode('.', $properties)); + + return null === $nestedPath ? $currentProperty : "$currentProperty.$nestedPath"; } }