diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index b78428aef..ebd1e9470 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -96,6 +96,36 @@ class Administrateur < ApplicationRecord destroy end + def merge(old_admin) + return if old_admin.nil? + + procedures_with_new_admin, procedures_without_new_admin = old_admin.procedures + .partition { |p| p.administrateurs.exists?(id) } + + procedures_with_new_admin.each do |p| + p.administrateurs.delete(old_admin) + end + + procedures_without_new_admin.each do |p| + p.administrateurs << self + p.administrateurs.delete(old_admin) + end + + old_admin.services.update_all(administrateur_id: id) + + instructeurs_with_new_admin, instructeurs_without_new_admin = old_admin.instructeurs + .partition { |i| i.administrateurs.exists?(id) } + + instructeurs_with_new_admin.each do |i| + i.administrateurs.delete(old_admin) + end + + instructeurs_without_new_admin.each do |i| + i.administrateurs << self + i.administrateurs.delete(old_admin) + end + end + # required to display feature flags field in manager def features end diff --git a/spec/models/administrateur_spec.rb b/spec/models/administrateur_spec.rb index f8c3e9a85..a00173c4d 100644 --- a/spec/models/administrateur_spec.rb +++ b/spec/models/administrateur_spec.rb @@ -75,4 +75,92 @@ describe Administrateur, type: :model do expect(Administrateur.find_by(id: administrateur.id)).to be_nil end end + + describe '#merge' do + let(:new_admin) { create(:administrateur) } + let(:old_admin) { create(:administrateur) } + + subject { new_admin.merge(old_admin) } + + context 'when the old admin does not exist' do + let(:old_admin) { nil } + + it { expect { subject }.not_to raise_error } + end + + context 'when the old admin has a procedure' do + let(:procedure) { create(:procedure) } + + before do + old_admin.procedures << procedure + subject + [new_admin, old_admin].map(&:reload) + end + + it 'transfers the procedure' do + expect(new_admin.procedures).to match_array(procedure) + expect(old_admin.procedures).to be_empty + end + end + + context 'when both admins share a procedure' do + let(:procedure) { create(:procedure) } + + before do + new_admin.procedures << procedure + old_admin.procedures << procedure + subject + [new_admin, old_admin].map(&:reload) + end + + it 'removes the procedure from the old one' do + expect(old_admin.procedures).to be_empty + end + end + + context 'when the old admin has a service' do + let(:service) { create(:service, administrateur: old_admin) } + + before do + service + subject + [new_admin, old_admin].map(&:reload) + end + + it 'transfers the service' do + expect(new_admin.services).to match_array(service) + end + end + + context 'when the old admin has an instructeur' do + let(:instructeur) { create(:instructeur) } + + before do + old_admin.instructeurs << instructeur + subject + [new_admin, old_admin].map(&:reload) + end + + it 'transfers the instructeur' do + expect(new_admin.instructeurs).to match_array(instructeur) + expect(old_admin.instructeurs).to be_empty + end + end + + context 'when both admins share an instructeur' do + let(:instructeur) { create(:instructeur) } + + before do + old_admin.instructeurs << instructeur + new_admin.instructeurs << instructeur + subject + [new_admin, old_admin].map(&:reload) + end + + it 'transfers the instructeur' do + expect(new_admin.instructeurs).to match_array(instructeur) + expect(old_admin.instructeurs).to be_empty + end + end + end end