summaryrefslogtreecommitdiff
path: root/spec/finders
diff options
context:
space:
mode:
Diffstat (limited to 'spec/finders')
-rw-r--r--spec/finders/autocomplete/routes_finder_spec.rb57
-rw-r--r--spec/finders/branches_finder_spec.rb8
-rw-r--r--spec/finders/ci/pipelines_for_merge_request_finder_spec.rb150
-rw-r--r--spec/finders/clusters/agent_authorizations_finder_spec.rb124
-rw-r--r--spec/finders/environments/environments_by_deployments_finder_spec.rb14
-rw-r--r--spec/finders/members_finder_spec.rb8
-rw-r--r--spec/finders/tags_finder_spec.rb81
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