From dbf44470aed45f8ccea0cc2cb261a28394b7685d Mon Sep 17 00:00:00 2001 From: JannesD Date: Thu, 10 Nov 2022 09:23:41 +0100 Subject: [PATCH] fix(metadata): check if elasticsearch is set to false by user through ApiResource (#5115) (#5177) --- ...viderResourceMetadataCollectionFactory.php | 12 ++- ...rResourceMetadataCollectionFactoryTest.php | 88 +++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 tests/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactoryTest.php diff --git a/src/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactory.php b/src/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactory.php index efc608acf93..91b79c5f037 100644 --- a/src/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactory.php +++ b/src/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactory.php @@ -16,6 +16,7 @@ use ApiPlatform\Elasticsearch\State\CollectionProvider; use ApiPlatform\Elasticsearch\State\ItemProvider; use ApiPlatform\Metadata\CollectionOperationInterface; +use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; use ApiPlatform\Util\Inflector; @@ -41,7 +42,7 @@ public function create(string $resourceClass): ResourceMetadataCollection if ($operations) { foreach ($resourceMetadata->getOperations() as $operationName => $operation) { - if ($this->hasIndices($operation->getShortName())) { + if ($this->hasIndices($operation)) { $operation = $operation->withElasticsearch(true); } @@ -59,7 +60,7 @@ public function create(string $resourceClass): ResourceMetadataCollection if ($graphQlOperations) { foreach ($graphQlOperations as $operationName => $graphQlOperation) { - if ($this->hasIndices($graphQlOperation->getShortName())) { + if ($this->hasIndices($graphQlOperation)) { $graphQlOperation = $graphQlOperation->withElasticsearch(true); } @@ -79,8 +80,13 @@ public function create(string $resourceClass): ResourceMetadataCollection return $resourceMetadataCollection; } - private function hasIndices(string $shortName): bool + private function hasIndices(Operation $operation): bool { + if (false === $operation->getElasticsearch()) { + return false; + } + + $shortName = $operation->getShortName(); $index = Inflector::tableize($shortName); try { diff --git a/tests/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactoryTest.php b/tests/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactoryTest.php new file mode 100644 index 00000000000..d741b7366a5 --- /dev/null +++ b/tests/Elasticsearch/Metadata/Resource/Factory/ElasticsearchProviderResourceMetadataCollectionFactoryTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Elasticsearch\Metadata\Resource\Factory; + +use ApiPlatform\Elasticsearch\Metadata\Resource\Factory\ElasticsearchProviderResourceMetadataCollectionFactory; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Operations; +use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; +use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; +use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Foo; +use ApiPlatform\Tests\Fixtures\TestBundle\Metadata\Get; +use Elasticsearch\Client; +use Elasticsearch\Common\Exceptions\Missing404Exception; +use Elasticsearch\Namespaces\CatNamespace; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; + +class ElasticsearchProviderResourceMetadataCollectionFactoryTest extends TestCase +{ + use ProphecyTrait; + + public function testConstruct(): void + { + self::assertInstanceOf( + ResourceMetadataCollectionFactoryInterface::class, + new ElasticsearchProviderResourceMetadataCollectionFactory( + $this->prophesize(Client::class)->reveal(), + $this->prophesize(ResourceMetadataCollectionFactoryInterface::class)->reveal() + ) + ); + } + + /** @dataProvider elasticsearchProvider */ + public function testCreate(?bool $elasticsearchFlag, int $expectedCatCallCount, ?bool $expectedResult): void + { + $get = (new Get())->withShortName('Foo')->withElasticsearch($elasticsearchFlag); + $resource = (new ApiResource())->withOperations(new Operations(['foo_get' => $get])); + $metadata = new ResourceMetadataCollection(Foo::class, [$resource]); + + $decorated = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class); + $decorated->create(Foo::class)->willReturn($metadata)->shouldBeCalled(); + + $catNamespace = $this->prophesize(CatNamespace::class); + if ($elasticsearchFlag) { + $catNamespace->indices(['index' => 'foo'])->willReturn([[ + 'health' => 'yellow', + 'status' => 'open', + 'index' => 'foo', + 'uuid' => '123456789abcdefghijklmn', + 'pri' => '5', + 'rep' => '1', + 'docs.count' => '42', + 'docs.deleted' => '0', + 'store.size' => '42kb', + 'pri.store.size' => '42kb', + ]]); + } else { + $catNamespace->indices(['index' => 'foo'])->willThrow(new Missing404Exception()); + } + + $client = $this->prophesize(Client::class); + $client->cat()->willReturn($catNamespace)->shouldBeCalledTimes($expectedCatCallCount); + + $resourceMetadataFactory = new ElasticsearchProviderResourceMetadataCollectionFactory($client->reveal(), $decorated->reveal()); + $elasticsearchResult = $resourceMetadataFactory->create(Foo::class)->getOperation('foo_get')->getElasticsearch(); + self::assertEquals($expectedResult, $elasticsearchResult); + } + + public function elasticsearchProvider(): array + { + return [ + 'elasticsearch: false' => [false, 0, false], + 'elasticsearch: null' => [null, 1, false], + 'elasticsearch: true' => [true, 1, true], + ]; + } +}