diff --git a/.travis.yml b/.travis.yml index 6972a30a6..709e50500 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,25 +15,18 @@ matrix: fast_finish: true include: # Minimum supported dependencies with min and max PHP version - - php: 5.6 - env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" - - php: 7.2 - env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" - - php: 7.3 + - php: 7.1 env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" # Latest supported dependencies with each PHP version - - php: 5.6 - - php: 7.0 - php: 7.1 - php: 7.2 - env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-clover=coverage.clover" - php: 7.3 env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-clover=coverage.clover" # Install all SF components in the same major version, see https://github.com/dunglas/symfony-lock - - php: 7.2 - env: SYMFONY_VERSION="^3" + - php: 7.3 + env: SYMFONY_VERSION="^4" before_install: - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi @@ -51,9 +44,6 @@ install: before_script: - phpenv config-add .travis/php.ini - - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; - - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then composer require --dev --no-update doctrine/mongodb-odm=^1; fi; - - if [ "$TRAVIS_PHP_VERSION" = "7.0" ]; then echo "extension = mongodb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then echo "extension = mongodb.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; script: diff --git a/CHANGELOG-5.1.md b/CHANGELOG-5.1.md new file mode 100644 index 000000000..71806bf1c --- /dev/null +++ b/CHANGELOG-5.1.md @@ -0,0 +1,9 @@ +CHANGELOG for 5.1.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 5.1 versions. + +### 5.1.0 (2019-xx-xx) + +* Added compatibility with Symfony 4.2. diff --git a/README.md b/README.md index 6cd94259f..37b6832e7 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,10 @@ The following table shows the compatibilities of different versions of the bundl | FOSElasticaBundle | Elastica | Elasticsearch | Symfony | PHP | | --------------------------------------------------------------------------------------- | ---------| ------------- | ---------- | ----- | -| [5.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/tree/master) | ^5.2\|^6 | 5.\*\|6.\* | ^3.2\|^4 | >=5.6 | -| [4.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/tree/4.x) (unmaintained) | 3.2.\* | 2.\* | ^2.8\|^3.2 | >=5.5 | -| [3.2.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/tree/3.2.x) (unmaintained)| ^2.1 | 1.\* | ^2.3\|^3 | >=5.3 | +| [5.1] (master) | ^5.3\|^6 | 5.\*\|6.\* | ^3.4\|^4 | >=7.1 | +| [5.0] (unmaintained) | ^5.2\|^6 | 5.\*\|6.\* | ^3.2\|^4 | >=5.6 | +| [4.x] (unmaintained) | 3.2.\* | 2.\* | ^2.8\|^3.2 | >=5.5 | +| [3.2.x] (unmaintained) | ^2.1 | 1.\* | ^2.3\|^3 | >=5.3 | License ------- diff --git a/composer.json b/composer.json index 5ba1b9a1b..5535a3591 100644 --- a/composer.json +++ b/composer.json @@ -12,30 +12,30 @@ { "name": "Jeremy Mikola", "email": "jmikola@gmail.com" } ], "require": { - "php": "^5.6.0|^7.0", - "symfony/framework-bundle": "^3.2|^4", - "symfony/console": "^3.2|^4", - "symfony/dependency-injection": "^3.3|^4", - "symfony/property-access": "^3.2|^4", + "php": "^7.1", + "symfony/framework-bundle": "^3.4|^4", + "symfony/console": "^3.4|^4", + "symfony/dependency-injection": "^3.4|^4", + "symfony/property-access": "^3.4|^4", "pagerfanta/pagerfanta": "^1.0.5|^2.0", "psr/log": "^1.0", - "ruflin/elastica": "^5.2.1|^6.0" + "ruflin/elastica": "^5.3|^6.1" }, "require-dev": { "doctrine/orm": "^2.5", "doctrine/doctrine-bundle": "^1.6", - "doctrine/phpcr-bundle": "^1.3", + "doctrine/phpcr-bundle": "^1.3|^2.0", "doctrine/phpcr-odm": "^1.4", "jackalope/jackalope-doctrine-dbal": "^1.2", "jms/serializer-bundle": "^2.2", "phpunit/phpunit": "^5.7.11|^6.5", "knplabs/knp-components": "^1.2", - "symfony/expression-language" : "^3.2|^4", - "symfony/twig-bundle": "^3.2|^4", - "symfony/serializer": "^3.2|^4", - "symfony/yaml": "^3.2|^4", + "symfony/expression-language" : "^3.4|^4", + "symfony/twig-bundle": "^3.4|^4", + "symfony/serializer": "^3.4|^4", + "symfony/yaml": "^3.4|^4", "friendsofphp/php-cs-fixer": "^2.2", - "symfony/web-profiler-bundle": "^3.0|^4.0", + "symfony/web-profiler-bundle": "^3.4|^4.0" "phpdocumentor/type-resolver": "~0.2.1" }, "suggest": { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 0cb6d9d14..519174e4b 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -78,8 +78,7 @@ public function getConfigTreeBuilder() */ public function getDynamicTemplateNode() { - $builder = new TreeBuilder(); - $node = $builder->root('dynamic_templates'); + $node = $this->createTreeBuilderNode('dynamic_templates'); $node ->prototype('array') @@ -109,8 +108,7 @@ public function getDynamicTemplateNode() */ protected function getTypesNode() { - $builder = new TreeBuilder(); - $node = $builder->root('types'); + $node = $this->createTreeBuilderNode('types'); $node ->useAttributeAsKey('name') @@ -169,8 +167,7 @@ protected function getTypesNode() */ protected function getPropertiesNode() { - $builder = new TreeBuilder(); - $node = $builder->root('properties'); + $node = $this->createTreeBuilderNode('properties'); $node ->useAttributeAsKey('name') @@ -185,8 +182,7 @@ protected function getPropertiesNode() */ protected function getIdNode() { - $builder = new TreeBuilder(); - $node = $builder->root('_id'); + $node = $this->createTreeBuilderNode('_id'); $node ->children() @@ -202,8 +198,7 @@ protected function getIdNode() */ protected function getSourceNode() { - $builder = new TreeBuilder(); - $node = $builder->root('_source'); + $node = $this->createTreeBuilderNode('_source'); $node ->children() @@ -229,8 +224,7 @@ protected function getSourceNode() */ protected function getRoutingNode() { - $builder = new TreeBuilder(); - $node = $builder->root('_routing'); + $node = $this->createTreeBuilderNode('_routing'); $node ->children() @@ -247,8 +241,7 @@ protected function getRoutingNode() */ protected function getParentNode() { - $builder = new TreeBuilder(); - $node = $builder->root('_parent'); + $node = $this->createTreeBuilderNode('_parent'); $node ->children() @@ -266,8 +259,7 @@ protected function getParentNode() */ protected function getAllNode() { - $builder = new TreeBuilder(); - $node = $builder->root('_all'); + $node = $this->createTreeBuilderNode('_all'); $node ->children() @@ -284,8 +276,7 @@ protected function getAllNode() */ protected function getPersistenceNode() { - $builder = new TreeBuilder(); - $node = $builder->root('persistence'); + $node = $this->createTreeBuilderNode('persistence'); $node ->validate() @@ -388,8 +379,7 @@ protected function getPersistenceNode() */ protected function getSerializerNode() { - $builder = new TreeBuilder(); - $node = $builder->root('serializer'); + $node = $this->createTreeBuilderNode('serializer'); $node ->addDefaultsIfNotSet() @@ -540,6 +530,23 @@ private function addIndexesSection(ArrayNodeDefinition $rootNode) ; } + /** + * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition + */ + private function createTreeBuilderNode($name) + { + $builder = new TreeBuilder($name); + + if (method_exists($builder, 'getRootNode')) { + $node = $builder->getRootNode(); + } else { + // BC layer for symfony/config 4.1 and older + $node = $builder->root($name); + } + + return $node; + } + /** * Adds the configuration for the "index_templates" key. * diff --git a/src/Transformer/AbstractElasticaToModelTransformer.php b/src/Transformer/AbstractElasticaToModelTransformer.php index 6f3103ca1..c811bce27 100644 --- a/src/Transformer/AbstractElasticaToModelTransformer.php +++ b/src/Transformer/AbstractElasticaToModelTransformer.php @@ -31,22 +31,4 @@ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor) { $this->propertyAccessor = $propertyAccessor; } - - /** - * Returns a sorting closure to be used with usort() to put retrieved objects - * back in the order that they were returned by ElasticSearch. - * - * @param array $idPos - * @param string $identifierPath - * - * @return callable - */ - protected function getSortingClosure(array $idPos, $identifierPath) - { - $propertyAccessor = $this->propertyAccessor; - - return function ($a, $b) use ($idPos, $identifierPath, $propertyAccessor) { - return $idPos[(string) $propertyAccessor->getValue($a, $identifierPath)] > $idPos[(string) $propertyAccessor->getValue($b, $identifierPath)]; - }; - } } diff --git a/tests/Functional/TypeObj.php b/tests/Functional/TypeObj.php index b047604b5..4daec76ae 100644 --- a/tests/Functional/TypeObj.php +++ b/tests/Functional/TypeObj.php @@ -9,15 +9,6 @@ * file that was distributed with this source code. */ -/** - * This file is part of the FOSElasticaBundle project. - * - * (c) Infinite Networks Pty Ltd - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace FOS\ElasticaBundle\Tests\Functional; class TypeObj diff --git a/tests/Functional/TypeObject.php b/tests/Functional/TypeObject.php index 02ae9538a..b663d12f0 100644 --- a/tests/Functional/TypeObject.php +++ b/tests/Functional/TypeObject.php @@ -9,15 +9,6 @@ * file that was distributed with this source code. */ -/** - * This file is part of the FOSElasticaBundle project. - * - * (c) Infinite Networks Pty Ltd - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace FOS\ElasticaBundle\Tests\Functional; class TypeObject diff --git a/tests/Functional/app/ORM/IndexableService.php b/tests/Functional/app/ORM/IndexableService.php index 5aecf0c50..cef885c11 100644 --- a/tests/Functional/app/ORM/IndexableService.php +++ b/tests/Functional/app/ORM/IndexableService.php @@ -9,15 +9,6 @@ * file that was distributed with this source code. */ -/** - * This file is part of the FOSElasticaBundle project. - * - * (c) Infinite Networks Pty Ltd - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace FOS\ElasticaBundle\Tests\Functional\app\ORM; class IndexableService diff --git a/tests/Unit/DataCollector/ElasticaDataCollectorTest.php b/tests/Unit/DataCollector/ElasticaDataCollectorTest.php index 79ba03500..f288f9370 100644 --- a/tests/Unit/DataCollector/ElasticaDataCollectorTest.php +++ b/tests/Unit/DataCollector/ElasticaDataCollectorTest.php @@ -13,14 +13,14 @@ use FOS\ElasticaBundle\DataCollector\ElasticaDataCollector; use FOS\ElasticaBundle\Logger\ElasticaLogger; -use PHPUnit\Framework\TestCase; +use FOS\ElasticaBundle\Tests\Unit\UnitTestHelper; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * @author Richard Miller */ -class ElasticaDataCollectorTest extends TestCase +class ElasticaDataCollectorTest extends UnitTestHelper { public function testCorrectAmountOfQueries() { @@ -103,4 +103,17 @@ public function testName() $this->assertSame('elastica', $elasticaDataCollector->getName()); } + + public function testReset() + { + /** @var $loggerMock \PHPUnit_Framework_MockObject_MockObject|ElasticaLogger */ + $loggerMock = $this->createMock(ElasticaLogger::class); + $loggerMock->expects($this->once()) + ->method('reset') + ->willReturn('foo'); + + $elasticaDataCollector = new ElasticaDataCollector($loggerMock); + $elasticaDataCollector->reset(); + $this->assertSame([], $this->getProtectedProperty($elasticaDataCollector, 'data')); + } } diff --git a/tests/Unit/Event/IndexEventTest.php b/tests/Unit/Event/IndexEventTest.php new file mode 100644 index 000000000..f22d4e9ed --- /dev/null +++ b/tests/Unit/Event/IndexEventTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Event\IndexEvent; +use PHPUnit\Framework\TestCase; + +class IndexEventTest extends TestCase +{ + /** + * @var IndexEvent + */ + private $event; + + protected function setUp() + { + $this->event = new IndexEvent('index'); + } + + public function testIndex() + { + $this->assertEquals('index', $this->event->getIndex()); + } +} diff --git a/tests/Unit/Event/IndexPopulateEventTest.php b/tests/Unit/Event/IndexPopulateEventTest.php new file mode 100644 index 000000000..c400800f4 --- /dev/null +++ b/tests/Unit/Event/IndexPopulateEventTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Event\IndexPopulateEvent; +use PHPUnit\Framework\TestCase; + +class IndexPopulateEventTest extends TestCase +{ + /** + * @var IndexPopulateEvent + */ + private $event; + + protected function setUp() + { + $this->event = new IndexPopulateEvent('index', false, []); + } + + public function testReset() + { + $this->assertFalse($this->event->isReset()); + $this->event->setReset(true); + $this->assertTrue($this->event->isReset()); + } + + public function testOptions() + { + $this->event->setOption('name', 'value'); + $this->assertEquals(['name' => 'value'], $this->event->getOptions()); + } + + public function testOptionValid() + { + $this->event->setOption('name', 'value'); + $this->assertEquals('value', $this->event->getOption('name')); + } + + public function testOptionInvalid() + { + $this->expectException(\InvalidArgumentException::class); + $this->event->getOption('name'); + $this->event->setOption('name', 'value'); + $this->assertEquals('value', $this->event->getOption('name')); + } +} diff --git a/tests/Unit/Event/IndexResetEventTest.php b/tests/Unit/Event/IndexResetEventTest.php new file mode 100644 index 000000000..5dfac08c0 --- /dev/null +++ b/tests/Unit/Event/IndexResetEventTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Event\IndexResetEvent; +use PHPUnit\Framework\TestCase; + +class IndexResetEventTest extends TestCase +{ + public function testForce() + { + $event = new IndexResetEvent('index', false, true); + $this->assertTrue($event->isForce()); + + $event = new IndexResetEvent('index', false, false); + $this->assertFalse($event->isForce()); + + $event->setForce(true); + $this->assertTrue($event->isForce()); + } + + public function testPopulating() + { + $event = new IndexResetEvent('index', true, false); + $this->assertTrue($event->isPopulating()); + + $event = new IndexResetEvent('index', false, false); + $this->assertFalse($event->isPopulating()); + } +} diff --git a/tests/Unit/Event/TransformEventTest.php b/tests/Unit/Event/TransformEventTest.php new file mode 100644 index 000000000..5aae506c8 --- /dev/null +++ b/tests/Unit/Event/TransformEventTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use Elastica\Document; +use FOS\ElasticaBundle\Event\TransformEvent; +use PHPUnit\Framework\TestCase; + +class TransformEventTest extends TestCase +{ + /** + * @var TransformEvent + */ + private $event; + + protected function setUp() + { + $document = new Document(); + $object = (object) []; + $this->event = new TransformEvent($document, [], $object); + } + + public function testDocument() + { + $this->assertNotNull($this->event->getDocument()); + $document = new Document(); + $this->event->setDocument($document); + $this->assertEquals($document, $this->event->getDocument()); + } + + public function testFields() + { + $document = new Document(); + $object = (object) []; + $fields = ['abc', '123']; + $event = new TransformEvent($document, $fields, $object); + $this->assertEquals($fields, $event->getFields()); + } + + public function testObject() + { + $document = new Document(); + $object = (object) ['abc', '123']; + $event = new TransformEvent($document, [], $object); + $this->assertEquals($object, $event->getObject()); + } +} diff --git a/tests/Unit/Event/TypePopulateEventTest.php b/tests/Unit/Event/TypePopulateEventTest.php new file mode 100644 index 000000000..d8536a62f --- /dev/null +++ b/tests/Unit/Event/TypePopulateEventTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Event\TypePopulateEvent; +use PHPUnit\Framework\TestCase; + +class TypePopulateEventTest extends TestCase +{ + public function testType() + { + $event = new TypePopulateEvent('index', 'type', false, []); + $this->assertEquals('type', $event->getType()); + } +} diff --git a/tests/Unit/Event/TypeResetEventTest.php b/tests/Unit/Event/TypeResetEventTest.php new file mode 100644 index 000000000..197a38d26 --- /dev/null +++ b/tests/Unit/Event/TypeResetEventTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Event\TypeResetEvent; +use PHPUnit\Framework\TestCase; + +class TypeResetEventTest extends TestCase +{ + public function testType() + { + $event = new TypeResetEvent('index', 'type'); + $this->assertEquals('type', $event->getType()); + } +} diff --git a/tests/Unit/EventListener/PopulateListenerTest.php b/tests/Unit/EventListener/PopulateListenerTest.php new file mode 100644 index 000000000..f5260d6c8 --- /dev/null +++ b/tests/Unit/EventListener/PopulateListenerTest.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\EventListener\PopulateListener; +use FOS\ElasticaBundle\Event\IndexPopulateEvent; +use FOS\ElasticaBundle\Index\Resetter; +use PHPUnit\Framework\TestCase; + +class PopulateListenerTest extends TestCase +{ + private function mockResetter($numberOfCalls, $indexName, $deleteOption) + { + $stub = $this + ->getMockBuilder(Resetter::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $stub + ->expects($this->exactly($numberOfCalls)) + ->method('switchIndexAlias') + ->with($indexName, $deleteOption); + + return $stub; + } + + public function testOnPostIndexPopulateWithReset() + { + $indexName = 'index'; + $deleteOption = true; + + $stub = $this->mockResetter(1, $indexName, $deleteOption); + $listener = new PopulateListener($stub); + + $event = new IndexPopulateEvent($indexName, true, ['delete' => $deleteOption]); + $listener->onPostIndexPopulate($event); + } + + public function testOnPostIndexPopulateWithoutReset() + { + $indexName = 'index'; + $deleteOption = true; + + $stub = $this->mockResetter(0, $indexName, $deleteOption); + $listener = new PopulateListener($stub); + + $event = new IndexPopulateEvent($indexName, false, ['delete' => $deleteOption]); + $listener->onPostIndexPopulate($event); + } +} diff --git a/tests/Unit/Exception/AliasIsIndexExceptionTest.php b/tests/Unit/Exception/AliasIsIndexExceptionTest.php new file mode 100644 index 000000000..6eaf30d49 --- /dev/null +++ b/tests/Unit/Exception/AliasIsIndexExceptionTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Exception\AliasIsIndexException; +use PHPUnit\Framework\TestCase; + +class AliasIsIndexExceptionTest extends TestCase +{ + public function testConstruct() + { + $exception = new AliasIsIndexException('indexName'); + } +} diff --git a/tests/Unit/Exception/InvalidArgumentTypeExceptionTest.php b/tests/Unit/Exception/InvalidArgumentTypeExceptionTest.php new file mode 100644 index 000000000..6aecdc800 --- /dev/null +++ b/tests/Unit/Exception/InvalidArgumentTypeExceptionTest.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException; +use PHPUnit\Framework\TestCase; + +class InvalidArgumentTypeExceptionTest extends TestCase +{ + public function testConstruct() + { + $exception = new InvalidArgumentTypeException('value', 'expectedType'); + } +} diff --git a/tests/Unit/Paginator/FantaPaginatorAdapterTest.php b/tests/Unit/Paginator/FantaPaginatorAdapterTest.php new file mode 100644 index 000000000..36d954731 --- /dev/null +++ b/tests/Unit/Paginator/FantaPaginatorAdapterTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter; +use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface; +use FOS\ElasticaBundle\Paginator\PartialResultsInterface; +use PHPUnit\Framework\TestCase; + +class FantaPaginatorAdapterTest extends TestCase +{ + private function mockPartialResults($results) + { + $mock = $this + ->getMockBuilder(PartialResultsInterface::class) + ->getMock(); + $mock + ->expects($this->exactly(1)) + ->method('toArray') + ->willReturn($results); + return $mock; + } + + private function mockPaginatorAdapter() + { + $mock = $this + ->getMockBuilder(PaginatorAdapterInterface::class) + ->getMock(); + return $mock; + } + + public function testGetNbResults() + { + $mock = $this->mockPaginatorAdapter(); + $mock + ->expects($this->exactly(1)) + ->method('getTotalHits') + ->willReturn(123); + $adapter = new FantaPaginatorAdapter($mock); + $this->assertEquals(123, $adapter->getNbResults()); + } + + public function testGetAggregations() + { + $mock = $this->mockPaginatorAdapter(); + $mock + ->expects($this->exactly(1)) + ->method('getAggregations') + ->willReturn([]); + $adapter = new FantaPaginatorAdapter($mock); + $this->assertEquals([], $adapter->getAggregations()); + } + + public function testGetSuggests() + { + $mock = $this->mockPaginatorAdapter(); + $mock + ->expects($this->exactly(1)) + ->method('getSuggests') + ->willReturn([]); + $adapter = new FantaPaginatorAdapter($mock); + $this->assertEquals([], $adapter->getSuggests()); + } + + public function testGetGetSlice() + { + $results = []; + $resultsMock = $this->mockPartialResults($results); + + $mock = $this->mockPaginatorAdapter(); + $mock + ->expects($this->exactly(1)) + ->method('getResults') + ->with(1, 10) + ->willReturn($resultsMock); + $adapter = new FantaPaginatorAdapter($mock); + $this->assertEquals($results, $adapter->getSlice(1, 10)); + } + + public function testGetMaxScore() + { + $mock = $this->mockPaginatorAdapter(); + $mock + ->expects($this->exactly(1)) + ->method('getMaxScore') + ->willReturn(123); + $adapter = new FantaPaginatorAdapter($mock); + $this->assertEquals(123, $adapter->getMaxScore()); + } +} diff --git a/tests/Unit/Paginator/RawPaginatorAdapterTest.php b/tests/Unit/Paginator/RawPaginatorAdapterTest.php new file mode 100644 index 000000000..13e3e2893 --- /dev/null +++ b/tests/Unit/Paginator/RawPaginatorAdapterTest.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Event; + +use FOS\ElasticaBundle\Paginator\RawPaginatorAdapter; +use Elastica\Query; +use Elastica\ResultSet; +use Elastica\SearchableInterface; +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; + +class RawPaginatorAdapterTest extends TestCase +{ + private function mockResultSet() + { + $methods = ['getTotalHits', 'getAggregations', 'getSuggests', 'getMaxScore']; + $mock = $this + ->getMockBuilder(ResultSet::class) + ->disableOriginalConstructor() + ->setMethods($methods) + ->getMock(); + return $mock; + } + + private function mockSearchable() + { + $mock = $this + ->getMockBuilder(SearchableInterface::class) + ->getMock(); + return $mock; + } + + private function createAdapterWithSearch($methodName, $value) + { + $resultSet = $this->mockResultSet(); + $resultSet + ->expects($this->exactly(1)) + ->method($methodName) + ->willReturn($value); + + $query = new Query(); + $options = []; + $searchable = $this->mockSearchable(); + $searchable + ->expects($this->exactly(1)) + ->method('search') + ->with($query) + ->willReturn($resultSet); + + $adapter = new RawPaginatorAdapter($searchable, $query, $options); + return $adapter; + } + + private function createAdapterWithCount($totalHits, $querySize = null) + { + $query = new Query(); + if ($querySize) { + $query->setParam('size', $querySize); + } + $options = []; + $searchable = $this->mockSearchable(); + $searchable + ->expects($this->exactly(1)) + ->method('count') + ->willReturn($totalHits); + + $adapter = new RawPaginatorAdapter($searchable, $query, $options); + return $adapter; + } + + public function testGetTotalHits() + { + $adapter = $this->createAdapterWithCount(123); + $this->assertEquals(123, $adapter->getTotalHits()); + + $adapter = $this->createAdapterWithCount(123, 100); + $this->assertEquals(100, $adapter->getTotalHits()); + } + + public function testGetTotalHitsGenuineTotal() + { + $adapter = $this->createAdapterWithCount(123); + $this->assertEquals(123, $adapter->getTotalHits(true)); + + $adapter = $this->createAdapterWithCount(123, 100); + $this->assertEquals(123, $adapter->getTotalHits(true)); + } + + public function testGetAggregations() + { + $value = []; + $adapter = $this->createAdapterWithSearch('getAggregations', $value); + $this->assertEquals($value, $adapter->getAggregations()); + } + + public function testGetSuggests() + { + $value = []; + $adapter = $this->createAdapterWithSearch('getSuggests', $value); + $this->assertEquals($value, $adapter->getSuggests()); + } + + public function testGetMaxScore() + { + $value = 1.0; + $adapter = $this->createAdapterWithSearch('getMaxScore', $value); + $this->assertEquals($value, $adapter->getMaxScore()); + } + + public function testGetQuery() + { + $resultSet = $this->mockResultSet(); + + $query = new Query(); + $options = []; + $searchable = $this->mockSearchable($query); + + $adapter = new RawPaginatorAdapter($searchable, $query, $options); + $this->assertEquals($query, $adapter->getQuery()); + } +} diff --git a/tests/Unit/Provider/IndexableTest.php b/tests/Unit/Provider/IndexableTest.php index 5aac883bd..99f241936 100644 --- a/tests/Unit/Provider/IndexableTest.php +++ b/tests/Unit/Provider/IndexableTest.php @@ -9,15 +9,6 @@ * file that was distributed with this source code. */ -/** - * This file is part of the FOSElasticaBundle project. - * - * (c) Infinite Networks Pty Ltd - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace FOS\ElasticaBundle\Tests\Unit\Provider; use FOS\ElasticaBundle\Provider\Indexable; diff --git a/tests/Unit/Provider/PagerProviderRegistryTest.php b/tests/Unit/Provider/PagerProviderRegistryTest.php new file mode 100644 index 000000000..70a08fe65 --- /dev/null +++ b/tests/Unit/Provider/PagerProviderRegistryTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Provider; + +use FOS\ElasticaBundle\Provider\PagerProviderRegistry; +use Symfony\Component\DependencyInjection\Container; +use PHPUnit\Framework\TestCase; + +class PagerProviderRegistryTest extends TestCase +{ + protected function mockPagerProviderRegistry(array $providers, $service = null) + { + $container = new Container(); + $container->set('the_service_id', $service); + + $registry = new PagerProviderRegistry($providers); + $registry->setContainer($container); + return $registry; + } + + public function testGetAllProviders() + { + $providers = [ + 'index' => [ + 'type' => 'the_service_id', + ], + ]; + $service = new \stdClass(); + $registry = $this->mockPagerProviderRegistry($providers, $service); + $this->assertEquals(['index/type' => $service], $registry->getAllProviders('index', 'type')); + } + + public function testGetIndexProvidersValid() + { + $providers = [ + 'index' => [ + 'type' => 'the_service_id', + ], + ]; + $service = new \stdClass(); + $registry = $this->mockPagerProviderRegistry($providers, $service); + $this->assertEquals(['type' => $service], $registry->getIndexProviders('index', 'type')); + } + + public function testGetIndexProvidersInvalid() + { + $registry = $this->mockPagerProviderRegistry([]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('No providers were registered for index "index".'); + $registry->getIndexProviders('index'); + } + + public function testGetProviderValid() + { + $providers = [ + 'index' => [ + 'type' => 'the_service_id', + ], + ]; + $service = new \stdClass(); + $registry = $this->mockPagerProviderRegistry($providers, $service); + $this->assertEquals($service, $registry->getProvider('index', 'type')); + } + + public function testGetProviderInvalid() + { + $registry = $this->mockPagerProviderRegistry([]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('No provider was registered for index "index" and type "type".'); + $registry->getProvider('index', 'type'); + } +} diff --git a/tests/Unit/RepositoryTest.php b/tests/Unit/RepositoryTest.php index 93601bdf5..163911b46 100644 --- a/tests/Unit/RepositoryTest.php +++ b/tests/Unit/RepositoryTest.php @@ -20,59 +20,67 @@ */ class RepositoryTest extends TestCase { - public function testThatFindCallsFindOnFinder() + public function testFind() { $testQuery = 'Test Query'; - $finderMock = $this->getFinderMock($testQuery); + $finderMock = $this->mockTransformedFinder('find', [$testQuery]); $repository = new Repository($finderMock); $repository->find($testQuery); } - public function testThatFindCallsFindOnFinderWithLimit() + public function testFindWithLimit() { $testQuery = 'Test Query'; $testLimit = 20; - $finderMock = $this->getFinderMock($testQuery, $testLimit); + $finderMock = $this->mockTransformedFinder('find', [$testQuery, $testLimit]); $repository = new Repository($finderMock); $repository->find($testQuery, $testLimit); } - public function testThatFindPaginatedCallsFindPaginatedOnFinder() + public function testFindPaginated() { $testQuery = 'Test Query'; - $finderMock = $this->getFinderMock($testQuery, [], 'findPaginated'); + $finderMock = $this->mockTransformedFinder('findPaginated', [$testQuery, []]); $repository = new Repository($finderMock); $repository->findPaginated($testQuery); } - public function testThatCreatePaginatorCreatesAPaginatorViaFinder() + public function testCreatePagitatorAdapter() { $testQuery = 'Test Query'; - $finderMock = $this->getFinderMock($testQuery, [], 'createPaginatorAdapter'); + $finderMock = $this->mockTransformedFinder('createPaginatorAdapter', [$testQuery, []]); $repository = new Repository($finderMock); $repository->createPaginatorAdapter($testQuery); } - public function testThatFindHybridCallsFindHybridOnFinder() + public function testCreateHybridPaginatorAdapter() { $testQuery = 'Test Query'; - $finderMock = $this->getFinderMock($testQuery, null, 'findHybrid'); + $finderMock = $this->mockTransformedFinder('createHybridPaginatorAdapter', [$testQuery]); + $repository = new Repository($finderMock); + $repository->createHybridPaginatorAdapter($testQuery); + } + + public function testFindHybrid() + { + $testQuery = 'Test Query'; + + $finderMock = $this->mockTransformedFinder('findHybrid', [$testQuery, null, []]); $repository = new Repository($finderMock); $repository->findHybrid($testQuery); } - private function getFinderMock($testQuery, $testLimit = null, $method = 'find') + private function mockTransformedFinder($name, $arguments) { $finderMock = $this->createMock(TransformedFinder::class); $finderMock->expects($this->once()) - ->method($method) - ->with($this->equalTo($testQuery), $this->equalTo($testLimit)); - + ->method($name) + ->withConsecutive($arguments); return $finderMock; } } diff --git a/tests/Unit/Transformer/AbstractElasticaToModelTransformerTest.php b/tests/Unit/Transformer/AbstractElasticaToModelTransformerTest.php new file mode 100644 index 000000000..f9e462e26 --- /dev/null +++ b/tests/Unit/Transformer/AbstractElasticaToModelTransformerTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit\Transformer; + +use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use FOS\ElasticaBundle\Tests\Unit\UnitTestHelper; + +class AbstractElasticaToModelTransformerTest extends UnitTestHelper +{ + public function testSetPropertyAccessor() + { + $propertyAccessor = $this->mockPropertyAccesor(); + $transformer = $this->mockAbstractElasticaToModelTransformer(); + $transformer->setPropertyAccessor($propertyAccessor); + $this->assertEquals($propertyAccessor, $this->getProtectedProperty($transformer, 'propertyAccessor')); + } + + protected function mockAbstractElasticaToModelTransformer() + { + $mock = $this + ->getMockBuilder(AbstractElasticaToModelTransformer::class) + ->getMockForAbstractClass(); + return $mock; + } + + protected function mockPropertyAccesor() + { + $mock = $this->createMock(PropertyAccessorInterface::class); + return $mock; + } +} diff --git a/tests/Unit/UnitTestHelper.php b/tests/Unit/UnitTestHelper.php new file mode 100644 index 000000000..0519a9d6a --- /dev/null +++ b/tests/Unit/UnitTestHelper.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\ElasticaBundle\Tests\Unit; + +use PHPUnit\Framework\TestCase; + +class UnitTestHelper extends TestCase +{ + /** + * Gets a protected property on a given object via reflection. + * + * @param object $object instance in which protected value is being modified + * @param string $property property on instance being modified + */ + protected function getProtectedProperty($object, string $property) + { + $reflection = new \ReflectionClass($object); + $reflectionProperty = $reflection->getProperty($property); + $reflectionProperty->setAccessible(true); + + return $reflectionProperty->getValue($object); + } +}