2019-07-31 22:56:46 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
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
|
|
|
|
project.save
|
|
|
|
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
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|