diff options
Diffstat (limited to 'spec/finders')
-rw-r--r-- | spec/finders/autocomplete/routes_finder_spec.rb | 57 | ||||
-rw-r--r-- | spec/finders/branches_finder_spec.rb | 8 | ||||
-rw-r--r-- | spec/finders/ci/pipelines_for_merge_request_finder_spec.rb | 150 | ||||
-rw-r--r-- | spec/finders/clusters/agent_authorizations_finder_spec.rb | 124 | ||||
-rw-r--r-- | spec/finders/environments/environments_by_deployments_finder_spec.rb | 14 | ||||
-rw-r--r-- | spec/finders/members_finder_spec.rb | 8 | ||||
-rw-r--r-- | spec/finders/tags_finder_spec.rb | 81 |
7 files changed, 331 insertions, 111 deletions
diff --git a/spec/finders/autocomplete/routes_finder_spec.rb b/spec/finders/autocomplete/routes_finder_spec.rb new file mode 100644 index 00000000000..c5b040a5640 --- /dev/null +++ b/spec/finders/autocomplete/routes_finder_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Autocomplete::RoutesFinder do + describe '#execute' do + let_it_be(:user) { create(:user, username: 'user_path') } + let_it_be(:admin) { create(:admin) } + let_it_be(:group) { create(:group, path: 'path1') } + let_it_be(:group2) { create(:group, path: 'path2') } + let_it_be(:group3) { create(:group, path: 'not-matching') } + let_it_be(:project) { create(:project, path: 'path3', namespace: user.namespace) } + let_it_be(:project2) { create(:project, path: 'path4') } + let_it_be(:project_namespace) { create(:project_namespace, parent: group, path: 'path5') } + + let(:current_user) { user } + let(:search) { 'path' } + + before do + group.add_owner(user) + end + + context 'for NamespacesOnly' do + subject { Autocomplete::RoutesFinder::NamespacesOnly.new(current_user, search: search).execute } + + let(:user_route) { Route.find_by_path(user.username) } + + it 'finds only user namespace and groups matching the search excluding project namespaces' do + is_expected.to match_array([group.route, user_route]) + end + + context 'when user is admin' do + let(:current_user) { admin } + + it 'finds all namespaces matching the search excluding project namespaces' do + is_expected.to match_array([group.route, group2.route, user_route]) + end + end + end + + context 'for ProjectsOnly' do + subject { Autocomplete::RoutesFinder::ProjectsOnly.new(current_user, search: 'path').execute } + + it 'finds only matching projects the user has access to' do + is_expected.to match_array([project.route]) + end + + context 'when user is admin' do + let(:current_user) { admin } + + it 'finds all projects matching the search' do + is_expected.to match_array([project.route, project2.route]) + end + end + end + end +end diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb index f9d525c33a4..11b7ab08fb2 100644 --- a/spec/finders/branches_finder_spec.rb +++ b/spec/finders/branches_finder_spec.rb @@ -208,10 +208,10 @@ RSpec.describe BranchesFinder do context 'by page_token only' do let(:params) { { page_token: 'feature' } } - it 'returns nothing' do - result = subject - - expect(result.count).to eq(0) + it 'raises an error' do + expect do + subject + end.to raise_error(Gitlab::Git::CommandError, '13:could not find page token.') end end diff --git a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb index 8a802e9660b..a7cf041f553 100644 --- a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb +++ b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb @@ -135,86 +135,6 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do end context 'when pipelines exist for the branch and merge request' do - shared_examples 'returns all pipelines for merge request' do - it 'returns merge request pipeline first' do - expect(subject.all).to eq([detached_merge_request_pipeline, branch_pipeline]) - end - - context 'when there are a branch pipeline and a merge request pipeline' do - let!(:branch_pipeline_2) do - create(:ci_pipeline, source: :push, project: project, - ref: source_ref, sha: shas.first) - end - - let!(:detached_merge_request_pipeline_2) do - create(:ci_pipeline, source: :merge_request_event, project: project, - ref: source_ref, sha: shas.first, merge_request: merge_request) - end - - it 'returns merge request pipelines first' do - expect(subject.all) - .to eq([detached_merge_request_pipeline_2, - detached_merge_request_pipeline, - branch_pipeline_2, - branch_pipeline]) - end - end - - context 'when there are multiple merge request pipelines from the same branch' do - let!(:branch_pipeline_2) do - create(:ci_pipeline, source: :push, project: project, - ref: source_ref, sha: shas.first) - end - - let!(:branch_pipeline_with_sha_not_belonging_to_merge_request) do - create(:ci_pipeline, source: :push, project: project, ref: source_ref) - end - - let!(:detached_merge_request_pipeline_2) do - create(:ci_pipeline, source: :merge_request_event, project: project, - ref: source_ref, sha: shas.first, merge_request: merge_request_2) - end - - let(:merge_request_2) do - create(:merge_request, source_project: project, source_branch: source_ref, - target_project: project, target_branch: 'stable') - end - - before do - shas.each.with_index do |sha, index| - create(:merge_request_diff_commit, - merge_request_diff: merge_request_2.merge_request_diff, - sha: sha, relative_order: index) - end - end - - it 'returns only related merge request pipelines' do - expect(subject.all) - .to eq([detached_merge_request_pipeline, - branch_pipeline_2, - branch_pipeline]) - - expect(described_class.new(merge_request_2, nil).all) - .to match_array([detached_merge_request_pipeline_2, branch_pipeline_2, branch_pipeline]) - end - end - - context 'when detached merge request pipeline is run on head ref of the merge request' do - let!(:detached_merge_request_pipeline) do - create(:ci_pipeline, source: :merge_request_event, project: project, - ref: merge_request.ref_path, sha: shas.second, merge_request: merge_request) - end - - it 'sets the head ref of the merge request to the pipeline ref' do - expect(detached_merge_request_pipeline.ref).to match(%r{refs/merge-requests/\d+/head}) - end - - it 'includes the detached merge request pipeline even though the ref is custom path' do - expect(merge_request.all_pipelines).to include(detached_merge_request_pipeline) - end - end - end - let(:source_ref) { 'feature' } let(:target_ref) { 'master' } @@ -240,20 +160,76 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do let(:project) { create(:project, :repository) } let(:shas) { project.repository.commits(source_ref, limit: 2).map(&:id) } - context 'when `decomposed_ci_query_in_pipelines_for_merge_request_finder` feature flag enabled' do - before do - stub_feature_flags(decomposed_ci_query_in_pipelines_for_merge_request_finder: merge_request.target_project) + it 'returns merge request pipeline first' do + expect(subject.all).to match_array([detached_merge_request_pipeline, branch_pipeline]) + end + + context 'when there are a branch pipeline and a merge request pipeline' do + let!(:branch_pipeline_2) do + create(:ci_pipeline, source: :push, project: project, + ref: source_ref, sha: shas.first) + end + + let!(:detached_merge_request_pipeline_2) do + create(:ci_pipeline, source: :merge_request_event, project: project, + ref: source_ref, sha: shas.first, merge_request: merge_request) end - it_behaves_like 'returns all pipelines for merge request' + it 'returns merge request pipelines first' do + expect(subject.all) + .to match_array([detached_merge_request_pipeline_2, detached_merge_request_pipeline, branch_pipeline_2, branch_pipeline]) + end end - context 'when `decomposed_ci_query_in_pipelines_for_merge_request_finder` feature flag disabled' do + context 'when there are multiple merge request pipelines from the same branch' do + let!(:branch_pipeline_2) do + create(:ci_pipeline, source: :push, project: project, + ref: source_ref, sha: shas.first) + end + + let!(:branch_pipeline_with_sha_not_belonging_to_merge_request) do + create(:ci_pipeline, source: :push, project: project, ref: source_ref) + end + + let!(:detached_merge_request_pipeline_2) do + create(:ci_pipeline, source: :merge_request_event, project: project, + ref: source_ref, sha: shas.first, merge_request: merge_request_2) + end + + let(:merge_request_2) do + create(:merge_request, source_project: project, source_branch: source_ref, + target_project: project, target_branch: 'stable') + end + before do - stub_feature_flags(decomposed_ci_query_in_pipelines_for_merge_request_finder: false) + shas.each.with_index do |sha, index| + create(:merge_request_diff_commit, + merge_request_diff: merge_request_2.merge_request_diff, + sha: sha, relative_order: index) + end end - it_behaves_like 'returns all pipelines for merge request' + it 'returns only related merge request pipelines' do + expect(subject.all).to match_array([detached_merge_request_pipeline, branch_pipeline_2, branch_pipeline]) + + expect(described_class.new(merge_request_2, nil).all) + .to match_array([detached_merge_request_pipeline_2, branch_pipeline_2, branch_pipeline]) + end + end + + context 'when detached merge request pipeline is run on head ref of the merge request' do + let!(:detached_merge_request_pipeline) do + create(:ci_pipeline, source: :merge_request_event, project: project, + ref: merge_request.ref_path, sha: shas.second, merge_request: merge_request) + end + + it 'sets the head ref of the merge request to the pipeline ref' do + expect(detached_merge_request_pipeline.ref).to match(%r{refs/merge-requests/\d+/head}) + end + + it 'includes the detached merge request pipeline even though the ref is custom path' do + expect(merge_request.all_pipelines).to include(detached_merge_request_pipeline) + end end end end diff --git a/spec/finders/clusters/agent_authorizations_finder_spec.rb b/spec/finders/clusters/agent_authorizations_finder_spec.rb new file mode 100644 index 00000000000..687906db0d7 --- /dev/null +++ b/spec/finders/clusters/agent_authorizations_finder_spec.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Clusters::AgentAuthorizationsFinder do + describe '#execute' do + let_it_be(:top_level_group) { create(:group) } + let_it_be(:subgroup1) { create(:group, parent: top_level_group) } + let_it_be(:subgroup2) { create(:group, parent: subgroup1) } + let_it_be(:bottom_level_group) { create(:group, parent: subgroup2) } + + let_it_be(:agent_configuration_project) { create(:project, namespace: subgroup1) } + let_it_be(:requesting_project, reload: true) { create(:project, namespace: bottom_level_group) } + + let_it_be(:staging_agent) { create(:cluster_agent, project: agent_configuration_project) } + let_it_be(:production_agent) { create(:cluster_agent, project: agent_configuration_project) } + + subject { described_class.new(requesting_project).execute } + + shared_examples_for 'access_as' do + let(:config) { { access_as: { access_as => {} } } } + + context 'agent' do + let(:access_as) { :agent } + + it { is_expected.to match_array [authorization] } + end + + context 'impersonate' do + let(:access_as) { :impersonate } + + it { is_expected.to be_empty } + end + + context 'ci_user' do + let(:access_as) { :ci_user } + + it { is_expected.to be_empty } + end + + context 'ci_job' do + let(:access_as) { :ci_job } + + it { is_expected.to be_empty } + end + end + + describe 'project authorizations' do + context 'agent configuration project does not share a root namespace with the given project' do + let(:unrelated_agent) { create(:cluster_agent) } + + before do + create(:agent_project_authorization, agent: unrelated_agent, project: requesting_project) + end + + it { is_expected.to be_empty } + end + + context 'with project authorizations present' do + let!(:authorization) { create(:agent_project_authorization, agent: production_agent, project: requesting_project) } + + it { is_expected.to match_array [authorization] } + end + + context 'with overlapping authorizations' do + let!(:agent) { create(:cluster_agent, project: requesting_project) } + let!(:project_authorization) { create(:agent_project_authorization, agent: agent, project: requesting_project) } + let!(:group_authorization) { create(:agent_group_authorization, agent: agent, group: bottom_level_group) } + + it { is_expected.to match_array [project_authorization] } + end + + it_behaves_like 'access_as' do + let!(:authorization) { create(:agent_project_authorization, agent: production_agent, project: requesting_project, config: config) } + end + end + + describe 'implicit authorizations' do + let!(:associated_agent) { create(:cluster_agent, project: requesting_project) } + + it 'returns authorizations for agents directly associated with the project' do + expect(subject.count).to eq(1) + + authorization = subject.first + expect(authorization).to be_a(Clusters::Agents::ImplicitAuthorization) + expect(authorization.agent).to eq(associated_agent) + end + end + + describe 'authorized groups' do + context 'agent configuration project is outside the requesting project hierarchy' do + let(:unrelated_agent) { create(:cluster_agent) } + + before do + create(:agent_group_authorization, agent: unrelated_agent, group: top_level_group) + end + + it { is_expected.to be_empty } + end + + context 'multiple agents are authorized for the same group' do + let!(:staging_auth) { create(:agent_group_authorization, agent: staging_agent, group: bottom_level_group) } + let!(:production_auth) { create(:agent_group_authorization, agent: production_agent, group: bottom_level_group) } + + it 'returns authorizations for all agents' do + expect(subject).to contain_exactly(staging_auth, production_auth) + end + end + + context 'a single agent is authorized to more than one matching group' do + let!(:bottom_level_auth) { create(:agent_group_authorization, agent: production_agent, group: bottom_level_group) } + let!(:top_level_auth) { create(:agent_group_authorization, agent: production_agent, group: top_level_group) } + + it 'picks the authorization for the closest group to the requesting project' do + expect(subject).to contain_exactly(bottom_level_auth) + end + end + + it_behaves_like 'access_as' do + let!(:authorization) { create(:agent_group_authorization, agent: production_agent, group: top_level_group, config: config) } + end + end + end +end diff --git a/spec/finders/environments/environments_by_deployments_finder_spec.rb b/spec/finders/environments/environments_by_deployments_finder_spec.rb index 1b86aced67d..7804ffa4ef1 100644 --- a/spec/finders/environments/environments_by_deployments_finder_spec.rb +++ b/spec/finders/environments/environments_by_deployments_finder_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Environments::EnvironmentsByDeploymentsFinder do project.add_maintainer(user) end - describe '#execute' do + shared_examples 'execute' do context 'tagged deployment' do let(:environment_two) { create(:environment, project: project) } # Environments need to include commits, so rewind two commits to fit @@ -124,4 +124,16 @@ RSpec.describe Environments::EnvironmentsByDeploymentsFinder do end end end + + describe "#execute" do + include_examples 'execute' + + context 'when environments_by_deployments_finder_exists_optimization is disabled' do + before do + stub_feature_flags(environments_by_deployments_finder_exists_optimization: false) + end + + include_examples 'execute' + end + end end diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb index 749e319f9c7..aa7d32e51ac 100644 --- a/spec/finders/members_finder_spec.rb +++ b/spec/finders/members_finder_spec.rb @@ -202,13 +202,5 @@ RSpec.describe MembersFinder, '#execute' do end it_behaves_like 'with invited_groups param' - - context 'when feature flag :linear_members_finder_ancestor_scopes is disabled' do - before do - stub_feature_flags(linear_members_finder_ancestor_scopes: false) - end - - it_behaves_like 'with invited_groups param' - end end end diff --git a/spec/finders/tags_finder_spec.rb b/spec/finders/tags_finder_spec.rb index fe015d53ac9..acc86547271 100644 --- a/spec/finders/tags_finder_spec.rb +++ b/spec/finders/tags_finder_spec.rb @@ -7,13 +7,8 @@ RSpec.describe TagsFinder do let_it_be(:project) { create(:project, :repository) } let_it_be(:repository) { project.repository } - def load_tags(params) - tags_finder = described_class.new(repository, params) - tags, error = tags_finder.execute - - expect(error).to eq(nil) - - tags + def load_tags(params, gitaly_pagination: false) + described_class.new(repository, params).execute(gitaly_pagination: gitaly_pagination) end describe '#execute' do @@ -101,15 +96,79 @@ RSpec.describe TagsFinder do end end + context 'with Gitaly pagination' do + subject { load_tags(params, gitaly_pagination: true) } + + context 'by page_token and per_page' do + let(:params) { { page_token: 'v1.0.0', per_page: 1 } } + + it 'filters tags' do + result = subject + + expect(result.map(&:name)).to eq(%w(v1.1.0)) + end + end + + context 'by next page_token and per_page' do + let(:params) { { page_token: 'v1.1.0', per_page: 2 } } + + it 'filters branches' do + result = subject + + expect(result.map(&:name)).to eq(%w(v1.1.1)) + end + end + + context 'by per_page only' do + let(:params) { { per_page: 2 } } + + it 'filters branches' do + result = subject + + expect(result.map(&:name)).to eq(%w(v1.0.0 v1.1.0)) + end + end + + context 'by page_token only' do + let(:params) { { page_token: 'feature' } } + + it 'raises an error' do + expect do + subject + end.to raise_error(Gitlab::Git::InvalidPageToken, 'Invalid page token: refs/tags/feature') + end + end + + context 'pagination and sort' do + context 'by per_page' do + let(:params) { { sort: 'updated_desc', per_page: 5 } } + + it 'filters branches' do + result = subject + + expect(result.map(&:name)).to eq(%w(v1.1.1 v1.1.0 v1.0.0)) + end + end + + context 'by page_token and per_page' do + let(:params) { { sort: 'updated_desc', page_token: 'v1.1.1', per_page: 2 } } + + it 'filters branches' do + result = subject + + expect(result.map(&:name)).to eq(%w(v1.1.0 v1.0.0)) + end + end + end + end + context 'when Gitaly is unavailable' do - it 'returns empty list of tags' do + it 'raises an exception' do expect(Gitlab::GitalyClient).to receive(:call).and_raise(GRPC::Unavailable) tags_finder = described_class.new(repository, {}) - tags, error = tags_finder.execute - expect(error).to be_a(Gitlab::Git::CommandError) - expect(tags).to eq([]) + expect { tags_finder.execute }.to raise_error(Gitlab::Git::CommandError) end end end |