Skip to content

Commit

Permalink
feat(search): Add additional search connectors support to text filters
Browse files Browse the repository at this point in the history
  • Loading branch information
albertisfu committed Jan 10, 2025
1 parent 57e3fe7 commit 9b58ac8
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 6 deletions.
6 changes: 6 additions & 0 deletions cl/lib/elasticsearch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@
)
from cl.lib.utils import (
check_for_proximity_tokens,
check_query_for_disallowed_wildcards,
check_unbalanced_parenthesis,
check_unbalanced_quotes,
cleanup_main_query,
get_array_of_selected_fields,
lookup_child_courts,
map_to_docket_entry_sorting,
perform_special_character_replacements,
)
from cl.people_db.models import Position
from cl.search.constants import (
Expand Down Expand Up @@ -77,6 +79,7 @@
)
from cl.search.exception import (
BadProximityQuery,
DisallowedWildcardPattern,
ElasticBadRequestError,
QueryType,
UnbalancedParenthesesQuery,
Expand Down Expand Up @@ -488,6 +491,9 @@ def build_text_filter(field: str, value: str) -> List:
if value:
if isinstance(value, str):
validate_query_syntax(value, QueryType.FILTER)
if check_query_for_disallowed_wildcards(value):
raise DisallowedWildcardPattern(QueryType.FILTER)
value = perform_special_character_replacements(value)
return [
Q(
"query_string",
Expand Down
2 changes: 1 addition & 1 deletion cl/search/templates/includes/no_results.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h2 class="alt">
{% elif error_message == "unbalanced_quotes" %}
Did you forget to close one or more quotes?
{% elif error_message == "disallowed_wildcard_pattern" %}
The query contains a disallowed wildcard pattern.
The query contains a disallowed expensive wildcard pattern.
{% endif %}
{% else %}
encountered an error.
Expand Down
90 changes: 89 additions & 1 deletion cl/search/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ def setUpTestData(cls):
docket=DocketFactory(
court=cls.child_court_2_2, docket_number="36-2000"
),
judges="Computer point",
precedential_status=PRECEDENTIAL_STATUS.PUBLISHED,
sub_opinions=RelatedFactory(
OpinionWithChildrenFactory,
Expand All @@ -471,6 +472,7 @@ def setUpTestData(cls):
docket=DocketFactory(
court=cls.child_gand_2, docket_number="38-1000"
),
judges="Composition plant",
precedential_status=PRECEDENTIAL_STATUS.PUBLISHED,
sub_opinions=RelatedFactory(
OpinionWithChildrenFactory,
Expand Down Expand Up @@ -1085,6 +1087,74 @@ def test_support_search_connectors(self) -> None:
msg=f"Failed on: {test_case['label']} missing {expected_str}",
)

def test_support_search_connectors_filters(self) -> None:
"""Verify that new supported custom search connectors yield the
expected results.
"""

tests = [
{
"label": "But not %",
"search_params": {
"case_name": "Strickland % Lorem % America",
},
"expected_count": 1,
"expected_in_content": ["1:21-cv-1234"],
},
{
"label": "& connector test",
"search_params": {
"case_name": "Strickland & Lorem",
},
"expected_count": 1,
"expected_in_content": ["123456"],
},
{
"label": "! Root expander suffix",
"search_params": {
"judge": "!Comp",
},
"expected_count": 2,
"expected_in_content": ["36-2000", "38-1000"],
},
{
"label": "Universal Character *",
"search_params": {
"judge": "p**nt",
},
"expected_count": 2,
"expected_in_content": ["36-2000", "38-1000"],
},
{
"label": "Combined operators",
"search_params": {
"case_name": "Calif*rnia & !Nev",
},
"expected_count": 1,
"expected_in_content": ["38-1000"],
},
]

for test_case in tests:
with self.subTest(label=test_case["label"]):
response = self.client.get(
reverse("show_results"),
test_case["search_params"],
)
actual = self.get_article_count(response)
self.assertEqual(
actual,
test_case["expected_count"],
msg=f"Failed on: {test_case['label']}",
)
decoded_content = response.content.decode()
for expected_str in test_case["expected_in_content"]:
self.assertIn(
expected_str,
decoded_content,
msg=f"Failed on: {test_case['label']} missing {expected_str}",
)

def test_disallowed_wildcard_pattern(self) -> None:
"""Verify that expensive wildcard queries thrown an error."""

Expand All @@ -1107,6 +1177,24 @@ def test_disallowed_wildcard_pattern(self) -> None:
"q": "*ing",
},
},
{
"label": "Disallowed ! in short queries - Filter.",
"search_params": {
"case_name": "!ap",
},
},
{
"label": "Disallowed * at the end in short queries - Filter.",
"search_params": {
"judge": "ap*",
},
},
{
"label": "Disallowed * at the beginning - Filter.",
"search_params": {
"case_name": "*ing",
},
},
]

for test_case in tests:
Expand All @@ -1117,7 +1205,7 @@ def test_disallowed_wildcard_pattern(self) -> None:
)
decoded_content = response.content.decode()
self.assertIn(
"The query contains a disallowed wildcard pattern.",
"The query contains a disallowed expensive wildcard pattern",
decoded_content,
msg=f"Failed on: {test_case['label']}, no disallowed wildcard pattern error.",
)
Expand Down
4 changes: 0 additions & 4 deletions cl/search/tests/tests_es_opinion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1818,10 +1818,6 @@ async def test_can_use_negation_in_queries(self) -> None:
r = await self._test_article_count(search_params, 0, "negation query")
self.assertIn("had no results", r.content.decode())

search_params["q"] = "Howard !Honda"
r = await self._test_article_count(search_params, 0, "negation query")
self.assertIn("had no results", r.content.decode())

search_params["q"] = "Howard -Honda"
r = await self._test_article_count(search_params, 0, "negation query")
self.assertIn("had no results", r.content.decode())
Expand Down

0 comments on commit 9b58ac8

Please sign in to comment.