Skip to content

Commit ef3188a

Browse files
committed
Merge branch '2.3-develop' of github.com:magento/magento2ce into EPAM-PR-7-8-10
2 parents 750628e + 7411604 commit ef3188a

File tree

8 files changed

+325
-4
lines changed

8 files changed

+325
-4
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="ChooseElasticSearchAsSearchEngine">
12+
<amOnPage url="{{AdminCatalogSearchConfigurationPage.url}}" stepKey="configureSearchEngine"/>
13+
<waitForPageLoad stepKey="waitForConfigPage"/>
14+
<scrollTo selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="scrollToCatalogSearchTab"/>
15+
<conditionalClick selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" dependentSelector="{{AdminCatalogSearchConfigurationSection.checkIfCatalogSearchTabExpand}}" visible="true" stepKey="expandCatalogSearchTab"/>
16+
<waitForElementVisible selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" stepKey="waitForDropdownToBeVisible"/>
17+
<uncheckOption selector="{{AdminCatalogSearchConfigurationSection.searchEngineDefaultSystemValue}}" stepKey="uncheckUseSystemValue"/>
18+
<selectOption selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" userInput="elasticsearch5" stepKey="chooseES5"/>
19+
<!--<scrollTo selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="scrollToCatalogSearchTab2"/>-->
20+
<!--<click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseCatalogSearchTab"/>-->
21+
<click selector="{{ContentManagementSection.Save}}" stepKey="saveConfiguration"/>
22+
<see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigurationSuccessMessage"/>
23+
</actionGroup>
24+
<actionGroup name="ResetSearchEngineConfiguration">
25+
<amOnPage url="{{AdminCatalogSearchConfigurationPage.url}}" stepKey="resetSearchEngine"/>
26+
<waitForPageLoad stepKey="waitForConfigPage2"/>
27+
<scrollTo selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="scrollToCatalogSearchTab2"/>
28+
<conditionalClick selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" dependentSelector="{{AdminCatalogSearchConfigurationSection.checkIfCatalogSearchTabExpand}}" visible="true" stepKey="expandCatalogSearchTab2"/>
29+
<waitForElementVisible selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" stepKey="waitForDropdownToBeVisible2"/>
30+
<selectOption selector="{{AdminCatalogSearchConfigurationSection.searchEngine}}" userInput="mysql" stepKey="chooseMySQL"/>
31+
<checkOption selector="{{AdminCatalogSearchConfigurationSection.searchEngineDefaultSystemValue}}" stepKey="checkUseSystemValue"/>
32+
<click selector="{{ContentManagementSection.Save}}" stepKey="saveConfiguration2"/>
33+
<see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigurationSuccessMessage2"/>
34+
</actionGroup>
35+
36+
</actionGroups>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
9+
<page name="AdminCatalogSearchConfigurationPage" url="admin/system_config/edit/section/catalog/" area="admin" module="Magento_Config">
10+
<section name="AdminCatalogSearchConfigurationSection"/>
11+
</page>
12+
</pages>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
9+
<section name="AdminCatalogSearchConfigurationSection">
10+
<element name="catalogSearchTab" type="button" selector="#catalog_search-head"/>
11+
<element name="checkIfCatalogSearchTabExpand" type="button" selector="#catalog_search-head:not(.open)"/>
12+
<element name="searchEngineDefaultSystemValue" type="checkbox" selector="#catalog_search_engine_inherit"/>
13+
<element name="searchEngine" type="select" selector="#catalog_search_engine"/>
14+
</section>
15+
</sections>

app/code/Magento/Elasticsearch/Elasticsearch5/SearchAdapter/Adapter.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
1313
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
1414
use \Magento\Elasticsearch\SearchAdapter\ResponseFactory;
15+
use Psr\Log\LoggerInterface;
1516

1617
/**
1718
* Elasticsearch Search Adapter
@@ -47,42 +48,79 @@ class Adapter implements AdapterInterface
4748
*/
4849
private $queryContainerFactory;
4950

