272 lines
9.6 KiB
PHP
Executable File
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();
|
|
}
|
|
}
|