debian-mirror-gitlab/spec/services/groups/destroy_service_spec.rb

257 lines
9.2 KiB
Ruby
Raw Normal View History

2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2017-08-17 22:00:37 +05:30
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec.describe Groups::DestroyService do
2017-08-17 22:00:37 +05:30
include DatabaseConnectionHelpers
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
2019-12-21 20:55:43 +05:30
let!(:project) { create(:project, :repository, :legacy_storage, namespace: group) }
2017-08-17 22:00:37 +05:30
let!(:notification_setting) { create(:notification_setting, source: group)}
2018-03-17 18:26:18 +05:30
let(:gitlab_shell) { Gitlab::Shell.new }
let(:remove_path) { group.path + "+#{group.id}+deleted" }
2017-08-17 22:00:37 +05:30
before do
group.add_user(user, Gitlab::Access::OWNER)
end
2017-09-10 17:25:29 +05:30
def destroy_group(group, user, async)
if async
Groups::DestroyService.new(group, user).async_execute
else
Groups::DestroyService.new(group, user).execute
end
end
2017-08-17 22:00:37 +05:30
shared_examples 'group destruction' do |async|
2019-12-26 22:10:19 +05:30
context 'database records', :sidekiq_might_not_need_inline do
2017-08-17 22:00:37 +05:30
before do
destroy_group(group, user, async)
end
it { expect(Group.unscoped.all).not_to include(group) }
it { expect(Group.unscoped.all).not_to include(nested_group) }
it { expect(Project.unscoped.all).not_to include(project) }
it { expect(NotificationSetting.unscoped.all).not_to include(notification_setting) }
end
2019-12-26 22:10:19 +05:30
context 'mattermost team', :sidekiq_might_not_need_inline do
2017-09-10 17:25:29 +05:30
let!(:chat_team) { create(:chat_team, namespace: group) }
it 'destroys the team too' do
2020-01-01 13:55:28 +05:30
expect_next_instance_of(Mattermost::Team) do |instance|
expect(instance).to receive(:destroy)
end
2017-09-10 17:25:29 +05:30
destroy_group(group, user, async)
end
end
2019-12-26 22:10:19 +05:30
context 'file system', :sidekiq_might_not_need_inline do
2017-08-17 22:00:37 +05:30
context 'Sidekiq inline' do
before do
2017-09-10 17:25:29 +05:30
# Run sidekiq immediately to check that renamed dir will be removed
2018-11-18 11:00:15 +05:30
perform_enqueued_jobs { destroy_group(group, user, async) }
2017-08-17 22:00:37 +05:30
end
2017-09-10 17:25:29 +05:30
it 'verifies that paths have been deleted' do
2019-12-26 22:10:19 +05:30
expect(TestEnv.storage_dir_exists?(project.repository_storage, group.path)).to be_falsey
expect(TestEnv.storage_dir_exists?(project.repository_storage, remove_path)).to be_falsey
2017-08-17 22:00:37 +05:30
end
end
end
end
describe 'asynchronous delete' do
it_behaves_like 'group destruction', true
2017-09-10 17:25:29 +05:30
context 'Sidekiq fake' do
before do
# Don't run Sidekiq to verify that group and projects are not actually destroyed
Sidekiq::Testing.fake! { destroy_group(group, user, true) }
end
after do
# Clean up stale directories
2019-12-26 22:10:19 +05:30
TestEnv.rm_storage_dir(project.repository_storage, group.path)
TestEnv.rm_storage_dir(project.repository_storage, remove_path)
2017-09-10 17:25:29 +05:30
end
it 'verifies original paths and projects still exist' do
2019-12-26 22:10:19 +05:30
expect(TestEnv.storage_dir_exists?(project.repository_storage, group.path)).to be_truthy
expect(TestEnv.storage_dir_exists?(project.repository_storage, remove_path)).to be_falsey
2017-09-10 17:25:29 +05:30
expect(Project.unscoped.count).to eq(1)
expect(Group.unscoped.count).to eq(2)
end
end
2017-08-17 22:00:37 +05:30
end
describe 'synchronous delete' do
it_behaves_like 'group destruction', false
end
context 'projects in pending_delete' do
before do
project.pending_delete = true
2021-01-29 00:20:46 +05:30
project.save!
2017-08-17 22:00:37 +05:30
end
it_behaves_like 'group destruction', false
end
2018-03-17 18:26:18 +05:30
2018-11-20 20:47:30 +05:30
context 'repository removal status is taken into account' do
it 'raises exception' do
expect_next_instance_of(::Projects::DestroyService) do |destroy_service|
expect(destroy_service).to receive(:execute).and_return(false)
end
expect { destroy_group(group, user, false) }
.to raise_error(Groups::DestroyService::DestroyError, "Project #{project.id} can't be deleted" )
end
end
2018-03-17 18:26:18 +05:30
describe 'repository removal' do
before do
destroy_group(group, user, false)
end
context 'legacy storage' do
2018-03-27 19:54:05 +05:30
let!(:project) { create(:project, :legacy_storage, :empty_repo, namespace: group) }
2018-03-17 18:26:18 +05:30
it 'removes repository' do
2019-12-21 20:55:43 +05:30
expect(gitlab_shell.repository_exists?(project.repository_storage, "#{project.disk_path}.git")).to be_falsey
2018-03-17 18:26:18 +05:30
end
end
context 'hashed storage' do
2018-03-27 19:54:05 +05:30
let!(:project) { create(:project, :empty_repo, namespace: group) }
2018-03-17 18:26:18 +05:30
it 'removes repository' do
2019-12-21 20:55:43 +05:30
expect(gitlab_shell.repository_exists?(project.repository_storage, "#{project.disk_path}.git")).to be_falsey
2018-03-17 18:26:18 +05:30
end
end
end
2020-04-15 14:45:12 +05:30
describe 'authorization updates', :sidekiq_inline do
2021-03-08 18:12:59 +05:30
context 'for solo groups' do
context 'group is deleted' do
it 'updates project authorization' do
expect { destroy_group(group, user, false) }.to(
change { user.can?(:read_project, project) }.from(true).to(false))
end
it 'does not make use of a specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.not_to receive(:new).with(group.user_ids_for_project_authorizations)
destroy_group(group, user, false)
end
end
end
context 'for shared groups within different hierarchies' do
let(:shared_with_group) { group }
2020-04-15 14:45:12 +05:30
let!(:shared_group) { create(:group, :private) }
let!(:shared_group_child) { create(:group, :private, parent: shared_group) }
2021-03-08 18:12:59 +05:30
let!(:shared_group_user) { create(:user) }
2020-04-15 14:45:12 +05:30
let!(:project) { create(:project, group: shared_group) }
let!(:project_child) { create(:project, group: shared_group_child) }
before do
2021-03-08 18:12:59 +05:30
shared_group.add_user(shared_group_user, Gitlab::Access::OWNER)
create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group)
shared_with_group.refresh_members_authorized_projects
end
context 'the shared group is deleted' do
it 'updates project authorization' do
expect(shared_group_user.can?(:read_project, project)).to eq(true)
expect(shared_group_user.can?(:read_project, project_child)).to eq(true)
destroy_group(shared_group, shared_group_user, false)
expect(shared_group_user.can?(:read_project, project)).to eq(false)
expect(shared_group_user.can?(:read_project, project_child)).to eq(false)
end
it 'does not make use of specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.not_to receive(:new).with(shared_group.user_ids_for_project_authorizations).and_call_original
destroy_group(shared_group, shared_group_user, false)
end
2020-04-15 14:45:12 +05:30
end
2021-03-08 18:12:59 +05:30
context 'the shared_with group is deleted' do
it 'updates project authorization' do
expect(user.can?(:read_project, project)).to eq(true)
expect(user.can?(:read_project, project_child)).to eq(true)
2020-04-15 14:45:12 +05:30
2021-03-08 18:12:59 +05:30
destroy_group(shared_with_group, user, false)
2020-04-15 14:45:12 +05:30
2021-03-08 18:12:59 +05:30
expect(user.can?(:read_project, project)).to eq(false)
expect(user.can?(:read_project, project_child)).to eq(false)
end
it 'makes use of a specific service to update project_authorizations records' do
expect(UserProjectAccessChangedService)
.to receive(:new).with(shared_with_group.user_ids_for_project_authorizations).and_call_original
destroy_group(shared_with_group, user, false)
end
2020-04-15 14:45:12 +05:30
end
end
2021-03-08 18:12:59 +05:30
context 'for shared groups in the same group hierarchy' do
let(:shared_group) { group }
let(:shared_with_group) { nested_group }
let!(:shared_with_group_user) { create(:user) }
2020-04-15 14:45:12 +05:30
before do
2021-03-08 18:12:59 +05:30
shared_with_group.add_user(shared_with_group_user, Gitlab::Access::MAINTAINER)
2020-04-15 14:45:12 +05:30
2021-03-08 18:12:59 +05:30
create(:group_group_link, shared_group: shared_group, shared_with_group: shared_with_group)
shared_with_group.refresh_members_authorized_projects
2020-04-15 14:45:12 +05:30
end
2021-03-08 18:12:59 +05:30
context 'the shared group is deleted' do
2020-04-15 14:45:12 +05:30
it 'updates project authorization' do
2021-03-08 18:12:59 +05:30
expect { destroy_group(shared_group, user, false) }.to(
change { shared_with_group_user.can?(:read_project, project) }.from(true).to(false))
end
it 'does not make use of a specific service to update project authorizations' do
# Due to the recursive nature of `Groups::DestroyService`, `UserProjectAccessChangedService`
# will still be executed for the nested group as they fall under the same hierarchy
# and hence we need to account for this scenario.
expect(UserProjectAccessChangedService)
2021-04-17 20:07:23 +05:30
.to receive(:new).with(shared_with_group.users_ids_of_direct_members).and_call_original
2021-03-08 18:12:59 +05:30
expect(UserProjectAccessChangedService)
2021-04-17 20:07:23 +05:30
.not_to receive(:new).with(shared_group.users_ids_of_direct_members)
2021-03-08 18:12:59 +05:30
destroy_group(shared_group, user, false)
2020-04-15 14:45:12 +05:30
end
end
2021-03-08 18:12:59 +05:30
context 'the shared_with group is deleted' do
2020-04-15 14:45:12 +05:30
it 'updates project authorization' do
2021-03-08 18:12:59 +05:30
expect { destroy_group(shared_with_group, user, false) }.to(
change { shared_with_group_user.can?(:read_project, project) }.from(true).to(false))
end
it 'makes use of a specific service to update project authorizations' do
expect(UserProjectAccessChangedService)
2021-04-17 20:07:23 +05:30
.to receive(:new).with(shared_with_group.users_ids_of_direct_members).and_call_original
2021-03-08 18:12:59 +05:30
destroy_group(shared_with_group, user, false)
2020-04-15 14:45:12 +05:30
end
end
end
end
2017-08-17 22:00:37 +05:30
end