+ <% else %>
+ <%= form_tag(add_administrateur_manager_procedure_path(procedure), style: 'margin-top: 1rem;') do %>
+
+ <% end %>
<% end %>
<% end %>
diff --git a/db/migrate/20211006164955_add_manager_to_administrateurs_procedures.rb b/db/migrate/20211006164955_add_manager_to_administrateurs_procedures.rb
new file mode 100644
index 000000000..8e424a92b
--- /dev/null
+++ b/db/migrate/20211006164955_add_manager_to_administrateurs_procedures.rb
@@ -0,0 +1,5 @@
+class AddManagerToAdministrateursProcedures < ActiveRecord::Migration[6.1]
+ def change
+ add_column :administrateurs_procedures, :manager, :boolean
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5c75e2aea..2d29640fd 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2021_10_01_143403) do
+ActiveRecord::Schema.define(version: 2021_10_06_164955) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -76,6 +76,7 @@ ActiveRecord::Schema.define(version: 2021_10_01_143403) do
t.bigint "procedure_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.boolean "manager"
t.index ["administrateur_id", "procedure_id"], name: "index_unique_admin_proc_couple", unique: true
t.index ["administrateur_id"], name: "index_administrateurs_procedures_on_administrateur_id"
t.index ["procedure_id"], name: "index_administrateurs_procedures_on_procedure_id"
diff --git a/spec/controllers/manager/instructeurs_controller_spec.rb b/spec/controllers/manager/instructeurs_controller_spec.rb
index 6dedf3797..11279083b 100644
--- a/spec/controllers/manager/instructeurs_controller_spec.rb
+++ b/spec/controllers/manager/instructeurs_controller_spec.rb
@@ -1,4 +1,4 @@
-xdescribe Manager::InstructeursController, type: :controller do
+describe Manager::InstructeursController, type: :controller do
let(:super_admin) { create(:super_admin) }
let(:instructeur) { create(:instructeur) }
diff --git a/spec/controllers/manager/procedures_controller_spec.rb b/spec/controllers/manager/procedures_controller_spec.rb
index 8391a59b6..ad27b784a 100644
--- a/spec/controllers/manager/procedures_controller_spec.rb
+++ b/spec/controllers/manager/procedures_controller_spec.rb
@@ -1,4 +1,4 @@
-xdescribe Manager::ProceduresController, type: :controller do
+describe Manager::ProceduresController, type: :controller do
let(:super_admin) { create :super_admin }
before { sign_in super_admin }
diff --git a/spec/controllers/manager/users_controller_spec.rb b/spec/controllers/manager/users_controller_spec.rb
index c6be09477..c1e43f856 100644
--- a/spec/controllers/manager/users_controller_spec.rb
+++ b/spec/controllers/manager/users_controller_spec.rb
@@ -1,6 +1,8 @@
-xdescribe Manager::UsersController, type: :controller do
+describe Manager::UsersController, type: :controller do
let(:super_admin) { create(:super_admin) }
+ before { sign_in super_admin }
+
describe '#show' do
render_views
@@ -8,7 +10,6 @@ xdescribe Manager::UsersController, type: :controller do
let(:user) { create(:user) }
before do
- sign_in(super_admin)
get :show, params: { id: user.id }
end
@@ -16,39 +17,119 @@ xdescribe Manager::UsersController, type: :controller do
end
describe '#update' do
- let!(:user) { create(:user, email: 'ancien.email@domaine.fr') }
+ let(:user) { create(:user, email: 'ancien.email@domaine.fr') }
- before {
- sign_in super_admin
- }
subject { patch :update, params: { id: user.id, user: { email: nouvel_email } } }
- describe 'with a valid email' do
- let(:nouvel_email) { 'nouvel.email@domaine.fr' }
+ context 'when the targeted email does not exist' do
+ describe 'with a valid email' do
+ let(:nouvel_email) { 'nouvel.email@domaine.fr' }
- it 'updates the user email' do
- subject
+ it 'updates the user email' do
+ subject
- expect(User.find_by(id: user.id).email).to eq(nouvel_email)
+ expect(User.find_by(id: user.id).email).to eq(nouvel_email)
+ end
+
+ context 'and the user is an administrateur' do
+ let(:user) { create(:administrateur).user }
+
+ it 'rejects the modification' do
+ subject
+
+ expect(flash[:error]).to match("« nouvel.email@domaine.fr » est un administrateur. On ne sait pas encore faire.")
+ expect(user.reload.email).not_to eq(nouvel_email)
+ end
+ end
+ end
+
+ describe 'with an invalid email' do
+ let(:nouvel_email) { 'plop' }
+
+ it 'does not update the user email' do
+ subject
+
+ expect(User.find_by(id: user.id).email).not_to eq(nouvel_email)
+ expect(flash[:error]).to match("Courriel invalide")
+ end
end
end
- describe 'with an invalid email' do
- let(:nouvel_email) { 'plop' }
+ context 'when the targeted email exists' do
+ let(:preexisting_user) { create(:user, email: 'email.existant@domaine.fr') }
+ let(:nouvel_email) { preexisting_user.email }
- it 'does not update the user email' do
- subject
+ context 'and the old account has a dossier' do
+ let!(:dossier) { create(:dossier, user: user) }
- expect(User.find_by(id: user.id).email).not_to eq(nouvel_email)
- expect(flash[:error]).to match("« #{nouvel_email} » n'est pas une adresse valide.")
+ it 'transfers the dossier' do
+ subject
+
+ expect(preexisting_user.dossiers).to match([dossier])
+ end
+ end
+
+ context 'and the old account belongs to an instructeur and expert' do
+ let!(:instructeur) { create(:instructeur, user: user) }
+ let!(:expert) { create(:expert, user: user) }
+
+ it 'transfers instructeur account' do
+ subject
+ preexisting_user.reload
+
+ expect(preexisting_user.instructeur).to match(instructeur)
+ expect(preexisting_user.expert).to match(expert)
+ expect(flash[:notice]).to match("Le compte « email.existant@domaine.fr » a absorbé le compte « ancien.email@domaine.fr ».")
+ end
+
+ context 'and the preexisting account owns an instructeur and expert as well' do
+ let!(:preexisting_instructeur) { create(:instructeur, user: preexisting_user) }
+ let!(:preexisting_expert) { create(:expert, user: preexisting_user) }
+
+ context 'and the source instructeur has some procedures and dossiers' do
+ let!(:procedure) { create(:procedure, instructeurs: [instructeur]) }
+ let(:dossier) { create(:dossier) }
+ let(:administrateur) { create(:administrateur) }
+ let!(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) }
+ let!(:bulk_message) { BulkMessage.create!(instructeur: instructeur, body: 'body', sent_at: Time.zone.now) }
+
+ before do
+ user.instructeur.followed_dossiers << dossier
+ user.instructeur.administrateurs << administrateur
+ end
+
+ it 'transferts all the stuff' do
+ subject
+ preexisting_user.reload
+
+ expect(procedure.instructeurs).to match([preexisting_user.instructeur])
+ expect(preexisting_user.instructeur.followed_dossiers).to match([dossier])
+ expect(preexisting_user.instructeur.administrateurs).to match([administrateur])
+ expect(preexisting_user.instructeur.commentaires).to match([commentaire])
+ expect(preexisting_user.instructeur.bulk_messages).to match([bulk_message])
+ end
+ end
+
+ context 'and the source expert has some avis and commentaires' do
+ let(:dossier) { create(:dossier) }
+ let(:experts_procedure) { create(:experts_procedure, expert: user.expert, procedure: dossier.procedure) }
+ let!(:avis) { create(:avis, dossier: dossier, claimant: create(:instructeur), experts_procedure: experts_procedure) }
+ let!(:commentaire) { create(:commentaire, expert: expert, dossier: dossier) }
+
+ it 'transfers the avis' do
+ subject
+
+ expect(preexisting_user.expert.avis).to match([avis])
+ expect(preexisting_user.expert.commentaires).to match([commentaire])
+ end
+ end
+ end
end
end
end
describe '#delete' do
- let!(:user) { create(:user) }
-
- before { sign_in super_admin }
+ let(:user) { create(:user) }
subject { delete :delete, params: { id: user.id } }
diff --git a/spec/models/expert_spec.rb b/spec/models/expert_spec.rb
index 2b3dd1c78..5b3ebf607 100644
--- a/spec/models/expert_spec.rb
+++ b/spec/models/expert_spec.rb
@@ -12,4 +12,67 @@ RSpec.describe Expert, type: :model do
it { expect(ExpertsProcedure.where(expert: expert, procedure: procedure).count).to eq(1) }
it { expect(ExpertsProcedure.where(expert: expert, procedure: procedure).first.allow_decision_access).to be_falsy }
end
+
+ describe '#merge' do
+ let(:old_expert) { create(:expert) }
+ let(:new_expert) { create(:expert) }
+
+ subject { new_expert.merge(old_expert) }
+
+ context 'when an old expert access a procedure' do
+ let(:procedure) { create(:procedure) }
+
+ before do
+ procedure.experts << old_expert
+ subject
+ end
+
+ it 'transfers the access to the new expert' do
+ expect(procedure.reload.experts). to match_array(new_expert)
+ end
+ end
+
+ context 'when both expert access a procedure' do
+ let(:procedure) { create(:procedure) }
+
+ before do
+ procedure.experts << old_expert
+ procedure.experts << new_expert
+ subject
+ end
+
+ it 'removes the old one' do
+ expect(procedure.reload.experts). to match_array(new_expert)
+ end
+ end
+
+ context 'when an old expert has a commentaire' do
+ let(:dossier) { create(:dossier) }
+ let(:commentaire) { CommentaireService.build(old_expert, dossier, body: "Mon commentaire") }
+
+ before do
+ commentaire.save
+ subject
+ end
+
+ it 'transfers the commentaire to the new expert' do
+ expect(new_expert.reload.commentaires).to match_array(commentaire)
+ end
+ end
+
+ context 'when an old expert claims for an avis' do
+ let!(:avis) { create(:avis, dossier: create(:dossier), claimant: old_expert) }
+
+ before do
+ subject
+ end
+
+ it 'transfers the claim to the new expert' do
+ avis_claimed_by_new_expert = Avis
+ .where(claimant_id: new_expert.id, claimant_type: Expert.name)
+
+ expect(avis_claimed_by_new_expert).to match_array(avis)
+ end
+ end
+ end
end
diff --git a/spec/models/instructeur_spec.rb b/spec/models/instructeur_spec.rb
index 065e3eb19..a9ffc2c4a 100644
--- a/spec/models/instructeur_spec.rb
+++ b/spec/models/instructeur_spec.rb
@@ -737,6 +737,94 @@ describe Instructeur, type: :model do
end
end
+ describe '#merge' do
+ let(:old_instructeur) { create(:instructeur) }
+ let(:new_instructeur) { create(:instructeur) }
+
+ subject { new_instructeur.merge(old_instructeur) }
+
+ context 'when an procedure is assigned to the old instructeur' do
+ let(:procedure) { create(:procedure) }
+
+ before do
+ procedure.defaut_groupe_instructeur.instructeurs << old_instructeur
+ subject
+ end
+
+ it 'transfers the assignment' do
+ expect(new_instructeur.procedures).to match_array(procedure)
+ end
+ end
+
+ context 'when both instructeurs are assigned to the same procedure' do
+ let(:procedure) { create(:procedure) }
+
+ before do
+ procedure.defaut_groupe_instructeur.instructeurs << old_instructeur
+ procedure.defaut_groupe_instructeur.instructeurs << new_instructeur
+ subject
+ end
+
+ it 'keeps the assignment' do
+ expect(new_instructeur.procedures).to match_array(procedure)
+ end
+ end
+
+ context 'when a dossier is followed by an old instructeur' do
+ let(:dossier) { create(:dossier) }
+
+ before do
+ old_instructeur.followed_dossiers << dossier
+ subject
+ end
+
+ it 'transfers the dossier' do
+ expect(new_instructeur.followed_dossiers).to match_array(dossier)
+ end
+ end
+
+ context 'when both instructeurs follow the same dossier' do
+ let(:dossier) { create(:dossier) }
+
+ before do
+ old_instructeur.followed_dossiers << dossier
+ new_instructeur.followed_dossiers << dossier
+ subject
+ end
+
+ it 'does not change anything' do
+ expect(new_instructeur.followed_dossiers.pluck(:id)).to match_array(dossier.id)
+ end
+ end
+
+ context 'when the old instructeur is on on admin list' do
+ let(:administrateur) { create(:administrateur) }
+
+ before do
+ administrateur.instructeurs << old_instructeur
+ subject
+ end
+
+ it 'is replaced by the new one' do
+ expect(administrateur.reload.instructeurs).to match_array(new_instructeur)
+ end
+ end
+
+ context 'when both are on the same admin list' do
+ let(:administrateur) { create(:administrateur) }
+
+ before do
+ administrateur.instructeurs << old_instructeur
+ administrateur.instructeurs << new_instructeur
+ subject
+ end
+
+ it 'removes the old one' do
+ expect(administrateur.reload.instructeurs).to match_array(new_instructeur)
+ end
+ end
+ end
+
private
def assign(procedure_to_assign, instructeur_assigne: instructeur)