51+
/**
52+
* Empty response from Elasticsearch.
53+
*
54+
* @var array
55+
*/
56+
private static $emptyRawResponse = [
57+
"hits" =>
58+
[
59+
"hits" => []
60+
],
61+
"aggregations" =>
62+
[
63+
"price_bucket" => [],
64+
"category_bucket" =>
65+
[
66+
"buckets" => []
67+
68+
]
69+
]
70+
];
71+
72+
/**
73+
* @var LoggerInterface
74+
*/
75+
private $logger;
76+
5077
/**
5178
* @param ConnectionManager $connectionManager
5279
* @param Mapper $mapper
5380
* @param ResponseFactory $responseFactory
5481
* @param AggregationBuilder $aggregationBuilder
5582
* @param \Magento\Elasticsearch\SearchAdapter\QueryContainerFactory $queryContainerFactory
83+
* @param LoggerInterface $logger
5684
*/
5785
public function __construct(
5886
ConnectionManager $connectionManager,
5987
Mapper $mapper,
6088
ResponseFactory $responseFactory,
6189
AggregationBuilder $aggregationBuilder,
62-
\Magento\Elasticsearch\SearchAdapter\QueryContainerFactory $queryContainerFactory
90+
\Magento\Elasticsearch\SearchAdapter\QueryContainerFactory $queryContainerFactory,
91+
LoggerInterface $logger = null
6392
) {
6493
$this->connectionManager = $connectionManager;
6594
$this->mapper = $mapper;
6695
$this->responseFactory = $responseFactory;
6796
$this->aggregationBuilder = $aggregationBuilder;
6897
$this->queryContainerFactory = $queryContainerFactory;
98+
$this->logger = $logger ?: ObjectManager::getInstance()
99+
->get(LoggerInterface::class);
69100
}
70101

71102
/**
103+
* Search query
104+
*
72105
* @param RequestInterface $request
73106
* @return QueryResponse
74107
*/
75108
public function query(RequestInterface $request)
76109
{
77110
$client = $this->connectionManager->getConnection();
78111
$aggregationBuilder = $this->aggregationBuilder;
79-
80112
$query = $this->mapper->buildQuery($request);
81113
$aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $query]));
82-
$rawResponse = $client->query($query);
83114

84-
$rawDocuments = isset($rawResponse['hits']['hits']) ? $rawResponse['hits']['hits'] : [];
115+
try {
116+
$rawResponse = $client->query($query);
117+
} catch (\Exception $e) {
118+
$this->logger->critical($e);
119+
// return empty search result in case an exception is thrown from Elasticsearch
120+
$rawResponse = self::$emptyRawResponse;
121+
}
85122

