diff --git a/Products/CMFPlone/browser/search.py b/Products/CMFPlone/browser/search.py index 7d68611a40..ce689127f2 100644 --- a/Products/CMFPlone/browser/search.py +++ b/Products/CMFPlone/browser/search.py @@ -67,9 +67,14 @@ def munge_search_term(query): continue r.append(f'"{clean_qp}"') - r += map(quote, query.strip().split()) + # Add wildcards to individual terms, not just at the end + if not original_query.endswith('"'): + individual_terms = [quote(term) + "*" for term in query.strip().split()] + else: + individual_terms = [quote(term) for term in query.strip().split()] + + r += individual_terms r = " AND ".join(r) - r = r + ("*" if r and not original_query.endswith('"') else "") return r diff --git a/Products/CMFPlone/tests/testSearch.py b/Products/CMFPlone/tests/testSearch.py index 7c8eb6b483..c86263e811 100644 --- a/Products/CMFPlone/tests/testSearch.py +++ b/Products/CMFPlone/tests/testSearch.py @@ -305,7 +305,6 @@ def test_quoted_phrase(self): self.assertEqual( view.results(query=dict(SearchableText='"ham spam"')).sequence_length, 0 ) - # arbitrary words within index self.assertEqual( view.results(query=dict(SearchableText="spam eggs")).sequence_length, 12 @@ -314,7 +313,6 @@ def test_quoted_phrase(self): self.assertEqual( view.results(query=dict(SearchableText='"spam eggs"')).sequence_length, 0 ) - # unquoted substring search self.assertEqual( view.results(query=dict(SearchableText="egg")).sequence_length, 12 @@ -323,13 +321,11 @@ def test_quoted_phrase(self): self.assertEqual( view.results(query=dict(SearchableText='"egg"')).sequence_length, 0 ) - # unquoted multi substring search - # XXX: this is munged to "egg AND spa*" and doesn't find any results + # XXX: this is munged to "egg* AND spa*" and SHOULD find results self.assertEqual( - view.results(query=dict(SearchableText="egg spa")).sequence_length, 0 + view.results(query=dict(SearchableText="egg spa")).sequence_length, 12 ) - # weird input self.assertEqual( view.results(query=dict(SearchableText='"eggs" ham spam')).sequence_length, @@ -352,7 +348,7 @@ def test_munge_search_term(self): ( # search term "spam ham", - "spam AND ham*", + "spam* AND ham*", ), ( # quoted term @@ -382,26 +378,28 @@ def test_munge_search_term(self): ( # mixed cases "Spam hAm", - "Spam AND 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*", + '"ham and eggs" AND let\'s* AND eat* AND some* ' + "AND without* AND spam*", ), ( + # UNQUOTED TERMS GET WILDCARDS 'test "Welcome" to "Plone" retest', - '"Welcome" AND "Plone" AND test AND to AND retest*', + '"Welcome" AND "Plone" AND test* AND to* AND retest*', ), ( # parentheses "spam (ham)", - 'spam AND "("ham")"*', + 'spam* AND "("ham")"*', ), ( # special keywords "spam or not ham and eggs", - 'spam AND "or" AND "not" AND ham AND "and" AND eggs*', + 'spam* AND "or"* AND "not"* AND ham* AND "and"* AND eggs*', ), ( # bad characters @@ -411,7 +409,7 @@ def test_munge_search_term(self): ( # weird input 'test ""Welcome" to "Plone"" retest', - '"to" AND test AND WelcomePlone AND retest*', + '"to" AND test* AND WelcomePlone* AND retest*', ), ] diff --git a/news/4205.bugfix b/news/4205.bugfix new file mode 100644 index 0000000000..a9ad3e4d7d --- /dev/null +++ b/news/4205.bugfix @@ -0,0 +1 @@ +Enhance munge_search_term to add wildcards to individual search terms @rohnsha0 \ No newline at end of file