Skip to content

Commit 6e5e444

Browse files
committed
Merge remote-tracking branch 'l3/MC-40981' into PR-L3-20210405
2 parents 0d4507b + edb6a99 commit 6e5e444

File tree

6 files changed

+395
-6
lines changed

6 files changed

+395
-6
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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\CatalogSearch\Model\Search\Request;
9+
10+
/**
11+
* Modifies match queries
12+
*/
13+
class MatchQueriesModifier implements ModifierInterface
14+
{
15+
/**
16+
* Queries node name
17+
*/
18+
private const NODE_QUERIES = 'queries';
19+
20+
/**
21+
* Match query node name
22+
*/
23+
private const NODE_MATCH = 'match';
24+
25+
/**
26+
* Match query node field attribute name
27+
*/
28+
private const NODE_MATCH_ATTRIBUTE_FIELD = 'field';
29+
30+
/**
31+
* @var array
32+
*/
33+
private $queries;
34+
35+
/**
36+
* @param array $queries
37+
*/
38+
public function __construct(array $queries = [])
39+
{
40+
$this->queries = $queries;
41+
}
42+
43+
/**
44+
* @inheritdoc
45+
*/
46+
public function modify(array $requests): array
47+
{
48+
foreach ($requests as &$request) {
49+
foreach ($this->queries as $query => $fields) {
50+
if (!empty($request[self::NODE_QUERIES][$query][self::NODE_MATCH])) {
51+
foreach ($request[self::NODE_QUERIES][$query][self::NODE_MATCH] as $index => $match) {
52+
$field = $match[self::NODE_MATCH_ATTRIBUTE_FIELD] ?? null;
53+
if ($field !== null && isset($fields[$field])) {
54+
$request[self::NODE_QUERIES][$query][self::NODE_MATCH][$index] += $fields[$field];
55+
}
56+
}
57+
}
58+
}
59+
}
60+
return $requests;
61+
}
62+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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="StorefrontPartialWordQuickSearchStemmingTest">
12+
<annotations>
13+
<features value="Search"/>
14+
<stories value="Partial Word search using Elasticsearch"/>
15+
<title value="Partial word search should match only the documents that contain the words of a provided text, in the same order as provided"/>
16+
<description value="Partial word search should match only the documents that contain the words of a provided text, in the same order as provided"/>
17+
<severity value="AVERAGE"/>
18+
<testCaseId value="MC-41570"/>
19+
<useCaseId value="MC-40981"/>
20+
<group value="SearchEngineElasticsearch"/>
21+
</annotations>
22+
<before>
23+
<!--Create category-->
24+
<createData entity="SimpleSubCategory" stepKey="category1"/>
25+
<!--Create product1-->
26+
<createData entity="SimpleProduct" stepKey="product1">
27+
<field key="name">5127SS YALE JUNIOR KNOB ENTRANCE SET 5 PINS SATIN STAI</field>
28+
<requiredEntity createDataKey="category1"/>
29+
</createData>
30+
<!--Create product2-->
31+
<createData entity="SimpleProduct" stepKey="product2">
32+
<field key="name">5127AC YALE JUNIOR KNOB ENTRANCE SET 5 PINS ANTIQUE CO</field>
33+
<requiredEntity createDataKey="category1"/>
34+
</createData>
35+
<!--Create product3-->
36+
<createData entity="SimpleProduct" stepKey="product3">
37+
<field key="name">5127AB YALE JUNIOR KNOB ENTRANCE SET 5 PINS ANTIQUE BRASS</field>
38+
<requiredEntity createDataKey="category1"/>
39+
</createData>
40+
<!--Create product4-->
41+
<createData entity="SimpleProduct" stepKey="product4">
42+
<field key="sku">5127SS-YALE</field>
43+
<requiredEntity createDataKey="category1"/>
44+
</createData>
45+
<!--Create product5-->
46+
<createData entity="SimpleProduct" stepKey="product5">
47+
<field key="sku">5127AC-CO</field>
48+
<requiredEntity createDataKey="category1"/>
49+
</createData>
50+
<!--Create product6-->
51+
<createData entity="SimpleProduct" stepKey="product6">
52+
<field key="sku">5127AB-BRASS</field>
53+
<requiredEntity createDataKey="category1"/>
54+
</createData>
55+
</before>
56+
<after>
57+
<!--Delete category-->
58+
<deleteData createDataKey="category1" stepKey="deleteCategory"/>
59+
<!--Delete product1-->
60+
<deleteData createDataKey="product1" stepKey="deleteProduct1"/>
61+
<!--Delete product2-->
62+
<deleteData createDataKey="product2" stepKey="deleteProduct2"/>
63+
<!--Delete product3-->
64+
<deleteData createDataKey="product3" stepKey="deleteProduct3"/>
65+
<!--Delete product4-->
66+
<deleteData createDataKey="product4" stepKey="deleteProduct4"/>
67+
<!--Delete product5-->
68+
<deleteData createDataKey="product5" stepKey="deleteProduct5"/>
69+
<!--Delete product6-->
70+
<deleteData createDataKey="product6" stepKey="deleteProduct6"/>
71+
</after>
72+
<!--Navigate to home page-->
73+
<actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/>
74+
<!--Search for word "5127S"-->
75+
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="search1">
76+
<argument name="phrase" value="5127S"/>
77+
</actionGroup>
78+
<!--Assert that product1 is present in the search result-->
79+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct1">
80+
<argument name="productName" value="$$product1.name$$"/>
81+
</actionGroup>
82+
<!--Assert that product2 is not present in the search result-->
83+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct2">
84+
<argument name="productName" value="$$product2.name$$"/>
85+
</actionGroup>
86+
<!--Assert that product2 is not present in the search result-->
87+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct3">
88+
<argument name="productName" value="$$product3.name$$"/>
89+
</actionGroup>
90+
<!--Assert that product4 is present in the search result-->
91+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct4">
92+
<argument name="productName" value="$$product4.name$$"/>
93+
</actionGroup>
94+
<!--Assert that product5 is not present in the search result-->
95+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct5">
96+
<argument name="productName" value="$$product5.name$$"/>
97+
</actionGroup>
98+
<!--Assert that product6 is not present in the search result-->
99+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct6">
100+
<argument name="productName" value="$$product6.name$$"/>
101+
</actionGroup>
102+
103+
<!--Search for word "5127A"-->
104+
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="search2">
105+
<argument name="phrase" value="5127A"/>
106+
</actionGroup>
107+
<!--Assert that product1 is not present in the search result-->
108+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct1">
109+
<argument name="productName" value="$$product1.name$$"/>
110+
</actionGroup>
111+
<!--Assert that product2 is present in the search result-->
112+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct2">
113+
<argument name="productName" value="$$product2.name$$"/>
114+
</actionGroup>
115+
<!--Assert that product3 is present in the search result-->
116+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct3">
117+
<argument name="productName" value="$$product3.name$$"/>
118+
</actionGroup>
119+
<!--Assert that product4 is not present in the search result-->
120+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct4">
121+
<argument name="productName" value="$$product4.name$$"/>
122+
</actionGroup>
123+
<!--Assert that product5 is present in the search result-->
124+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct5">
125+
<argument name="productName" value="$$product5.name$$"/>
126+
</actionGroup>
127+
<!--Assert that product6 is present in the search result-->
128+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct6">
129+
<argument name="productName" value="$$product6.name$$"/>
130+
</actionGroup>
131+
132+
<!--Search for word "5127SS"-->
133+
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="search3">
134+
<argument name="phrase" value="5127SS"/>
135+
</actionGroup>
136+
<!--Assert that product1 is present in the search result-->
137+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct1b">
138+
<argument name="productName" value="$$product1.name$$"/>
139+
</actionGroup>
140+
<!--Assert that product2 is not present in the search result-->
141+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct2b">
142+
<argument name="productName" value="$$product2.name$$"/>
143+
</actionGroup>
144+
<!--Assert that product3 is not present in the search result-->
145+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct3b">
146+
<argument name="productName" value="$$product3.name$$"/>
147+
</actionGroup>
148+
<!--Assert that product4 is present in the search result-->
149+
<actionGroup ref="StorefrontAssertProductNameOnProductMainPageActionGroup" stepKey="seeProduct4b">
150+
<argument name="productName" value="$$product4.name$$"/>
151+
</actionGroup>
152+
<!--Assert that product5 is not present in the search result-->
153+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct5b">
154+
<argument name="productName" value="$$product5.name$$"/>
155+
</actionGroup>
156+
<!--Assert that product6 is not present in the search result-->
157+
<actionGroup ref="AssertStorefrontProductNameIsNotOnProductMainPageActionGroup" stepKey="dontSeeProduct6b">
158+
<argument name="productName" value="$$product6.name$$"/>
159+
</actionGroup>
160+
</test>
161+
</tests>
162+
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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\CatalogSearch\Test\Unit\Model\Search\Request;
9+
10+
use Magento\CatalogSearch\Model\Search\Request\MatchQueriesModifier;
11+
use PHPUnit\Framework\TestCase;
12+
13+
/**
14+
* Test match queries modifier
15+
*/
16+
class MatchQueriesModifierTest extends TestCase
17+
{
18+
/**
19+
* Test that queries configuration are merged into request
20+
*
21+
* @param array $queries
22+
* @param array $requests
23+
* @param array $expected
24+
* @dataProvider modifyDataProvider
25+
*/
26+
public function testModify(array $queries, array $requests, array $expected): void
27+
{
28+
$model = new MatchQueriesModifier($queries);
29+
$this->assertEquals($expected, $model->modify($requests));
30+
}
31+
32+
/**
33+
* @return array
34+
*/
35+
public function modifyDataProvider(): array
36+
{
37+
return [
38+
[
39+
[
40+
'partial_search' => [
41+
'name' => [
42+
'analyzer' => 'standard',
43+
'max_expansions' => 20,
44+
]
45+
],
46+
],
47+
[
48+
'search_1' => [
49+
'filters' => [
50+
'category_filter' => [
51+
'name' => 'category_filter',
52+
'field' => 'category_ids',
53+
'value' => '$category_ids$',
54+
]
55+
],
56+
'queries' => [
57+
'partial_search' => [
58+
'name' => 'partial_search',
59+
'value' => '$search_term$',
60+
'match' => [
61+
[
62+
'field' => '*'
63+
],
64+
[
65+
'field' => 'sku',
66+
'matchCondition' => 'match_phrase_prefix',
67+
],
68+
[
69+
'field' => 'name',
70+
'matchCondition' => 'match_phrase_prefix',
71+
],
72+
]
73+
]
74+
]
75+
],
76+
'search_2' => [
77+
'filters' => [
78+
'category_filter' => [
79+
'name' => 'category_filter',
80+
'field' => 'category_ids',
81+
'value' => '$category_ids$',
82+
]
83+
]
84+
]
85+
],
86+
[
87+
'search_1' => [
88+
'filters' => [
89+
'category_filter' => [
90+
'name' => 'category_filter',
91+
'field' => 'category_ids',
92+
'value' => '$category_ids$',
93+
]
94+
],
95+
'queries' => [
96+
'partial_search' => [
97+
'name' => 'partial_search',
98+
'value' => '$search_term$',
99+
'match' => [
100+
[
101+
'field' => '*'
102+
],
103+
[
104+
'field' => 'sku',
105+
'matchCondition' => 'match_phrase_prefix',
106+
],
107+
[
108+
'field' => 'name',
109+
'matchCondition' => 'match_phrase_prefix',
110+
'analyzer' => 'standard',
111+
'max_expansions' => 20,
112+
],
113+
]
114+
]
115+
]
116+
],
117+
'search_2' => [
118+
'filters' => [
119+
'category_filter' => [
120+
'name' => 'category_filter',
121+
'field' => 'category_ids',
122+
'value' => '$category_ids$',
123+
]
124+
]
125+
]
126+
]
127+
]
128+
];
129+
}
130+
}

app/code/Magento/CatalogSearch/etc/di.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,21 @@
254254
<argument name="modifiers" xsi:type="array">
255255
<item name="search" xsi:type="object">Magento\CatalogSearch\Model\Search\Request\SearchModifier</item>
256256
<item name="partial_search" xsi:type="object">Magento\CatalogSearch\Model\Search\Request\PartialSearchModifier</item>
257+
<item name="match_queries" xsi:type="object">Magento\CatalogSearch\Model\Search\Request\MatchQueriesModifier</item>
258+
</argument>
259+
</arguments>
260+
</type>
261+
<type name="Magento\CatalogSearch\Model\Search\Request\MatchQueriesModifier">
262+
<arguments>
263+
<argument name="queries" xsi:type="array">
264+
<item name="partial_search" xsi:type="array">
265+
<item name="name" xsi:type="array">
266+
<item name="analyzer" xsi:type="string">prefix_search</item>
267+
</item>
268+
<item name="sku" xsi:type="array">
269+
<item name="analyzer" xsi:type="string">sku_prefix_search</item>
270+
</item>
271+
</item>
257272
</argument>
258273
</arguments>
259274
</type>

0 commit comments

Comments
 (0)