From 52e8f32e19d0e56344b4caf59781edd8b7282224 Mon Sep 17 00:00:00 2001 From: Christophe Robillard Date: Thu, 16 Jul 2020 20:42:50 +0200 Subject: [PATCH] expert can only revoke avis claimed by him/her --- .../instructeurs/avis_controller.rb | 2 +- app/models/avis.rb | 8 ++- .../instructeurs/shared/avis/_list.html.haml | 6 +- .../instructeurs/avis_controller_spec.rb | 4 +- spec/models/avis_spec.rb | 57 +++++++++++++++++-- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/app/controllers/instructeurs/avis_controller.rb b/app/controllers/instructeurs/avis_controller.rb index aebcc31df..322734006 100644 --- a/app/controllers/instructeurs/avis_controller.rb +++ b/app/controllers/instructeurs/avis_controller.rb @@ -117,7 +117,7 @@ module Instructeurs def revoquer avis = Avis.find(params[:id]) - if avis.revoke! + if avis.revoke_by!(current_instructeur) flash.notice = "#{avis.email_to_display} ne peut plus donner son avis sur ce dossier." redirect_back(fallback_location: avis_instructeur_dossier_path(avis.procedure, avis.dossier)) end diff --git a/app/models/avis.rb b/app/models/avis.rb index 2374ef365..3834469a0 100644 --- a/app/models/avis.rb +++ b/app/models/avis.rb @@ -60,7 +60,13 @@ class Avis < ApplicationRecord revoked_at.present? end - def revoke! + def revokable_by?(revocator) + revocator.dossiers.include?(dossier) || revocator == claimant + end + + def revoke_by!(revocator) + return false if !revokable_by?(revocator) + if answer.present? update!(revoked_at: Time.zone.now) else diff --git a/app/views/instructeurs/shared/avis/_list.html.haml b/app/views/instructeurs/shared/avis/_list.html.haml index 6b5a30e07..72016270e 100644 --- a/app/views/instructeurs/shared/avis/_list.html.haml +++ b/app/views/instructeurs/shared/avis/_list.html.haml @@ -28,13 +28,15 @@ %span.waiting{ class: highlight_if_unseen_class(avis_seen_at, avis.revoked_at) } Demande d'avis révoquée le #{l(avis.revoked_at, format: '%d/%m/%y à %H:%M')} - else - %span.waiting= link_to("Révoquer l'avis", revoquer_instructeur_avis_path(avis.procedure, avis), data: { confirm: "Souhaitez-vous révoquer la demande d'avis à #{avis.email_to_display} ?" }, method: :patch) + - if avis.revokable_by?(current_instructeur) + %span.waiting= link_to("Révoquer l'avis", revoquer_instructeur_avis_path(avis.procedure, avis), data: { confirm: "Souhaitez-vous révoquer la demande d'avis à #{avis.email_to_display} ?" }, method: :patch) %span.date{ class: highlight_if_unseen_class(avis_seen_at, avis.updated_at) } Réponse donnée le #{l(avis.updated_at, format: '%d/%m/%y à %H:%M')} - else %span.waiting En attente de réponse - = link_to("Révoquer l'avis", revoquer_instructeur_avis_path(avis.procedure, avis), data: { confirm: "Souhaitez-vous révoquer la demande d'avis à #{avis.email_to_display} ?" }, method: :patch) + - if avis.revokable_by?(current_instructeur) + = link_to("Révoquer l'avis", revoquer_instructeur_avis_path(avis.procedure, avis), data: { confirm: "Souhaitez-vous révoquer la demande d'avis à #{avis.email_to_display} ?" }, method: :patch) - if avis.piece_justificative_file.attached? = render partial: 'shared/attachment/show', locals: { attachment: avis.piece_justificative_file.attachment } .answer-body diff --git a/spec/controllers/instructeurs/avis_controller_spec.rb b/spec/controllers/instructeurs/avis_controller_spec.rb index cfdd85011..0e73fc559 100644 --- a/spec/controllers/instructeurs/avis_controller_spec.rb +++ b/spec/controllers/instructeurs/avis_controller_spec.rb @@ -48,7 +48,7 @@ describe Instructeurs::AvisController, type: :controller do context 'with a revoked avis' do it "refuse l'accès au dossier" do - avis_with_answer.revoke! + avis_with_answer.update!(revoked_at: Time.zone.now) subject expect(flash.alert).to eq("Vous n'avez plus accès à ce dossier.") expect(response).to redirect_to(root_path) @@ -273,7 +273,7 @@ describe Instructeurs::AvisController, type: :controller do end describe "#revoker" do - let(:avis) { create(:avis) } + let(:avis) { create(:avis, claimant: instructeur) } let(:procedure) { avis.procedure } it "revoke the dossier" do diff --git a/spec/models/avis_spec.rb b/spec/models/avis_spec.rb index 7c2b75ee5..bd6cd64c5 100644 --- a/spec/models/avis_spec.rb +++ b/spec/models/avis_spec.rb @@ -132,25 +132,72 @@ RSpec.describe Avis, type: :model do end end - describe ".revoke!" do + describe ".revoke_by!" do + let(:claimant) { create(:instructeur) } + context "when no answer" do - let(:avis) { create(:avis) } + let(:avis) { create(:avis, claimant: claimant) } it "supprime l'avis" do - avis.revoke! + avis.revoke_by!(claimant) expect(avis).to be_destroyed expect(Avis.count).to eq 0 end end context "with answer" do - let(:avis) { create(:avis, :with_answer) } + let(:avis) { create(:avis, :with_answer, claimant: claimant) } it "revoque l'avis" do - avis.revoke! + avis.revoke_by!(claimant) expect(avis).not_to be_destroyed expect(avis).to be_revoked end end + + context "by an instructeur who can't revoke" do + let(:avis) { create(:avis, :with_answer, claimant: claimant) } + let(:expert) { create(:instructeur) } + + it "doesn't revoke avis and returns false" do + result = avis.revoke_by!(expert) + expect(result).to be_falsey + expect(avis).not_to be_destroyed + expect(avis).not_to be_revoked + end + end + end + + describe "revokable_by?" do + let(:instructeur) { create(:instructeur) } + let(:instructeurs) { [instructeur] } + let(:procedure) { create(:procedure, :published, instructeurs: instructeurs) } + let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + let(:claimant_expert) { create(:instructeur) } + let(:expert) { create(:instructeur) } + let(:another_expert) { create(:instructeur) } + + context "when avis claimed by an expert" do + let(:avis) { create(:avis, dossier: dossier, claimant: claimant_expert, instructeur: expert) } + let(:another_avis) { create(:avis, dossier: dossier, claimant: instructeur, instructeur: another_expert) } + it "is revokable by this expert or any instructeurs of the dossier" do + expect(avis.revokable_by?(claimant_expert)).to be_truthy + expect(avis.revokable_by?(another_expert)).to be_falsy + expect(avis.revokable_by?(instructeur)).to be_truthy + end + end + + context "when avis claimed by an instructeur" do + let(:avis) { create(:avis, dossier: dossier, claimant: instructeur, instructeur: expert) } + let(:another_avis) { create(:avis, dossier: dossier, claimant: expert, instructeur: another_expert) } + let(:another_instructeur) { create(:instructeur) } + let(:instructeurs) { [instructeur, another_instructeur] } + + it "is revokable by any instructeur of the dossier, not by an expert" do + expect(avis.revokable_by?(instructeur)).to be_truthy + expect(avis.revokable_by?(another_expert)).to be_falsy + expect(avis.revokable_by?(another_instructeur)).to be_truthy + end + end end end