require 'spec_helper' describe Gitlab::Elastic::SearchResults, lib: true do before do allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(true) end after do allow(Gitlab.config.elasticsearch).to receive(:enabled).and_return(false) end let(:user) { create(:user) } let(:project_1) { create(:project) } let(:project_2) { create(:project) } let(:limit_project_ids) { [project_1.id] } describe 'issues' do before do Issue.__elasticsearch__.create_index! @issue_1 = create( :issue, project: project_1, title: 'Hello world, here I am!', iid: 1 ) @issue_2 = create( :issue, project: project_1, title: 'Issue 2', description: 'Hello world, here I am!', iid: 2 ) @issue_3 = create( :issue, project: project_2, title: 'Issue 3', iid: 2 ) Issue.__elasticsearch__.refresh_index! end after do Issue.__elasticsearch__.delete_index! end it 'should list issues that title or description contain the query' do results = described_class.new(user, limit_project_ids, 'hello world') issues = results.objects('issues') expect(issues).to include @issue_1 expect(issues).to include @issue_2 expect(issues).not_to include @issue_3 expect(results.issues_count).to eq 2 end it 'should return empty list when issues title or description does not contain the query' do results = described_class.new(user, limit_project_ids, 'security') expect(results.objects('issues')).to be_empty expect(results.issues_count).to eq 0 end it 'should list issue when search by a valid iid' do results = described_class.new(user, limit_project_ids, '#2') 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(results.issues_count).to eq 1 end it 'should return empty list when search by invalid iid' do results = described_class.new(user, limit_project_ids, '#222') expect(results.objects('issues')).to be_empty expect(results.issues_count).to eq 0 end end describe 'confidential issues' do let(:project_3) { create(:empty_project) } let(:project_4) { create(:empty_project) } let(:query) { 'issue' } let(:limit_project_ids) { [project_1.id, project_2.id, project_3.id] } let(:author) { create(:user) } let(:non_member) { create(:user) } let(:member) { create(:user) } let(:admin) { create(:admin) } let!(:issue) { create(:issue, project: project_1, title: 'Issue 1') } let!(:security_issue_1) { create(:issue, :confidential, project: project_1, title: 'Security issue 1', author: author) } let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project_1) } let!(:security_issue_3) { create(:issue, :confidential, project: project_2, title: 'Security issue 3', author: author) } let!(:security_issue_4) { create(:issue, :confidential, project: project_3, title: 'Security issue 4') } let!(:security_issue_5) { create(:issue, :confidential, project: project_4, title: 'Security issue 5') } before do Issue.__elasticsearch__.refresh_index! end it 'should not list confidential issues for non project members' do results = described_class.new(non_member, limit_project_ids, query) issues = results.objects('issues') expect(issues).to include issue expect(issues).not_to include security_issue_1 expect(issues).not_to include security_issue_2 expect(issues).not_to include security_issue_3 expect(issues).not_to include security_issue_4 expect(issues).not_to include security_issue_5 expect(results.issues_count).to eq 1 end it 'should list confidential issues for author' do results = described_class.new(author, limit_project_ids, query) issues = results.objects('issues') expect(issues).to include issue expect(issues).to include security_issue_1 expect(issues).not_to include security_issue_2 expect(issues).to include security_issue_3 expect(issues).not_to include security_issue_4 expect(issues).not_to include security_issue_5 expect(results.issues_count).to eq 3 end it 'should list confidential issues for project members' do project_1.team << [member, :developer] project_2.team << [member, :developer] results = described_class.new(member, limit_project_ids, query) issues = results.objects('issues') expect(issues).to include issue expect(issues).to include security_issue_1 expect(issues).to include security_issue_2 expect(issues).to include security_issue_3 expect(issues).not_to include security_issue_4 expect(issues).not_to include security_issue_5 expect(results.issues_count).to eq 4 end it 'should list all issues for admin' do results = described_class.new(admin, limit_project_ids, query) issues = results.objects('issues') expect(issues).to include issue expect(issues).to include security_issue_1 expect(issues).to include security_issue_2 expect(issues).to include security_issue_3 expect(issues).to include security_issue_4 expect(issues).not_to include security_issue_5 expect(results.issues_count).to eq 5 end end describe 'merge requests' do before do MergeRequest.__elasticsearch__.create_index! @merge_request_1 = create( :merge_request, source_project: project_1, target_project: project_1, title: 'Hello world, here I am!', iid: 1 ) @merge_request_2 = create( :merge_request, :conflict, source_project: project_1, target_project: project_1, title: 'Merge Request 2', description: 'Hello world, here I am!', iid: 2 ) @merge_request_3 = create( :merge_request, source_project: project_2, target_project: project_2, title: 'Merge Request 3', iid: 2 ) MergeRequest.__elasticsearch__.refresh_index! end after do MergeRequest.__elasticsearch__.delete_index! end it 'should list merge requests that title or description contain the query' do results = described_class.new(user, limit_project_ids, 'hello world') 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(results.merge_requests_count).to eq 2 end it 'should return empty list when merge requests title or description does not contain the query' do results = described_class.new(user, limit_project_ids, 'security') expect(results.objects('merge_requests')).to be_empty expect(results.merge_requests_count).to eq 0 end it 'should list merge request when search by a valid iid' do results = described_class.new(user, limit_project_ids, '#2') 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(results.merge_requests_count).to eq 1 end it 'should return empty list when search by invalid iid' do results = described_class.new(user, limit_project_ids, '#222') expect(results.objects('merge_requests')).to be_empty expect(results.merge_requests_count).to eq 0 end end describe 'project scoping' do before do [Project, MergeRequest, Issue, Milestone].each do |model| model.__elasticsearch__.create_index! end end after do [Project, MergeRequest, Issue, Milestone].each do |model| model.__elasticsearch__.delete_index! end end it "returns items for project" do project = create :project, name: "term" # Create issue create :issue, title: 'bla-bla term', project: project create :issue, description: 'bla-bla term', project: project create :issue, project: project # The issue I have no access to create :issue, title: 'bla-bla term' # Create Merge Request create :merge_request, title: 'bla-bla term', source_project: project create :merge_request, description: 'term in description', source_project: project, target_branch: "feature2" create :merge_request, source_project: project, target_branch: "feature3" # The merge request you have no access to create :merge_request, title: 'also with term' create :milestone, title: 'bla-bla term', project: project create :milestone, description: 'bla-bla term', project: project create :milestone, project: project # The Milestone you have no access to create :milestone, title: 'bla-bla term' [Project, MergeRequest, Issue, Milestone].each do |model| model.__elasticsearch__.refresh_index! end result = Gitlab::Elastic::SearchResults.new([project.id], 'term') expect(result.issues_count).to eq(2) expect(result.merge_requests_count).to eq(2) expect(result.milestones_count).to eq(2) expect(result.projects_count).to eq(1) end end end