2019-04-11 08:17:24 -04:00
# frozen_string_literal: true
2016-03-08 19:01:33 -05:00
require 'spec_helper'
2020-06-24 11:08:50 -04:00
RSpec . describe Groups :: UpdateService do
2016-12-20 11:52:27 -05:00
let! ( :user ) { create ( :user ) }
let! ( :private_group ) { create ( :group , :private ) }
let! ( :internal_group ) { create ( :group , :internal ) }
let! ( :public_group ) { create ( :group , :public ) }
2016-03-08 19:01:33 -05:00
2016-03-20 18:09:33 -04:00
describe " # execute " do
2020-07-19 23:09:39 -04:00
shared_examples 'with packages' do
before do
group . add_owner ( user )
end
context 'with npm packages' do
let! ( :package ) { create ( :npm_package , project : project ) }
it 'does not allow a path update' do
expect ( update_group ( group , user , path : 'updated' ) ) . to be false
expect ( group . errors [ :path ] ) . to include ( 'cannot change when group contains projects with NPM packages' )
end
it 'allows name update' do
expect ( update_group ( group , user , name : 'Updated' ) ) . to be true
expect ( group . errors ) . to be_empty
expect ( group . name ) . to eq ( 'Updated' )
end
end
end
context 'with project' do
let! ( :group ) { create ( :group , :public ) }
let ( :project ) { create ( :project , namespace : group ) }
it_behaves_like 'with packages'
context 'located in a subgroup' do
let ( :subgroup ) { create ( :group , parent : group ) }
let! ( :project ) { create ( :project , namespace : subgroup ) }
before do
subgroup . add_owner ( user )
end
it_behaves_like 'with packages'
it 'does allow a path update if there is not a root namespace change' do
expect ( update_group ( subgroup , user , path : 'updated' ) ) . to be true
expect ( subgroup . errors [ :path ] ) . to be_empty
end
end
end
2016-03-08 19:01:33 -05:00
context " project visibility_level validation " do
context " public group with public projects " do
2016-12-20 11:52:27 -05:00
let! ( :service ) { described_class . new ( public_group , user , visibility_level : Gitlab :: VisibilityLevel :: INTERNAL ) }
2016-03-08 19:01:33 -05:00
before do
2018-08-02 10:16:58 -04:00
public_group . add_user ( user , Gitlab :: Access :: OWNER )
2017-08-02 15:55:11 -04:00
create ( :project , :public , group : public_group )
2018-08-02 10:16:58 -04:00
expect ( TodosDestroyer :: GroupPrivateWorker ) . not_to receive ( :perform_in )
2016-03-08 19:01:33 -05:00
end
2016-03-20 18:26:58 -04:00
it " does not change permission level " do
service . execute
expect ( public_group . errors . count ) . to eq ( 1 )
2018-08-02 10:16:58 -04:00
expect ( TodosDestroyer :: GroupPrivateWorker ) . not_to receive ( :perform_in )
2016-03-08 19:01:33 -05:00
end
2018-10-18 04:43:49 -04:00
it " returns false if save failed " do
allow ( public_group ) . to receive ( :save ) . and_return ( false )
expect ( service . execute ) . to be_falsey
end
2019-11-08 04:06:07 -05:00
context 'when a project has container images' do
let ( :params ) { { path : SecureRandom . hex } }
let! ( :container_repository ) { create ( :container_repository , project : project ) }
subject { described_class . new ( public_group , user , params ) . execute }
context 'within group' do
let ( :project ) { create ( :project , group : public_group ) }
context 'with path updates' do
it 'does not allow the update' do
expect ( subject ) . to be false
expect ( public_group . errors [ :base ] . first ) . to match ( / Docker images in their Container Registry / )
end
end
context 'with name updates' do
let ( :params ) { { name : 'new-name' } }
it 'allows the update' do
expect ( subject ) . to be true
expect ( public_group . reload . name ) . to eq ( 'new-name' )
end
end
end
context 'within subgroup' do
let ( :subgroup ) { create ( :group , parent : public_group ) }
let ( :project ) { create ( :project , group : subgroup ) }
it 'does not allow path updates' do
expect ( subject ) . to be false
expect ( public_group . errors [ :base ] . first ) . to match ( / Docker images in their Container Registry / )
end
end
end
2016-03-08 19:01:33 -05:00
end
2016-03-18 08:28:16 -04:00
context " internal group with internal project " do
2016-12-20 11:52:27 -05:00
let! ( :service ) { described_class . new ( internal_group , user , visibility_level : Gitlab :: VisibilityLevel :: PRIVATE ) }
2016-03-20 18:09:33 -04:00
before do
2018-08-02 10:16:58 -04:00
internal_group . add_user ( user , Gitlab :: Access :: OWNER )
2017-08-02 15:55:11 -04:00
create ( :project , :internal , group : internal_group )
2018-08-02 10:16:58 -04:00
expect ( TodosDestroyer :: GroupPrivateWorker ) . not_to receive ( :perform_in )
2016-03-20 18:09:33 -04:00
end
2016-03-20 18:26:58 -04:00
it " does not change permission level " do
service . execute
expect ( internal_group . errors . count ) . to eq ( 1 )
2016-03-08 19:01:33 -05:00
end
2016-03-20 18:09:33 -04:00
end
2018-08-02 10:16:58 -04:00
context " internal group with private project " do
let! ( :service ) { described_class . new ( internal_group , user , visibility_level : Gitlab :: VisibilityLevel :: PRIVATE ) }
before do
internal_group . add_user ( user , Gitlab :: Access :: OWNER )
create ( :project , :private , group : internal_group )
expect ( TodosDestroyer :: GroupPrivateWorker ) . to receive ( :perform_in )
2018-12-11 13:15:10 -05:00
. with ( Todo :: WAIT_FOR_DELETE , internal_group . id )
2018-08-02 10:16:58 -04:00
end
it " changes permission level to private " do
service . execute
expect ( internal_group . visibility_level )
. to eq ( Gitlab :: VisibilityLevel :: PRIVATE )
end
end
2016-03-08 19:01:33 -05:00
end
2017-03-28 07:09:44 -04:00
context " with parent_id user doesn't have permissions for " do
let ( :service ) { described_class . new ( public_group , user , parent_id : private_group . id ) }
before do
service . execute
end
it 'does not update parent_id' do
updated_group = public_group . reload
expect ( updated_group . parent_id ) . to be_nil
end
end
2016-03-08 19:01:33 -05:00
end
context " unauthorized visibility_level validation " do
2016-12-20 11:52:27 -05:00
let! ( :service ) { described_class . new ( internal_group , user , visibility_level : 99 ) }
2019-08-15 13:37:36 -04:00
2016-03-20 18:09:33 -04:00
before do
2018-07-11 10:36:08 -04:00
internal_group . add_user ( user , Gitlab :: Access :: MAINTAINER )
2016-03-20 18:09:33 -04:00
end
2016-03-08 19:01:33 -05:00
it " does not change permission level " do
2016-03-20 18:26:58 -04:00
service . execute
2016-03-08 19:01:33 -05:00
expect ( internal_group . errors . count ) . to eq ( 1 )
end
end
2016-12-20 11:52:27 -05:00
2019-08-15 13:37:36 -04:00
context 'when updating #emails_disabled' do
let ( :service ) { described_class . new ( internal_group , user , emails_disabled : true ) }
it 'updates the attribute' do
internal_group . add_user ( user , Gitlab :: Access :: OWNER )
expect { service . execute } . to change { internal_group . emails_disabled } . to ( true )
end
it 'does not update when not group owner' do
expect { service . execute } . not_to change { internal_group . emails_disabled }
end
end
2020-04-24 05:09:44 -04:00
context 'updating default_branch_protection' do
let ( :service ) do
described_class . new ( internal_group , user , default_branch_protection : Gitlab :: Access :: PROTECTION_NONE )
end
context 'for users who have the ability to update default_branch_protection' do
it 'updates the attribute' do
internal_group . add_owner ( user )
expect { service . execute } . to change { internal_group . default_branch_protection } . to ( Gitlab :: Access :: PROTECTION_NONE )
end
end
context 'for users who do not have the ability to update default_branch_protection' do
it 'does not update the attribute' do
expect { service . execute } . not_to change { internal_group . default_branch_protection }
end
end
end
2016-12-20 11:52:27 -05:00
context 'rename group' do
2017-02-06 23:08:51 -05:00
let! ( :service ) { described_class . new ( internal_group , user , path : SecureRandom . hex ) }
2016-12-20 11:52:27 -05:00
before do
2018-07-11 10:36:08 -04:00
internal_group . add_user ( user , Gitlab :: Access :: MAINTAINER )
2017-08-02 15:55:11 -04:00
create ( :project , :internal , group : internal_group )
2016-12-20 11:52:27 -05:00
end
it 'returns true' do
expect ( service . execute ) . to eq ( true )
end
context 'error moving group' do
before do
allow ( internal_group ) . to receive ( :move_dir ) . and_raise ( Gitlab :: UpdatePathError )
end
it 'does not raise an error' do
expect { service . execute } . not_to raise_error
end
it 'returns false' do
expect ( service . execute ) . to eq ( false )
end
it 'has the right error' do
service . execute
expect ( internal_group . errors . full_messages . first ) . to eq ( 'Gitlab::UpdatePathError' )
end
2016-12-21 07:29:27 -05:00
it " hasn't changed the path " do
expect { service . execute } . not_to change { internal_group . reload . path }
end
2016-12-20 11:52:27 -05:00
end
end
2017-09-01 21:00:46 -04:00
2019-07-24 05:20:54 -04:00
context 'for a subgroup' do
2017-09-01 21:00:46 -04:00
let ( :subgroup ) { create ( :group , :private , parent : private_group ) }
context 'when the parent group share_with_group_lock is enabled' do
before do
private_group . update_column ( :share_with_group_lock , true )
end
context 'for the parent group owner' do
it 'allows disabling share_with_group_lock' do
private_group . add_owner ( user )
result = described_class . new ( subgroup , user , share_with_group_lock : false ) . execute
expect ( result ) . to be_truthy
expect ( subgroup . reload . share_with_group_lock ) . to be_falsey
end
end
context 'for a subgroup owner (who does not own the parent)' do
it 'does not allow disabling share_with_group_lock' do
subgroup_owner = create ( :user )
subgroup . add_owner ( subgroup_owner )
result = described_class . new ( subgroup , subgroup_owner , share_with_group_lock : false ) . execute
expect ( result ) . to be_falsey
2017-09-06 14:31:45 -04:00
expect ( subgroup . errors . full_messages . first ) . to match ( / cannot be disabled when the parent group "Share with group lock" is enabled, except by the owner of the parent group / )
2017-09-01 21:00:46 -04:00
expect ( subgroup . reload . share_with_group_lock ) . to be_truthy
end
end
end
end
2020-07-19 23:09:39 -04:00
2020-09-30 11:09:46 -04:00
context 'change shared Runners config' do
let ( :group ) { create ( :group ) }
let ( :project ) { create ( :project , shared_runners_enabled : true , group : group ) }
subject { described_class . new ( group , user , shared_runners_setting : 'disabled_and_unoverridable' ) . execute }
before do
group . add_owner ( user )
end
it 'calls the shared runners update service' do
expect_any_instance_of ( :: Groups :: UpdateSharedRunnersService ) . to receive ( :execute ) . and_return ( { status : :success } )
expect ( subject ) . to be_truthy
end
it 'handles errors in the shared runners update service' do
expect_any_instance_of ( :: Groups :: UpdateSharedRunnersService ) . to receive ( :execute ) . and_return ( { status : :error , message : 'something happened' } )
expect ( subject ) . to be_falsy
expect ( group . errors [ :update_shared_runners ] . first ) . to eq ( 'something happened' )
end
end
2020-10-15 08:09:06 -04:00
context 'changes allowing subgroups to establish own 2FA' do
let ( :group ) { create ( :group ) }
let ( :params ) { { allow_mfa_for_subgroups : false } }
subject { described_class . new ( group , user , params ) . execute }
it 'changes settings' do
subject
expect ( group . namespace_settings . reload . allow_mfa_for_subgroups ) . to eq ( false )
end
it 'enqueues update subgroups and its members' do
expect ( DisallowTwoFactorForSubgroupsWorker ) . to receive ( :perform_async ) . with ( group . id )
subject
end
end
2020-07-19 23:09:39 -04:00
def update_group ( group , user , opts )
Groups :: UpdateService . new ( group , user , opts ) . execute
end
2016-03-08 19:01:33 -05:00
end