From 6607de48278a6653d23aa77abe960d35418fb562 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Wed, 13 Mar 2019 17:59:33 +0100 Subject: [PATCH] Notification: add service to send notifications --- app/mailers/gestionnaire_mailer.rb | 7 +++ app/models/gestionnaire.rb | 19 ++++++ app/services/notification_service.rb | 19 ++++++ .../send_notifications.html.haml | 20 ++++++ .../previews/gestionnaire_mailer_preview.rb | 24 ++++++- spec/models/gestionnaire_spec.rb | 47 ++++++++++++++ spec/services/notification_service_spec.rb | 63 +++++++++++++++++++ .../send_notifications.html.haml_spec.rb | 45 +++++++++++++ 8 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 app/services/notification_service.rb create mode 100644 app/views/gestionnaire_mailer/send_notifications.html.haml create mode 100644 spec/services/notification_service_spec.rb create mode 100644 spec/views/gestionnaire_mailer/send_notifications.html.haml_spec.rb diff --git a/app/mailers/gestionnaire_mailer.rb b/app/mailers/gestionnaire_mailer.rb index 09f7af238..472f09dae 100644 --- a/app/mailers/gestionnaire_mailer.rb +++ b/app/mailers/gestionnaire_mailer.rb @@ -43,4 +43,11 @@ class GestionnaireMailer < ApplicationMailer mail(to: gestionnaire.email, subject: subject) end + + def send_notifications(gestionnaire, data) + @data = data + subject = "Vous avez du nouveau sur vos démarches" + + mail(to: gestionnaire.email, subject: subject) + end end diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 8d00dda66..9bfa8e211 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -209,6 +209,25 @@ class Gestionnaire < ApplicationRecord trusted_device_token&.token_young? end + def email_notification_data + procedures_with_email_notifications + .reduce([]) do |acc, procedure| + + h = { + nb_en_construction: procedure.dossiers.en_construction.count, + nb_notification: notifications_per_procedure(procedure).count + } + + if h[:nb_en_construction] > 0 || h[:nb_notification] > 0 + h[:procedure_id] = procedure.id + h[:procedure_libelle] = procedure.libelle + acc << h + end + + acc + end + end + private def annotations_hash(demande, annotations_privees, avis, messagerie) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb new file mode 100644 index 000000000..da8a1bb44 --- /dev/null +++ b/app/services/notification_service.rb @@ -0,0 +1,19 @@ +class NotificationService + class << self + def send_gestionnaire_email_notification + Gestionnaire + .includes(assign_to: { procedure: :dossiers }) + .where(assign_tos: { email_notifications_enabled: true }) + .find_in_batches { |gestionnaires| send_batch_of_gestionnaires_email_notification(gestionnaires) } + end + + private + + def send_batch_of_gestionnaires_email_notification(gestionnaires) + gestionnaires + .map { |gestionnaire| [gestionnaire, gestionnaire.email_notification_data] } + .reject { |(_gestionnaire, data)| data.empty? } + .each { |(gestionnaire, data)| GestionnaireMailer.send_notifications(gestionnaire, data).deliver_later } + end + end +end diff --git a/app/views/gestionnaire_mailer/send_notifications.html.haml b/app/views/gestionnaire_mailer/send_notifications.html.haml new file mode 100644 index 000000000..50f76c55f --- /dev/null +++ b/app/views/gestionnaire_mailer/send_notifications.html.haml @@ -0,0 +1,20 @@ +- content_for(:title, 'Du nouveau sur vos démarches') + +%p + Bonjour, + +%p + Vous avez du nouveau sur demarches-simplifiees.fr. + +%ul + - @data.each do |datum| + %li + = link_to(datum[:procedure_libelle], procedure_url(datum[:procedure_id])) + - if datum[:nb_en_construction] > 0 + %br + #{datum[:nb_en_construction]} #{'dossier'.pluralize(datum[:nb_en_construction])} en construction + - if datum[:nb_notification] > 0 + %br + #{datum[:nb_notification]} #{'notification'.pluralize(datum[:nb_notification])} + += render partial: "layouts/mailers/signature" diff --git a/spec/mailers/previews/gestionnaire_mailer_preview.rb b/spec/mailers/previews/gestionnaire_mailer_preview.rb index ddafd66b4..eda8b78aa 100644 --- a/spec/mailers/previews/gestionnaire_mailer_preview.rb +++ b/spec/mailers/previews/gestionnaire_mailer_preview.rb @@ -19,6 +19,24 @@ class GestionnaireMailerPreview < ActionMailer::Preview GestionnaireMailer.user_to_gestionnaire(gestionnaire.email) end + def send_notifications + data = [ + { + procedure_libelle: 'une superbe démarche', + procedure_id: 213, + nb_en_construction: 2, + nb_notification: 2 + }, + { + procedure_libelle: 'une démarche incroyable', + procedure_id: 213, + nb_en_construction: 1, + nb_notification: 1 + } + ] + GestionnaireMailer.send_notifications(gestionnaire, data) + end + private def gestionnaire @@ -30,6 +48,10 @@ class GestionnaireMailerPreview < ActionMailer::Preview end def procedure - Procedure.new(id: 15) + Procedure.new(id: 15, libelle: 'libelle') + end + + def dossier + Dossier.new(id: 15, procedure: procedure) end end diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 6b7a6febb..ee3cfbafa 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -413,6 +413,53 @@ describe Gestionnaire, type: :model do end end + describe '#email_notification_data' do + let(:gestionnaire) { create(:gestionnaire) } + let(:procedure_to_assign) { create(:procedure) } + + before do + create(:assign_to, gestionnaire: gestionnaire, procedure: procedure_to_assign, email_notifications_enabled: true) + end + + context 'when a dossier in construction exists' do + let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) } + + it do + expect(gestionnaire.email_notification_data).to eq([ + { + nb_en_construction: 1, + nb_notification: 0, + procedure_id: procedure_to_assign.id, + procedure_libelle: procedure_to_assign.libelle + } + ]) + end + end + + context 'when a notification exists' do + before do + allow(gestionnaire).to receive(:notifications_per_procedure) + .with(procedure_to_assign) + .and_return([1, 2, 3]) + end + + it do + expect(gestionnaire.email_notification_data).to eq([ + { + nb_en_construction: 0, + nb_notification: 3, + procedure_id: procedure_to_assign.id, + procedure_libelle: procedure_to_assign.libelle + } + ]) + end + end + + context 'otherwise' do + it { expect(gestionnaire.email_notification_data).to eq([]) } + end + end + private def assign(procedure_to_assign) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb new file mode 100644 index 000000000..7c9a9e116 --- /dev/null +++ b/spec/services/notification_service_spec.rb @@ -0,0 +1,63 @@ +describe NotificationService do + describe '.send_gestionnaire_email_notification' do + let(:procedure) { create(:procedure) } + + before do + allow(GestionnaireMailer).to receive(:send_notifications) + .and_return(double(deliver_later: true)) + end + + subject { NotificationService.send_gestionnaire_email_notification } + + context 'when a gestionnaire does not enable its email notification' do + let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + let(:gestionnaire) { create(:gestionnaire) } + + before { create(:assign_to, gestionnaire: gestionnaire, procedure: procedure) } + + it do + subject + expect(GestionnaireMailer).not_to have_received(:send_notifications) + end + end + + context 'when a gestionnaire enables its email_notification on one procedure' do + let(:gestionnaire_with_email_notifications) { create(:gestionnaire) } + + before do + create(:assign_to, + gestionnaire: gestionnaire_with_email_notifications, + procedure: procedure, + email_notifications_enabled: true) + end + + context "when there is no activity on the gestionnaire's procedures" do + it do + subject + expect(GestionnaireMailer).not_to have_received(:send_notifications) + end + end + + context 'when a dossier en construction exists on this procedure' do + let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + + it do + subject + expect(GestionnaireMailer).to have_received(:send_notifications) + end + end + + context 'when there is a notification on this procedure' do + before do + allow_any_instance_of(Gestionnaire).to receive(:notifications_per_procedure) + .and_return([12]) + end + + it do + subject + expect(GestionnaireMailer).to have_received(:send_notifications) + end + end + end + end +end diff --git a/spec/views/gestionnaire_mailer/send_notifications.html.haml_spec.rb b/spec/views/gestionnaire_mailer/send_notifications.html.haml_spec.rb new file mode 100644 index 000000000..df3fbbecc --- /dev/null +++ b/spec/views/gestionnaire_mailer/send_notifications.html.haml_spec.rb @@ -0,0 +1,45 @@ +require 'rails_helper' + +describe 'gestionnaire_mailer/send_notifications.html.haml', type: :view do + let(:gestionnaire) { create(:gestionnaire) } + + before do + assign(:data, data) + + render + end + + context 'when there is one dossier in contruction' do + let(:data) do + [ + { + procedure_libelle: 'une superbe démarche', + procedure_id: 213, + nb_en_construction: 1, + nb_notification: 0 + } + ] + end + + it { expect(rendered).to have_link('une superbe démarche', href: procedure_url(213)) } + it { expect(rendered).to have_text('une superbe démarche') } + it { expect(rendered).to have_text('1 dossier en construction') } + it { expect(rendered).not_to have_text('notification') } + end + + context 'when there is one notification' do + let(:data) do + [ + { + procedure_libelle: 'une superbe démarche', + procedure_id: 213, + nb_en_construction: 0, + nb_notification: 1 + } + ] + end + + it { expect(rendered).not_to have_text('en construction') } + it { expect(rendered).to have_text('1 notification') } + end +end