require 'spec_helper' describe NewGestionnaire::DossiersController, type: :controller do render_views let(:gestionnaire) { create(:gestionnaire) } let(:gestionnaires) { [gestionnaire] } let(:procedure) { create(:procedure, :published, gestionnaires: gestionnaires) } let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } before { sign_in(gestionnaire) } describe '#attestation' do context 'when a dossier has an attestation' do let(:fake_pdf) { double(read: 'pdf content') } let!(:dossier) { create(:dossier, :en_construction, attestation: Attestation.new, procedure: procedure) } let!(:procedure) { create(:procedure, :published, gestionnaires: [gestionnaire]) } let!(:dossier) { create(:dossier, :en_construction, attestation: Attestation.new, procedure: procedure) } it 'returns the attestation pdf' do allow_any_instance_of(Attestation).to receive(:pdf).and_return(fake_pdf) expect(controller).to receive(:send_data) .with('pdf content', filename: 'attestation.pdf', type: 'application/pdf') do controller.head :ok end get :attestation, params: { procedure_id: procedure.id, dossier_id: dossier.id } expect(response).to have_http_status(:success) end end end describe '#send_to_instructeurs' do let(:recipient) { create(:gestionnaire) } let(:gestionnaires) { [gestionnaire, recipient] } let(:mail) { double("mail") } before do expect(mail).to receive(:deliver_later) expect(GestionnaireMailer) .to receive(:send_dossier) .with(gestionnaire, dossier, recipient) .and_return(mail) post( :send_to_instructeurs, params: { recipients: [recipient], procedure_id: procedure.id, dossier_id: dossier.id } ) end it { expect(response).to redirect_to(personnes_impliquees_gestionnaire_dossier_url) } end describe '#follow' do before do patch :follow, params: { procedure_id: procedure.id, dossier_id: dossier.id } end it { expect(gestionnaire.followed_dossiers).to match([dossier]) } it { expect(flash.notice).to eq('Dossier suivi') } it { expect(response).to redirect_to(gestionnaire_procedures_url) } end describe '#unfollow' do before do gestionnaire.followed_dossiers << dossier patch :unfollow, params: { procedure_id: procedure.id, dossier_id: dossier.id } gestionnaire.reload end it { expect(gestionnaire.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(gestionnaire_procedures_url) } end describe '#archive' do before do gestionnaire.follow(dossier) patch :archive, params: { procedure_id: procedure.id, dossier_id: dossier.id } dossier.reload gestionnaire.reload end it { expect(dossier.archived).to be true } it { expect(response).to redirect_to(gestionnaire_procedures_url) } it { expect(gestionnaire.followed_dossiers).not_to include(dossier) } end describe '#unarchive' do before do dossier.update(archived: true) patch :unarchive, params: { procedure_id: procedure.id, dossier_id: dossier.id } dossier.reload end it { expect(dossier.archived).to be false } it { expect(response).to redirect_to(gestionnaire_procedures_url) } end describe '#passer_en_instruction' do before do dossier.en_construction! sign_in gestionnaire post :passer_en_instruction, params: { procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' dossier.reload end it { expect(dossier.state).to eq(Dossier.states.fetch(:en_instruction)) } it { expect(response.body).to include('.state-button') } it { expect(gestionnaire.follow?(dossier)).to be true } end describe '#repasser_en_construction' do before do dossier.en_instruction! sign_in gestionnaire end subject { post :repasser_en_construction, params: { procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' } it 'change state to en_construction' do subject dossier.reload expect(dossier.state).to eq(Dossier.states.fetch(:en_construction)) end it { expect(subject.body).to include('.state-button') } end describe '#terminer' do context "with refuser" do before do dossier.en_instruction! sign_in gestionnaire end subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' } it 'change state to refuse' do subject dossier.reload expect(dossier.state).to eq(Dossier.states.fetch(:refuse)) end it 'Notification email is sent' do expect(NotificationMailer).to receive(:send_refused_notification) .with(dossier).and_return(NotificationMailer) expect(NotificationMailer).to receive(:deliver_later) subject end it { expect(subject.body).to include('.state-button') } end context "with classer_sans_suite" do before do dossier.en_instruction! sign_in gestionnaire end subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' } it 'change state to sans_suite' do subject dossier.reload expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite)) end it 'Notification email is sent' do expect(NotificationMailer).to receive(:send_without_continuation_notification) .with(dossier).and_return(NotificationMailer) expect(NotificationMailer).to receive(:deliver_later) subject end it { expect(subject.body).to include('.state-button') } end context "with accepter" do before do dossier.en_instruction! sign_in gestionnaire expect(NotificationMailer).to receive(:send_closed_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: 'js' } it 'change state to accepte' do subject dossier.reload expect(dossier.state).to eq(Dossier.states.fetch(:accepte)) 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)) allow_any_instance_of(Dossier).to receive(:build_attestation).and_return(attestation) end it 'The gestionnaire is sent back to the dossier page' do expect(subject.body).to include('.state-button') 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('.state-button') 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, attestation_template: template, gestionnaires: [gestionnaire]) } subject do post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { motivation: "Yallah" } }, format: 'js' end before do Timecop.freeze(Time.zone.now) expect_any_instance_of(AttestationTemplate) .to receive(:attestation_for) .with(have_attributes(motivation: "Yallah", processed_at: Time.zone.now)) end after { Timecop.return } it { subject } end end end describe "#create_commentaire" do let(:saved_commentaire) { dossier.commentaires.first } let(:body) { "avant\napres" } let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } let(:scan_result) { true } subject { post :create_commentaire, params: { procedure_id: procedure.id, dossier_id: dossier.id, commentaire: { body: body, file: file } } } before do allow(ClamavService).to receive(:safe_file?).and_return(scan_result) end it "creates a commentaire" do expect { subject }.to change(Commentaire, :count).by(1) expect(gestionnaire.followed_dossiers).to include(dossier) expect(response).to redirect_to(messagerie_gestionnaire_dossier_path(dossier.procedure, dossier)) expect(flash.notice).to be_present end context "when the commentaire creation fails" do let(:scan_result) { false } it "renders the messagerie page with the invalid commentaire" do expect { subject }.not_to change(Commentaire, :count) expect(response).to render_template :messagerie expect(flash.alert).to be_present expect(assigns(:commentaire).body).to eq("avant\napres") end end end describe "#create_avis" do let(:saved_avis) { dossier.avis.first } let!(:old_avis_count) { Avis.count } subject do post :create_avis, params: { procedure_id: procedure.id, dossier_id: dossier.id, avis: { emails: emails, introduction: 'intro', confidentiel: true } } end before do subject end let(:emails) { ['email@a.com'] } it { expect(saved_avis.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(gestionnaire) } it { expect(response).to redirect_to(avis_gestionnaire_dossier_path(dossier.procedure, dossier)) } context "with an invalid email" do let(:emails) { ['emaila.com'] } it { expect(response).to render_template :avis } it { expect(flash.alert).to eq(["emaila.com : Email n'est pas valide"]) } it { expect { subject }.not_to change(Avis, :count) } end context 'with multiple emails' do let(:emails) { ["toto.fr,titi@titimail.com"] } it { expect(response).to render_template :avis } it { expect(flash.alert).to eq(["toto.fr : Email n'est pas valide"]) } it { expect(flash.notice).to eq("Une demande d'avis a été envoyée à titi@titimail.com") } it { expect(Avis.count).to eq(old_avis_count + 1) } it { expect(saved_avis.email).to eq("titi@titimail.com") } end end describe "#update_annotations" do let(:champ_multiple_drop_down_list) do create(:type_de_champ_multiple_drop_down_list, :private, libelle: 'libelle').champ.create end let(:champ_linked_drop_down_list) do create(:type_de_champ_linked_drop_down_list, :private, libelle: 'libelle').champ.create end let(:champ_datetime) do create(:type_de_champ_datetime, :private, libelle: 'libelle').champ.create end let(:dossier) do create(:dossier, :en_construction, procedure: procedure, champs_private: [champ_multiple_drop_down_list, champ_linked_drop_down_list, champ_datetime]) end before do patch :update_annotations, params: { 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(1i)': 2019, 'value(2i)': 12, 'value(3i)': 21, 'value(4i)': 13, 'value(5i)': 17 }, '2': { id: champ_linked_drop_down_list.id, primary_value: 'primary', secondary_value: 'secondary' } } } } champ_multiple_drop_down_list.reload champ_linked_drop_down_list.reload champ_datetime.reload end it { expect(champ_multiple_drop_down_list.value).to eq('["un", "deux"]') } it { expect(champ_linked_drop_down_list.primary_value).to eq('primary') } it { expect(champ_linked_drop_down_list.secondary_value).to eq('secondary') } it { expect(champ_datetime.value).to eq('21/12/2019 13:17') } it { expect(response).to redirect_to(annotations_privees_gestionnaire_dossier_path(dossier.procedure, dossier)) } end describe '#purge_champ_piece_justificative' do before { sign_in(gestionnaire) } subject { delete :purge_champ_piece_justificative, params: { procedure_id: champ.dossier.procedure.id, dossier_id: champ.dossier.id, champ_id: champ.id }, format: :js } context 'when gestionnaire can process dossier' do let(:champ){ create(:champ_piece_justificative, dossier_id: dossier.id, private: true) } it { is_expected.to have_http_status(200) } it do subject expect(champ.reload.piece_justificative_file.attached?).to be(false) end context 'but champ is not linked to this dossier' do let(:champ){ create(:champ_piece_justificative, dossier: create(:dossier), private: true) } it { is_expected.to redirect_to(root_path) } it do subject expect(champ.reload.piece_justificative_file.attached?).to be(true) end end end context 'when gestionnaire cannot process dossier' do let(:dossier){ create(:dossier, procedure: create(:procedure)) } let(:champ){ create(:champ_piece_justificative, dossier_id: dossier.id, private: true) } it { is_expected.to redirect_to(root_path) } it do subject expect(champ.reload.piece_justificative_file.attached?).to be(true) end end end end