Commit 1bf799e2 authored by George Thomas's avatar George Thomas Committed by Jarka Košanová

Migrate project snippets to the ghost user when the user is deleted

Closes #205772
parent b7509c46
......@@ -102,6 +102,10 @@ class Snippet < ApplicationRecord
where(project_id: nil)
end
def self.only_project_snippets
where.not(project_id: nil)
end
def self.only_include_projects_visible_to(current_user = nil)
levels = Gitlab::VisibilityLevel.levels_for_user(current_user)
......
......@@ -52,6 +52,7 @@ module Users
migrate_notes
migrate_abuse_reports
migrate_award_emoji
migrate_snippets
end
# rubocop: disable CodeReuse/ActiveRecord
......@@ -79,6 +80,11 @@ module Users
def migrate_award_emoji
user.award_emoji.update_all(user_id: ghost_user.id)
end
def migrate_snippets
snippets = user.snippets.only_project_snippets
snippets.update_all(author_id: ghost_user.id)
end
end
end
......
---
title: Migrate project snippets to the ghost user when the user is deleted
merge_request: 28870
author: George Thomas @thegeorgeous
type: added
......@@ -42,13 +42,11 @@ describe Users::DestroyService do
it 'calls the bulk snippet destroy service for the user personal snippets' do
repo1 = create(:personal_snippet, :repository, author: user).snippet_repository
repo2 = create(:project_snippet, :repository, author: user).snippet_repository
repo3 = create(:project_snippet, :repository, project: project, author: user).snippet_repository
repo2 = create(:project_snippet, :repository, project: project, author: user).snippet_repository
aggregate_failures do
expect(gitlab_shell.repository_exists?(repo1.shard_name, repo1.disk_path + '.git')).to be_truthy
expect(gitlab_shell.repository_exists?(repo2.shard_name, repo2.disk_path + '.git')).to be_truthy
expect(gitlab_shell.repository_exists?(repo3.shard_name, repo3.disk_path + '.git')).to be_truthy
end
# Call made when destroying user personal projects
......@@ -59,17 +57,23 @@ describe Users::DestroyService do
# project snippets where projects are not user personal
# ones
expect(Snippets::BulkDestroyService).to receive(:new)
.with(admin, user.snippets).and_call_original
.with(admin, user.snippets.only_personal_snippets).and_call_original
service.execute(user)
aggregate_failures do
expect(gitlab_shell.repository_exists?(repo1.shard_name, repo1.disk_path + '.git')).to be_falsey
expect(gitlab_shell.repository_exists?(repo2.shard_name, repo2.disk_path + '.git')).to be_falsey
expect(gitlab_shell.repository_exists?(repo3.shard_name, repo3.disk_path + '.git')).to be_falsey
end
end
it 'does not delete project snippets that the user is the author of' do
repo = create(:project_snippet, :repository, author: user).snippet_repository
service.execute(user)
expect(gitlab_shell.repository_exists?(repo.shard_name, repo.disk_path + '.git')).to be_truthy
expect(User.ghost.snippets).to include(repo.snippet)
end
context 'when an error is raised deleting snippets' do
it 'does not delete user' do
snippet = create(:personal_snippet, :repository, author: user)
......
......@@ -78,6 +78,12 @@ describe Users::MigrateToGhostUserService do
end
end
context 'snippets' do
include_examples "migrating a deleted user's associated records to the ghost user", Snippet do
let(:created_record) { create(:snippet, project: project, author: user) }
end
end
context "when record migration fails with a rollback exception" do
before do
expect_any_instance_of(ActiveRecord::Associations::CollectionProxy)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment