summaryrefslogtreecommitdiff
path: root/spec/lib/api
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 07:33:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 07:33:21 +0000
commit36a59d088eca61b834191dacea009677a96c052f (patch)
treee4f33972dab5d8ef79e3944a9f403035fceea43f /spec/lib/api
parenta1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff)
downloadgitlab-ce-36a59d088eca61b834191dacea009677a96c052f.tar.gz
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/lib/api')
-rw-r--r--spec/lib/api/ci/helpers/runner_helpers_spec.rb12
-rw-r--r--spec/lib/api/entities/ci/job_request/dependency_spec.rb7
-rw-r--r--spec/lib/api/entities/plan_limit_spec.rb11
-rw-r--r--spec/lib/api/entities/projects/topic_spec.rb1
-rw-r--r--spec/lib/api/entities/user_spec.rb45
-rw-r--r--spec/lib/api/helpers_spec.rb249
6 files changed, 285 insertions, 40 deletions
diff --git a/spec/lib/api/ci/helpers/runner_helpers_spec.rb b/spec/lib/api/ci/helpers/runner_helpers_spec.rb
index c4d740f0adc..c6cdc1732f5 100644
--- a/spec/lib/api/ci/helpers/runner_helpers_spec.rb
+++ b/spec/lib/api/ci/helpers/runner_helpers_spec.rb
@@ -70,5 +70,17 @@ RSpec.describe API::Ci::Helpers::Runner do
expect(details['ip_address']).to eq(ip_address)
end
end
+
+ describe '#log_artifact_size' do
+ subject { runner_helper.log_artifact_size(artifact) }
+
+ let(:runner_params) { {} }
+ let(:artifact) { create(:ci_job_artifact, size: 42) }
+ let(:expected_params) { { artifact_size: artifact.size } }
+ let(:subject_proc) { proc { subject } }
+
+ it_behaves_like 'storing arguments in the application context'
+ it_behaves_like 'not executing any extra queries for the application context'
+ end
end
end
diff --git a/spec/lib/api/entities/ci/job_request/dependency_spec.rb b/spec/lib/api/entities/ci/job_request/dependency_spec.rb
index fa5f3da554c..bbeb864c2ee 100644
--- a/spec/lib/api/entities/ci/job_request/dependency_spec.rb
+++ b/spec/lib/api/entities/ci/job_request/dependency_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
RSpec.describe API::Entities::Ci::JobRequest::Dependency do
+ let(:running_job) { create(:ci_build, :artifacts) }
let(:job) { create(:ci_build, :artifacts) }
- let(:entity) { described_class.new(job) }
+ let(:entity) { described_class.new(job, { running_job: running_job }) }
subject { entity.as_json }
@@ -16,8 +17,8 @@ RSpec.describe API::Entities::Ci::JobRequest::Dependency do
expect(subject[:name]).to eq(job.name)
end
- it 'returns the dependency token' do
- expect(subject[:token]).to eq(job.token)
+ it 'returns the token belonging to the running job' do
+ expect(subject[:token]).to eq(running_job.token)
end
it 'returns the dependency artifacts_file', :aggregate_failures do
diff --git a/spec/lib/api/entities/plan_limit_spec.rb b/spec/lib/api/entities/plan_limit_spec.rb
index 1b8b21d47f3..a88ea3f4cad 100644
--- a/spec/lib/api/entities/plan_limit_spec.rb
+++ b/spec/lib/api/entities/plan_limit_spec.rb
@@ -9,6 +9,14 @@ RSpec.describe API::Entities::PlanLimit do
it 'exposes correct attributes' do
expect(subject).to include(
+ :ci_pipeline_size,
+ :ci_active_jobs,
+ :ci_active_pipelines,
+ :ci_project_subscriptions,
+ :ci_pipeline_schedules,
+ :ci_needs_size_limit,
+ :ci_registered_group_runners,
+ :ci_registered_project_runners,
:conan_max_file_size,
:generic_packages_max_file_size,
:helm_max_file_size,
@@ -16,7 +24,8 @@ RSpec.describe API::Entities::PlanLimit do
:npm_max_file_size,
:nuget_max_file_size,
:pypi_max_file_size,
- :terraform_module_max_file_size
+ :terraform_module_max_file_size,
+ :storage_size_limit
)
end
diff --git a/spec/lib/api/entities/projects/topic_spec.rb b/spec/lib/api/entities/projects/topic_spec.rb
index cdf142dbb7d..1ea0e724fed 100644
--- a/spec/lib/api/entities/projects/topic_spec.rb
+++ b/spec/lib/api/entities/projects/topic_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe API::Entities::Projects::Topic do
expect(subject).to include(
:id,
:name,
+ :title,
:description,
:total_projects_count,
:avatar_url
diff --git a/spec/lib/api/entities/user_spec.rb b/spec/lib/api/entities/user_spec.rb
index be5e8e8e8c2..407f2894f01 100644
--- a/spec/lib/api/entities/user_spec.rb
+++ b/spec/lib/api/entities/user_spec.rb
@@ -12,7 +12,40 @@ RSpec.describe API::Entities::User do
subject { entity.as_json }
it 'exposes correct attributes' do
- expect(subject).to include(:name, :bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization, :job_title, :work_information, :pronouns)
+ expect(subject.keys).to contain_exactly(
+ # UserSafe
+ :id, :username, :name,
+ # UserBasic
+ :state, :avatar_url, :web_url,
+ # User
+ :created_at, :bio, :location, :public_email, :skype, :linkedin, :twitter,
+ :website_url, :organization, :job_title, :pronouns, :bot, :work_information,
+ :followers, :following, :is_followed, :local_time
+ )
+ end
+
+ context 'exposing follow relationships' do
+ before do
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, user).and_return(can_read_user_profile)
+ end
+
+ %i(followers following is_followed).each do |relationship|
+ context 'when current user cannot read user profile' do
+ let(:can_read_user_profile) { false }
+
+ it "does not expose #{relationship}" do
+ expect(subject).not_to include(relationship)
+ end
+ end
+
+ context 'when current user can read user profile' do
+ let(:can_read_user_profile) { true }
+
+ it "exposes #{relationship}" do
+ expect(subject).to include(relationship)
+ end
+ end
+ end
end
it 'exposes created_at if the current user can read the user profile' do
@@ -135,6 +168,16 @@ RSpec.describe API::Entities::User do
end
end
+ context 'with logged-out user' do
+ let(:current_user) { nil }
+
+ it 'exposes is_followed as nil' do
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, user).and_return(true)
+
+ expect(subject.keys).not_to include(:is_followed)
+ end
+ end
+
it 'exposes local_time' do
local_time = '2:30 PM'
expect(entity).to receive(:local_time).with(timezone).and_return(local_time)
diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb
index 2afe5a1a9d7..78ce9642392 100644
--- a/spec/lib/api/helpers_spec.rb
+++ b/spec/lib/api/helpers_spec.rb
@@ -150,8 +150,8 @@ RSpec.describe API::Helpers do
context 'when user is authenticated' do
before do
- subject.instance_variable_set(:@current_user, user)
- subject.instance_variable_set(:@initial_current_user, user)
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:initial_current_user).and_return(user)
end
context 'public project' do
@@ -167,8 +167,8 @@ RSpec.describe API::Helpers do
context 'when user is not authenticated' do
before do
- subject.instance_variable_set(:@current_user, nil)
- subject.instance_variable_set(:@initial_current_user, nil)
+ allow(subject).to receive(:current_user).and_return(nil)
+ allow(subject).to receive(:initial_current_user).and_return(nil)
end
context 'public project' do
@@ -181,59 +181,214 @@ RSpec.describe API::Helpers do
it_behaves_like 'private project without access'
end
end
+
+ context 'support for IDs and paths as argument' do
+ let_it_be(:project) { create(:project) }
+
+ let(:user) { project.first_owner}
+
+ before do
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:authorized_project_scope?).and_return(true)
+ allow(subject).to receive(:job_token_authentication?).and_return(false)
+ allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ end
+
+ shared_examples 'project finder' do
+ context 'when project exists' do
+ it 'returns requested project' do
+ expect(subject.find_project!(existing_id)).to eq(project)
+ end
+
+ it 'returns nil' do
+ expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
+ expect(subject.find_project!(non_existing_id)).to be_nil
+ end
+ end
+ end
+
+ context 'when ID is used as an argument' do
+ let(:existing_id) { project.id }
+ let(:non_existing_id) { non_existing_record_id }
+
+ it_behaves_like 'project finder'
+ end
+
+ context 'when PATH is used as an argument' do
+ let(:existing_id) { project.full_path }
+ let(:non_existing_id) { 'something/else' }
+
+ it_behaves_like 'project finder'
+
+ context 'with an invalid PATH' do
+ let(:non_existing_id) { 'undefined' } # path without slash
+
+ it_behaves_like 'project finder'
+
+ it 'does not hit the database' do
+ expect(Project).not_to receive(:find_by_full_path)
+ expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
+
+ subject.find_project!(non_existing_id)
+ end
+ end
+ end
+ end
end
- describe '#find_project!' do
- let_it_be(:project) { create(:project) }
+ describe '#find_group!' do
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:user) { create(:user) }
- let(:user) { project.first_owner}
+ shared_examples 'private group without access' do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
+ allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ end
- before do
- allow(subject).to receive(:current_user).and_return(user)
- allow(subject).to receive(:authorized_project_scope?).and_return(true)
- allow(subject).to receive(:job_token_authentication?).and_return(false)
- allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ it 'returns not found' do
+ expect(subject).to receive(:not_found!)
+
+ subject.find_group!(group.id)
+ end
end
- shared_examples 'project finder' do
- context 'when project exists' do
- it 'returns requested project' do
- expect(subject.find_project!(existing_id)).to eq(project)
+ context 'when user is authenticated' do
+ before do
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:initial_current_user).and_return(user)
+ end
+
+ context 'public group' do
+ it 'returns requested group' do
+ expect(subject.find_group!(group.id)).to eq(group)
end
+ end
- it 'returns nil' do
- expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
- expect(subject.find_project!(non_existing_id)).to be_nil
+ context 'private group' do
+ it_behaves_like 'private group without access'
+ end
+ end
+
+ context 'when user is not authenticated' do
+ before do
+ allow(subject).to receive(:current_user).and_return(nil)
+ allow(subject).to receive(:initial_current_user).and_return(nil)
+ end
+
+ context 'public group' do
+ it 'returns requested group' do
+ expect(subject.find_group!(group.id)).to eq(group)
end
end
+
+ context 'private group' do
+ it_behaves_like 'private group without access'
+ end
end
- context 'when ID is used as an argument' do
- let(:existing_id) { project.id }
- let(:non_existing_id) { non_existing_record_id }
+ context 'support for IDs and paths as arguments' do
+ let_it_be(:group) { create(:group) }
- it_behaves_like 'project finder'
+ let(:user) { group.first_owner }
+
+ before do
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:authorized_project_scope?).and_return(true)
+ allow(subject).to receive(:job_token_authentication?).and_return(false)
+ allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ end
+
+ shared_examples 'group finder' do
+ context 'when group exists' do
+ it 'returns requested group' do
+ expect(subject.find_group!(existing_id)).to eq(group)
+ end
+
+ it 'returns nil' do
+ expect(subject).to receive(:render_api_error!).with('404 Group Not Found', 404)
+ expect(subject.find_group!(non_existing_id)).to be_nil
+ end
+ end
+ end
+
+ context 'when ID is used as an argument' do
+ let(:existing_id) { group.id }
+ let(:non_existing_id) { non_existing_record_id }
+
+ it_behaves_like 'group finder'
+ end
+
+ context 'when PATH is used as an argument' do
+ let(:existing_id) { group.full_path }
+ let(:non_existing_id) { 'something/else' }
+
+ it_behaves_like 'group finder'
+ end
end
+ end
- context 'when PATH is used as an argument' do
- let(:existing_id) { project.full_path }
- let(:non_existing_id) { 'something/else' }
+ describe '#find_group_by_full_path!' do
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:user) { create(:user) }
- it_behaves_like 'project finder'
+ shared_examples 'private group without access' do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
+ allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ end
- context 'with an invalid PATH' do
- let(:non_existing_id) { 'undefined' } # path without slash
+ it 'returns not found' do
+ expect(subject).to receive(:not_found!)
- it_behaves_like 'project finder'
+ subject.find_group_by_full_path!(group.full_path)
+ end
+ end
- it 'does not hit the database' do
- expect(Project).not_to receive(:find_by_full_path)
- expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
+ context 'when user is authenticated' do
+ before do
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:initial_current_user).and_return(user)
+ end
- subject.find_project!(non_existing_id)
+ context 'public group' do
+ it 'returns requested group' do
+ expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
+ end
+ end
+
+ context 'private group' do
+ it_behaves_like 'private group without access'
+
+ context 'with access' do
+ before do
+ group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
+ group.add_developer(user)
+ end
+
+ it 'returns requested group with access' do
+ expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
+ end
end
end
end
+
+ context 'when user is not authenticated' do
+ before do
+ allow(subject).to receive(:current_user).and_return(nil)
+ allow(subject).to receive(:initial_current_user).and_return(nil)
+ end
+
+ context 'public group' do
+ it 'returns requested group' do
+ expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
+ end
+ end
+
+ context 'private group' do
+ it_behaves_like 'private group without access'
+ end
+ end
end
describe '#find_namespace' do
@@ -433,7 +588,7 @@ RSpec.describe API::Helpers do
end
end
- describe '#order_options_with_tie_breaker' do
+ shared_examples '#order_options_with_tie_breaker' do
subject { Class.new.include(described_class).new.order_options_with_tie_breaker }
before do
@@ -475,6 +630,30 @@ RSpec.describe API::Helpers do
end
end
+ describe '#order_options_with_tie_breaker' do
+ include_examples '#order_options_with_tie_breaker'
+
+ context 'with created_at order given' do
+ let(:params) { { order_by: 'created_at', sort: 'asc' } }
+
+ it 'converts to id' do
+ is_expected.to eq({ 'id' => 'asc' })
+ end
+
+ context 'when replace_order_by_created_at_with_id feature flag is disabled' do
+ before do
+ stub_feature_flags(replace_order_by_created_at_with_id: false)
+ end
+
+ include_examples '#order_options_with_tie_breaker'
+
+ it 'maintains created_at order' do
+ is_expected.to eq({ 'created_at' => 'asc', 'id' => 'asc' })
+ end
+ end
+ end
+ end
+
describe "#destroy_conditionally!" do
let!(:project) { create(:project) }