diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 07:33:21 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 07:33:21 +0000 |
commit | 36a59d088eca61b834191dacea009677a96c052f (patch) | |
tree | e4f33972dab5d8ef79e3944a9f403035fceea43f /spec/lib/api | |
parent | a1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff) | |
download | gitlab-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.rb | 12 | ||||
-rw-r--r-- | spec/lib/api/entities/ci/job_request/dependency_spec.rb | 7 | ||||
-rw-r--r-- | spec/lib/api/entities/plan_limit_spec.rb | 11 | ||||
-rw-r--r-- | spec/lib/api/entities/projects/topic_spec.rb | 1 | ||||
-rw-r--r-- | spec/lib/api/entities/user_spec.rb | 45 | ||||
-rw-r--r-- | spec/lib/api/helpers_spec.rb | 249 |
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) } |