From cf327a09a1d72ab44c8a208416048539140192a1 Mon Sep 17 00:00:00 2001 From: Billy Zhou Date: Tue, 3 Jul 2018 15:18:55 +0800 Subject: [PATCH] Fixed issue #2058 - Autocomplete hangs on dot in the new user form --- lib/search_index_backend.rb | 17 +++--- test/controllers/search_controller_test.rb | 31 +++++++++++ test/unit/search_index_backend_test.rb | 64 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 test/unit/search_index_backend_test.rb diff --git a/lib/search_index_backend.rb b/lib/search_index_backend.rb index fa3efd36d..f537c62d5 100644 --- a/lib/search_index_backend.rb +++ b/lib/search_index_backend.rb @@ -332,18 +332,10 @@ return search result data['query']['bool'] ||= {} data['query']['bool']['must'] ||= [] - # add * on simple query like "somephrase23" or "attribute: somephrase23" - if query.present? - query.strip! - if query.match?(/^([[:alpha:],0-9]+|[[:alpha:],0-9]+\:\s+[[:alpha:],0-9]+)$/) - query += '*' - end - end - # real search condition condition = { 'query_string' => { - 'query' => query, + 'query' => append_wildcard_to_simple_query(query), 'default_operator' => 'AND', } } @@ -616,4 +608,11 @@ return true if backend is configured Rails.logger.error result.first(40_000) result end + + # add * on simple query like "somephrase23" or "attribute: somephrase23" + def self.append_wildcard_to_simple_query(query) + query.strip! + query += '*' if query.match?(/^([[:alnum:]._]+|[[:alnum:]]+\:\s*[[:alnum:]._]+)$/) + query + end end diff --git a/test/controllers/search_controller_test.rb b/test/controllers/search_controller_test.rb index 18d69425d..b9c3f9b80 100644 --- a/test/controllers/search_controller_test.rb +++ b/test/controllers/search_controller_test.rb @@ -61,6 +61,12 @@ class SearchControllerTest < ActionDispatch::IntegrationTest @organization3 = Organization.create!( name: 'Rest Org #3', ) + @organization4 = Organization.create!( + name: 'Tes.t. Org', + ) + @organization5 = Organization.create!( + name: 'ABC_D Org', + ) # create customer with org @customer_with_org2 = User.create!( @@ -414,4 +420,29 @@ class SearchControllerTest < ActionDispatch::IntegrationTest assert_not(result['result'][0]) end + # Verify fix for Github issue #2058 - Autocomplete hangs on dot in the new user form + test 'searching for organization with a dot in its name' do + credentials = ActionController::HttpAuthentication::Basic.encode_credentials('search-agent@example.com', 'agentpw') + + get '/api/v1/search/organization?query=tes.', headers: @headers.merge('Authorization' => credentials) + assert_response(200) + result = JSON.parse(@response.body) + assert_equal(1, result['result'].size) + assert_equal('Organization', result['result'][0]['type']) + target_id = result['result'][0]['id'] + assert_equal('Tes.t. Org', result['assets']['Organization'][target_id.to_s]['name']) + end + + # Search query H& should correctly match H&M + test 'searching for organization with _ in its name' do + credentials = ActionController::HttpAuthentication::Basic.encode_credentials('search-agent@example.com', 'agentpw') + + get '/api/v1/search/organization?query=abc_', headers: @headers.merge('Authorization' => credentials) + assert_response(200) + result = JSON.parse(@response.body) + assert_equal(1, result['result'].size) + assert_equal('Organization', result['result'][0]['type']) + target_id = result['result'][0]['id'] + assert_equal('ABC_D Org', result['assets']['Organization'][target_id.to_s]['name']) + end end diff --git a/test/unit/search_index_backend_test.rb b/test/unit/search_index_backend_test.rb new file mode 100644 index 000000000..102486349 --- /dev/null +++ b/test/unit/search_index_backend_test.rb @@ -0,0 +1,64 @@ + +require 'test_helper' + +class SearchIndexBackendTest < ActiveSupport::TestCase + + test 'simple_query_append_wildcard correctly modifies simple queries' do + def clean_queries(query_string) + query_string.each_line + .map(&:strip) + .reject(&:empty?) + .map { |x| x.split('#')[0] } + end + + # Examples of complex queries from https://docs.zammad.org/en/latest/general-search.html + complex_queries = clean_queries %( + title:”some words with spaces” # exact phrase / without quotation marks ” an AND search for the words will be performed (in Zammad 1.5 and lower an OR search will be performed) + title:”some wor*” # exact phrase beginning with “some wor*” will be searched + created_at:[2017-01-01 TO 2017-12-31] # a time range + created_at:>now-1h # created within last hour + state:new OR state:open + (state:new OR state:open) OR priority:”3 normal” + (state:new OR state:open) AND customer.lastname:smith + state:(new OR open) AND title:(full text search) # state: new OR open & title: full OR text OR search + tag: “some tag” + owner.email: “bod@example.com” AND state: (new OR open OR pending*) # show all open tickets of a certain agent + state:closed AND _missing_:tag # all closed objects without tags + article_count: [1 TO 5] # tickets with 1 to 5 articles + article_count: [10 TO *] # tickets with 10 or more articles + article.from: bob # also article.from can be used + article.body: heat~ # using the fuzzy operator will also find terms that are similar, in this case also “head” + article.body: /joh?n(ath[oa]n)/ # using regular expressions + ) + + simple_queries = clean_queries %( + M + Max + Max. # dot and underscore are acceptable characters in simple queries + A_ + A_B + äöü + 123 + user:M + user:Max + user:Max. + organization:A_B + user: M + user: Max + user: Max. + organization: A_B + ) + + complex_queries.each do |query| + result_query = SearchIndexBackend.append_wildcard_to_simple_query(query) + # Verify that the result query is still the same as the input query + assert_equal(query, result_query) + end + + simple_queries.each do |query| + result_query = SearchIndexBackend.append_wildcard_to_simple_query(query) + # Verify that * is correctly appended to simple queries + assert_equal(query + '*', result_query) + end + end +end