Skip to content

Commit 3cdac0c

Browse files
ericholschersafwanrahman
authored andcommitted
Merge pull request #4277 from safwanrahman/insensitive
[Fix #2328 #2013] Refresh search index and test for case insensitive search
2 parents d4f6708 + 10b7f36 commit 3cdac0c

File tree

3 files changed

+46
-9
lines changed

3 files changed

+46
-9
lines changed

readthedocs/search/documents.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,14 @@ def update(self, thing, refresh=None, action='index', **kwargs):
9696
# TODO: remove this overwrite when the issue has been fixed
9797
# See below link for more information
9898
# https://github.com/sabricot/django-elasticsearch-dsl/issues/111
99-
if isinstance(thing, HTMLFile):
99+
# Moreover, do not need to check if its a delete action
100+
# Because while delete action, the object is already remove from database
101+
if isinstance(thing, HTMLFile) and action != 'delete':
100102
# Its a model instance.
101103
queryset = self.get_queryset()
102104
obj = queryset.filter(pk=thing.pk)
103105
if not obj.exists():
104106
return None
105107

106-
return super(PageDocument, self).update(thing=thing, refresh=None, action='index', **kwargs)
108+
return super(PageDocument, self).update(thing=thing, refresh=refresh,
109+
action=action, **kwargs)

readthedocs/search/tests/test_views.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from readthedocs.builds.constants import LATEST
1010
from readthedocs.builds.models import Version
11-
from readthedocs.projects.models import Project
11+
from readthedocs.projects.models import Project, HTMLFile
1212
from readthedocs.search.tests.utils import get_search_query_from_project_file
1313

1414

@@ -64,26 +64,60 @@ def test_search_project_filter_language(self, client, project):
6464

6565
@pytest.mark.django_db
6666
@pytest.mark.search
67-
class TestElasticSearch(object):
67+
class TestPageSearch(object):
6868
url = reverse('search')
6969

7070
def _get_search_result(self, url, client, search_params):
7171
resp = client.get(url, search_params)
7272
assert resp.status_code == 200
7373

7474
page = pq(resp.content)
75-
result = page.find('.module-list-wrapper .module-item-title')
75+
result = page.find('.module-list-wrapper .search-result-item')
7676
return result, page
7777

7878
@pytest.mark.parametrize('data_type', ['content', 'headers', 'title'])
7979
@pytest.mark.parametrize('page_num', [0, 1])
80-
def test_search_by_file_content(self, client, project, data_type, page_num):
80+
def test_file_search(self, client, project, data_type, page_num):
8181
query = get_search_query_from_project_file(project_slug=project.slug, page_num=page_num,
8282
data_type=data_type)
8383

8484
result, _ = self._get_search_result(url=self.url, client=client,
8585
search_params={'q': query, 'type': 'file'})
86-
assert len(result) == 1, ("failed"+ query)
86+
assert len(result) == 1
87+
assert query in result.text()
88+
89+
@pytest.mark.parametrize('case', ['upper', 'lower', 'title'])
90+
def test_file_search_case_insensitive(self, client, project, case):
91+
"""Check File search is case insensitive
92+
93+
It tests with uppercase, lowercase and camelcase
94+
"""
95+
query_text = get_search_query_from_project_file(project_slug=project.slug)
96+
97+
cased_query = getattr(query_text, case)
98+
query = cased_query()
99+
100+
result, _ = self._get_search_result(url=self.url, client=client,
101+
search_params={'q': query, 'type': 'file'})
102+
103+
assert len(result) == 1
104+
# Check the actual text is in the result, not the cased one
105+
assert query_text in result.text()
106+
107+
def test_page_search_not_return_removed_page(self, client, project):
108+
"""Check removed page are not in the search index"""
109+
query = get_search_query_from_project_file(project_slug=project.slug)
110+
# Make a query to check it returns result
111+
result, _ = self._get_search_result(url=self.url, client=client,
112+
search_params={'q': query, 'type': 'file'})
113+
assert len(result) == 1
114+
115+
# Delete all the HTML files of the project
116+
HTMLFile.objects.filter(project=project).delete()
117+
# Run the query again and this time there should not be any result
118+
result, _ = self._get_search_result(url=self.url, client=client,
119+
search_params={'q': query, 'type': 'file'})
120+
assert len(result) == 0
87121

88122
def test_file_search_show_projects(self, client, all_projects):
89123
"""Test that search result page shows list of projects while searching for files"""

readthedocs/templates/search/elastic_search.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,13 @@ <h3>{% blocktrans with query=query|default:"" %}Results for {{ query }}{% endblo
123123

124124
<ul>
125125
{% for result in results %}
126-
<li class="module-item">
126+
<li class="module-item search-result-item">
127127
<p class="module-item-title">
128128
{% if result.name %}
129129

130130
{# Project #}
131131
<a href="{{ result.url }}">{{ result.name }}</a>
132+
</p>
132133
{{ result.meta.description }}
133134
{% for fragment in result.meta.highlight.description|slice:":3" %}
134135
<p>
@@ -150,7 +151,6 @@ <h3>{% blocktrans with query=query|default:"" %}Results for {{ query }}{% endblo
150151
{# End File #}
151152

152153
{% endif %}
153-
</p>
154154
</li>
155155
{% empty %}
156156
<li class="module-item"><span class="quiet">{% trans "No results found. Bummer." %}</span></li>

0 commit comments

Comments
 (0)