demarches-normaliennes/spec/controllers/instructeurs/dossiers_controller_spec.rb
Damien Le Thiec 4b0e6ea382
Convert datetime field to datetime_local (#8572)
* Convert datetime field to datetime_local

* Fix tests

* Add value formatting view datetime component

* Add helper datetime component value
2023-02-09 15:18:38 +01:00

1032 lines
38 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

describe Instructeurs::DossiersController, type: :controller do
render_views
let(:instructeur) { create(:instructeur) }
let(:administrateur) { create(:administrateur) }
let(:administration) { create(:administration) }
let(:instructeurs) { [instructeur] }
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') }
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) }
it 'redirects to a service tmp_url' do
get :attestation, params: { procedure_id: procedure.id, dossier_id: dossier.id }
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
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) }
it { expect(response.body).to include('.header-actions') }
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
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) }
it { expect(response.body).to include('.header-actions') }
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
describe '#repasser_en_instruction' do
let(:dossier) { create(:dossier, :refuse, procedure: procedure) }
let(:batch_operation) {}
let(:current_user) { instructeur.user }
before do
sign_in current_user
batch_operation
post :repasser_en_instruction,
params: { procedure_id: procedure.id, dossier_id: dossier.id },
format: :turbo_stream
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) }
it { expect(response.body).to include('.header-actions') }
end
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 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
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) }
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
end
describe '#terminer' do
context "with refuser" do
before do
dossier.passer_en_instruction!(instructeur: instructeur)
sign_in(instructeur.user)
end
context 'simple refusal' do
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
it 'change state to refuse' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
expect(dossier.justificatif_motivation).to_not be_attached
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_refuse_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
subject
end
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
it { expect(subject.body).to include('.header-actions') }
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
end
context "with classer_sans_suite" do
before do
dossier.passer_en_instruction!(instructeur: instructeur)
sign_in(instructeur.user)
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 }
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_not be_attached
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_sans_suite_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
subject
end
it { expect(subject.body).to include('.header-actions') }
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
it { expect(subject.body).to include('.header-actions') }
end
end
context "with accepter" do
before do
dossier.passer_en_instruction!(instructeur: instructeur)
sign_in(instructeur.user)
expect(NotificationMailer).to receive(:send_accepte_notification)
.with(dossier)
.and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
end
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id }, 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_not be_attached
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))
allow(attestation).to receive(:pdf_url).and_return('http://some_document_url')
allow_any_instance_of(Dossier).to receive(:build_attestation).and_return(attestation)
end
it 'The instructeur is sent back to the dossier page' do
expect(subject.body).to include('.header-actions')
end
context 'and the dossier has already an attestation' do
it 'should not crash' do
dossier.attestation = Attestation.new
dossier.save
expect(subject.body).to include('.header-actions')
end
end
end
context 'when the attestation template uses the motivation field' do
let(:emailable) { false }
let(:template) { create(:attestation_template) }
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
it { expect(subject.body).to include('.header-actions') }
end
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
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') }
let(:scan_result) { true }
let(:now) { Timecop.freeze("09/11/1989") }
subject {
post :create_commentaire, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
commentaire: {
body: body,
file: file
}
}
}
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :messagerie)
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)
end
context "when the commentaire created with virus file" do
let(:scan_result) { false }
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)
expect(response).to redirect_to(messagerie_instructeur_dossier_path(dossier.procedure, dossier))
expect(flash.notice).to be_present
end
end
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
describe "#create_avis" do
let(:expert) { create(:expert) }
let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: dossier.procedure) }
let(:invite_linked_dossiers) { false }
let(:saved_avis) { dossier.avis.first }
let!(:old_avis_count) { Avis.count }
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :avis)
end
subject do
post :create_avis, params: {
procedure_id: procedure.id,
dossier_id: dossier.id,
avis: { emails: emails, introduction: 'intro', confidentiel: true, invite_linked_dossiers: invite_linked_dossiers, claimant: instructeur, experts_procedure: experts_procedure }
}
end
let(:emails) { "[\"email@a.com\"]" }
context "notifications updates" do
context 'when an instructeur follows the dossier' do
let(:follower) { create(:instructeur) }
before { follower.follow(dossier) }
it 'the follower has a notification' do
expect(follower.followed_dossiers.with_notifications).to eq([])
subject
expect(follower.followed_dossiers.with_notifications).to eq([dossier.reload])
end
end
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
context 'email sending' do
before do
subject
end
it { expect(saved_avis.expert.email).to eq('email@a.com') }
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)) }
context "with an invalid email" do
let(:emails) { "[\"emaila.com\"]" }
before { subject }
it { expect(response).to render_template :avis }
it { expect(flash.alert).to eq(["emaila.com : Le champ « Email » n'est pas valide"]) }
it { expect { subject }.not_to change(Avis, :count) }
it { expect(dossier.last_avis_updated_at).to eq(nil) }
end
context 'with multiple emails' do
let(:emails) { "[\"toto.fr\",\"titi@titimail.com\"]" }
before { subject }
it { expect(response).to render_template :avis }
it { expect(flash.alert).to eq(["toto.fr : Le champ « Email » n'est pas valide"]) }
it { expect(flash.notice).to eq("Une demande davis a été envoyée à titi@titimail.com") }
it { expect(Avis.count).to eq(old_avis_count + 1) }
it { expect(saved_avis.expert.email).to eq("titi@titimail.com") }
end
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
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
expect(Avis.count).to eq(old_avis_count + 1)
expect(saved_avis.expert.email).to eq("email@a.com")
expect(saved_avis.dossier).to eq(dossier)
end
end
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)) }
let(:invite_linked_dossiers) do
instructeur.assign_to_procedure(linked_dossier.procedure)
true
end
it 'sends one avis for the main dossier' do
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
expect(saved_avis.expert.email).to eq("email@a.com")
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
expect(flash.notice).to eq("Une demande davis a été envoyée à email@a.com")
expect(Avis.count).to eq(old_avis_count + 1)
expect(saved_avis.expert.email).to eq("email@a.com")
expect(saved_avis.dossier).to eq(dossier)
end
end
end
end
end
end
describe "#show" do
context "when the dossier is exported as PDF" do
let(:instructeur) { create(:instructeur) }
let(:expert) { create(:expert) }
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
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' }
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
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: [{}] }
], 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) do
dossier.champs_private.first
end
let(:champ_linked_drop_down_list) do
dossier.champs_private.second
end
let(:champ_datetime) do
dossier.champs_private.third
end
let(:champ_repetition) do
dossier.champs_private.fourth
end
before do
expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :annotations_privees)
another_instructeur.follow(dossier)
Timecop.freeze(now)
patch :update_annotations, params: params
champ_multiple_drop_down_list.reload
champ_linked_drop_down_list.reload
champ_datetime.reload
champ_repetition.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,
value: ['', 'un', 'deux']
},
'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'
}
}
}
}
end
it {
expect(champ_multiple_drop_down_list.value).to eq('["un", "deux"]')
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(dossier.reload.last_champ_private_updated_at).to eq(now)
expect(response).to redirect_to(annotations_privees_instructeur_dossier_path(dossier.procedure, dossier))
}
it 'updates the annotations' do
Timecop.travel(now + 1.hour)
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,
value: ['', 'un', 'deux']
}
}
}
}
end
it {
expect(dossier.reload.last_champ_private_updated_at).to eq(nil)
expect(response).to redirect_to(annotations_privees_instructeur_dossier_path(dossier.procedure, dossier))
}
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).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
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")
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
expect(DossierOperationLog.where(dossier_id: dossier.id).count).to eq(3)
expect(DossierOperationLog.where(dossier_id: dossier.id).last.operation).to eq('supprimer')
end
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
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')
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
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
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
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) {}
before do
sign_in(instructeur.user)
batch_operation
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
end
end