diff --git a/ee/changelogs/unreleased/search-issue-and-mr-id.yml b/ee/changelogs/unreleased/search-issue-and-mr-id.yml new file mode 100644 index 0000000000000000000000000000000000000000..5d12546d6ff910be933bfd3f767aec55c2aafc58 --- /dev/null +++ b/ee/changelogs/unreleased/search-issue-and-mr-id.yml @@ -0,0 +1,5 @@ +--- +title: Make searching issues/MRs by IID even easier +merge_request: 40467 +author: +type: added diff --git a/ee/lib/elastic/latest/issue_class_proxy.rb b/ee/lib/elastic/latest/issue_class_proxy.rb index daf97f2c500579bbde5100eea7902f3add53362b..b5f69cda2750acf9aec8feb240f2c45debdef138 100644 --- a/ee/lib/elastic/latest/issue_class_proxy.rb +++ b/ee/lib/elastic/latest/issue_class_proxy.rb @@ -8,7 +8,14 @@ def elastic_search(query, options: {}) if query =~ /#(\d+)\z/ iid_query_hash(Regexp.last_match(1)) else - basic_query_hash(%w(title^2 description), query) + fields = %w(title^2 description) + + # We can only allow searching the iid field if the query is + # just a number, otherwise Elasticsearch will error since this + # field is type integer. + fields << "iid^3" if query =~ /\A\d+\z/ + + basic_query_hash(fields, query) end options[:features] = 'issues' diff --git a/ee/lib/elastic/latest/merge_request_class_proxy.rb b/ee/lib/elastic/latest/merge_request_class_proxy.rb index cdcf76a0069217ee29f48d14d4890d0d4d3f6206..19f63869bdbf5a750663d9db4ef4d40a3710864f 100644 --- a/ee/lib/elastic/latest/merge_request_class_proxy.rb +++ b/ee/lib/elastic/latest/merge_request_class_proxy.rb @@ -8,7 +8,14 @@ def elastic_search(query, options: {}) if query =~ /\!(\d+)\z/ iid_query_hash(Regexp.last_match(1)) else - basic_query_hash(%w(title^2 description), query) + fields = %w(title^2 description) + + # We can only allow searching the iid field if the query is + # just a number, otherwise Elasticsearch will error since this + # field is type integer. + fields << "iid^3" if query =~ /\A\d+\z/ + + basic_query_hash(fields, query) end options[:features] = 'merge_requests' diff --git a/ee/spec/lib/gitlab/elastic/search_results_spec.rb b/ee/spec/lib/gitlab/elastic/search_results_spec.rb index fbeb46634c6196029522572ae31457d71e618f7b..e0b9dca34943578199274c3fe30759b3167954fd 100644 --- a/ee/spec/lib/gitlab/elastic/search_results_spec.rb +++ b/ee/spec/lib/gitlab/elastic/search_results_spec.rb @@ -118,14 +118,14 @@ @issue_2 = create( :issue, project: project_1, - title: 'Issue 2', + title: 'Issue Two', description: 'Hello world, here I am!', iid: 2 ) @issue_3 = create( :issue, project: project_2, - title: 'Issue 3', + title: 'Issue Three', iid: 2 ) @@ -138,9 +138,7 @@ results = described_class.new(user, 'hello world', limit_projects) issues = results.objects('issues') - expect(issues).to include @issue_1 - expect(issues).to include @issue_2 - expect(issues).not_to include @issue_3 + expect(issues).to contain_exactly(@issue_1, @issue_2) expect(results.issues_count).to eq 2 end @@ -155,9 +153,15 @@ results = described_class.new(user, '#2', limit_projects, public_and_internal_projects: false) issues = results.objects('issues') - expect(issues).not_to include @issue_1 - expect(issues).to include @issue_2 - expect(issues).not_to include @issue_3 + expect(issues).to contain_exactly(@issue_2) + expect(results.issues_count).to eq 1 + end + + it 'can also find an issue by iid without the prefixed #' do + results = described_class.new(user, '2', limit_projects, public_and_internal_projects: false) + issues = results.objects('issues') + + expect(issues).to contain_exactly(@issue_2) expect(results.issues_count).to eq 1 end @@ -421,7 +425,7 @@ :conflict, source_project: project_1, target_project: project_1, - title: 'Merge Request 2', + title: 'Merge Request Two', description: 'Hello world, here I am!', iid: 2 ) @@ -429,7 +433,7 @@ :merge_request, source_project: project_2, target_project: project_2, - title: 'Merge Request 3', + title: 'Merge Request Three', iid: 2 ) @@ -439,12 +443,10 @@ it_behaves_like 'a paginated object', 'merge_requests' it 'lists found merge requests' do - results = described_class.new(user, 'hello world', limit_projects) + results = described_class.new(user, 'hello world', limit_projects, public_and_internal_projects: false) merge_requests = results.objects('merge_requests') - expect(merge_requests).to include @merge_request_1 - expect(merge_requests).to include @merge_request_2 - expect(merge_requests).not_to include @merge_request_3 + expect(merge_requests).to contain_exactly(@merge_request_1, @merge_request_2) expect(results.merge_requests_count).to eq 2 end @@ -456,12 +458,18 @@ end it 'lists merge request when search by a valid iid' do - results = described_class.new(user, '#2', limit_projects) + results = described_class.new(user, '!2', limit_projects, public_and_internal_projects: false) + merge_requests = results.objects('merge_requests') + + expect(merge_requests).to contain_exactly(@merge_request_2) + expect(results.merge_requests_count).to eq 1 + end + + it 'can also find an issue by iid without the prefixed !' do + results = described_class.new(user, '2', limit_projects, public_and_internal_projects: false) merge_requests = results.objects('merge_requests') - expect(merge_requests).not_to include @merge_request_1 - expect(merge_requests).to include @merge_request_2 - expect(merge_requests).not_to include @merge_request_3 + expect(merge_requests).to contain_exactly(@merge_request_2) expect(results.merge_requests_count).to eq 1 end