demarches-normaliennes/spec/controllers/instructeurs/dossiers_controller_spec.rb

1193 lines
44 KiB
Ruby
Raw Normal View History

describe Instructeurs::DossiersController, type: :controller do
render_views
let(:instructeur) { create(:instructeur) }
let(:administrateur) { create(:administrateur) }
let(:administration) { create(:administration) }
let(:instructeurs) { [instructeur] }
2021-01-28 13:53:18 +01:00
let(:procedure) { create(:procedure, :published, :for_individual, instructeurs: instructeurs) }
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
let(:fake_justificatif) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
2019-08-07 11:15:16 +02:00
before { sign_in(instructeur.user) }
describe '#attestation' do
context 'when a dossier has an attestation' do
let(:dossier) { create(:dossier, :accepte, attestation: create(:attestation, :with_pdf), procedure: procedure) }
2019-12-19 18:29:01 +01:00
it 'redirects to a service tmp_url' do
get :attestation, params: { procedure_id: procedure.id, dossier_id: dossier.id }
2019-12-19 18:29:01 +01:00
expect(response.location).to match '/rails/active_storage/disk/'
end
end
end
describe '#send_to_instructeurs' do
let(:mail) { double("mail") }
before do
allow(mail).to receive(:deliver_later)
allow(InstructeurMailer)
.to receive(:send_dossier)
.with(instructeur, dossier, recipient)
.and_return(mail)
post(
:send_to_instructeurs,
params: {
recipients: [recipient.id].to_json,
procedure_id: procedure.id,
dossier_id: dossier.id
}
)
end
context 'when the recipient belongs to the dossier groupe instructeur' do
let(:recipient) { instructeur }
it do
expect(InstructeurMailer).to have_received(:send_dossier)
expect(response).to redirect_to(personnes_impliquees_instructeur_dossier_url)
expect(recipient.followed_dossiers).to include(dossier)
end
end
context 'when the recipient is random' do
let(:recipient) { create(:instructeur) }
it do
expect(InstructeurMailer).not_to have_received(:send_dossier)
expect(response).to redirect_to(personnes_impliquees_instructeur_dossier_url)
expect(recipient.followed_dossiers).not_to include(dossier)
end
end
end
describe '#follow' do
let(:batch_operation) {}
before do
batch_operation
patch :follow, params: { procedure_id: procedure.id, dossier_id: dossier.id }
end
it { expect(instructeur.followed_dossiers).to match([dossier]) }
it { expect(flash.notice).to eq('Dossier suivi') }
it { expect(response).to redirect_to(instructeur_procedure_path(dossier.procedure)) }
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(instructeur.followed_dossiers).to eq([]) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
describe '#unfollow' do
let(:batch_operation) {}
before do
batch_operation
instructeur.followed_dossiers << dossier
patch :unfollow, params: { procedure_id: procedure.id, dossier_id: dossier.id }
instructeur.reload
end
it { expect(instructeur.followed_dossiers).to match([]) }
it { expect(flash.notice).to eq("Vous ne suivez plus le dossier nº #{dossier.id}") }
it { expect(response).to redirect_to(instructeur_procedure_path(dossier.procedure)) }
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(instructeur.followed_dossiers).to eq([dossier]) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
describe '#archive' do
let(:batch_operation) {}
before do
batch_operation
patch :archive, params: { procedure_id: procedure.id, dossier_id: dossier.id }
dossier.reload
instructeur.follow(dossier)
end
it { expect(dossier.archived).to eq(true) }
it { expect(response).to redirect_to(instructeur_procedure_path(dossier.procedure)) }
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(dossier.archived).to eq(false) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
describe '#unarchive' do
let(:batch_operation) {}
before do
batch_operation
dossier.update(archived: true)
patch :unarchive, params: { procedure_id: procedure.id, dossier_id: dossier.id }
end
it { expect(dossier.reload.archived).to eq(false) }
it { expect(response).to redirect_to(instructeur_procedure_path(dossier.procedure)) }
context 'with dossier in batch_operation' do
let!(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(dossier.reload.archived).to eq(true) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
describe '#passer_en_instruction' do
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:batch_operation) {}
before do
batch_operation
2019-08-07 11:15:16 +02:00
sign_in(instructeur.user)
post :passer_en_instruction, params: { procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream
end
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction)) }
it { expect(instructeur.follow?(dossier)).to be true }
it { expect(response).to have_http_status(:ok) }
2023-02-28 17:28:17 +01:00
it { expect(response.body).to include('header-top') }
context 'when the dossier has already been put en_instruction' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
it 'warns about the error' do
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
expect(response).to have_http_status(:ok)
expect(response.body).to include('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 'doesnt 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 include('Le dossier est en ce moment accepté : il nest pas possible de le passer en instruction.')
end
end
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
describe '#repasser_en_construction' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
let(:batch_operation) {}
before do
batch_operation
2019-08-07 11:15:16 +02:00
sign_in(instructeur.user)
post :repasser_en_construction,
params: { procedure_id: procedure.id, dossier_id: dossier.id },
format: :turbo_stream
end
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction)) }
it { expect(response).to have_http_status(:ok) }
2023-02-28 17:28:17 +01:00
it { expect(response.body).to include('header-top') }
context 'when the dossier has already been put en_construction' do
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
it 'warns about the error' do
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
expect(response).to have_http_status(:ok)
expect(response.body).to include('Le dossier est déjà en construction.')
end
end
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(dossier.reload.state).to eq('en_instruction') }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
end
2019-07-11 11:52:24 +02:00
describe '#repasser_en_instruction' do
let(:dossier) { create(:dossier, :refuse, procedure: procedure) }
let(:batch_operation) {}
2019-08-07 11:15:16 +02:00
let(:current_user) { instructeur.user }
2019-07-11 11:52:24 +02:00
before do
sign_in current_user
batch_operation
2021-11-29 11:34:42 +01:00
post :repasser_en_instruction,
params: { procedure_id: procedure.id, dossier_id: dossier.id },
format: :turbo_stream
2021-11-29 11:34:42 +01:00
end
context 'when the dossier is refuse' do
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction)) }
it { expect(response).to have_http_status(:ok) }
2023-02-28 17:28:17 +01:00
it { expect(response.body).to include('header-top') }
2021-11-29 11:34:42 +01:00
end
2019-07-11 11:52:24 +02:00
context 'when the dossier has already been put en_instruction' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
it 'warns about the error' do
2019-07-11 11:52:24 +02:00
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
expect(response).to have_http_status(:ok)
expect(response.body).to include('Le dossier est déjà en instruction.')
2019-07-11 11:52:24 +02:00
end
end
context 'when the dossier is accepte' do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
it 'it is possible to go back to en_instruction as instructeur' do
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
expect(response).to have_http_status(:ok)
end
end
2021-11-29 11:34:42 +01:00
context 'when the dossier is done and the user delete it' do
let!(:dossier) { create(:dossier, :accepte, procedure: procedure, user: current_user, hidden_by_user_at: Time.zone.now) }
2021-11-29 11:34:42 +01:00
it 'reveals the dossier' do
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_instruction))
expect(dossier.reload.hidden_by_user_at).to be_nil
end
end
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(dossier.reload.state).to eq('refuse') }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
2019-07-11 11:52:24 +02:00
end
2017-12-01 12:57:01 +01:00
describe '#terminer' do
context "with refuser" do
2017-12-01 12:57:01 +01:00
before do
dossier.passer_en_instruction!(instructeur: instructeur)
2019-08-07 11:15:16 +02:00
sign_in(instructeur.user)
2017-12-01 12:57:01 +01:00
end
context 'simple refusal' do
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
2017-12-01 12:57:01 +01:00
it 'change state to refuse' do
subject
2017-12-01 12:57:01 +01:00
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
expect(dossier.justificatif_motivation).to_not be_attached
end
2017-12-01 12:57:01 +01:00
it 'Notification email is sent' do
2021-04-29 19:10:22 +02:00
expect(NotificationMailer).to receive(:send_refuse_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
2017-12-01 12:57:01 +01:00
subject
end
2017-12-01 12:57:01 +01:00
end
context 'refusal with a justificatif' do
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: :turbo_stream }
it 'attachs a justificatif' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
expect(dossier.justificatif_motivation).to be_attached
end
2023-02-28 17:28:17 +01:00
it { expect(subject.body).to include('header-top') }
end
context 'with dossier in batch_operation' do
let!(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
it { expect { subject }.not_to change { dossier.reload.state } }
it { is_expected.to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it 'flashes message' do
subject
expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.")
end
end
2017-12-01 12:57:01 +01:00
end
context "with classer_sans_suite" do
2017-12-01 12:57:01 +01:00
before do
dossier.passer_en_instruction!(instructeur: instructeur)
2019-08-07 11:15:16 +02:00
sign_in(instructeur.user)
2017-12-01 12:57:01 +01:00
end
context 'without attachment' do
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
2017-12-01 12:57:01 +01:00
it 'change state to sans_suite' do
subject
2017-12-01 12:57:01 +01:00
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite))
expect(dossier.justificatif_motivation).to_not be_attached
end
2017-12-01 12:57:01 +01:00
it 'Notification email is sent' do
2021-04-29 19:10:22 +02:00
expect(NotificationMailer).to receive(:send_sans_suite_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
2017-12-01 12:57:01 +01:00
subject
end
2017-12-01 12:57:01 +01:00
2023-02-28 17:28:17 +01:00
it { expect(subject.body).to include('header-top') }
2017-12-01 12:57:01 +01:00
end
context 'with attachment' do
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: :turbo_stream }
it 'change state to sans_suite' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite))
expect(dossier.justificatif_motivation).to be_attached
end
2023-02-28 17:28:17 +01:00
it { expect(subject.body).to include('header-top') }
end
2017-12-01 12:57:01 +01:00
end
context "with accepter" do
2017-12-01 12:57:01 +01:00
before do
dossier.passer_en_instruction!(instructeur: instructeur)
2019-08-07 11:15:16 +02:00
sign_in(instructeur.user)
2017-12-01 12:57:01 +01:00
2021-04-29 19:10:22 +02:00
expect(NotificationMailer).to receive(:send_accepte_notification)
.with(dossier)
2017-12-01 12:57:01 +01:00
.and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
2017-12-01 12:57:01 +01:00
end
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
2017-12-01 12:57:01 +01:00
2017-12-04 18:00:12 +01:00
it 'change state to accepte' do
2017-12-01 12:57:01 +01:00
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:accepte))
expect(dossier.justificatif_motivation).to_not be_attached
2017-12-01 12:57:01 +01:00
end
context 'when the dossier does not have any attestation' do
it 'Notification email is sent' do
subject
end
end
context 'when the dossier has an attestation' do
before do
attestation = Attestation.new
allow(attestation).to receive(:pdf).and_return(double(read: 'pdf', size: 2.megabytes, attached?: false))
2020-09-14 22:31:09 +02:00
allow(attestation).to receive(:pdf_url).and_return('http://some_document_url')
2017-12-01 12:57:01 +01:00
allow_any_instance_of(Dossier).to receive(:build_attestation).and_return(attestation)
end
it 'The instructeur is sent back to the dossier page' do
2023-02-28 17:28:17 +01:00
expect(subject.body).to include('header-top')
2017-12-01 12:57:01 +01:00
end
2018-07-25 17:16:24 +02:00
context 'and the dossier has already an attestation' do
it 'should not crash' do
dossier.attestation = Attestation.new
dossier.save
2023-02-28 17:28:17 +01:00
expect(subject.body).to include('header-top')
2018-07-25 17:16:24 +02:00
end
end
2017-12-01 12:57:01 +01:00
end
context 'when the attestation template uses the motivation field' do
let(:emailable) { false }
let(:template) { create(:attestation_template) }
2021-01-28 13:53:18 +01:00
let(:procedure) { create(:procedure, :published, :for_individual, attestation_template: template, instructeurs: [instructeur]) }
subject do
post :terminer, params: {
process_action: "accepter",
procedure_id: procedure.id,
dossier_id: dossier.id,
dossier: { motivation: "Yallah" }
}, format: :turbo_stream
end
before do
expect_any_instance_of(AttestationTemplate)
.to receive(:attestation_for)
.with(have_attributes(motivation: "Yallah"))
end
it { subject }
end
context 'with an attachment' do
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: :turbo_stream }
it 'change state to accepte' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:accepte))
expect(dossier.justificatif_motivation).to be_attached
end
2023-02-28 17:28:17 +01:00
it { expect(subject.body).to include('header-top') }
end
2017-12-01 12:57:01 +01:00
end
context 'when related etablissement is still in degraded_mode' do
let(:procedure) { create(:procedure, :published, for_individual: false, instructeurs: instructeurs) }
let(:dossier) { create(:dossier, :en_instruction, :with_entreprise, procedure: procedure, as_degraded_mode: true) }
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
context "with accepter" do
it 'warns about the error' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:en_instruction))
expect(response).to have_http_status(:ok)
expect(response.body).to match(/Les données relatives au SIRET .+ de le passer accepté/)
end
end
end
context 'when a dossier is already closed' do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
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: :turbo_stream }
it 'does not close it again' do
subject
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.body).to include('Le dossier est déjà accepté.')
end
end
2017-12-01 12:57:01 +01:00
end
describe '#pending_correction' do
let(:message) { 'do that' }
let(:justificatif) { nil }
subject do
post :pending_correction, params: {
procedure_id: procedure.id, dossier_id: dossier.id,
dossier: { motivation: message, justificatif_motivation: justificatif }
}, format: :turbo_stream
end
before do
sign_in(instructeur.user)
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :messagerie)
end
context "dossier en instruction sends an email to user" do
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:) }
it { expect { subject }.to have_enqueued_mail(DossierMailer, :notify_pending_correction) }
end
context "dossier en instruction" do
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
before { subject }
it 'pass en_construction and create a pending correction' do
expect(response).to have_http_status(:ok)
expect(response.body).to include('en attente de correction')
expect(dossier.reload).to be_en_construction
expect(dossier).to be_pending_correction
end
it 'create a comment with text body' do
expect(dossier.commentaires.last.body).to eq("do that")
expect(dossier.commentaires.last).to be_flagged_pending_correction
end
context 'with an attachment' do
let(:justificatif) { fake_justificatif }
it 'attach file to comment' do
expect(dossier.commentaires.last.piece_jointe).to be_attached
end
end
context 'with an invalid comment / attachment' do
let(:justificatif) { Rack::Test::UploadedFile.new(Rails.root.join('Gemfile.lock'), 'text/lock') }
it 'does not save anything' do
expect(dossier.reload).not_to be_pending_correction
expect(dossier.commentaires.count).to eq(0)
expect(response.body).to include('pas dun type accepté')
end
end
context 'with an empty message' do
let(:message) { '' }
it 'requires a message' do
expect(dossier.reload).not_to be_pending_correction
expect(dossier.commentaires.count).to eq(0)
expect(response.body).to include('Vous devez préciser')
end
end
context 'dossier already having pending corrections' do
before do
create(:dossier_correction, dossier:)
end
it 'does not create an new pending correction' do
expect { subject }.not_to change { DossierCorrection.count }
end
it 'shows a flash alert' do
subject
expect(response.body).to include('')
end
end
end
context 'dossier en_construction' do
it 'can create a pending correction' do
subject
expect(dossier.reload).to be_pending_correction
expect(dossier.commentaires.last).to be_flagged_pending_correction
end
end
context 'dossier is termine' do
let(:dossier) { create(:dossier, :accepte, :with_individual, procedure: procedure) }
it 'does not create a pending correction' do
expect { subject }.not_to change { DossierCorrection.count }
expect(response.body).to include('Impossible')
end
end
end
describe '#messagerie' do
before { expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :messagerie) }
subject { get :messagerie, params: { procedure_id: procedure.id, dossier_id: dossier.id } }
it { expect(subject).to have_http_status(:ok) }
end
describe "#create_commentaire" do
let(:saved_commentaire) { dossier.commentaires.first }
let(:body) { "avant\napres" }
let(:file) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
2017-11-08 16:37:04 +01:00
let(:scan_result) { true }
let(:now) { Timecop.freeze("09/11/1989") }
2017-11-08 16:37:04 +01:00
subject {
post :create_commentaire, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
commentaire: {
2017-11-07 20:40:00 +01:00
body: body,
file: file
}
}
2017-11-08 16:37:04 +01:00
}
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :messagerie)
2017-11-08 16:37:04 +01:00
allow(ClamavService).to receive(:safe_file?).and_return(scan_result)
Timecop.freeze(now)
end
after { Timecop.return }
it "creates a commentaire" do
expect { subject }.to change(Commentaire, :count).by(1)
expect(instructeur.followed_dossiers).to include(dossier)
expect(response).to redirect_to(messagerie_instructeur_dossier_path(dossier.procedure, dossier))
expect(flash.notice).to be_present
expect(dossier.reload.last_commentaire_updated_at).to eq(now)
2017-11-07 20:40:00 +01:00
end
context "when the commentaire created with virus file" do
let(:scan_result) { false }
2017-11-08 16:37:04 +01:00
it "creates a commentaire (shows message that file have a virus)" do
expect { subject }.to change(Commentaire, :count).by(1)
expect(instructeur.followed_dossiers).to include(dossier)
2017-11-08 16:37:04 +01:00
expect(response).to redirect_to(messagerie_instructeur_dossier_path(dossier.procedure, dossier))
expect(flash.notice).to be_present
2017-11-08 16:37:04 +01:00
end
end
2022-03-17 11:21:45 +01:00
context "when the dossier is deleted by user" do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
before do
dossier.update!(hidden_by_user_at: 1.hour.ago)
subject
end
it "does not create a commentaire" do
expect { subject }.to change(Commentaire, :count).by(0)
expect(flash.alert).to be_present
end
end
end
2017-08-28 14:16:13 +02:00
describe "#create_avis" do
2021-02-28 22:20:24 +01:00
let(:expert) { create(:expert) }
let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: dossier.procedure) }
let(:invite_linked_dossiers) { false }
2017-08-28 14:16:13 +02:00
let(:saved_avis) { dossier.avis.first }
let!(:old_avis_count) { Avis.count }
2017-08-28 14:16:13 +02:00
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :avis)
end
2018-02-27 16:58:22 +01:00
subject do
2017-08-28 14:16:13 +02:00
post :create_avis, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
2021-02-28 22:20:24 +01:00
avis: { emails: emails, introduction: 'intro', confidentiel: true, invite_linked_dossiers: invite_linked_dossiers, claimant: instructeur, experts_procedure: experts_procedure }
2017-08-28 14:16:13 +02:00
}
end
2021-03-30 17:55:35 +02:00
let(:emails) { "[\"email@a.com\"]" }
2018-02-27 16:58:22 +01:00
2020-09-07 14:55:15 +02:00
context "notifications updates" do
context 'when an instructeur follows the dossier' do
let(:follower) { create(:instructeur) }
before { follower.follow(dossier) }
2018-02-27 16:58:22 +01:00
2020-09-07 14:55:15 +02:00
it 'the follower has a notification' do
2020-09-18 15:40:26 +02:00
expect(follower.followed_dossiers.with_notifications).to eq([])
2020-09-07 14:55:15 +02:00
subject
2020-09-18 15:40:26 +02:00
expect(follower.followed_dossiers.with_notifications).to eq([dossier.reload])
2020-09-07 14:55:15 +02:00
end
end
2018-02-27 16:58:22 +01:00
end
context 'as an instructeur, i auto follow the dossier so I get the notifications' do
it 'works' do
subject
expect(instructeur.followed_dossiers).to match_array([dossier])
end
end
2020-09-07 14:55:15 +02:00
context 'email sending' do
before do
subject
end
2021-02-28 22:20:24 +01:00
it { expect(saved_avis.expert.email).to eq('email@a.com') }
2020-09-07 14:55:15 +02:00
it { expect(saved_avis.introduction).to eq('intro') }
it { expect(saved_avis.confidentiel).to eq(true) }
it { expect(saved_avis.dossier).to eq(dossier) }
it { expect(saved_avis.claimant).to eq(instructeur) }
it { expect(response).to redirect_to(avis_instructeur_dossier_path(dossier.procedure, dossier)) }
2020-09-07 14:55:15 +02:00
context "with an invalid email" do
2021-03-30 17:55:35 +02:00
let(:emails) { "[\"emaila.com\"]" }
2020-09-07 14:55:15 +02:00
before { subject }
2020-09-07 14:55:15 +02:00
it { expect(response).to render_template :avis }
it { expect(flash.alert).to eq(["emaila.com : Le champ « Email » n'est pas valide"]) }
2020-09-07 14:55:15 +02:00
it { expect { subject }.not_to change(Avis, :count) }
it { expect(dossier.last_avis_updated_at).to eq(nil) }
end
2023-03-10 12:31:49 +01:00
context "with no email" do
let(:emails) { "" }
before { subject }
it { expect(response).to render_template :avis }
it { expect(flash.alert).to eq("Le champ « Emails » doit être rempli") }
2023-03-10 12:31:49 +01:00
it { expect { subject }.not_to change(Avis, :count) }
it { expect(dossier.last_avis_updated_at).to eq(nil) }
end
2020-09-07 14:55:15 +02:00
context 'with multiple emails' do
2021-03-30 17:55:35 +02:00
let(:emails) { "[\"toto.fr\",\"titi@titimail.com\"]" }
2020-09-07 14:55:15 +02:00
before { subject }
2020-09-07 14:55:15 +02:00
it { expect(response).to render_template :avis }
it { expect(flash.alert).to eq(["toto.fr : Le champ « Email » n'est pas valide"]) }
2021-05-26 15:16:30 +02:00
it { expect(flash.notice).to eq("Une demande davis a été envoyée à titi@titimail.com") }
2020-09-07 14:55:15 +02:00
it { expect(Avis.count).to eq(old_avis_count + 1) }
2021-02-28 22:20:24 +01:00
it { expect(saved_avis.expert.email).to eq("titi@titimail.com") }
2020-09-07 14:55:15 +02:00
end
2020-09-07 14:55:15 +02:00
context 'with linked dossiers' do
let(:asked_confidentiel) { false }
let(:previous_avis_confidentiel) { false }
let(:dossier) { create(:dossier, :en_construction, :with_dossier_link, procedure: procedure) }
before { subject }
context 'when the expert doesnt share linked dossiers' do
let(:invite_linked_dossiers) { false }
it 'sends a single avis for the main dossier, but doesnt give access to the linked dossiers' do
2021-05-26 15:16:30 +02:00
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
expect(Avis.count).to eq(old_avis_count + 1)
2021-02-28 22:20:24 +01:00
expect(saved_avis.expert.email).to eq("email@a.com")
expect(saved_avis.dossier).to eq(dossier)
end
end
2020-09-07 14:55:15 +02:00
context 'when the expert also shares the linked dossiers' do
let(:invite_linked_dossiers) { true }
context 'and the expert can access the linked dossiers' do
let(:saved_avis) { Avis.last(2).first }
let(:linked_avis) { Avis.last }
let(:linked_dossier) { Dossier.find_by(id: dossier.reload.champs_public.filter(&:dossier_link?).filter_map(&:value)) }
2020-09-07 14:55:15 +02:00
let(:invite_linked_dossiers) do
instructeur.assign_to_procedure(linked_dossier.procedure)
true
end
it 'sends one avis for the main dossier' do
2021-05-26 15:16:30 +02:00
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
2021-02-28 22:20:24 +01:00
expect(saved_avis.expert.email).to eq("email@a.com")
2020-09-07 14:55:15 +02:00
expect(saved_avis.dossier).to eq(dossier)
end
it 'sends another avis for the linked dossiers' do
expect(Avis.count).to eq(old_avis_count + 2)
expect(linked_avis.dossier).to eq(linked_dossier)
end
end
context 'but the expert cant access the linked dossier' do
it 'sends a single avis for the main dossier, but doesnt give access to the linked dossiers' do
2021-05-26 15:16:30 +02:00
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
2020-09-07 14:55:15 +02:00
expect(Avis.count).to eq(old_avis_count + 1)
2021-02-28 22:20:24 +01:00
expect(saved_avis.expert.email).to eq("email@a.com")
2020-09-07 14:55:15 +02:00
expect(saved_avis.dossier).to eq(dossier)
end
end
end
end
end
2017-08-28 14:16:13 +02:00
end
2017-08-02 15:33:23 +02:00
describe "#show" do
context "when the dossier is exported as PDF" do
let(:instructeur) { create(:instructeur) }
2021-02-28 22:20:24 +01:00
let(:expert) { create(:expert) }
2021-01-28 13:53:18 +01:00
let(:procedure) { create(:procedure, :published, instructeurs: instructeurs) }
let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: procedure) }
let(:dossier) do
create(:dossier,
:accepte,
:with_populated_champs,
:with_populated_annotations,
:with_motivation,
:with_entreprise,
:with_commentaires, procedure: procedure)
end
2021-02-28 22:20:24 +01:00
let!(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure) }
subject do
avis
get :show, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
format: :pdf
}
end
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :demande)
subject
end
it { expect(assigns(:include_infos_administration)).to eq(true) }
it { expect(assigns(:is_dossier_in_batch_operation)).to eq(false) }
it { expect(response).to render_template 'dossiers/show' }
context 'empty champs commune' do
let(:procedure) { create(:procedure, :published, :with_commune, instructeurs:) }
let(:dossier) { create(:dossier, :accepte, procedure:) }
it { expect(response).to render_template 'dossiers/show' }
end
end
context 'with dossier in batch_operation' do
let!(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it 'assigns variable with true value' do
get :show, params: { procedure_id: procedure.id, dossier_id: dossier.id }
expect(assigns(:is_dossier_in_batch_operation)).to eq(true)
end
end
end
2017-08-02 15:33:23 +02:00
describe "#update_annotations" do
let(:procedure) do
create(:procedure, :published, types_de_champ_private: [
{ type: :multiple_drop_down_list },
{ type: :linked_drop_down_list },
{ type: :datetime },
{ type: :repetition, children: [{}] },
{ type: :drop_down_list, options: [:a, :b, :other] }
], instructeurs: instructeurs)
end
let(:dossier) { create(:dossier, :en_construction, :with_populated_annotations, procedure: procedure) }
let(:another_instructeur) { create(:instructeur) }
let(:now) { Time.zone.parse('01/01/2100') }
let(:champ_multiple_drop_down_list) { dossier.champs_private.first }
let(:champ_linked_drop_down_list) { dossier.champs_private.second }
let(:champ_datetime) { dossier.champs_private.third }
let(:champ_repetition) { dossier.champs_private.fourth }
let(:champ_drop_down_list) { dossier.champs_private.fifth }
2019-03-25 11:08:41 +01:00
2017-08-02 15:33:23 +02:00
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :annotations_privees)
another_instructeur.follow(dossier)
Timecop.freeze(now)
2023-03-01 18:30:10 +01:00
patch :update_annotations, params: params, format: :turbo_stream
champ_multiple_drop_down_list.reload
champ_linked_drop_down_list.reload
champ_datetime.reload
champ_repetition.reload
champ_drop_down_list.reload
end
after do
Timecop.return
end
context "with new values for champs_private" do
let(:params) do
{
procedure_id: procedure.id,
dossier_id: dossier.id,
dossier: {
champs_private_attributes: {
'0': {
id: champ_multiple_drop_down_list.id,
2023-01-24 15:10:25 +01:00
value: ['', 'val1', 'val2']
},
'1': {
id: champ_datetime.id,
value: '2019-12-21T13:17'
},
'2': {
id: champ_linked_drop_down_list.id,
primary_value: 'primary',
secondary_value: 'secondary'
},
'3': {
id: champ_repetition.champs.first.id,
value: 'text'
},
'4': {
id: champ_drop_down_list.id,
value: '__other__',
value_other: 'other value'
2019-03-25 11:08:41 +01:00
}
2017-08-02 15:33:23 +02:00
}
}
}
end
it {
expect(champ_multiple_drop_down_list.value).to eq('["val1","val2"]')
expect(champ_linked_drop_down_list.primary_value).to eq('primary')
expect(champ_linked_drop_down_list.secondary_value).to eq('secondary')
expect(champ_datetime.value).to eq('2019-12-21T13:17:00+01:00')
expect(champ_repetition.champs.first.value).to eq('text')
expect(champ_drop_down_list.value).to eq('other value')
expect(dossier.reload.last_champ_private_updated_at).to eq(now)
2023-03-01 18:30:10 +01:00
expect(response).to have_http_status(200)
}
it 'updates the annotations' do
Timecop.travel(now + 1.hour)
2020-09-18 15:40:26 +02:00
expect(instructeur.followed_dossiers.with_notifications).to eq([])
expect(another_instructeur.followed_dossiers.with_notifications).to eq([dossier.reload])
end
end
context "without new values for champs_private" do
let(:params) do
{
procedure_id: procedure.id,
dossier_id: dossier.id,
dossier: {
champs_private_attributes: {},
champs_public_attributes: {
'0': {
id: champ_multiple_drop_down_list.id,
2023-01-24 15:10:25 +01:00
value: ['', 'val1', 'val2']
}
}
}
}
end
it {
expect(dossier.reload.last_champ_private_updated_at).to eq(nil)
2023-03-01 18:30:10 +01:00
expect(response).to have_http_status(200)
}
2017-08-02 15:33:23 +02:00
end
end
describe "#telecharger_pjs" do
subject do
get :telecharger_pjs, params: {
procedure_id: procedure.id,
dossier_id: dossier.id
}
end
before do
allow(PiecesJustificativesService).to receive(:generate_dossier_export).with([dossier], include_infos_administration: true, include_avis_for_expert: false).and_call_original
end
it 'includes an attachment' do
expect(subject.headers['Content-Disposition']).to start_with('attachment; ')
end
it 'the attachment.zip is extractable' do
content = ZipTricks::FileReader.read_zip_structure(io: StringIO.new(subject.body))
file_names = content.map(&:filename)
expect(file_names.size).to eq(1)
expect(file_names.first).to start_with("dossier-#{dossier.id}/export-")
end
end
describe "#destroy" do
let(:batch_operation) {}
subject do
batch_operation
delete :destroy, params: {
procedure_id: procedure.id,
dossier_id: dossier.id
}
end
before do
dossier.passer_en_instruction(instructeur: instructeur)
end
context 'just before delete the dossier, the operation must be equal to 2' do
before do
dossier.accepter!(instructeur: instructeur, motivation: 'le dossier est correct')
end
it 'has 2 operations logs before deletion' do
expect(DossierOperationLog.where(dossier_id: dossier.id).count).to eq(2)
end
end
2021-12-08 12:27:12 +01:00
context 'when the instructeur want to delete a dossier with a decision and already hidden by user' do
before do
dossier.accepter!(instructeur: instructeur, motivation: "le dossier est correct")
2021-12-08 12:27:12 +01:00
dossier.update!(hidden_by_user_at: Time.zone.now.beginning_of_day.utc)
subject
end
it 'deletes previous logs and add a suppression log' do
2020-11-26 15:13:32 +01:00
expect(DossierOperationLog.where(dossier_id: dossier.id).count).to eq(3)
expect(DossierOperationLog.where(dossier_id: dossier.id).last.operation).to eq('supprimer')
end
2022-02-08 11:19:50 +01:00
it 'does not add a record into deleted_dossiers table' do
expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(0)
end
it 'is not visible by administration' do
expect(dossier.reload.visible_by_administration?).to be_falsy
end
end
2021-12-08 12:27:12 +01:00
context 'when the instructeur want to delete a dossier with a decision and not hidden by user' do
before do
dossier.accepter!(instructeur: instructeur, motivation: "le dossier est correct")
subject
end
it 'does not deletes previous logs and adds a suppression log' do
expect(DossierOperationLog.where(dossier_id: dossier.id).count).to eq(3)
expect(DossierOperationLog.where(dossier_id: dossier.id).last.operation).to eq('supprimer')
2021-12-08 12:27:12 +01:00
end
it 'add a record into deleted_dossiers table' do
expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(0)
end
it 'does not discard the dossier' do
expect(dossier.reload.hidden_at).to eq(nil)
end
2022-02-08 11:19:50 +01:00
it 'fill hidden by reason' do
expect(dossier.reload.hidden_by_reason).not_to eq(nil)
expect(dossier.reload.hidden_by_reason).to eq("instructeur_request")
end
2021-12-08 12:27:12 +01:00
end
context 'when the instructeur want to delete a dossier without a decision' do
before do
subject
end
it 'does not delete the dossier' do
expect { dossier.reload }.not_to raise_error # A deleted dossier would raise an ActiveRecord::RecordNotFound
end
it 'does not add a record into deleted_dossiers table' do
expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(0)
end
end
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect { subject }.not_to change { dossier.reload.hidden_at } }
it { is_expected.to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it 'flashes message' do
subject
expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.")
end
end
end
describe '#extend_conservation' do
subject { post :extend_conservation, params: { procedure_id: procedure.id, dossier_id: dossier.id } }
context 'when user logged in' do
it 'works' do
expect(subject).to redirect_to(instructeur_dossier_path(procedure, dossier))
end
it 'extends conservation_extension by 1 month' do
subject
expect(dossier.reload.conservation_extension).to eq(1.month)
end
it 'flashed notice success' do
subject
expect(flash[:notice]).to eq(I18n.t('views.instructeurs.dossiers.archived_dossier'))
end
end
context 'with dossier in batch_operation' do
let!(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect { subject }.not_to change { dossier.reload.conservation_extension } }
it { is_expected.to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it 'flashes message' do
subject
expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.")
end
end
end
2022-01-28 15:08:08 +01:00
describe '#restore' do
let(:instructeur) { create(:instructeur) }
let!(:gi_p1_1) { GroupeInstructeur.create(label: '1', procedure: procedure) }
let!(:procedure) { create(:procedure, :published, :for_individual, instructeurs: [instructeur]) }
let!(:dossier) { create(:dossier, :accepte, :with_individual, procedure: procedure, groupe_instructeur: procedure.groupe_instructeurs.first, hidden_by_administration_at: 1.hour.ago) }
let(:batch_operation) {}
2022-01-28 15:08:08 +01:00
before do
sign_in(instructeur.user)
batch_operation
2022-01-28 15:08:08 +01:00
instructeur.groupe_instructeurs << gi_p1_1
patch :restore,
params: {
procedure_id: procedure.id,
dossier_id: dossier.id
}
end
it "puts hidden_by_administration_at to nil" do
expect(dossier.reload.hidden_by_administration_at).to eq(nil)
end
context 'with dossier in batch_operation' do
let(:batch_operation) { create(:batch_operation, operation: :archiver, dossiers: [dossier], instructeur: instructeur) }
it { expect(dossier.hidden_by_administration_at).not_to eq(nil) }
it { expect(response).to redirect_to(instructeur_dossier_path(dossier.procedure, dossier)) }
it { expect(flash.alert).to eq("Votre action n'a pas été effectuée, ce dossier fait parti d'un traitement de masse.") }
end
2022-01-28 15:08:08 +01:00
end
describe '#reaffectation' do
let!(:gi_2) { GroupeInstructeur.create(label: 'deuxième groupe', procedure: procedure) }
let!(:gi_3) { GroupeInstructeur.create(label: 'troisième groupe', procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure, groupe_instructeur: procedure.groupe_instructeurs.first) }
before do
post :reaffectation,
params: {
procedure_id: procedure.id,
dossier_id: dossier.id
}
end
it do
expect(response).to have_http_status(:ok)
expect(response.body).to include("Vous pouvez réaffecter le dossier nº #{dossier.id} à l'un des groupes d'instructeurs suivants.")
expect(response.body).to include('2 groupes existent')
end
end
describe '#reaffecter' do
let!(:gi_2) { GroupeInstructeur.create(label: 'deuxième groupe', procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure, groupe_instructeur: procedure.groupe_instructeurs.first) }
before do
post :reaffecter,
params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
groupe_instructeur_id: gi_2.id
}
end
it do
expect(dossier.reload.groupe_instructeur.id).to eq(gi_2.id)
expect(dossier.forced_groupe_instructeur).to be_truthy
expect(response).to redirect_to(instructeur_procedure_path(procedure))
expect(flash.notice).to eq("Le dossier nº #{dossier.id} a été réaffecté au groupe dinstructeurs « deuxième groupe ».")
end
end
end