Skip to content

Commit 6dbbd92

Browse files
Yeray Diaz Diazdi
Yeray Diaz Diaz
andcommitted
Refactor search logic out of views.py (#6118)
* Refactor search logic out of views.py * Fix linting errors * Fix views tests * Remove unused import * Reset gettext calls in template Co-authored-by: Dustin Ingram <[email protected]>
1 parent 964cfbc commit 6dbbd92

File tree

4 files changed

+283
-278
lines changed

4 files changed

+283
-278
lines changed

tests/unit/test_search.py

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
13+
14+
import pytest
15+
16+
from elasticsearch_dsl import Search
17+
18+
from warehouse.search import queries
19+
20+
EXPECTED_SEARCH_FIELDS = [
21+
"author",
22+
"author_email",
23+
"description^5",
24+
"download_url",
25+
"home_page",
26+
"keywords^5",
27+
"license",
28+
"maintainer",
29+
"maintainer_email",
30+
"normalized_name^10",
31+
"platform",
32+
"summary^5",
33+
]
34+
35+
36+
class TestQueries:
37+
def test_no_querystring(self):
38+
es = Search()
39+
40+
query = queries.get_es_query(es, "", "", [])
41+
42+
assert query == es.query()
43+
44+
@pytest.mark.parametrize(
45+
"querystring,expected_prefix,expected_type",
46+
[
47+
('"foo bar"', '"foo bar"', "phrase"),
48+
('"a"', '"a"', "phrase"),
49+
("foo bar", "foo bar", "best_fields"),
50+
],
51+
)
52+
def test_quoted_query(self, querystring, expected_prefix, expected_type):
53+
es = Search()
54+
55+
query = queries.get_es_query(es, querystring, "", [])
56+
57+
query_dict = query.to_dict()
58+
assert len(query_dict["query"]["bool"]["should"]) == 2
59+
assert query_dict["query"]["bool"]["should"][1] == {
60+
"prefix": {"normalized_name": expected_prefix}
61+
}
62+
must_params = query_dict["query"]["bool"]["should"][0]["bool"]["must"]
63+
assert len(must_params) == 1
64+
assert must_params[0]["multi_match"] == {
65+
"fields": EXPECTED_SEARCH_FIELDS,
66+
"type": expected_type,
67+
"query": "foo bar" if querystring != '"a"' else "a",
68+
}
69+
assert query_dict["suggest"] == {
70+
"name_suggestion": {"text": querystring, "term": {"field": "name"}}
71+
}
72+
assert "sort" not in query_dict # default "relevance" mode does no sorting
73+
74+
def test_single_not_quoted_character(self):
75+
es = Search()
76+
querystring = "a"
77+
78+
query = queries.get_es_query(es, querystring, "", [])
79+
80+
query_dict = query.to_dict()
81+
must_params = query_dict["query"]["bool"]["must"]
82+
assert len(must_params) == 1
83+
assert must_params[0]["multi_match"] == {
84+
"fields": EXPECTED_SEARCH_FIELDS,
85+
"type": "best_fields",
86+
"query": "a",
87+
}
88+
assert query_dict["suggest"] == {
89+
"name_suggestion": {"text": querystring, "term": {"field": "name"}}
90+
}
91+
assert "sort" not in query_dict # default "relevance" mode does no sorting
92+
93+
def test_mixed_quoted_query(self):
94+
es = Search()
95+
querystring = '"foo bar" baz'
96+
97+
query = queries.get_es_query(es, querystring, "", [])
98+
99+
query_dict = query.to_dict()
100+
assert len(query_dict["query"]["bool"]["should"]) == 2
101+
assert query_dict["query"]["bool"]["should"][1] == {
102+
"prefix": {"normalized_name": '"foo bar" baz'}
103+
}
104+
must_params = query_dict["query"]["bool"]["should"][0]["bool"]["must"]
105+
assert len(must_params) == 2
106+
assert must_params[0]["multi_match"] == {
107+
"fields": EXPECTED_SEARCH_FIELDS,
108+
"type": "phrase",
109+
"query": "foo bar",
110+
}
111+
assert must_params[1]["multi_match"] == {
112+
"fields": EXPECTED_SEARCH_FIELDS,
113+
"type": "best_fields",
114+
"query": "baz",
115+
}
116+
assert query_dict["suggest"] == {
117+
"name_suggestion": {"text": querystring, "term": {"field": "name"}}
118+
}
119+
assert "sort" not in query_dict # default "relevance" mode does no sorting
120+
121+
@pytest.mark.parametrize(
122+
"order,field", [("created", "created"), ("-zscore", "zscore")]
123+
)
124+
def test_sort_order(self, order, field):
125+
es = Search()
126+
querystring = "foo bar"
127+
128+
query = queries.get_es_query(es, querystring, order, [])
129+
130+
query_dict = query.to_dict()
131+
assert len(query_dict["query"]["bool"]["should"]) == 2
132+
assert query_dict["query"]["bool"]["should"][1] == {
133+
"prefix": {"normalized_name": "foo bar"}
134+
}
135+
must_params = query_dict["query"]["bool"]["should"][0]["bool"]["must"]
136+
assert len(must_params) == 1
137+
assert must_params[0]["multi_match"] == {
138+
"fields": EXPECTED_SEARCH_FIELDS,
139+
"type": "best_fields",
140+
"query": "foo bar",
141+
}
142+
assert query_dict["suggest"] == {
143+
"name_suggestion": {"text": querystring, "term": {"field": "name"}}
144+
}
145+
assert query_dict["sort"] == [
146+
{
147+
field: {
148+
"order": "desc" if order.startswith("-") else "asc",
149+
"unmapped_type": "long",
150+
}
151+
}
152+
]
153+
154+
def test_with_classifiers(self):
155+
es = Search()
156+
querystring = "foo bar"
157+
classifiers = [("c", "foo :: bar"), ("c", "fiz :: buz")]
158+
159+
query = queries.get_es_query(es, querystring, "", classifiers)
160+
161+
query_dict = query.to_dict()
162+
assert len(query_dict["query"]["bool"]["should"]) == 2
163+
assert query_dict["query"]["bool"]["should"][1] == {
164+
"prefix": {"normalized_name": "foo bar"}
165+
}
166+
must_params = query_dict["query"]["bool"]["should"][0]["bool"]["must"]
167+
assert len(must_params) == 1
168+
assert must_params[0]["multi_match"] == {
169+
"fields": EXPECTED_SEARCH_FIELDS,
170+
"type": "best_fields",
171+
"query": "foo bar",
172+
}
173+
assert query_dict["suggest"] == {
174+
"name_suggestion": {"text": querystring, "term": {"field": "name"}}
175+
}
176+
assert "sort" not in query_dict
177+
assert query_dict["query"]["bool"]["must"] == [
178+
{"prefix": {"classifiers": classifier}} for classifier in classifiers
179+
]
180+
assert query_dict["query"]["bool"]["minimum_should_match"] == 1

0 commit comments

Comments
 (0)