diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-16 09:07:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-16 09:07:51 +0000 |
commit | 914ea32e0efca21436220df2c10e1bfbe4ed3da9 (patch) | |
tree | e8eb3b97aea2006bd863c586b7ec41d51f654b3b /spec | |
parent | 3546e1bb0971347e9e9984de0799e3fb53743b33 (diff) | |
download | gitlab-ce-914ea32e0efca21436220df2c10e1bfbe4ed3da9.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
56 files changed, 666 insertions, 61 deletions
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index a35ef99ef12..3c39a6468e5 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -385,6 +385,29 @@ describe GroupsController do expect(response).to have_gitlab_http_status(302) expect(group.reload.project_creation_level).to eq(::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) end + + context 'when a project inside the group has container repositories' do + before do + stub_container_registry_config(enabled: true) + stub_container_registry_tags(repository: /image/, tags: %w[rc1]) + create(:container_repository, project: project, name: :image) + end + + it 'does allow the group to be renamed' do + post :update, params: { id: group.to_param, group: { name: 'new_name' } } + + expect(controller).to set_flash[:notice] + expect(response).to have_gitlab_http_status(302) + expect(group.reload.name).to eq('new_name') + end + + it 'does not allow to path of the group to be changed' do + post :update, params: { id: group.to_param, group: { path: 'new_path' } } + + expect(assigns(:group).errors[:base].first).to match(/Docker images in their Container Registry/) + expect(response).to have_gitlab_http_status(200) + end + end end describe '#ensure_canonical_path' do @@ -673,6 +696,28 @@ describe GroupsController do expect(response).to have_gitlab_http_status(404) end end + + context 'transferring when a project has container images' do + let(:group) { create(:group, :public, :nested) } + let!(:group_member) { create(:group_member, :owner, group: group, user: user) } + + before do + stub_container_registry_config(enabled: true) + stub_container_registry_tags(repository: /image/, tags: %w[rc1]) + create(:container_repository, project: project, name: :image) + + put :transfer, + params: { + id: group.to_param, + new_parent_group_id: '' + } + end + + it 'does not allow the group to be transferred' do + expect(controller).to set_flash[:alert].to match(/Docker images in their Container Registry/) + expect(response).to redirect_to(edit_group_path(group)) + end + end end context 'token authentication' do diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index d964b0672a9..e3ad36f8d24 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -217,6 +217,193 @@ describe Projects::PipelinesController do end end + context 'with triggered pipelines' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:source_project) { create(:project, :repository) } + let_it_be(:target_project) { create(:project, :repository) } + let_it_be(:root_pipeline) { create_pipeline(project) } + let_it_be(:source_pipeline) { create_pipeline(source_project) } + let_it_be(:source_of_source_pipeline) { create_pipeline(source_project) } + let_it_be(:target_pipeline) { create_pipeline(target_project) } + let_it_be(:target_of_target_pipeline) { create_pipeline(target_project) } + + before do + create_link(source_of_source_pipeline, source_pipeline) + create_link(source_pipeline, root_pipeline) + create_link(root_pipeline, target_pipeline) + create_link(target_pipeline, target_of_target_pipeline) + end + + shared_examples 'not expanded' do + let(:expected_stages) { be_nil } + + it 'does return base details' do + get_pipeline_json(root_pipeline) + + expect(json_response['triggered_by']).to include('id' => source_pipeline.id) + expect(json_response['triggered']).to contain_exactly( + include('id' => target_pipeline.id)) + end + + it 'does not expand triggered_by pipeline' do + get_pipeline_json(root_pipeline) + + triggered_by = json_response['triggered_by'] + expect(triggered_by['triggered_by']).to be_nil + expect(triggered_by['triggered']).to be_nil + expect(triggered_by['details']['stages']).to expected_stages + end + + it 'does not expand triggered pipelines' do + get_pipeline_json(root_pipeline) + + first_triggered = json_response['triggered'].first + expect(first_triggered['triggered_by']).to be_nil + expect(first_triggered['triggered']).to be_nil + expect(first_triggered['details']['stages']).to expected_stages + end + end + + shared_examples 'expanded' do + it 'does return base details' do + get_pipeline_json(root_pipeline) + + expect(json_response['triggered_by']).to include('id' => source_pipeline.id) + expect(json_response['triggered']).to contain_exactly( + include('id' => target_pipeline.id)) + end + + it 'does expand triggered_by pipeline' do + get_pipeline_json(root_pipeline) + + triggered_by = json_response['triggered_by'] + expect(triggered_by['triggered_by']).to include( + 'id' => source_of_source_pipeline.id) + expect(triggered_by['details']['stages']).not_to be_nil + end + + it 'does not recursively expand triggered_by' do + get_pipeline_json(root_pipeline) + + triggered_by = json_response['triggered_by'] + expect(triggered_by['triggered']).to be_nil + end + + it 'does expand triggered pipelines' do + get_pipeline_json(root_pipeline) + + first_triggered = json_response['triggered'].first + expect(first_triggered['triggered']).to contain_exactly( + include('id' => target_of_target_pipeline.id)) + expect(first_triggered['details']['stages']).not_to be_nil + end + + it 'does not recursively expand triggered' do + get_pipeline_json(root_pipeline) + + first_triggered = json_response['triggered'].first + expect(first_triggered['triggered_by']).to be_nil + end + end + + context 'when it does have permission to read other projects' do + before do + source_project.add_developer(user) + target_project.add_developer(user) + end + + context 'when not-expanding any pipelines' do + let(:expanded) { nil } + + it_behaves_like 'not expanded' + end + + context 'when expanding non-existing pipeline' do + let(:expanded) { [-1] } + + it_behaves_like 'not expanded' + end + + context 'when expanding pipeline that is not directly expandable' do + let(:expanded) { [source_of_source_pipeline.id, target_of_target_pipeline.id] } + + it_behaves_like 'not expanded' + end + + context 'when expanding self' do + let(:expanded) { [root_pipeline.id] } + + context 'it does not recursively expand pipelines' do + it_behaves_like 'not expanded' + end + end + + context 'when expanding source and target pipeline' do + let(:expanded) { [source_pipeline.id, target_pipeline.id] } + + it_behaves_like 'expanded' + + context 'when expand depth is limited to 1' do + before do + stub_const('TriggeredPipelineEntity::MAX_EXPAND_DEPTH', 1) + end + + it_behaves_like 'not expanded' do + # We expect that triggered/triggered_by is not expanded, + # but we still return details.stages for that pipeline + let(:expected_stages) { be_a(Array) } + end + end + end + + context 'when expanding all' do + let(:expanded) do + [ + source_of_source_pipeline.id, + source_pipeline.id, + root_pipeline.id, + target_pipeline.id, + target_of_target_pipeline.id + ] + end + + it_behaves_like 'expanded' + end + end + + context 'when does not have permission to read other projects' do + let(:expanded) { [source_pipeline.id, target_pipeline.id] } + + it_behaves_like 'not expanded' + end + + def create_pipeline(project) + create(:ci_empty_pipeline, project: project).tap do |pipeline| + create(:ci_build, pipeline: pipeline, stage: 'test', name: 'rspec') + end + end + + def create_link(source_pipeline, pipeline) + source_pipeline.sourced_pipelines.create!( + source_job: source_pipeline.builds.all.sample, + source_project: source_pipeline.project, + project: pipeline.project, + pipeline: pipeline + ) + end + + def get_pipeline_json(pipeline) + params = { + namespace_id: pipeline.project.namespace, + project_id: pipeline.project, + id: pipeline, + expanded: expanded + } + + get :show, params: params.compact, format: :json + end + end + def get_pipeline_json get :show, params: { namespace_id: project.namespace, project_id: project, id: pipeline }, format: :json end diff --git a/spec/dependencies/omniauth_saml_spec.rb b/spec/dependencies/omniauth_saml_spec.rb index ccc604dc230..8a685648c71 100644 --- a/spec/dependencies/omniauth_saml_spec.rb +++ b/spec/dependencies/omniauth_saml_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'omniauth/strategies/saml' diff --git a/spec/factories/ci/sources/pipelines.rb b/spec/factories/ci/sources/pipelines.rb new file mode 100644 index 00000000000..57495502944 --- /dev/null +++ b/spec/factories/ci/sources/pipelines.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_sources_pipeline, class: Ci::Sources::Pipeline do + after(:build) do |source| + source.project ||= source.pipeline.project + source.source_pipeline ||= source.source_job.pipeline + source.source_project ||= source.source_pipeline.project + end + + source_job factory: :ci_build + + pipeline factory: :ci_empty_pipeline + end +end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 458c67760d5..f5d5bc7f5b9 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'tempfile' @@ -424,8 +426,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do it 'loads job trace' do expect(page).to have_content 'BUILD TRACE' - job.trace.write('a+b') do |stream| - stream.append(' and more trace', 11) + job.trace.write(+'a+b') do |stream| + stream.append(+' and more trace', 11) end expect(page).to have_content 'BUILD TRACE and more trace' diff --git a/spec/finders/access_requests_finder_spec.rb b/spec/finders/access_requests_finder_spec.rb index 605777462bb..4c67087b50f 100644 --- a/spec/finders/access_requests_finder_spec.rb +++ b/spec/finders/access_requests_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe AccessRequestsFinder do diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb index 44cc8debd04..eb5d0bba183 100644 --- a/spec/finders/admin/projects_finder_spec.rb +++ b/spec/finders/admin/projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Admin::ProjectsFinder do diff --git a/spec/finders/autocomplete/move_to_project_finder_spec.rb b/spec/finders/autocomplete/move_to_project_finder_spec.rb index 4a87b47bd08..f997dd32c40 100644 --- a/spec/finders/autocomplete/move_to_project_finder_spec.rb +++ b/spec/finders/autocomplete/move_to_project_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Autocomplete::MoveToProjectFinder do diff --git a/spec/finders/autocomplete/users_finder_spec.rb b/spec/finders/autocomplete/users_finder_spec.rb index f3b54ca0461..5d340c46114 100644 --- a/spec/finders/autocomplete/users_finder_spec.rb +++ b/spec/finders/autocomplete/users_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Autocomplete::UsersFinder do diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb index 3fc86f3e408..1a33bdf11d7 100644 --- a/spec/finders/branches_finder_spec.rb +++ b/spec/finders/branches_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe BranchesFinder do diff --git a/spec/finders/clusters_finder_spec.rb b/spec/finders/clusters_finder_spec.rb index da529e0670f..f6ea8347f67 100644 --- a/spec/finders/clusters_finder_spec.rb +++ b/spec/finders/clusters_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe ClustersFinder do diff --git a/spec/finders/concerns/finder_methods_spec.rb b/spec/finders/concerns/finder_methods_spec.rb index e074e53c2c5..2e44df8b044 100644 --- a/spec/finders/concerns/finder_methods_spec.rb +++ b/spec/finders/concerns/finder_methods_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe FinderMethods do diff --git a/spec/finders/concerns/finder_with_cross_project_access_spec.rb b/spec/finders/concerns/finder_with_cross_project_access_spec.rb index f29acb521a8..7f6190f96e0 100644 --- a/spec/finders/concerns/finder_with_cross_project_access_spec.rb +++ b/spec/finders/concerns/finder_with_cross_project_access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe FinderWithCrossProjectAccess do diff --git a/spec/finders/contributed_projects_finder_spec.rb b/spec/finders/contributed_projects_finder_spec.rb index ee84fd067d4..1d907261fe9 100644 --- a/spec/finders/contributed_projects_finder_spec.rb +++ b/spec/finders/contributed_projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe ContributedProjectsFinder do diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb index 25835bb4d94..69687eaa99f 100644 --- a/spec/finders/environments_finder_spec.rb +++ b/spec/finders/environments_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe EnvironmentsFinder do diff --git a/spec/finders/events_finder_spec.rb b/spec/finders/events_finder_spec.rb index 3bce46cc4d1..848030262cd 100644 --- a/spec/finders/events_finder_spec.rb +++ b/spec/finders/events_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe EventsFinder do diff --git a/spec/finders/fork_projects_finder_spec.rb b/spec/finders/fork_projects_finder_spec.rb index 98cff37205e..2fba53a74a0 100644 --- a/spec/finders/fork_projects_finder_spec.rb +++ b/spec/finders/fork_projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe ForkProjectsFinder do diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb index 5fb6739d6e2..17875a9b9ab 100644 --- a/spec/finders/group_descendants_finder_spec.rb +++ b/spec/finders/group_descendants_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe GroupDescendantsFinder do diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb index 49b0e14241e..12f92f6b5b0 100644 --- a/spec/finders/group_members_finder_spec.rb +++ b/spec/finders/group_members_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe GroupMembersFinder, '#execute' do diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb index f4bd8a3f6ba..b291b5d4b90 100644 --- a/spec/finders/group_projects_finder_spec.rb +++ b/spec/finders/group_projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe GroupProjectsFinder do diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb index c8875d1f92d..741a89a270b 100644 --- a/spec/finders/groups_finder_spec.rb +++ b/spec/finders/groups_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe GroupsFinder do diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index a17ff1ad50d..c27ce263bf0 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe IssuesFinder do diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb index ae3e55f90f1..b01bd44470a 100644 --- a/spec/finders/joined_groups_finder_spec.rb +++ b/spec/finders/joined_groups_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe JoinedGroupsFinder do diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb index ba41ded112a..2681f098fec 100644 --- a/spec/finders/labels_finder_spec.rb +++ b/spec/finders/labels_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe LabelsFinder do diff --git a/spec/finders/license_template_finder_spec.rb b/spec/finders/license_template_finder_spec.rb index f6f40bf33cc..183ee67d801 100644 --- a/spec/finders/license_template_finder_spec.rb +++ b/spec/finders/license_template_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe LicenseTemplateFinder do diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb index 5134db96133..9849808c255 100644 --- a/spec/finders/members_finder_spec.rb +++ b/spec/finders/members_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe MembersFinder, '#execute' do diff --git a/spec/finders/merge_request_target_project_finder_spec.rb b/spec/finders/merge_request_target_project_finder_spec.rb index d26a75179de..1d78b7ba4e3 100644 --- a/spec/finders/merge_request_target_project_finder_spec.rb +++ b/spec/finders/merge_request_target_project_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe MergeRequestTargetProjectFinder do diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index 6c0bbeff4f4..a396284f1e9 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe MergeRequestsFinder do diff --git a/spec/finders/milestones_finder_spec.rb b/spec/finders/milestones_finder_spec.rb index 34c7b508c56..3545ff35ed8 100644 --- a/spec/finders/milestones_finder_spec.rb +++ b/spec/finders/milestones_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe MilestonesFinder do diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb index 88906adfeeb..44636a22ef9 100644 --- a/spec/finders/notes_finder_spec.rb +++ b/spec/finders/notes_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe NotesFinder do diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb index 3e849c9a644..a44daf585ba 100644 --- a/spec/finders/personal_access_tokens_finder_spec.rb +++ b/spec/finders/personal_access_tokens_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe PersonalAccessTokensFinder do diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb index ef7dd0cd4a8..7686dd3dc9d 100644 --- a/spec/finders/personal_projects_finder_spec.rb +++ b/spec/finders/personal_projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe PersonalProjectsFinder do diff --git a/spec/finders/pipeline_schedules_finder_spec.rb b/spec/finders/pipeline_schedules_finder_spec.rb index 2fefa0280d1..8d0bde15e03 100644 --- a/spec/finders/pipeline_schedules_finder_spec.rb +++ b/spec/finders/pipeline_schedules_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe PipelineSchedulesFinder do diff --git a/spec/finders/pipelines_finder_spec.rb b/spec/finders/pipelines_finder_spec.rb index b23fd8ccdc6..05d13a76e0e 100644 --- a/spec/finders/pipelines_finder_spec.rb +++ b/spec/finders/pipelines_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe PipelinesFinder do diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index ac866e49fcd..4ec12b5a7f7 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe ProjectsFinder do diff --git a/spec/finders/runner_jobs_finder_spec.rb b/spec/finders/runner_jobs_finder_spec.rb index 01f45a37ba8..c11f9182036 100644 --- a/spec/finders/runner_jobs_finder_spec.rb +++ b/spec/finders/runner_jobs_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe RunnerJobsFinder do diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb index 72de05b5131..e7372189d17 100644 --- a/spec/finders/snippets_finder_spec.rb +++ b/spec/finders/snippets_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe SnippetsFinder do diff --git a/spec/finders/tags_finder_spec.rb b/spec/finders/tags_finder_spec.rb index 460e278e2d3..85f970b71c4 100644 --- a/spec/finders/tags_finder_spec.rb +++ b/spec/finders/tags_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe TagsFinder do diff --git a/spec/finders/template_finder_spec.rb b/spec/finders/template_finder_spec.rb index 114af9461e0..ed47752cf60 100644 --- a/spec/finders/template_finder_spec.rb +++ b/spec/finders/template_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe TemplateFinder do diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb index 9a3ffffb3f2..5d284f4cf17 100644 --- a/spec/finders/todos_finder_spec.rb +++ b/spec/finders/todos_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe TodosFinder do diff --git a/spec/finders/user_recent_events_finder_spec.rb b/spec/finders/user_recent_events_finder_spec.rb index 5ebceeb7586..eef6448a4a2 100644 --- a/spec/finders/user_recent_events_finder_spec.rb +++ b/spec/finders/user_recent_events_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe UserRecentEventsFinder do diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb index d71d3c99272..7f1fc1cc1c5 100644 --- a/spec/finders/users_finder_spec.rb +++ b/spec/finders/users_finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe UsersFinder do diff --git a/spec/lib/gitlab/daemon_spec.rb b/spec/lib/gitlab/daemon_spec.rb index 0372b770844..cf1f089c577 100644 --- a/spec/lib/gitlab/daemon_spec.rb +++ b/spec/lib/gitlab/daemon_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Daemon do subject { described_class.new } before do - allow(subject).to receive(:start_working) + allow(subject).to receive(:run_thread) allow(subject).to receive(:stop_working) end @@ -44,7 +44,7 @@ describe Gitlab::Daemon do it 'starts the Daemon' do expect { subject.start.join }.to change { subject.thread? }.from(false).to(true) - expect(subject).to have_received(:start_working) + expect(subject).to have_received(:run_thread) end end @@ -52,7 +52,21 @@ describe Gitlab::Daemon do it "doesn't shutdown stopped Daemon" do expect { subject.stop }.not_to change { subject.thread? } - expect(subject).not_to have_received(:start_working) + expect(subject).not_to have_received(:run_thread) + end + end + end + + describe '#start_working' do + context 'when start_working fails' do + before do + expect(subject).to receive(:start_working) { false } + end + + it 'does not start thread' do + expect(subject).not_to receive(:run_thread) + + expect(subject.start).to eq(nil) end end end @@ -66,7 +80,7 @@ describe Gitlab::Daemon do it "doesn't start running Daemon" do expect { subject.start.join }.not_to change { subject.thread } - expect(subject).to have_received(:start_working).once + expect(subject).to have_received(:run_thread).once end end @@ -79,7 +93,7 @@ describe Gitlab::Daemon do context 'when stop_working raises exception' do before do - allow(subject).to receive(:start_working) do + allow(subject).to receive(:run_thread) do sleep(1000) end end @@ -108,7 +122,7 @@ describe Gitlab::Daemon do expect(subject.start).to be_nil expect { subject.start }.not_to change { subject.thread? } - expect(subject).not_to have_received(:start_working) + expect(subject).not_to have_received(:run_thread) end end diff --git a/spec/lib/gitlab/danger/teammate_spec.rb b/spec/lib/gitlab/danger/teammate_spec.rb index ca036390bde..36486cbbc7d 100644 --- a/spec/lib/gitlab/danger/teammate_spec.rb +++ b/spec/lib/gitlab/danger/teammate_spec.rb @@ -2,11 +2,13 @@ require 'fast_spec_helper' +require 'rspec-parameterized' + require 'gitlab/danger/teammate' describe Gitlab::Danger::Teammate do - subject { described_class.new(options) } - let(:options) { { 'projects' => projects, 'role' => role } } + subject { described_class.new(options.stringify_keys) } + let(:options) { { username: 'luigi', projects: projects, role: role } } let(:projects) { { project => capabilities } } let(:role) { 'Engineer, Manage' } let(:labels) { [] } @@ -95,4 +97,64 @@ describe Gitlab::Danger::Teammate do expect(subject.maintainer?(project, :frontend, labels)).to be_falsey end end + + describe '#status' do + let(:capabilities) { ['dish washing'] } + + context 'with empty cache' do + context 'for successful request' do + it 'returns the response' do + mock_status = double(does_not: 'matter') + expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json) + .and_return(mock_status) + + expect(subject.status).to be mock_status + end + end + + context 'for failing request' do + it 'returns nil' do + expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json) + .and_raise(Gitlab::Danger::RequestHelper::HTTPError.new) + + expect(subject.status).to be nil + end + end + end + + context 'with filled cache' do + it 'returns the cached response' do + mock_status = double(does_not: 'matter') + expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json) + .and_return(mock_status) + subject.status + + expect(Gitlab::Danger::RequestHelper).not_to receive(:http_get_json) + expect(subject.status).to be mock_status + end + end + end + + describe '#out_of_office?' do + using RSpec::Parameterized::TableSyntax + + let(:capabilities) { ['dry head'] } + + where(:status, :result) do + nil | false + {} | false + { message: 'dear reader' } | false + { message: 'OOO: massage' } | true + { message: 'love it SOOO much' } | true + end + + with_them do + before do + expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json) + .and_return(status&.stringify_keys) + end + + it { expect(subject.out_of_office?).to be result } + end + end end diff --git a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb index 263cc821c1a..adea2ba30b3 100644 --- a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb +++ b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::SidekiqDaemon::MemoryKiller do allow(Sidekiq.logger).to receive(:warn) end - describe '#start_working' do - subject { memory_killer.send(:start_working) } + describe '#run_thread' do + subject { memory_killer.send(:run_thread) } before do # let enabled? return 3 times: true, true, false @@ -37,7 +37,7 @@ describe Gitlab::SidekiqDaemon::MemoryKiller do .with( class: described_class.to_s, pid: pid, - message: "Exception from start_working: My Exception") + message: "Exception from run_thread: My Exception") expect(memory_killer).to receive(:rss_within_range?).twice.and_raise(StandardError, 'My Exception') expect(memory_killer).to receive(:sleep).twice.with(Gitlab::SidekiqDaemon::MemoryKiller::CHECK_INTERVAL_SECONDS) @@ -50,7 +50,7 @@ describe Gitlab::SidekiqDaemon::MemoryKiller do .with( class: described_class.to_s, pid: pid, - message: "Exception from start_working: My Exception") + message: "Exception from run_thread: My Exception") expect(memory_killer).to receive(:rss_within_range?).once.and_raise(Exception, 'My Exception') diff --git a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb index 397098ed5a4..3f49ef0e9a7 100644 --- a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb +++ b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb @@ -37,8 +37,8 @@ describe Gitlab::SidekiqDaemon::Monitor do end end - describe '#start_working when notification channel not enabled' do - subject { monitor.send(:start_working) } + describe '#run_thread when notification channel not enabled' do + subject { monitor.send(:run_thread) } it 'return directly' do allow(monitor).to receive(:notification_channel_enabled?).and_return(nil) @@ -52,8 +52,8 @@ describe Gitlab::SidekiqDaemon::Monitor do end end - describe '#start_working when notification channel enabled' do - subject { monitor.send(:start_working) } + describe '#run_thread when notification channel enabled' do + subject { monitor.send(:run_thread) } before do # we want to run at most once cycle diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index de90e4c2fba..15281c9e826 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -19,17 +19,24 @@ describe Ci::Build do it { is_expected.to belong_to(:runner) } it { is_expected.to belong_to(:trigger_request) } it { is_expected.to belong_to(:erased_by) } + it { is_expected.to have_many(:trace_sections) } it { is_expected.to have_many(:needs) } + it { is_expected.to have_many(:sourced_pipelines) } + it { is_expected.to have_many(:job_variables) } + it { is_expected.to have_one(:deployment) } it { is_expected.to have_one(:runner_session) } - it { is_expected.to have_many(:job_variables) } + it { is_expected.to validate_presence_of(:ref) } + it { is_expected.to respond_to(:has_trace?) } it { is_expected.to respond_to(:trace) } + it { is_expected.to delegate_method(:merge_request_event?).to(:pipeline) } it { is_expected.to delegate_method(:merge_request_ref?).to(:pipeline) } it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) } + it { is_expected.to include_module(Ci::PipelineDelegator) } describe 'associations' do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 0e11c595388..de0ce9932e8 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -28,7 +28,13 @@ describe Ci::Pipeline, :mailer do it { is_expected.to have_many(:builds) } it { is_expected.to have_many(:auto_canceled_pipelines) } it { is_expected.to have_many(:auto_canceled_jobs) } + it { is_expected.to have_many(:sourced_pipelines) } + it { is_expected.to have_many(:triggered_pipelines) } + it { is_expected.to have_one(:chat_data) } + it { is_expected.to have_one(:source_pipeline) } + it { is_expected.to have_one(:triggered_by_pipeline) } + it { is_expected.to have_one(:source_job) } it { is_expected.to validate_presence_of(:sha) } it { is_expected.to validate_presence_of(:status) } diff --git a/spec/models/ci/sources/pipeline_spec.rb b/spec/models/ci/sources/pipeline_spec.rb new file mode 100644 index 00000000000..63bee5bfb55 --- /dev/null +++ b/spec/models/ci/sources/pipeline_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::Sources::Pipeline do + it { is_expected.to belong_to(:project) } + it { is_expected.to belong_to(:pipeline) } + + it { is_expected.to belong_to(:source_project) } + it { is_expected.to belong_to(:source_job) } + it { is_expected.to belong_to(:source_pipeline) } + + it { is_expected.to validate_presence_of(:project) } + it { is_expected.to validate_presence_of(:pipeline) } + + it { is_expected.to validate_presence_of(:source_project) } + it { is_expected.to validate_presence_of(:source_job) } + it { is_expected.to validate_presence_of(:source_pipeline) } +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 1490955f4a3..68833fdaf73 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -101,6 +101,8 @@ describe Project do it { is_expected.to have_many(:deploy_tokens).through(:project_deploy_tokens) } it { is_expected.to have_many(:cycle_analytics_stages) } it { is_expected.to have_many(:external_pull_requests) } + it { is_expected.to have_many(:sourced_pipelines) } + it { is_expected.to have_many(:source_pipelines) } it 'has an inverse relationship with merge requests' do expect(described_class.reflect_on_association(:merge_requests).has_inverse?).to eq(:target_project) diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb index d7c40b8e7b9..b180ede51eb 100644 --- a/spec/serializers/pipeline_details_entity_spec.rb +++ b/spec/serializers/pipeline_details_entity_spec.rb @@ -138,5 +138,40 @@ describe PipelineDetailsEntity do expect(subject[:flags][:yaml_errors]).to be false end end + + context 'when pipeline is triggered by other pipeline' do + let(:pipeline) { create(:ci_empty_pipeline) } + + before do + create(:ci_sources_pipeline, pipeline: pipeline) + end + + it 'contains an information about depedent pipeline' do + expect(subject[:triggered_by]).to be_a(Hash) + expect(subject[:triggered_by][:path]).not_to be_nil + expect(subject[:triggered_by][:details]).not_to be_nil + expect(subject[:triggered_by][:details][:status]).not_to be_nil + expect(subject[:triggered_by][:project]).not_to be_nil + end + end + + context 'when pipeline triggered other pipeline' do + let(:pipeline) { create(:ci_empty_pipeline) } + let(:build) { create(:ci_build, pipeline: pipeline) } + + before do + create(:ci_sources_pipeline, source_job: build) + create(:ci_sources_pipeline, source_job: build) + end + + it 'contains an information about depedent pipeline' do + expect(subject[:triggered]).to be_a(Array) + expect(subject[:triggered].length).to eq(2) + expect(subject[:triggered].first[:path]).not_to be_nil + expect(subject[:triggered].first[:details]).not_to be_nil + expect(subject[:triggered].first[:details][:status]).not_to be_nil + expect(subject[:triggered].first[:project]).not_to be_nil + end + end end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index a1d275cfa2a..9762c83ed6a 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -158,7 +158,7 @@ describe PipelineSerializer do it 'verifies number of queries', :request_store do recorded = ActiveRecord::QueryRecorder.new { subject } - expected_queries = Gitlab.ee? ? 38 : 31 + expected_queries = Gitlab.ee? ? 38 : 35 expect(recorded.count).to be_within(2).of(expected_queries) expect(recorded.cached_count).to eq(0) @@ -179,7 +179,8 @@ describe PipelineSerializer do # pipeline. With the same ref this check is cached but if refs are # different then there is an extra query per ref # https://gitlab.com/gitlab-org/gitlab-foss/issues/46368 - expected_queries = Gitlab.ee? ? 44 : 38 + expected_queries = Gitlab.ee? ? 44 : 41 + expect(recorded.count).to be_within(2).of(expected_queries) expect(recorded.cached_count).to eq(0) end diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb index 76251b5b557..24d42f402f4 100644 --- a/spec/services/ci/pipeline_trigger_service_spec.rb +++ b/spec/services/ci/pipeline_trigger_service_spec.rb @@ -11,76 +11,158 @@ describe Ci::PipelineTriggerService do describe '#execute' do let(:user) { create(:user) } - let(:trigger) { create(:ci_trigger, project: project, owner: user) } let(:result) { described_class.new(project, user, params).execute } before do project.add_developer(user) end - context 'when trigger belongs to a different project' do - let(:params) { { token: trigger.token, ref: 'master', variables: nil } } - let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) } + context 'with a trigger token' do + let(:trigger) { create(:ci_trigger, project: project, owner: user) } - it 'does nothing' do - expect { result }.not_to change { Ci::Pipeline.count } - end - end - - context 'when params have an existsed trigger token' do - context 'when params have an existsed ref' do + context 'when trigger belongs to a different project' do let(:params) { { token: trigger.token, ref: 'master', variables: nil } } + let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) } - it 'triggers a pipeline' do - expect { result }.to change { Ci::Pipeline.count }.by(1) - expect(result[:pipeline].ref).to eq('master') - expect(result[:pipeline].project).to eq(project) - expect(result[:pipeline].user).to eq(trigger.owner) - expect(result[:pipeline].trigger_requests.to_a) - .to eq(result[:pipeline].builds.map(&:trigger_request).uniq) - expect(result[:status]).to eq(:success) + it 'does nothing' do + expect { result }.not_to change { Ci::Pipeline.count } end + end - context 'when commit message has [ci skip]' do - before do - allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' } - end + context 'when params have an existsed trigger token' do + context 'when params have an existsed ref' do + let(:params) { { token: trigger.token, ref: 'master', variables: nil } } - it 'ignores [ci skip] and create as general' do + it 'triggers a pipeline' do expect { result }.to change { Ci::Pipeline.count }.by(1) + expect(result[:pipeline].ref).to eq('master') + expect(result[:pipeline].project).to eq(project) + expect(result[:pipeline].user).to eq(trigger.owner) + expect(result[:pipeline].trigger_requests.to_a) + .to eq(result[:pipeline].builds.map(&:trigger_request).uniq) expect(result[:status]).to eq(:success) end + + context 'when commit message has [ci skip]' do + before do + allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' } + end + + it 'ignores [ci skip] and create as general' do + expect { result }.to change { Ci::Pipeline.count }.by(1) + expect(result[:status]).to eq(:success) + end + end + + context 'when params have a variable' do + let(:params) { { token: trigger.token, ref: 'master', variables: variables } } + let(:variables) { { 'AAA' => 'AAA123' } } + + it 'has a variable' do + expect { result }.to change { Ci::PipelineVariable.count }.by(1) + .and change { Ci::TriggerRequest.count }.by(1) + expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables) + expect(result[:pipeline].trigger_requests.last.variables).to be_nil + end + end end - context 'when params have a variable' do - let(:params) { { token: trigger.token, ref: 'master', variables: variables } } - let(:variables) { { 'AAA' => 'AAA123' } } + context 'when params have a non-existsed ref' do + let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } } - it 'has a variable' do - expect { result }.to change { Ci::PipelineVariable.count }.by(1) - .and change { Ci::TriggerRequest.count }.by(1) - expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables) - expect(result[:pipeline].trigger_requests.last.variables).to be_nil + it 'does not trigger a pipeline' do + expect { result }.not_to change { Ci::Pipeline.count } + expect(result[:http_status]).to eq(400) end end end - context 'when params have a non-existsed ref' do - let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } } + context 'when params have a non-existsed trigger token' do + let(:params) { { token: 'invalid-token', ref: nil, variables: nil } } it 'does not trigger a pipeline' do expect { result }.not_to change { Ci::Pipeline.count } - expect(result[:http_status]).to eq(400) + expect(result).to be_nil end end end - context 'when params have a non-existsed trigger token' do - let(:params) { { token: 'invalid-token', ref: nil, variables: nil } } + context 'with a pipeline job token' do + let!(:pipeline) { create(:ci_empty_pipeline, project: project) } + let(:job) { create(:ci_build, :running, pipeline: pipeline, user: user) } + + context 'when job user does not have a permission to read a project' do + let(:params) { { token: job.token, ref: 'master', variables: nil } } + let(:job) { create(:ci_build, pipeline: pipeline, user: create(:user)) } + + it 'does nothing' do + expect { result }.not_to change { Ci::Pipeline.count } + end + end + + context 'when job is not running' do + let(:params) { { token: job.token, ref: 'master', variables: nil } } + let(:job) { create(:ci_build, :success, pipeline: pipeline, user: user) } + + it 'does nothing' do + expect { result }.not_to change { Ci::Pipeline.count } + expect(result[:message]).to eq('400 Job has to be running') + end + end - it 'does not trigger a pipeline' do - expect { result }.not_to change { Ci::Pipeline.count } - expect(result).to be_nil + context 'when params have an existsed job token' do + context 'when params have an existsed ref' do + let(:params) { { token: job.token, ref: 'master', variables: nil } } + + it 'triggers a pipeline' do + expect { result }.to change { Ci::Pipeline.count }.by(1) + expect(result[:pipeline].ref).to eq('master') + expect(result[:pipeline].project).to eq(project) + expect(result[:pipeline].user).to eq(job.user) + expect(result[:status]).to eq(:success) + end + + context 'when commit message has [ci skip]' do + before do + allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' } + end + + it 'ignores [ci skip] and create as general' do + expect { result }.to change { Ci::Pipeline.count }.by(1) + expect(result[:status]).to eq(:success) + end + end + + context 'when params have a variable' do + let(:params) { { token: job.token, ref: 'master', variables: variables } } + let(:variables) { { 'AAA' => 'AAA123' } } + + it 'has a variable' do + expect { result }.to change { Ci::PipelineVariable.count }.by(1) + .and change { Ci::Sources::Pipeline.count }.by(1) + expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables) + expect(job.sourced_pipelines.last.pipeline_id).to eq(result[:pipeline].id) + end + end + end + + context 'when params have a non-existsed ref' do + let(:params) { { token: job.token, ref: 'invalid-ref', variables: nil } } + + it 'does not job a pipeline' do + expect { result }.not_to change { Ci::Pipeline.count } + expect(result[:http_status]).to eq(400) + end + end + end + + context 'when params have a non-existsed trigger token' do + let(:params) { { token: 'invalid-token', ref: nil, variables: nil } } + + it 'does not trigger a pipeline' do + expect { result }.not_to change { Ci::Pipeline.count } + expect(result).to be_nil + end end end end diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb index 0cbb3122bb0..5ef1fb1932f 100644 --- a/spec/services/groups/transfer_service_spec.rb +++ b/spec/services/groups/transfer_service_spec.rb @@ -426,5 +426,22 @@ describe Groups::TransferService do end end end + + context 'when a project in group has container images' do + let(:group) { create(:group, :public, :nested) } + let!(:project) { create(:project, :repository, :public, namespace: group) } + + before do + stub_container_registry_tags(repository: /image/, tags: %w[rc1]) + create(:container_repository, project: project, name: :image) + create(:group_member, :owner, group: new_parent_group, user: user) + end + + it 'does not allow group to be transferred' do + transfer_service.execute(new_parent_group) + + expect(transfer_service.error).to match(/Docker images in their Container Registry/) + end + end end end diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb index 12e9c2b2f3a..ca8eaf4c970 100644 --- a/spec/services/groups/update_service_spec.rb +++ b/spec/services/groups/update_service_spec.rb @@ -148,6 +148,30 @@ describe Groups::UpdateService do end end + context 'projects in group have container images' do + let(:service) { described_class.new(public_group, user, path: SecureRandom.hex) } + let(:project) { create(:project, :internal, group: public_group) } + + before do + stub_container_registry_tags(repository: /image/, tags: %w[rc1]) + create(:container_repository, project: project, name: :image) + end + + it 'does not allow path to be changed' do + result = described_class.new(public_group, user, path: 'new-path').execute + + expect(result).to eq false + expect(public_group.errors[:base].first).to match(/Docker images in their Container Registry/) + end + + it 'allows other settings to be changed' do + result = described_class.new(public_group, user, name: 'new-name').execute + + expect(result).to eq true + expect(public_group.reload.name).to eq('new-name') + end + end + context 'for a subgroup' do let(:subgroup) { create(:group, :private, parent: private_group) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 948e5e6250b..61e50fe5723 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -154,6 +154,17 @@ RSpec.configure do |config| .with(:force_autodevops_on_by_default, anything) .and_return(false) + # The following can be removed once Vue Issuable Sidebar + # is feature-complete and can be made default in place + # of older sidebar. + # See https://gitlab.com/groups/gitlab-org/-/epics/1863 + allow(Feature).to receive(:enabled?) + .with(:vue_issuable_sidebar, anything) + .and_return(false) + allow(Feature).to receive(:enabled?) + .with(:vue_issuable_epic_sidebar, anything) + .and_return(false) + # Stub these calls due to being expensive operations # It can be reenabled for specific tests via: # |