123+
$rawDocuments = isset($rawResponse['hits']['hits']) ? $rawResponse['hits']['hits'] : [];
86124
$queryResponse = $this->responseFactory->create(
87125
[
88126
'documents' => $rawDocuments,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="ProductQuickSearchUsingElasticSearchTest">
12+
<annotations>
13+
<features value="Search"/>
14+
<stories value="Quick Search of products on Storefront when ES 5.0+ is enabled"/>
15+
<title value="Product quick search doesn't throw exception after ES is chosen as search engine"/>
16+
<description value="Verify no elastic search exception is thrown when searching for product before catalogsearch reindexing"/>
17+
<severity value="CRITICAL"/>
18+
<testCaseId value="MAGETWO-94995"/>
19+
<group value="Catalog"/>
20+
</annotations>
21+
<before>
22+
<createData entity="SimpleSubCategory" stepKey="categoryFirst"/>
23+
<createData entity="SimpleProduct" stepKey="simpleProduct1">
24+
<requiredEntity createDataKey="categoryFirst"/>
25+
</createData>
26+
</before>
27+
28+
<after>
29+
<deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/>
30+
<deleteData createDataKey="categoryFirst" stepKey="deleteCategory"/>
31+
<actionGroup ref="ResetSearchEngineConfiguration" stepKey="resetCatalogSearchConfiguration"/>
32+
<actionGroup ref="updateIndexerOnSave" stepKey="resetIndexerBackToOriginalState">
33+
<argument name="indexerName" value="catalogsearch_fulltext"/>
34+
</actionGroup>
35+
<actionGroup ref="logout" stepKey="logoutOfAdmin"/>
36+
</after>
37+
38+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
39+
<comment userInput="Change Catalog search engine option to Elastic Search 5.0+" stepKey="chooseElasticSearch5"/>
40+
<actionGroup ref="ChooseElasticSearchAsSearchEngine" stepKey="chooseES5"/>
41+
<actionGroup ref="ClearPageCacheActionGroup" stepKey="clearing"/>
42+
<actionGroup ref="updateIndexerBySchedule" stepKey="updateAnIndexerBySchedule">
43+
<argument name="indexerName" value="catalogsearch_fulltext"/>
44+
</actionGroup>
45+
<actionGroup ref="logout" stepKey="logoutOfAdmin"/>
46+
<!--Navigate to storefront and do a quick search for the product -->
47+
<comment userInput="Navigate to Storefront to check if quick search works" stepKey="commentCheckQuickSearch" />
48+
<amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToHomePage"/>
49+
50+
<waitForPageLoad stepKey="waitForHomePageToLoad" time="30"/>
51+
<fillField userInput="Simple" selector="{{StorefrontQuickSearchSection.searchPhrase}}" stepKey="fillSearchBar"/>
52+
<waitForPageLoad stepKey="wait2" time="30"/>
53+
<click selector="{{StorefrontQuickSearchSection.searchButton}}" stepKey="clickSearchButton"/>
54+
<seeInCurrentUrl url="{{StorefrontCatalogSearchPage.url}}" stepKey="checkUrl"/>
55+
<seeInTitle userInput="Search results for: 'Simple'" stepKey="assertQuickSearchTitle"/>
56+
<see userInput="Search results for: 'Simple'" selector="{{StorefrontCatalogSearchMainSection.SearchTitle}}" stepKey="assertQuickSearchName"/>
57+
<comment userInput="End of searching products" stepKey="endOfSearchingProducts"/>
58+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin2"/>
59+
</test>
60+
</tests>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="updateIndexerBySchedule">
12+
<arguments>
13+
<argument name="indexerName" type="string"/>
14+
</arguments>
15+
<amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}/indexer/indexer/list/" stepKey="amOnIndexManagementPage"/>
16+
<waitForPageLoad stepKey="waitForIndexManagementPageToLoad"/>
17+
<click selector="{{AdminIndexManagementSection.indexerCheckbox(indexerName)}}" stepKey="selectIndexer1"/>
18+
<selectOption selector="{{AdminIndexManagementSection.massActionSelect}}" userInput="change_mode_changelog" stepKey="selectUpdateBySchedule"/>
19+
<click selector="{{AdminIndexManagementSection.massActionSubmit}}" stepKey="submitIndexerForm"/>
20+
<!-- No re-indexing is done as part of this actionGroup since the test required no re-indexing -->
21+
<waitForPageLoad stepKey="waitForSave"/>
22+
</actionGroup>
23+
<actionGroup name="updateIndexerOnSave">
24+
<arguments>
25+
<argument name="indexerName" type="string"/>
26+
</arguments>
27+
<amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}/indexer/indexer/list/" stepKey="amOnIndexManagementPage2"/>
28+
<waitForPageLoad stepKey="waitForIndexManagementPageToLoad2"/>
29+
<click selector="{{AdminIndexManagementSection.indexerCheckbox(indexerName)}}" stepKey="selectIndexer2"/>
30+
<selectOption selector="{{AdminIndexManagementSection.massActionSelect}}" userInput="change_mode_onthefly" stepKey="selectUpdateOnSave"/>
31+
<click selector="{{AdminIndexManagementSection.massActionSubmit}}" stepKey="submitIndexerForm2"/>
32+
<!-- No re-indexing is done as part of this actionGroup since the test required no re-indexing -->
33+
<waitForPageLoad stepKey="waitForSave2"/>
34+
35+
</actionGroup>
36+
</actionGroups>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
11+
<section name="AdminIndexManagementSection">
12+
<!--<element name="catalogSearchCheckbox" type="checkbox" selector="input[value='catalogsearch_fulltext']"/>-->
13+
<element name="indexerCheckbox" type="checkbox" selector="input[value='{{var1}}']" parameterized="true"/>
14+
<element name="massActionSelect" type="select" selector="#gridIndexer_massaction-select"/>
15+
<element name="massActionSubmit" type="button" selector="#gridIndexer_massaction-form button"/>
16+
</section>
17+
</sections>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Elasticsearch\Elasticsearch5\SearchAdapter;
9+
10+
use Magento\TestFramework\Helper\Bootstrap;
11+
12+
/**
13+
* Class AdapterTest
14+
*/
15+
class AdapterTest extends \PHPUnit\Framework\TestCase
16+
{
17+
/**
18+
* @var \Magento\Elasticsearch\Elasticsearch5\SearchAdapter\Adapter
19+
*/
20+
private $adapter;
21+
22+
/**
23+
* @var \Magento\Elasticsearch\Model\Client\Elasticsearch|\PHPUnit\Framework\MockObject\MockObject
24+
*/
25+
private $clientMock;
26+
27+
/**
28+
* @var \Magento\Framework\Search\Request\Builder
29+
*/
30+
private $requestBuilder;
31+
32+
/**
33+
* @var \Psr\Log\LoggerInterface|\PHPUnit\Framework\MockObject\MockObject
34+
*/
35+
private $loggerMock;
36+
37+
/**
38+
* @return void
39+
*/
40+
protected function setUp()
41+
{
42+
$objectManager = Bootstrap::getObjectManager();
43+
$contentManager = $this->getMockBuilder(\Magento\Elasticsearch\SearchAdapter\ConnectionManager::class)
44+
->disableOriginalConstructor()
45+
->getMock();
46+
$this->clientMock = $this->getMockBuilder(\Magento\Elasticsearch\Model\Client\Elasticsearch::class)
47+
->disableOriginalConstructor()
48+
->getMock();
49+
$contentManager
50+
->expects($this->any())
51+
->method('getConnection')
52+
->willReturn($this->clientMock);
53+
/** @var \Magento\Framework\Search\Request\Config\Converter $converter */
54+
$converter = $objectManager->create(\Magento\Framework\Search\Request\Config\Converter::class);
55+
56+
$document = new \DOMDocument();
57+
$document->load($this->getRequestConfigPath());
58+
$requestConfig = $converter->convert($document);
59+
60+
/** @var \Magento\Framework\Search\Request\Config $config */
61+
$config = $objectManager->create(\Magento\Framework\Search\Request\Config::class);
62+
$config->merge($requestConfig);
63+
64+
$this->requestBuilder = $objectManager->create(
65+
\Magento\Framework\Search\Request\Builder::class,
66+
['config' => $config]
67+
);
68+
$this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class);
69+
70+
$this->adapter = $objectManager->create(
71+
\Magento\Elasticsearch\Elasticsearch5\SearchAdapter\Adapter::class,
72+
[
73+
'connectionManager' => $contentManager,
74+
'logger' => $this->loggerMock
75+
]
76+
);
77+
}
78+
79+
/**
80+
* @magentoAppIsolation enabled
81+
* @magentoConfigFixture default/catalog/search/engine elasticsearch
82+
* @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix adaptertest
83+
* @return void
84+
*/
85+
public function testQuery()
86+
{
87+
$this->requestBuilder->bind('fulltext_search_query', 'socks');
88+
$this->requestBuilder->setRequestName('one_match');
89+
$queryRequest = $this->requestBuilder->create();
90+
$exception = new \Exception('Test Message');
91+
$this->loggerMock->expects($this->once())->method('critical')->with($exception);
92+
$this->clientMock->expects($this->once())->method('query')->willThrowException($exception);
93+
$actualResponse = $this->adapter->query($queryRequest);
94+
$this->assertEmpty($actualResponse->getAggregations()->getBuckets());
95+
$this->assertEquals(0, $actualResponse->count());
96+
}
97+
98+
/**
99+
* Get request config path
100+
*
101+
* @return string
102+
*/
103+
private function getRequestConfigPath()
104+
{
105+
return __DIR__ . '/../../_files/requests.xml';
106+
}
107+
}

0 commit comments

Comments
 (0)