diff --git a/lib/tasks/support.rake b/lib/tasks/support.rake index 1060aebb9..b708e8c49 100644 --- a/lib/tasks/support.rake +++ b/lib/tasks/support.rake @@ -42,4 +42,48 @@ namespace :support do end end end + + task remove_ex_team_member: :environment do + super_admin = SuperAdmin.find_by(email: ENV['SUPER_ADMIN_EMAIL']) + fail "Must specify the ADMIN_EMAIL of the operator performing the deletion (yourself)" if super_admin.nil? + super_admin_admin = User.find_by(email: super_admin.email).administrateur + + user = User.find_by!(email: ENV['USER_EMAIL']) + fail "Must specify a USER_EMAIL" if user.nil? + + ActiveRecord::Base.transaction do + # destroy all en_instruction dossier + # because the normal workflow forbid to hide them. + rake_puts "brutally deleting #{user.dossiers.en_instruction.count} en_instruction dossiers" + user.dossiers.en_instruction.destroy_all + + # remove all the other dossier from the user side + rake_puts "hide #{user.reload.dossiers.count} dossiers" + user.delete_and_keep_track_dossiers(super_admin) + + owned_procedures, shared_procedures = user.administrateur + .procedures + .partition { _1.administrateurs.one? } + + rake_puts "unlink #{shared_procedures.count} shared procedures" + shared_procedures.each { _1.administrateurs.delete(user.administrateur) } + + procedures_without_dossier, procedures_with_dossiers = + owned_procedures.partition { _1.dossiers.empty? } + + rake_puts "discard #{procedures_without_dossier.count} procedures without dossier" + procedures_without_dossier.each { _1.discard_and_keep_track!(super_admin) } + + procedures_with_only_admin_dossiers, + other_procedures = procedures_with_dossiers.partition do |p| + p.dossiers.all? { _1.user == user || _1.deleted_user_email_never_send == user.email } + end + + rake_puts "discard #{procedures_with_only_admin_dossiers.count} procedures with only admin dossiers" + # TODO: clean this ugly hack to delete dossier from admin side + procedures_with_only_admin_dossiers.each { _1.discard_and_keep_track!(super_admin_admin) } + + rake_puts "#{other_procedures.count} remaining" + end + end end diff --git a/spec/lib/tasks/support_spec.rb b/spec/lib/tasks/support_spec.rb new file mode 100644 index 000000000..dbc682f62 --- /dev/null +++ b/spec/lib/tasks/support_spec.rb @@ -0,0 +1,66 @@ +describe 'support' do + describe 'remove_ex_team_member' do + let(:rake_task) { Rake::Task['support:remove_ex_team_member'] } + + subject do + ENV['SUPER_ADMIN_EMAIL'] = super_admin.email + ENV['USER_EMAIL'] = admin.email + rake_task.invoke + end + after { rake_task.reenable } + + # the admin to remove + let(:admin) { create(:administrateur) } + + # the super admin doing the removal + let(:super_admin) { create(:super_admin) } + let!(:super_admin_admin) { create(:administrateur, email: super_admin.email) } + + context 'an empty procedure is discarded' do + let!(:empty_procedure) { create(:procedure, :published, administrateur: admin) } + + it do + subject + expect(admin.procedures).to be_empty + expect(admin.procedures.with_discarded.discarded).to match_array(empty_procedure) + end + end + + context 'a procedure only with the admins dossiers is discarded' do + let!(:procedure_with_admin_dossiers) { create(:procedure, :published, administrateur: admin) } + let!(:admin_instruction_dossier) { create(:dossier, :en_instruction, procedure: procedure_with_admin_dossiers, user: admin.user) } + let!(:admin_termine_dossier) { create(:dossier, :accepte, procedure: procedure_with_admin_dossiers, user: admin.user) } + + it do + subject + expect(admin.procedures).to be_empty + expect(admin.procedures.with_discarded.discarded).to match_array(procedure_with_admin_dossiers) + expect { admin_instruction_dossier.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect(admin_termine_dossier.reload.user).to be_nil + end + end + + context 'a procedure only with others dossiers is kept' do + let!(:procedure_with_dossiers) { create(:procedure, :published, administrateur: admin) } + let!(:admin_dossier) { create(:dossier, :en_instruction, procedure: procedure_with_dossiers, user: admin.user) } + let!(:another_dossier) { create(:dossier, :en_instruction, procedure: procedure_with_dossiers) } + + it do + subject + expect(admin.procedures).to match_array(procedure_with_dossiers) + expect { admin_dossier.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + context 'a procedure shared with another admin' do + let!(:another_admin) { create(:administrateur) } + let!(:shared_procedure) { create(:procedure, :published, administrateurs: [admin, another_admin]) } + + it do + subject + expect(admin.procedures).to be_empty + expect(another_admin.procedures).to match_array(shared_procedure) + end + end + end +end