123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Elasticsearch\Model\Indexer;
- use Magento\Catalog\Model\Product\Action as ProductAction;
- use Magento\Catalog\Api\ProductRepositoryInterface;
- use Magento\CatalogInventory\Api\StockRegistryInterface;
- use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
- use Magento\CatalogSearch\Model\Indexer\Fulltext as CatalogSearchFulltextIndexer;
- use Magento\TestFramework\Helper\Bootstrap;
- use Magento\Store\Model\StoreManagerInterface;
- use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
- use Magento\Elasticsearch6\Model\Client\Elasticsearch as ElasticsearchClient;
- use Magento\Elasticsearch\Model\Config;
- use Magento\Elasticsearch\SearchAdapter\SearchIndexNameResolver;
- use Magento\Indexer\Model\Indexer;
- /**
- * Important: Please make sure that each integration test file works with unique elastic search index. In order to
- * achieve this, use @magentoConfigFixture to pass unique value for 'elasticsearch_index_prefix' for every test
- * method. E.g. '@magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest'
- *
- * @magentoDbIsolation disabled
- * @magentoDataFixture Magento/Elasticsearch/_files/indexer.php
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class IndexHandlerTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @var ProductRepositoryInterface
- */
- private $productRepository;
- /**
- * @var ElasticsearchClient
- */
- private $client;
- /**
- * @var StoreManagerInterface
- */
- private $storeManager;
- /**
- * @var int[]
- */
- private $storeIds;
- /**
- * @var string
- */
- private $entityType;
- /**
- * @var Indexer
- */
- private $indexer;
- /**
- * @var SearchIndexNameResolver
- */
- private $searchIndexNameResolver;
- /**
- * {@inheritdoc}
- */
- protected function setUp()
- {
- $connectionManager = Bootstrap::getObjectManager()->create(ConnectionManager::class);
- $this->client = $connectionManager->getConnection();
- $this->storeManager = Bootstrap::getObjectManager()->create(StoreManagerInterface::class);
- $this->storeIds = array_keys($this->storeManager->getStores());
- $clientConfig = Bootstrap::getObjectManager()->create(Config::class);
- $this->entityType = $clientConfig->getEntityType();
- $this->indexer = Bootstrap::getObjectManager()->create(Indexer::class);
- $this->indexer->load(CatalogSearchFulltextIndexer::INDEXER_ID);
- $this->indexer->reindexAll();
- $this->searchIndexNameResolver = Bootstrap::getObjectManager()->create(SearchIndexNameResolver::class);
- $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class);
- }
- /**
- * @magentoConfigFixture default/catalog/search/engine elasticsearch6
- * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest
- * @return void
- */
- public function testReindexAll(): void
- {
- $productApple = $this->productRepository->get('fulltext-1');
- foreach ($this->storeIds as $storeId) {
- $products = $this->searchByName('Apple', $storeId);
- $this->assertCount(1, $products);
- $this->assertEquals($productApple->getId(), $products[0]['_id']);
- $products = $this->searchByName('Simple Product', $storeId);
- $this->assertCount(5, $products);
- }
- }
- /**
- * @magentoAppIsolation enabled
- * @magentoConfigFixture default/catalog/search/engine elasticsearch6
- * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest
- * @return void
- */
- public function testReindexRowAfterEdit(): void
- {
- $this->storeManager->setCurrentStore('admin');
- $productApple = $this->productRepository->get('fulltext-1');
- $productApple->setName('Simple Product Cucumber');
- $this->productRepository->save($productApple);
- foreach ($this->storeIds as $storeId) {
- $products = $this->searchByName('Apple', $storeId);
- $this->assertCount(0, $products);
- $products = $this->searchByName('Cucumber', $storeId);
- $this->assertCount(1, $products);
- $this->assertEquals($productApple->getId(), $products[0]['_id']);
- $products = $this->searchByName('Simple Product', $storeId);
- $this->assertCount(5, $products);
- }
- }
- /**
- * @magentoConfigFixture default/catalog/search/engine elasticsearch6
- * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest
- * @return void
- */
- public function testReindexRowAfterMassAction(): void
- {
- $productApple = $this->productRepository->get('fulltext-1');
- $productBanana = $this->productRepository->get('fulltext-2');
- $productIds = [
- $productApple->getId(),
- $productBanana->getId(),
- ];
- $attrData = [
- 'name' => 'Simple Product Common',
- ];
- /** @var ProductAction $action */
- $action = Bootstrap::getObjectManager()->get(ProductAction::class);
- foreach ($this->storeIds as $storeId) {
- $action->updateAttributes($productIds, $attrData, $storeId);
- $products = $this->searchByName('Apple', $storeId);
- $this->assertCount(0, $products);
- $products = $this->searchByName('Banana', $storeId);
- $this->assertCount(0, $products);
- $products = $this->searchByName('Unknown', $storeId);
- $this->assertCount(0, $products);
- $products = $this->searchByName('Common', $storeId);
- $this->assertCount(2, $products);
- $products = $this->searchByName('Simple Product', $storeId);
- $this->assertCount(5, $products);
- }
- }
- /**
- * @magentoConfigFixture default/catalog/search/engine elasticsearch6
- * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest
- * @magentoAppArea adminhtml
- * @return void
- */
- public function testReindexRowAfterDelete(): void
- {
- $productBanana = $this->productRepository->get('fulltext-2');
- $this->productRepository->delete($productBanana);
- foreach ($this->storeIds as $storeId) {
- $products = $this->searchByName('Banana', $storeId);
- $this->assertEmpty($products);
- $products = $this->searchByName('Simple Product', $storeId);
- $this->assertCount(4, $products);
- }
- }
- /**
- * @magentoDbIsolation enabled
- * @magentoAppArea adminhtml
- * @magentoConfigFixture default/catalog/search/engine elasticsearch6
- * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest
- * @magentoDataFixture Magento/Elasticsearch/_files/configurable_products.php
- * @return void
- */
- public function testReindexRowAfterUpdateStockStatus(): void
- {
- foreach ($this->storeIds as $storeId) {
- $products = $this->searchByName('ProductOption1', $storeId);
- $this->assertNotEmpty($products);
- }
- $product = $this->productRepository->get('simple_10');
- /** @var StockRegistryInterface $stockRegistry */
- $stockRegistry = Bootstrap::getObjectManager()->create(StockRegistryInterface::class);
- $stockItem = $stockRegistry->getStockItem($product->getId());
- $stockItem->setIsInStock(false);
- /** @var StockItemRepositoryInterface $stockRepository */
- $stockRepository = Bootstrap::getObjectManager()->create(StockItemRepositoryInterface::class);
- $stockRepository->save($stockItem);
- foreach ($this->storeIds as $storeId) {
- $products = $this->searchByName('ProductOption1', $storeId);
- $this->assertEmpty($products);
- $products = $this->searchByName('Configurable', $storeId);
- $this->assertNotEmpty($products);
- }
- }
- /**
- * Search docs in Elasticsearch by name.
- *
- * @param string $text
- * @param int $storeId
- * @return array
- */
- private function searchByName(string $text, int $storeId): array
- {
- $index = $this->searchIndexNameResolver->getIndexName($storeId, $this->indexer->getId());
- $searchQuery = [
- 'index' => $index,
- 'type' => $this->entityType,
- 'body' => [
- 'query' => [
- 'bool' => [
- 'minimum_should_match' => 1,
- 'should' => [
- [
- 'match' => [
- 'name' => $text,
- ],
- ],
- ],
- ],
- ],
- ],
- ];
- $queryResult = $this->client->query($searchQuery);
- $products = isset($queryResult['hits']['hits']) ? $queryResult['hits']['hits'] : [];
- return $products;
- }
- }
|