dossiers: avoid exceptions on invalid AASM transitions
When attempting an invalid transition on a dossier, provide a meaningful error message (instead of letting an `AASM::InvalidTransition` exception propagate). This handles not only the case where the same state is applied twice (which was already handled manually), but all cases where the transition is invalid.
This commit is contained in:
parent
c7a307553c
commit
8eb295d67e
2 changed files with 47 additions and 17 deletions
|
@ -88,33 +88,33 @@ module Instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def passer_en_instruction
|
def passer_en_instruction
|
||||||
if dossier.en_instruction?
|
begin
|
||||||
flash.notice = 'Le dossier est déjà en instruction.'
|
|
||||||
else
|
|
||||||
dossier.passer_en_instruction!(current_instructeur)
|
dossier.passer_en_instruction!(current_instructeur)
|
||||||
flash.notice = 'Dossier passé en instruction.'
|
flash.notice = 'Dossier passé en instruction.'
|
||||||
|
rescue AASM::InvalidTransition => e
|
||||||
|
flash.alert = aasm_error_message(e, target_state: :en_instruction)
|
||||||
end
|
end
|
||||||
|
|
||||||
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
||||||
end
|
end
|
||||||
|
|
||||||
def repasser_en_construction
|
def repasser_en_construction
|
||||||
if dossier.en_construction?
|
begin
|
||||||
flash.notice = 'Le dossier est déjà en construction.'
|
|
||||||
else
|
|
||||||
dossier.repasser_en_construction!(current_instructeur)
|
dossier.repasser_en_construction!(current_instructeur)
|
||||||
flash.notice = 'Dossier repassé en construction.'
|
flash.notice = 'Dossier repassé en construction.'
|
||||||
|
rescue AASM::InvalidTransition => e
|
||||||
|
flash.alert = aasm_error_message(e, target_state: :en_construction)
|
||||||
end
|
end
|
||||||
|
|
||||||
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
||||||
end
|
end
|
||||||
|
|
||||||
def repasser_en_instruction
|
def repasser_en_instruction
|
||||||
if dossier.en_instruction?
|
begin
|
||||||
flash.notice = 'Le dossier est déjà en instruction.'
|
|
||||||
else
|
|
||||||
flash.notice = "Le dossier #{dossier.id} a été repassé en instruction."
|
flash.notice = "Le dossier #{dossier.id} a été repassé en instruction."
|
||||||
dossier.repasser_en_instruction!(current_instructeur)
|
dossier.repasser_en_instruction!(current_instructeur)
|
||||||
|
rescue AASM::InvalidTransition => e
|
||||||
|
flash.alert = aasm_error_message(e, target_state: :en_instruction)
|
||||||
end
|
end
|
||||||
|
|
||||||
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
||||||
|
@ -124,20 +124,23 @@ module Instructeurs
|
||||||
motivation = params[:dossier] && params[:dossier][:motivation]
|
motivation = params[:dossier] && params[:dossier][:motivation]
|
||||||
justificatif = params[:dossier] && params[:dossier][:justificatif_motivation]
|
justificatif = params[:dossier] && params[:dossier][:justificatif_motivation]
|
||||||
|
|
||||||
if dossier.termine?
|
begin
|
||||||
flash.notice = "Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"
|
|
||||||
else
|
|
||||||
case params[:process_action]
|
case params[:process_action]
|
||||||
when "refuser"
|
when "refuser"
|
||||||
|
target_state = :refuse
|
||||||
dossier.refuser!(current_instructeur, motivation, justificatif)
|
dossier.refuser!(current_instructeur, motivation, justificatif)
|
||||||
flash.notice = "Dossier considéré comme refusé."
|
flash.notice = "Dossier considéré comme refusé."
|
||||||
when "classer_sans_suite"
|
when "classer_sans_suite"
|
||||||
|
target_state = :sans_suite
|
||||||
dossier.classer_sans_suite!(current_instructeur, motivation, justificatif)
|
dossier.classer_sans_suite!(current_instructeur, motivation, justificatif)
|
||||||
flash.notice = "Dossier considéré comme sans suite."
|
flash.notice = "Dossier considéré comme sans suite."
|
||||||
when "accepter"
|
when "accepter"
|
||||||
|
target_state = :accepte
|
||||||
dossier.accepter!(current_instructeur, motivation, justificatif)
|
dossier.accepter!(current_instructeur, motivation, justificatif)
|
||||||
flash.notice = "Dossier traité avec succès."
|
flash.notice = "Dossier traité avec succès."
|
||||||
end
|
end
|
||||||
|
rescue AASM::InvalidTransition => e
|
||||||
|
flash.alert = aasm_error_message(e, target_state: target_state)
|
||||||
end
|
end
|
||||||
|
|
||||||
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
render partial: 'state_button_refresh', locals: { dossier: dossier }
|
||||||
|
@ -219,5 +222,13 @@ module Instructeurs
|
||||||
def mark_annotations_privees_as_read
|
def mark_annotations_privees_as_read
|
||||||
current_instructeur.mark_tab_as_seen(dossier, :annotations_privees)
|
current_instructeur.mark_tab_as_seen(dossier, :annotations_privees)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def aasm_error_message(exception, target_state:)
|
||||||
|
if exception.originating_state == target_state
|
||||||
|
"Le dossier est déjà #{dossier_display_state(target_state, lower: true)}."
|
||||||
|
else
|
||||||
|
"Le dossier est en ce moment #{dossier_display_state(exception.originating_state, lower: true)} : il n’est pas possible de le passer #{dossier_display_state(target_state, lower: true)}."
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -112,9 +112,23 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
context 'when the dossier has already been put en_instruction' do
|
context 'when the dossier has already been put en_instruction' do
|
||||||
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||||
|
|
||||||
it 'warns about the error, but doesn’t raise' do
|
it 'warns about the error' do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(response.body).to have_text('Le dossier est déjà en instruction.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier has already been closed' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
||||||
|
|
||||||
|
it 'doesn’t change the dossier state' do
|
||||||
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:accepte))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'warns about the error' do
|
||||||
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(response.body).to have_text('Le dossier est en ce moment accepté : il n’est pas possible de le passer en instruction.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -136,9 +150,10 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
context 'when the dossier has already been put en_construction' do
|
context 'when the dossier has already been put en_construction' do
|
||||||
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||||
|
|
||||||
it 'warns about the error, but doesn’t raise' do
|
it 'warns about the error' do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(response.body).to have_text('Le dossier est déjà en construction.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -161,9 +176,10 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
context 'when the dossier has already been put en_instruction' do
|
context 'when the dossier has already been put en_instruction' do
|
||||||
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||||
|
|
||||||
it 'warns about the error, but doesn’t raise' do
|
it 'warns about the error' do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(response.body).to have_text('Le dossier est déjà en instruction.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -355,15 +371,18 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
context 'when a dossier is already closed' do
|
context 'when a dossier is already closed' do
|
||||||
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
||||||
|
|
||||||
before { allow(dossier).to receive(:accepter!) }
|
before { allow(dossier).to receive(:after_accepter) }
|
||||||
|
|
||||||
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: 'js' }
|
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: 'js' }
|
||||||
|
|
||||||
it 'does not close it again' do
|
it 'does not close it again' do
|
||||||
subject
|
subject
|
||||||
|
|
||||||
expect(dossier).not_to have_received(:accepter!)
|
expect(dossier).not_to have_received(:after_accepter)
|
||||||
|
expect(dossier.state).to eq(Dossier.states.fetch(:accepte))
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(response.body).to have_text('Le dossier est déjà accepté.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue