diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 04:45:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 04:45:44 +0300 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /spec/lib/gitlab/project_search_results_spec.rb | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) |
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'spec/lib/gitlab/project_search_results_spec.rb')
-rw-r--r-- | spec/lib/gitlab/project_search_results_spec.rb | 290 |
1 files changed, 126 insertions, 164 deletions
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb index 6e3c60b58dc..fe0735b8043 100644 --- a/spec/lib/gitlab/project_search_results_spec.rb +++ b/spec/lib/gitlab/project_search_results_spec.rb @@ -5,31 +5,34 @@ require 'spec_helper' RSpec.describe Gitlab::ProjectSearchResults do include SearchHelpers - let(:user) { create(:user) } - let(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } let(:query) { 'hello world' } + let(:repository_ref) { nil } + let(:filters) { {} } - describe 'initialize with empty ref' do - let(:results) { described_class.new(user, project, query, '') } + subject(:results) { described_class.new(user, query, project: project, repository_ref: repository_ref, filters: filters) } - it { expect(results.project).to eq(project) } - it { expect(results.query).to eq('hello world') } - end + context 'with a repository_ref' do + context 'when empty' do + let(:repository_ref) { '' } + + it { expect(results.project).to eq(project) } + it { expect(results.query).to eq('hello world') } + end - describe 'initialize with ref' do - let(:ref) { 'refs/heads/test' } - let(:results) { described_class.new(user, project, query, ref) } + context 'when set' do + let(:repository_ref) { 'refs/heads/test' } - it { expect(results.project).to eq(project) } - it { expect(results.repository_ref).to eq(ref) } - it { expect(results.query).to eq('hello world') } + it { expect(results.project).to eq(project) } + it { expect(results.repository_ref).to eq(repository_ref) } + it { expect(results.query).to eq('hello world') } + end end describe '#formatted_count' do using RSpec::Parameterized::TableSyntax - let(:results) { described_class.new(user, project, query) } - where(:scope, :count_method, :expected) do 'blobs' | :limited_blobs_count | max_limited_count 'notes' | :limited_notes_count | max_limited_count @@ -63,7 +66,8 @@ RSpec.describe Gitlab::ProjectSearchResults do shared_examples 'general blob search' do |entity_type, blob_type| let(:query) { 'files' } - subject(:results) { described_class.new(user, project, query).objects(blob_type) } + + subject(:objects) { results.objects(blob_type) } context "when #{entity_type} is disabled" do let(:project) { disabled_project } @@ -94,17 +98,17 @@ RSpec.describe Gitlab::ProjectSearchResults do end it 'finds by name' do - expect(results.map(&:path)).to include(expected_file_by_path) + expect(objects.map(&:path)).to include(expected_file_by_path) end it "loads all blobs for path matches in single batch" do expect(Gitlab::Git::Blob).to receive(:batch).once.and_call_original - results.map(&:data) + expect { objects.map(&:data) }.not_to raise_error end it 'finds by content' do - blob = results.select { |result| result.path == expected_file_by_content }.flatten.last + blob = objects.select { |result| result.path == expected_file_by_content }.flatten.last expect(blob.path).to eq(expected_file_by_content) end @@ -115,7 +119,7 @@ RSpec.describe Gitlab::ProjectSearchResults do let(:file_finder) { double } let(:project_branch) { 'project_branch' } - subject(:results) { described_class.new(user, project, query, repository_ref).objects(blob_type) } + subject(:objects) { results.objects(blob_type) } before do allow(entity).to receive(:default_branch).and_return(project_branch) @@ -128,7 +132,7 @@ RSpec.describe Gitlab::ProjectSearchResults do it 'uses it' do expect(Gitlab::FileFinder).to receive(:new).with(project, repository_ref).and_return(file_finder) - results + expect { objects }.not_to raise_error end end @@ -138,7 +142,7 @@ RSpec.describe Gitlab::ProjectSearchResults do it "uses #{entity_type} repository default reference" do expect(Gitlab::FileFinder).to receive(:new).with(project, project_branch).and_return(file_finder) - results + expect { objects }.not_to raise_error end end @@ -148,7 +152,7 @@ RSpec.describe Gitlab::ProjectSearchResults do it "uses #{entity_type} repository default reference" do expect(Gitlab::FileFinder).to receive(:new).with(project, project_branch).and_return(file_finder) - results + expect { objects }.not_to raise_error end end end @@ -157,7 +161,6 @@ RSpec.describe Gitlab::ProjectSearchResults do let(:per_page) { 20 } let(:count_limit) { described_class::COUNT_LIMIT } let(:file_finder) { instance_double('Gitlab::FileFinder') } - let(:results) { described_class.new(user, project, query) } let(:repository_ref) { 'master' } before do @@ -228,139 +231,97 @@ RSpec.describe Gitlab::ProjectSearchResults do context 'return type' do let(:blobs) { [Gitlab::Search::FoundBlob.new(project: project)] } - let(:results) { described_class.new(user, project, "Files", per_page: 20) } + let(:query) { "Files" } + + subject(:objects) { results.objects('wiki_blobs', per_page: 20) } before do allow(results).to receive(:wiki_blobs).and_return(blobs) end it 'returns list of FoundWikiPage type object' do - objects = results.objects('wiki_blobs') - expect(objects).to be_present expect(objects).to all(be_a(Gitlab::Search::FoundWikiPage)) end end end - it 'does not list issues on private projects' do - issue = create(:issue, project: project) - - results = described_class.new(user, project, issue.title) - - expect(results.objects('issues')).not_to include issue - end - - describe 'confidential issues' do - let(:query) { 'issue' } - let(:author) { create(:user) } - let(:assignee) { create(:user) } - let(:non_member) { create(:user) } - let(:member) { create(:user) } - let(:admin) { create(:admin) } - let(:project) { create(:project, :internal) } - let!(:issue) { create(:issue, project: project, title: 'Issue 1') } - let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) } - let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignees: [assignee]) } - - it 'does not list project confidential issues for non project members' do - results = described_class.new(non_member, project, 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(results.limited_issues_count).to eq 1 - end - - it 'does not list project confidential issues for project members with guest role' do - project.add_guest(member) + describe 'issues search' do + let(:issue) { create(:issue, project: project) } + let(:query) { issue.title } + let(:scope) { 'issues' } - results = described_class.new(member, project, query) - issues = results.objects('issues') + subject(:objects) { results.objects(scope) } - expect(issues).to include issue - expect(issues).not_to include security_issue_1 - expect(issues).not_to include security_issue_2 - expect(results.limited_issues_count).to eq 1 + it 'does not list issues on private projects' do + expect(objects).not_to include issue end - it 'lists project confidential issues for author' do - results = described_class.new(author, project, 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(results.limited_issues_count).to eq 2 + describe "confidential issues" do + include_examples "access restricted confidential issues" end - it 'lists project confidential issues for assignee' do - results = described_class.new(assignee, project, query) - issues = results.objects('issues') + context 'filtering' do + let_it_be(:project) { create(:project, :public) } + let_it_be(:closed_result) { create(:issue, :closed, project: project, title: 'foo closed') } + let_it_be(:opened_result) { create(:issue, :opened, project: project, title: 'foo opened') } + let(:query) { 'foo' } - expect(issues).to include issue - expect(issues).not_to include security_issue_1 - expect(issues).to include security_issue_2 - expect(results.limited_issues_count).to eq 2 + include_examples 'search results filtered by state' end + end - it 'lists project confidential issues for project members' do - project.add_developer(member) - - results = described_class.new(member, project, 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(results.limited_issues_count).to eq 3 - end + describe 'merge requests search' do + let(:scope) { 'merge_requests' } + let(:project) { create(:project, :public) } - it 'lists all project issues for admin' do - results = described_class.new(admin, project, query) - issues = results.objects('issues') + context 'filtering' do + let!(:project) { create(:project, :public) } + let!(:opened_result) { create(:merge_request, :opened, source_project: project, title: 'foo opened') } + let!(:closed_result) { create(:merge_request, :closed, source_project: project, title: 'foo closed') } + let(:query) { 'foo' } - expect(issues).to include issue - expect(issues).to include security_issue_1 - expect(issues).to include security_issue_2 - expect(results.limited_issues_count).to eq 3 + include_examples 'search results filtered by state' end end describe 'notes search' do - it 'lists notes' do - project = create(:project, :public) - note = create(:note, project: project) + let(:query) { note.note } - results = described_class.new(user, project, note.note) + subject(:notes) { results.objects('notes') } - expect(results.objects('notes')).to include note - end + context 'with a public project' do + let(:project) { create(:project, :public) } + let(:note) { create(:note, project: project) } - it "doesn't list issue notes when access is restricted" do - project = create(:project, :public, :issues_private) - note = create(:note_on_issue, project: project) + it 'lists notes' do + expect(notes).to include note + end + end - results = described_class.new(user, project, note.note) + context 'with private issues' do + let(:project) { create(:project, :public, :issues_private) } + let(:note) { create(:note_on_issue, project: project) } - expect(results.objects('notes')).not_to include note + it "doesn't list issue notes when access is restricted" do + expect(notes).not_to include note + end end - it "doesn't list merge_request notes when access is restricted" do - project = create(:project, :public, :merge_requests_private) - note = create(:note_on_merge_request, project: project) + context 'with private merge requests' do + let(:project) { create(:project, :public, :merge_requests_private) } + let(:note) { create(:note_on_merge_request, project: project) } - results = described_class.new(user, project, note.note) - - expect(results.objects('notes')).not_to include note + it "doesn't list merge_request notes when access is restricted" do + expect(notes).not_to include note + end end end describe '#limited_notes_count' do let(:project) { create(:project, :public) } let(:note) { create(:note_on_issue, project: project) } - let(:results) { described_class.new(user, project, note.note) } + let(:query) { note.note } context 'when count_limit is lower than total amount' do before do @@ -375,11 +336,6 @@ RSpec.describe Gitlab::ProjectSearchResults do context 'when count_limit is higher than total amount' do it 'calls note finder multiple times to get the limited amount of notes' do - project = create(:project, :public) - note = create(:note_on_issue, project: project) - - results = described_class.new(user, project, note.note) - expect(results).to receive(:notes_finder).exactly(4).times.and_call_original expect(results.limited_notes_count).to eq(1) end @@ -395,7 +351,7 @@ RSpec.describe Gitlab::ProjectSearchResults do .with(anything, anything, anything, described_class::COUNT_LIMIT) .and_call_original - described_class.new(user, project, '.').commits_count + results.commits_count end end @@ -406,19 +362,23 @@ RSpec.describe Gitlab::ProjectSearchResults do # * commit # shared_examples 'access restricted commits' do + let(:query) { search_phrase } + context 'when project is internal' do let(:project) { create(:project, :internal, :repository) } - it 'does not search if user is not authenticated' do - commits = described_class.new(nil, project, search_phrase).objects('commits') + subject(:commits) { results.objects('commits') } - expect(commits).to be_empty + it 'searches if user is authenticated' do + expect(commits).to contain_exactly commit end - it 'searches if user is authenticated' do - commits = described_class.new(user, project, search_phrase).objects('commits') + context 'when the user is not authenticated' do + let(:user) { nil } - expect(commits).to contain_exactly commit + it 'does not search' do + expect(commits).to be_empty + end end end @@ -437,29 +397,35 @@ RSpec.describe Gitlab::ProjectSearchResults do user end - it 'does not show commit to stranger' do - commits = described_class.new(nil, private_project, search_phrase).objects('commits') + let(:project) { private_project } - expect(commits).to be_empty + subject(:commits) { results.objects('commits') } + + context 'when the user is not authenticated' do + let(:user) { nil } + + it 'does not show commit to stranger' do + expect(commits).to be_empty + end end context 'team access' do - it 'shows commit to creator' do - commits = described_class.new(creator, private_project, search_phrase).objects('commits') + context 'when the user is the creator' do + let(:user) { creator } - expect(commits).to contain_exactly commit + it { expect(commits).to contain_exactly commit } end - it 'shows commit to master' do - commits = described_class.new(team_master, private_project, search_phrase).objects('commits') + context 'when the user is a master' do + let(:user) { team_master } - expect(commits).to contain_exactly commit + it { expect(commits).to contain_exactly commit } end - it 'shows commit to reporter' do - commits = described_class.new(team_reporter, private_project, search_phrase).objects('commits') + context 'when the user is a reporter' do + let(:user) { team_reporter } - expect(commits).to contain_exactly commit + it { expect(commits).to contain_exactly commit } end end end @@ -471,9 +437,7 @@ RSpec.describe Gitlab::ProjectSearchResults do it 'returns the correct results for each page' do expect(results_page(1)).to contain_exactly(commit('b83d6e391c22777fca1ed3012fce84f633d7fed0')) - expect(results_page(2)).to contain_exactly(commit('498214de67004b1da3d820901307bed2a68a8ef6')) - expect(results_page(3)).to contain_exactly(commit('1b12f15a11fc6e62177bef08f47bc7b5ce50b141')) end @@ -506,7 +470,7 @@ RSpec.describe Gitlab::ProjectSearchResults do end def results_page(page) - described_class.new(user, project, '.').objects('commits', per_page: 1, page: page) + described_class.new(user, '.', project: project).objects('commits', per_page: 1, page: page) end def commit(hash) @@ -518,26 +482,27 @@ RSpec.describe Gitlab::ProjectSearchResults do let(:project) { create(:project, :public, :repository) } let(:commit) { project.repository.commit('59e29889be61e6e0e5e223bfa9ac2721d31605b8') } let(:message) { 'Sorry, I did a mistake' } + let(:query) { message } - it 'finds commit by message' do - commits = described_class.new(user, project, message).objects('commits') + subject(:commits) { results.objects('commits') } + it 'finds commit by message' do expect(commits).to contain_exactly commit end - it 'handles when no commit match' do - commits = described_class.new(user, project, 'not really an existing description').objects('commits') + context 'when there are not hits' do + let(:query) { 'not really an existing description' } - expect(commits).to be_empty + it 'handles when no commit match' do + expect(commits).to be_empty + end end context 'when repository_ref is provided' do - let(:message) { 'Feature added' } + let(:query) { 'Feature added' } let(:repository_ref) { 'feature' } it 'searches in the specified ref' do - commits = described_class.new(user, project, message, repository_ref).objects('commits') - # This commit is unique to the feature branch expect(commits).to contain_exactly(project.repository.commit('0b4bc9a49b562e85de7cc9e834518ea6828729b9')) end @@ -557,14 +522,14 @@ RSpec.describe Gitlab::ProjectSearchResults do commit_hashes.each do |type, commit_hash| it "shows commit by #{type} hash id" do - commits = described_class.new(user, project, commit_hash).objects('commits') + commits = described_class.new(user, commit_hash, project: project).objects('commits') expect(commits).to contain_exactly commit end end it 'handles not existing commit hash correctly' do - commits = described_class.new(user, project, 'deadbeef').objects('commits') + commits = described_class.new(user, 'deadbeef', project: project).objects('commits') expect(commits).to be_empty end @@ -577,9 +542,13 @@ RSpec.describe Gitlab::ProjectSearchResults do end describe 'user search' do - it 'returns the user belonging to the project matching the search query' do - project = create(:project) + let(:query) { 'gob' } + let(:group) { create(:group) } + let(:project) { create(:project, namespace: group) } + subject(:objects) { results.objects('users') } + + it 'returns the user belonging to the project matching the search query' do user1 = create(:user, username: 'gob_bluth') create(:project_member, :developer, user: user1, project: project) @@ -588,23 +557,16 @@ RSpec.describe Gitlab::ProjectSearchResults do create(:user, username: 'gob_2018') - result = described_class.new(user, project, 'gob').objects('users') - - expect(result).to eq [user1] + expect(objects).to contain_exactly(user1) end it 'returns the user belonging to the group matching the search query' do - group = create(:group) - project = create(:project, namespace: group) - user1 = create(:user, username: 'gob_bluth') create(:group_member, :developer, user: user1, group: group) create(:user, username: 'gob_2018') - result = described_class.new(user, project, 'gob').objects('users') - - expect(result).to eq [user1] + expect(objects).to contain_exactly(user1) end end end |