magento2-docker/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Indexer/ReindexAllTest.php

272 lines
9.6 KiB
PHP
Executable File

<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Elasticsearch\Model\Indexer;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Indexer\Model\Indexer;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
use Magento\AdvancedSearch\Model\Client\ClientInterface as ElasticsearchClient;
use Magento\Elasticsearch\Model\Config;
use Magento\Elasticsearch\SearchAdapter\SearchIndexNameResolver;
use Magento\Framework\Search\EngineResolverInterface;
use Magento\TestModuleCatalogSearch\Model\SearchEngineVersionReader;
/**
* Important: Please make sure that each integration test file works with unique search index. In order to
* achieve this, use @magentoConfigFixture to pass unique value for index_prefix for every test
* method.
* E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch7_index_prefix indexerhandlertest_configurable'
*
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ReindexAllTest extends \PHPUnit\Framework\TestCase
{
/**
* @var ConnectionManager
*/
private $connectionManager;
/**
* @var ElasticsearchClient
*/
private $client;
/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var Config
*/
private $clientConfig;
/**
* @var SearchIndexNameResolver
*/
private $searchIndexNameResolver;
/**
* @var ProductRepositoryInterface
*/
private $productRepository;
protected function setUp(): void
{
$this->connectionManager = Bootstrap::getObjectManager()->create(ConnectionManager::class);
$this->client = $this->connectionManager->getConnection();
$this->storeManager = Bootstrap::getObjectManager()->create(StoreManagerInterface::class);
$this->clientConfig = Bootstrap::getObjectManager()->create(Config::class);
$this->searchIndexNameResolver = Bootstrap::getObjectManager()->create(SearchIndexNameResolver::class);
$this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class);
}
/**
* Make sure that correct engine is set
*/
protected function assertPreConditions(): void
{
$objectManager = Bootstrap::getObjectManager();
$currentEngine = $objectManager->get(EngineResolverInterface::class)->getCurrentSearchEngine();
$installedEngine = $objectManager->get(SearchEngineVersionReader::class)->getFullVersion();
$this->assertEquals(
$installedEngine,
$currentEngine,
sprintf(
'Search engine configuration "%s" is not compatible with the installed version',
$currentEngine
)
);
}
/**
* Test search of all products after full reindex
*
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_products.php
*/
public function testSearchAll()
{
$this->reindexAll();
$result = $this->searchByName('Configurable Product');
self::assertGreaterThanOrEqual(2, $result);
}
/**
* Test sorting of all products after full reindex
*
* @magentoDbIsolation enabled
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_products.php
*/
public function testSort()
{
/** @var $productFifth \Magento\Catalog\Model\Product */
$productSimple = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
$productSimple->setTypeId('simple')
->setAttributeSetId(4)
->setWebsiteIds([1])
->setName('ABC')
->setSku('abc-first-in-sort')
->setPrice(20)
->setMetaTitle('meta title')
->setMetaKeyword('meta keyword')
->setMetaDescription('meta description')
->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
->setStockData(['use_config_manage_stock' => 0])
->save();
$productConfigurableOption = $this->productRepository->get('simple_10');
$productConfigurableOption->setName('1ABC');
$this->productRepository->save($productConfigurableOption);
$this->reindexAll();
$productSimple = $this->productRepository->get('abc-first-in-sort');
$result = $this->sortByName();
$firstInSearchResults = (int) $result[0]['_id'];
$productSimpleId = (int) $productSimple->getId();
$this->assertEquals($productSimpleId, $firstInSearchResults);
}
/**
* Test sorting of products with lower and upper case names after full reindex
*
* @magentoDbIsolation enabled
* @magentoDataFixture Magento/Elasticsearch/_files/case_sensitive.php
*/
public function testSortCaseSensitive(): void
{
$productFirst = $this->productRepository->get('fulltext-1');
$productSecond = $this->productRepository->get('fulltext-2');
$productThird = $this->productRepository->get('fulltext-3');
$productFourth = $this->productRepository->get('fulltext-4');
$productFifth = $this->productRepository->get('fulltext-5');
$this->reindexAll();
$result = $this->sortByName();
$firstInSearchResults = (int) $result[0]['_id'];
$secondInSearchResults = (int) $result[1]['_id'];
$thirdInSearchResults = (int) $result[2]['_id'];
$fourthInSearchResults = (int) $result[3]['_id'];
$fifthInSearchResults = (int) $result[4]['_id'];
self::assertCount(5, $result);
self::assertEqualsCanonicalizing(
[$productFirst->getId(), $productFourth->getId()],
[$firstInSearchResults, $secondInSearchResults]
);
self::assertEqualsCanonicalizing(
[$productSecond->getId(), $productFifth->getId()],
[$thirdInSearchResults, $fourthInSearchResults]
);
self::assertEquals($productThird->getId(), $fifthInSearchResults);
}
/**
* Test search of specific product after full reindex
*
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_products.php
* @magentoDataFixture Magento/Catalog/_files/products.php
* @dataProvider searchSpecificProductDataProvider
* @param string $searchName
* @param string $sku
* @param int $expectedCount
*/
public function testSearchSpecificProduct(string $searchName, string $sku, int $expectedCount)
{
$this->reindexAll();
$result = $this->searchByName($searchName);
self::assertCount($expectedCount, $result);
$specificProduct = $this->productRepository->get($sku);
self::assertEquals($specificProduct->getId(), $result[0]['_id']);
}
public function searchSpecificProductDataProvider(): array
{
return [
'search by numeric name' => ['12345', 'configurable_12345', 1],
'search by name with diacritics' => ['Cùstöm Dèsign', 'custom-design-simple-product', 1],
];
}
/**
* @param string $text
* @return array
*/
private function searchByName($text)
{
$storeId = $this->storeManager->getDefaultStoreView()->getId();
$searchQuery = [
'index' => $this->searchIndexNameResolver->getIndexName($storeId, 'catalogsearch_fulltext'),
'type' => $this->clientConfig->getEntityType(),
'body' => [
'query' => [
'bool' => [
'minimum_should_match' => 1,
'should' => [
[
'match' => [
'name' => $text,
],
],
],
],
],
],
];
$queryResult = $this->client->query($searchQuery);
return isset($queryResult['hits']['hits']) ? $queryResult['hits']['hits'] : [];
}
/**
* @return array
*/
private function sortByName()
{
$storeId = $this->storeManager->getDefaultStoreView()->getId();
$searchQuery = [
'index' => $this->searchIndexNameResolver->getIndexName($storeId, 'catalogsearch_fulltext'),
'type' => $this->clientConfig->getEntityType(),
'body' => [
'sort' => [
'name.sort_name' => [
'order' => 'asc'
],
],
'query' => [
'bool' => [
'must' => [
[
'terms' => [
'visibility' => [2, 4],
],
],
],
],
],
],
];
$queryResult = $this->client->query($searchQuery);
return isset($queryResult['hits']['hits']) ? $queryResult['hits']['hits'] : [];
}
/**
* Make fulltext catalog search reindex
*
* @return void
*/
private function reindexAll()
{
// Perform full reindex
/** @var Indexer $indexer */
$indexer = Bootstrap::getObjectManager()->create(Indexer::class);
$indexer->load('catalogsearch_fulltext');
$indexer->reindexAll();
}
}