Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle parenthesis inside quotes #140

Merged
merged 2 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/139.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Handle parenthesis inside quotes
[erral]
5 changes: 3 additions & 2 deletions plone/app/querystring/querybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ def _quote(term):
# being parsed as logical query atoms.
if term.lower() in ("and", "or", "not"):
term = '"%s"' % term
return term
return _quote_chars(term)


def munge_search_term(query):
original_query = query
for char in _BAD_CHARS:
query = query.replace(char, " ")

Expand All @@ -66,7 +67,7 @@ def munge_search_term(query):

r += map(_quote, query.strip().split())
r = " AND ".join(r)
r = _quote_chars(r) + ("*" if r and not r.endswith('"') else "")
r = r + ("*" if r and not original_query.endswith('"') else "")
return r


Expand Down
74 changes: 74 additions & 0 deletions plone/app/querystring/tests/testQueryBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,80 @@ def testQueryBuilderCustomQueryDoNotOverrideValues(self):
self.assertEqual(len(results), 1)
self.assertEqual(results[0].Title(), "Collectionstestpage 2")

def test_munge_search_term(self):
from plone.app.querystring.querybuilder import _BAD_CHARS
from plone.app.querystring.querybuilder import munge_search_term

search_term_tests = [
(
# search term
"spam ham",
"spam AND ham*",
),
(
# quoted term
'"spam ham"',
'"spam ham"',
),
(
# cleanup quoted terms
'" spam ham "',
'"spam ham"',
),
(
# quoted term with inner parenthesis
'"spam (ham)"',
'"spam (ham)"',
),
(
# quoted term with inner parenthesis
'"spam" (ham)',
'"spam" AND "("ham")"*',
),
(
# quoted term with inner parenthesis
'"(spam ham)"',
'"(spam ham)"',
),
(
# mixed cases
"Spam hAm",
"Spam AND hAm*",
),
(
# mix quoting and unquoted
'let\'s eat some "ham and eggs " without spam ',
'"ham and eggs" AND let\'s AND eat AND some ' "AND without AND spam*",
),
(
'test "Welcome" to "Plone" retest',
'"Welcome" AND "Plone" AND test AND to AND retest*',
),
(
# parentheses
"spam (ham)",
'spam AND "("ham")"*',
),
(
# special keywords
"spam or not ham and eggs",
'spam AND "or" AND "not" AND ham AND "and" AND eggs*',
),
(
# bad characters
" ".join(_BAD_CHARS),
"",
),
(
# weird input
'test ""Welcome" to "Plone"" retest',
'"to" AND test AND WelcomePlone AND retest*',
),
]

for _in, _out in search_term_tests:
self.assertEqual(munge_search_term(_in), _out)


class TestQuerybuilderResultTypes(unittest.TestCase):
layer = TEST_PROFILE_PLONEAPPQUERYSTRING_INTEGRATION_TESTING
Expand Down