From e60ce35ae8f3747b3fb8770ee27ba90add9b99e0 Mon Sep 17 00:00:00 2001 From: Simon Lehericey Date: Fri, 9 Jun 2017 22:29:48 +0200 Subject: [PATCH] [Fix #196] Attestation: join the attestation to the closed mail Add a upper limit to the attachment size as it could be a problem with Mailjet and receiver (https://www.mailjet.com/support/what-is-the-size-limit-for-attachments-files-sent-via-mailjet,289.htm) If the attestation cannot be sent, it is logged in sentry --- Gemfile | 7 +-- .../backoffice/dossiers_controller.rb | 19 ++++++- app/mailers/notification_mailer.rb | 6 ++- app/models/attestation.rb | 6 +++ .../backoffice/dossiers_controller_spec.rb | 53 +++++++++++++++---- spec/mailers/notification_mailer_spec.rb | 18 ++++++- spec/models/attestation_spec.rb | 23 ++++++++ 7 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 spec/models/attestation_spec.rb diff --git a/Gemfile b/Gemfile index c6e525175..c7b560dd2 100644 --- a/Gemfile +++ b/Gemfile @@ -106,6 +106,8 @@ gem 'select2-rails' gem 'prawn', '~> 2.0.1' gem 'prawn_rails', '~> 0.0.11' +gem 'sentry-raven' + group :test do gem 'capybara' gem 'launchy' @@ -148,8 +150,3 @@ group :development, :test do # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'dotenv-rails' end - -group :production, :staging do - gem 'sentry-raven' -end - diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index a5477430f..9ab9c4d08 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -1,4 +1,6 @@ class Backoffice::DossiersController < Backoffice::DossiersListController + include ActionView::Helpers::NumberHelper + respond_to :html, :xlsx, :ods, :csv prepend_before_action :store_current_location, only: :show @@ -112,6 +114,8 @@ class Backoffice::DossiersController < Backoffice::DossiersListController dossier = @facade.dossier + attestation_pdf = nil + case params[:process_action] when "refuse" next_step = "refuse" @@ -125,12 +129,15 @@ class Backoffice::DossiersController < Backoffice::DossiersListController next_step = "close" notice = "Dossier traité avec succès." template = dossier.procedure.closed_mail_template + if check_attestation_emailable(dossier) + attestation_pdf = dossier.attestation.pdf.read + end end dossier.next_step! 'gestionnaire', next_step, motivation flash.notice = notice - NotificationMailer.send_notification(dossier, template).deliver_now! + NotificationMailer.send_notification(dossier, template, attestation_pdf).deliver_now! redirect_to backoffice_dossier_path(id: dossier.id) end @@ -185,6 +192,16 @@ class Backoffice::DossiersController < Backoffice::DossiersListController private + def check_attestation_emailable(dossier) + if dossier&.attestation&.emailable? == false + human_size = number_to_human_size(dossier.attestation.pdf.size) + msg = "the attestation of the dossier #{dossier.id} cannot be mailed because it is too heavy: #{human_size}" + capture_message(msg, level: 'error') + end + + dossier&.attestation&.emailable? + end + def store_current_location if !gestionnaire_signed_in? store_location_for(:gestionnaire, request.url) diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 6c7d4b91c..6c75975df 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -3,12 +3,16 @@ class NotificationMailer < ApplicationMailer after_action :create_commentaire_for_notification, only: :send_notification - def send_notification(dossier, mail_template) + def send_notification(dossier, mail_template, attestation = nil) vars_mailer(dossier) @object = mail_template.object_for_dossier dossier @body = mail_template.body_for_dossier dossier + if attestation.present? + attachments['attestation.pdf'] = attestation + end + mail(subject: @object) { |format| format.html { @body } } end diff --git a/app/models/attestation.rb b/app/models/attestation.rb index 605ed11a4..220e2c364 100644 --- a/app/models/attestation.rb +++ b/app/models/attestation.rb @@ -2,4 +2,10 @@ class Attestation < ApplicationRecord belongs_to :dossier mount_uploader :pdf, AttestationUploader + + MAX_SIZE_EMAILABLE = 2.megabytes + + def emailable? + pdf.size <= MAX_SIZE_EMAILABLE + end end diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 5d11f4b2d..e019314ba 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -268,7 +268,7 @@ describe Backoffice::DossiersController, type: :controller do it 'Notification email is sent' do expect(NotificationMailer).to receive(:send_notification) - .with(dossier, kind_of(Mails::RefusedMail)).and_return(NotificationMailer) + .with(dossier, kind_of(Mails::RefusedMail), nil).and_return(NotificationMailer) expect(NotificationMailer).to receive(:deliver_now!) subject @@ -294,7 +294,7 @@ describe Backoffice::DossiersController, type: :controller do it 'Notification email is sent' do expect(NotificationMailer).to receive(:send_notification) - .with(dossier, kind_of(Mails::WithoutContinuationMail)).and_return(NotificationMailer) + .with(dossier, kind_of(Mails::WithoutContinuationMail), nil).and_return(NotificationMailer) expect(NotificationMailer).to receive(:deliver_now!) subject @@ -304,9 +304,17 @@ describe Backoffice::DossiersController, type: :controller do end context "with close" do + let(:expected_attestation) { nil } + before do dossier.received! sign_in gestionnaire + + expect(NotificationMailer).to receive(:send_notification) + .with(dossier, kind_of(Mails::ClosedMail), expected_attestation) + .and_return(NotificationMailer) + + expect(NotificationMailer).to receive(:deliver_now!) end subject { post :process_dossier, params: { process_action: "close", dossier_id: dossier_id} } @@ -318,15 +326,42 @@ describe Backoffice::DossiersController, type: :controller do expect(dossier.state).to eq('closed') end - it 'Notification email is sent' do - expect(NotificationMailer).to receive(:send_notification) - .with(dossier, kind_of(Mails::ClosedMail)).and_return(NotificationMailer) - expect(NotificationMailer).to receive(:deliver_now!) - - subject + context 'when the dossier does not have any attestation' do + it 'Notification email is sent' do + subject + end end - it { is_expected.to redirect_to backoffice_dossier_path(id: dossier.id) } + context 'when the dossier has an attestation' do + let(:emailable) { false } + + before do + fake_attestation = double(pdf: double(read: 'pdf', size: 2.megabytes), emailable?: emailable) + allow_any_instance_of(Dossier).to receive(:attestation).and_return(fake_attestation) + end + + context 'emailable' do + let(:emailable) { true } + let(:expected_attestation) { 'pdf' } + + it 'Notification email is sent with the attestation' do + subject + end + end + + context 'when the dossier has an attestation not emailable' do + let(:emailable) { false } + let(:expected_attestation) { nil } + + it 'Notification email is sent without the attestation' do + expect(controller).to receive(:capture_message) + + subject + end + end + + it { is_expected.to redirect_to backoffice_dossier_path(id: dossier.id) } + end end end diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index e9a66e4a7..9fcfba7bf 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -5,11 +5,25 @@ RSpec.describe NotificationMailer, type: :mailer do let(:user) { create(:user) } let(:dossier) { create(:dossier, user: user) } let(:email) { instance_double('email', object_for_dossier: 'object', body_for_dossier: 'body') } - let (:notifications_count_before) { Notification.count } - subject { described_class.send_notification(dossier, email) } + let(:attestation) { nil } + let(:notifications_count_before) { Notification.count } + + subject { described_class.send_notification(dossier, email, attestation) } it { expect(subject.subject).to eq(email.object_for_dossier) } it { expect(subject.body).to eq(email.body_for_dossier) } + it { expect(subject.attachments['attestation.pdf']).to eq(nil) } + + context 'when an attestation is provided' do + let(:attestation) { 'attestation' } + + it do + expect(subject.attachments['attestation.pdf'].content_type) + .to eq('application/pdf; filename=attestation.pdf') + + expect(subject.attachments['attestation.pdf'].body).to eq('attestation') + end + end it "creates a commentaire, which is not notified" do described_class.send_notification(dossier, email).deliver_now diff --git a/spec/models/attestation_spec.rb b/spec/models/attestation_spec.rb new file mode 100644 index 000000000..5bf9e89f5 --- /dev/null +++ b/spec/models/attestation_spec.rb @@ -0,0 +1,23 @@ +RSpec.describe Attestation, type: :model do + describe 'emailable' do + let(:attestation) do + attestation = Attestation.new + expect(attestation).to receive(:pdf).and_return(double(size: size)) + attestation + end + + subject { attestation.emailable? } + + context 'when the pdf size is acceptable' do + let(:size) { Attestation::MAX_SIZE_EMAILABLE } + + it { is_expected.to be true } + end + + context 'when the pdf size is unacceptable' do + let(:size) { Attestation::MAX_SIZE_EMAILABLE + 1 } + + it { is_expected.to be false } + end + end +end