From 9f7b78ff8b2319a70b216af323ea8b7578561de8 Mon Sep 17 00:00:00 2001 From: Christophe Robillard Date: Mon, 17 Feb 2020 16:11:22 +0100 Subject: [PATCH 01/15] =?UTF-8?q?supprime=20les=20colonnes=20ignor=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/administrateur.rb | 1 - app/models/instructeur.rb | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index 908b95be3..3d3e878ef 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -1,5 +1,4 @@ class Administrateur < ApplicationRecord - self.ignored_columns = ['features', 'encrypted_password', 'reset_password_token', 'reset_password_sent_at', 'remember_created_at', 'sign_in_count', 'current_sign_in_at', 'last_sign_in_at', 'current_sign_in_ip', 'last_sign_in_ip', 'failed_attempts', 'unlock_token', 'locked_at'] include ActiveRecord::SecureToken has_and_belongs_to_many :instructeurs diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index cb5bbbca1..83909d7ec 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -1,6 +1,4 @@ class Instructeur < ApplicationRecord - self.ignored_columns = ['features', 'encrypted_password', 'reset_password_token', 'reset_password_sent_at', 'remember_created_at', 'sign_in_count', 'current_sign_in_at', 'last_sign_in_at', 'current_sign_in_ip', 'last_sign_in_ip', 'failed_attempts', 'unlock_token', 'locked_at'] - has_and_belongs_to_many :administrateurs has_many :assign_to, dependent: :destroy From 6afddd864783a9dece2e52098bbdd069e92ea8a9 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 17 Feb 2020 14:53:47 +0100 Subject: [PATCH 02/15] spec: fix a flaky experts feature spec When "invite linked dossiers" is checked, the invitation will generate one avis per dossier (including the linked ones). So when we retrieve the email send to the expert, and try to match it with the avis record, we need to specify wich avis (the one for the main dossier, or for the linked dossier). Otherwise the test is flaky, and sometimes doesn't match the right avis with the sent email. --- spec/features/instructeurs/expert_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/features/instructeurs/expert_spec.rb b/spec/features/instructeurs/expert_spec.rb index 75dbc8bec..2e365f10f 100644 --- a/spec/features/instructeurs/expert_spec.rb +++ b/spec/features/instructeurs/expert_spec.rb @@ -41,8 +41,9 @@ feature 'Inviting an expert:' do expect(Avis.count).to eq(4) expect(all_emails.size).to eq(2) + invitation_email = open_email('expert2@exemple.fr') - avis = Avis.find_by(email: 'expert2@exemple.fr') + avis = Avis.find_by(email: 'expert2@exemple.fr', dossier: dossier) sign_up_link = sign_up_instructeur_avis_path(avis.id, avis.email) expect(invitation_email.body).to include(sign_up_link) end From d8223bafa82e4fd9fc5a26d2ae34f5ab0c3368f6 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Tue, 18 Feb 2020 15:27:19 +0100 Subject: [PATCH 03/15] Add thousand separator on tabs instructors general view --- app/views/instructeurs/procedures/_list.html.haml | 10 +++++----- app/views/instructeurs/procedures/show.html.haml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/instructeurs/procedures/_list.html.haml b/app/views/instructeurs/procedures/_list.html.haml index e8e6fb21f..0ed5f470c 100644 --- a/app/views/instructeurs/procedures/_list.html.haml +++ b/app/views/instructeurs/procedures/_list.html.haml @@ -15,7 +15,7 @@ = link_to(instructeur_procedure_path(p, statut: 'a-suivre')) do - a_suivre_count = dossiers_a_suivre_count_per_procedure[p.id] || 0 .stats-number - = a_suivre_count + = number_with_html_delimiter(a_suivre_count) .stats-legend à suivre %li @@ -25,7 +25,7 @@ %span.notifications{ 'aria-label': "notifications" } - followed_count = followed_dossiers_count_per_procedure[p.id] || 0 .stats-number - = followed_count + = number_with_html_delimiter(followed_count) .stats-legend = t('pluralize.followed', count: followed_count) %li @@ -35,7 +35,7 @@ %span.notifications{ 'aria-label': "notifications" } - termines_count = dossiers_termines_count_per_procedure[p.id] || 0 .stats-number - = termines_count + = number_with_html_delimiter(termines_count) .stats-legend = t('pluralize.processed', count: termines_count) %li @@ -43,7 +43,7 @@ = link_to(instructeur_procedure_path(p, statut: 'tous')) do - dossier_count = dossiers_count_per_procedure[p.id] || 0 .stats-number - = dossier_count + = number_with_html_delimiter(dossier_count) .stats-legend = t('pluralize.case', count: dossier_count) %li @@ -51,7 +51,7 @@ = link_to(instructeur_procedure_path(p, statut: 'archives')) do - archived_count = dossiers_archived_count_per_procedure[p.id] || 0 .stats-number - = archived_count + = number_with_html_delimiter(archived_count) .stats-legend = t('pluralize.archived', count: archived_count) diff --git a/app/views/instructeurs/procedures/show.html.haml b/app/views/instructeurs/procedures/show.html.haml index 828079590..a93ef3493 100644 --- a/app/views/instructeurs/procedures/show.html.haml +++ b/app/views/instructeurs/procedures/show.html.haml @@ -24,29 +24,29 @@ = tab_item('à suivre', instructeur_procedure_path(@procedure, statut: 'a-suivre'), active: @statut == 'a-suivre', - badge: @a_suivre_dossiers.count) + badge: number_with_html_delimiter(@a_suivre_dossiers.count)) = tab_item(t('pluralize.followed', count: @followed_dossiers.count), instructeur_procedure_path(@procedure, statut: 'suivis'), active: @statut == 'suivis', - badge: @followed_dossiers.count, + badge: number_with_html_delimiter(@followed_dossiers.count), notification: current_instructeur.notifications_for_procedure(@procedure, :en_cours).exists?) = tab_item(t('pluralize.processed', count: @termines_dossiers.count), instructeur_procedure_path(@procedure, statut: 'traites'), active: @statut == 'traites', - badge: @termines_dossiers.count, + badge: number_with_html_delimiter(@termines_dossiers.count), notification: current_instructeur.notifications_for_procedure(@procedure, :termine).exists?) = tab_item('tous les dossiers', instructeur_procedure_path(@procedure, statut: 'tous'), active: @statut == 'tous', - badge: @all_state_dossiers.count) + badge: number_with_html_delimiter(@all_state_dossiers.count)) = tab_item(t('pluralize.archived', count: @archived_dossiers.count), instructeur_procedure_path(@procedure, statut: 'archives'), active: @statut == 'archives', - badge: @archived_dossiers.count) + badge: number_with_html_delimiter(@archived_dossiers.count)) .procedure-actions = render partial: "download_dossiers", From 4e116f06a6504ded258af327f7cea3885db98e6e Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 18 Feb 2020 17:15:32 +0100 Subject: [PATCH 04/15] Add notify_automatic_deletion_to_user mailer --- app/mailers/dossier_mailer.rb | 7 +++++++ .../notify_automatic_deletion_to_user.html.haml | 14 ++++++++++++++ .../notify_automatic_deletion_to_user/fr.yml | 12 ++++++++++++ spec/mailers/dossier_mailer_spec.rb | 16 ++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml create mode 100644 config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 8813730fe..5a8fbb00e 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -83,4 +83,11 @@ class DossierMailer < ApplicationMailer mail(to: user.email, subject: @subject) end + + def notify_automatic_deletion_to_user(user, dossier_hashes) + @subject = default_i18n_subject(count: dossier_hashes.count) + @dossier_hashes = dossier_hashes + + mail(to: user.email, subject: @subject) + end end diff --git a/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml b/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml new file mode 100644 index 000000000..337151682 --- /dev/null +++ b/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml @@ -0,0 +1,14 @@ +- content_for(:title, "#{@subject}") + +%p + Bonjour, + +%p= t('.automatic_dossier_deletion', count: @dossier_hashes.count) + +%ul + - @dossier_hashes.each do |d| + %li= link_to("n° #{d[:id]} (#{d[:procedure_libelle]})", dossier_url(d)) + +%p= t('.dossier_will_not_be_processed', count: @dossier_hashes.count) + += render partial: "layouts/mailers/signature" diff --git a/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml new file mode 100644 index 000000000..7f5aef939 --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml @@ -0,0 +1,12 @@ +fr: + dossier_mailer: + notify_automatic_deletion_to_user: + subject: + one: "Un dossier a été supprimé automatiquement" + other: "Des dossiers ont été supprimés automatiquement" + automatic_dossier_deletion: + one: "Le délai maximum de conservation du dossier suivant a été atteint, il a donc été supprimé :" + other: "Le délai maximum de conservation des dossiers suivants a été atteint, ils ont donc été supprimés :" + dossier_will_not_be_processed: + one: "Le dossier ne sera pas traité, nous nous excusons de la gène occasionnée." + other: "Les dossiers ne seront pas traités, nous nous excusons de la gène occasionnée." diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index 38c121a51..071498fad 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -106,4 +106,20 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.subject).to eq("Un dossier en brouillon a été supprimé automatiquement") } it { expect(subject.body).to include("n° #{dossier.id} (#{dossier.procedure.libelle})") } end + + describe '.notify_automatic_deletion_to_user' do + let(:dossier) { create(:dossier) } + + before do + duree = dossier.procedure.duree_conservation_dossiers_dans_ds + @date_suppression = dossier.created_at + duree.months + end + + subject { described_class.notify_automatic_deletion_to_user(dossier.user, [dossier.hash_for_deletion_mail]) } + + it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("nous nous excusons de la gène occasionnée") } + end end From 8c77d91e9f79e0eeeda1ed9a3edbe67f8fe686c5 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 18 Feb 2020 17:18:06 +0100 Subject: [PATCH 05/15] Add notify_automatic_deletion_to_administration mailer --- app/mailers/dossier_mailer.rb | 7 +++++++ ...fy_automatic_deletion_to_administration.html.haml | 12 ++++++++++++ .../fr.yml | 9 +++++++++ spec/mailers/dossier_mailer_spec.rb | 9 +++++++++ 4 files changed, 37 insertions(+) create mode 100644 app/views/dossier_mailer/notify_automatic_deletion_to_administration.html.haml create mode 100644 config/locales/views/dossier_mailer/notify_automatic_deletion_to_administration/fr.yml diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 5a8fbb00e..ea6edd58c 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -90,4 +90,11 @@ class DossierMailer < ApplicationMailer mail(to: user.email, subject: @subject) end + + def notify_automatic_deletion_to_administration(user, dossier_hashes) + @subject = default_i18n_subject(count: dossier_hashes.count) + @dossier_hashes = dossier_hashes + + mail(to: user.email, subject: @subject) + end end diff --git a/app/views/dossier_mailer/notify_automatic_deletion_to_administration.html.haml b/app/views/dossier_mailer/notify_automatic_deletion_to_administration.html.haml new file mode 100644 index 000000000..e466b459b --- /dev/null +++ b/app/views/dossier_mailer/notify_automatic_deletion_to_administration.html.haml @@ -0,0 +1,12 @@ +- content_for(:title, "#{@subject}") + +%p + Bonjour, + +%p= t('.automatic_dossier_deletion', count: @dossier_hashes.count) + +%ul + - @dossier_hashes.each do |d| + %li= "n° #{d[:id]} (#{d[:procedure_libelle]})" + += render partial: "layouts/mailers/signature" diff --git a/config/locales/views/dossier_mailer/notify_automatic_deletion_to_administration/fr.yml b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_administration/fr.yml new file mode 100644 index 000000000..c0f77813f --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_administration/fr.yml @@ -0,0 +1,9 @@ +fr: + dossier_mailer: + notify_automatic_deletion_to_administration: + subject: + one: "Un dossier a été supprimé automatiquement" + other: "Des dossiers ont été supprimés automatiquement" + automatic_dossier_deletion: + one: "Le délai maximum de conservation du dossier suivant a été atteint, il a donc été supprimé :" + other: "Le délai maximum de conservation des dossiers suivants a été atteint, ils ont donc été supprimés :" diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index 071498fad..d1984d616 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -122,4 +122,13 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.body).to include(dossier.procedure.libelle) } it { expect(subject.body).to include("nous nous excusons de la gène occasionnée") } end + + describe '.notify_automatic_deletion_to_administration' do + let(:dossier) { create(:dossier) } + + subject { described_class.notify_automatic_deletion_to_administration(dossier.user, [dossier.hash_for_deletion_mail]) } + + it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") } + it { expect(subject.body).to include("n° #{dossier.id} (#{dossier.procedure.libelle})") } + end end From 318baf316ee06921ea5a2a2b3f31ddbef5bcfcd3 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 18 Feb 2020 17:18:14 +0100 Subject: [PATCH 06/15] Add notify_en_construction_near_deletion mailer --- app/mailers/dossier_mailer.rb | 8 +++++ ...fy_en_construction_near_deletion.html.haml | 27 +++++++++++++++ .../fr.yml | 15 ++++++++ spec/mailers/dossier_mailer_spec.rb | 34 +++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 app/views/dossier_mailer/notify_en_construction_near_deletion.html.haml create mode 100644 config/locales/views/dossier_mailer/notify_en_construction_near_deletion/fr.yml diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index ea6edd58c..b2065b26d 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -97,4 +97,12 @@ class DossierMailer < ApplicationMailer mail(to: user.email, subject: @subject) end + + def notify_en_construction_near_deletion(user, dossiers, for_user) + @subject = default_i18n_subject(count: dossiers.count) + @dossiers = dossiers + @for_user = for_user + + mail(to: user.email, subject: @subject) + end end diff --git a/app/views/dossier_mailer/notify_en_construction_near_deletion.html.haml b/app/views/dossier_mailer/notify_en_construction_near_deletion.html.haml new file mode 100644 index 000000000..896138408 --- /dev/null +++ b/app/views/dossier_mailer/notify_en_construction_near_deletion.html.haml @@ -0,0 +1,27 @@ +- content_for(:title, "#{@subject}") + +%p + Bonjour, + +%p + - if !@for_user + Afin de limiter la conservation de vos données personnelles, + + = t('.automatic_dossier_deletion', count: @dossiers.count) + + %ul + - @dossiers.each do |d| + - if !@for_user + %li + #{link_to("n° #{d.id} (#{d.procedure.libelle})", dossier_url(d))}. Retrouvez le dossier au format #{link_to("PDF", instructeur_dossier_url(d.procedure, d, format: :pdf))} + - else + %li + #{link_to("n° #{d.id} (#{d.procedure.libelle})", dossier_url(d))}. Retrouvez le dossier au format #{link_to("PDF", dossier_url(d, format: :pdf))} + +%p + - if @for_user + = sanitize(t('.send_user_draft', count: @dossiers.count)) + - else + = sanitize(t('.send_other_draft', count: @dossiers.count)) + += render partial: "layouts/mailers/signature" diff --git a/config/locales/views/dossier_mailer/notify_en_construction_near_deletion/fr.yml b/config/locales/views/dossier_mailer/notify_en_construction_near_deletion/fr.yml new file mode 100644 index 000000000..6a4955e0b --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_en_construction_near_deletion/fr.yml @@ -0,0 +1,15 @@ +fr: + dossier_mailer: + notify_en_construction_near_deletion: + subject: + one: Un dossier en construction va bientôt être supprimé + other: Des dossiers en construction vont bientôt être supprimés + automatic_dossier_deletion: + one: "le dossier en construction suivant sera bientôt automatiquement supprimé :" + other: "les dossiers en construction suivant seront bientôt automatiquement supprimés :" + send_user_draft: + one: "Vous pouvez retrouver votre dossier pendant encore un mois. Vous n'avez rien à faire." + other: "Vous pouvez retrouver vos dossiers pendant encore un mois. Vous n'avez rien à faire." + send_other_draft: + one: "Vous avez un mois pour traiter le dossier." + other: "Vous avez un mois pour traiter les dossiers." diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index d1984d616..00a76d4e6 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -131,4 +131,38 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") } it { expect(subject.body).to include("n° #{dossier.id} (#{dossier.procedure.libelle})") } end + + describe '.notify_en_construction_near_deletion_to_administration' do + let(:dossier) { create(:dossier) } + + before do + duree = dossier.procedure.duree_conservation_dossiers_dans_ds + @date_suppression = dossier.created_at + duree.months + end + + subject { described_class.notify_en_construction_near_deletion(dossier.user, [dossier], true) } + + it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("PDF") } + it { expect(subject.body).to include("Vous pouvez retrouver votre dossier pendant encore un mois. Vous n'avez rien à faire.") } + end + + describe '.notify_en_construction_near_deletion_to_user' do + let(:dossier) { create(:dossier) } + + before do + duree = dossier.procedure.duree_conservation_dossiers_dans_ds + @date_suppression = dossier.created_at + duree.months + end + + subject { described_class.notify_en_construction_near_deletion(dossier.user, [dossier], false) } + + it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("PDF") } + it { expect(subject.body).to include("Vous avez un mois pour traiter le dossier.") } + end end From e931c0800d9c833bd3a82ea676c0530124f89a1e Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 18 Feb 2020 16:28:59 +0100 Subject: [PATCH 07/15] Remove notify_unhide_to_user and notify_undelete_to_user mailers --- app/mailers/dossier_mailer.rb | 15 --------------- .../notify_undelete_to_user.html.haml | 12 ------------ .../notify_unhide_to_user.html.haml | 10 ---------- spec/mailers/dossier_mailer_spec.rb | 11 ----------- 4 files changed, 48 deletions(-) delete mode 100644 app/views/dossier_mailer/notify_undelete_to_user.html.haml delete mode 100644 app/views/dossier_mailer/notify_unhide_to_user.html.haml diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index b2065b26d..ce7d05964 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -43,21 +43,6 @@ class DossierMailer < ApplicationMailer mail(to: to_email, subject: subject) end - def notify_unhide_to_user(dossier) - @dossier = dossier - subject = "Votre dossier nº #{@dossier.id} n'a pas pu être supprimé" - - mail(to: dossier.user.email, subject: subject) - end - - def notify_undelete_to_user(dossier) - @dossier = dossier - @dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier' - @subject = "Votre #{@dossier_kind} nº #{@dossier.id} est à nouveau accessible" - - mail(to: dossier.user.email, subject: @subject) - end - def notify_revert_to_instruction(dossier) @dossier = dossier @service = dossier.procedure.service diff --git a/app/views/dossier_mailer/notify_undelete_to_user.html.haml b/app/views/dossier_mailer/notify_undelete_to_user.html.haml deleted file mode 100644 index a3b2c58e8..000000000 --- a/app/views/dossier_mailer/notify_undelete_to_user.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -- content_for(:title, @subject) - -%h1 Bonjour, - -%p - En raison d’un incident, votre - = link_to("#{@dossier_kind} n° #{@dossier.id}", dossier_url(@dossier)) - sur la procédure « #{@dossier.procedure.libelle} » a été inaccessible pendant quelques jours. - - L’accès est à présent à nouveau possible. Nous vous présentons nos excuses pour toute gène occasionnée. - -= render partial: "layouts/mailers/signature" diff --git a/app/views/dossier_mailer/notify_unhide_to_user.html.haml b/app/views/dossier_mailer/notify_unhide_to_user.html.haml deleted file mode 100644 index b3ea4eef5..000000000 --- a/app/views/dossier_mailer/notify_unhide_to_user.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -- content_for(:title, "Votre dossier n° #{@dossier.id} n'a pas pu être supprimé") - -%h1 Bonjour, - -%p - L'instruction de votre dossier n° #{@dossier.id} (« #{@dossier.procedure.libelle} ») - ayant commencé, il n'a pas pu être supprimé. - Le dossier a été rétabli dans votre tableau de bord. - -= render partial: "layouts/mailers/signature" diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index 00a76d4e6..b7b50111c 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -61,17 +61,6 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.body).to include(deleted_dossier.procedure.libelle) } end - describe '.notify_unhide_to_user' do - let(:dossier) { create(:dossier) } - - subject { described_class.notify_unhide_to_user(dossier) } - - it { expect(subject.subject).to eq("Votre dossier nº #{dossier.id} n'a pas pu être supprimé") } - it { expect(subject.body).to include(dossier.id) } - it { expect(subject.body).to include("n'a pas pu être supprimé") } - it { expect(subject.body).to include(dossier.procedure.libelle) } - end - describe '.notify_revert_to_instruction' do let(:dossier) { create(:dossier, procedure: build(:simple_procedure)) } From 32d1ebe56557f6c868eac15db150a5a24bda78be Mon Sep 17 00:00:00 2001 From: Christophe Robillard Date: Tue, 18 Feb 2020 16:41:56 +0100 Subject: [PATCH 08/15] add administrateur from manager --- app/views/manager/administrateurs/_form.html.haml | 13 +++++++++++++ .../manager/administrateurs_controller_spec.rb | 12 ++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 app/views/manager/administrateurs/_form.html.haml diff --git a/app/views/manager/administrateurs/_form.html.haml b/app/views/manager/administrateurs/_form.html.haml new file mode 100644 index 000000000..fb64c934a --- /dev/null +++ b/app/views/manager/administrateurs/_form.html.haml @@ -0,0 +1,13 @@ += form_for([namespace, Administrateur.new(user: User.new)], html: { class: "form" }) do |f| + - if page.resource.errors.any? + #error_explanation + %h2 + = t("administrate.form.errors", pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")), resource_name: display_resource_name(page.resource_name)) + %ul + - page.resource.errors.full_messages.each do |message| + %li.flash-error= message + - page.attributes.each do |attribute| + %div{ :class => "field-unit field-unit--#{attribute.html_class}" } + = render_field attribute, f: f + .form-actions + = f.submit diff --git a/spec/controllers/manager/administrateurs_controller_spec.rb b/spec/controllers/manager/administrateurs_controller_spec.rb index 0d954ee3c..63246eeb0 100644 --- a/spec/controllers/manager/administrateurs_controller_spec.rb +++ b/spec/controllers/manager/administrateurs_controller_spec.rb @@ -1,6 +1,18 @@ describe Manager::AdministrateursController, type: :controller do let(:administration) { create(:administration) } + describe 'GET #new' do + render_views + before do + sign_in administration + end + + it 'displays form to create a new admin' do + get :new + expect(response).to be_success + end + end + describe 'POST #create' do let(:email) { 'plop@plop.com' } let(:password) { 'démarches-simplifiées-pwd' } From ba3d2f1b9f9543d836a57df821a9d8dc16fd0ef4 Mon Sep 17 00:00:00 2001 From: Christophe Robillard Date: Tue, 18 Feb 2020 16:43:05 +0100 Subject: [PATCH 09/15] refactor --- .../manager/administrateurs_controller_spec.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/spec/controllers/manager/administrateurs_controller_spec.rb b/spec/controllers/manager/administrateurs_controller_spec.rb index 63246eeb0..33fb6096b 100644 --- a/spec/controllers/manager/administrateurs_controller_spec.rb +++ b/spec/controllers/manager/administrateurs_controller_spec.rb @@ -1,12 +1,12 @@ describe Manager::AdministrateursController, type: :controller do let(:administration) { create(:administration) } + before do + sign_in administration + end + describe 'GET #new' do render_views - before do - sign_in administration - end - it 'displays form to create a new admin' do get :new expect(response).to be_success @@ -17,10 +17,6 @@ describe Manager::AdministrateursController, type: :controller do let(:email) { 'plop@plop.com' } let(:password) { 'démarches-simplifiées-pwd' } - before do - sign_in administration - end - subject { post :create, params: { administrateur: { email: email } } } context 'when email and password are correct' do @@ -47,8 +43,6 @@ describe Manager::AdministrateursController, type: :controller do describe '#delete' do let!(:admin) { create(:administrateur) } - before { sign_in administration } - subject { delete :delete, params: { id: admin.id } } it 'deletes the admin' do From bb61500f9b8f61fab15a8086ef804992296f0b70 Mon Sep 17 00:00:00 2001 From: Christophe Robillard Date: Tue, 18 Feb 2020 17:40:30 +0100 Subject: [PATCH 10/15] recherche un administrateur par email dans manager --- app/dashboards/administrateur_dashboard.rb | 2 +- .../manager/administrateurs_controller_spec.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/dashboards/administrateur_dashboard.rb b/app/dashboards/administrateur_dashboard.rb index 48fd715dd..ba6f91072 100644 --- a/app/dashboards/administrateur_dashboard.rb +++ b/app/dashboards/administrateur_dashboard.rb @@ -16,7 +16,7 @@ class AdministrateurDashboard < Administrate::BaseDashboard registration_state: Field::String.with_options(searchable: false), current_sign_in_at: Field::DateTime, features: FeaturesField, - email: Field::Email + email: Field::Email.with_options(searchable: false) }.freeze # COLLECTION_ATTRIBUTES diff --git a/spec/controllers/manager/administrateurs_controller_spec.rb b/spec/controllers/manager/administrateurs_controller_spec.rb index 33fb6096b..b1504511a 100644 --- a/spec/controllers/manager/administrateurs_controller_spec.rb +++ b/spec/controllers/manager/administrateurs_controller_spec.rb @@ -51,4 +51,14 @@ describe Manager::AdministrateursController, type: :controller do expect(Administrateur.find_by(id: admin.id)).to be_nil end end + + describe '#index' do + render_views + let(:admin) { create(:administrateur) } + + it 'searches admin by email' do + get :index, params: { search: admin.email } + expect(response).to be_success + end + end end From b7051da2789f4b2281116925671eeb231806b872 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 19 Feb 2020 17:25:25 +0100 Subject: [PATCH 11/15] Remove old export code --- app/jobs/cleanup_stale_exports_job.rb | 26 --- app/jobs/export_procedure_job.rb | 6 - app/mailers/instructeur_mailer.rb | 8 - app/models/procedure.rb | 105 +----------- ...otify_procedure_export_available.html.haml | 11 -- spec/factories/procedure.rb | 42 ----- spec/mailers/instructeur_mailer_spec.rb | 14 -- .../previews/instructeur_mailer_preview.rb | 4 - spec/models/procedure_spec.rb | 161 ------------------ 9 files changed, 1 insertion(+), 376 deletions(-) delete mode 100644 app/jobs/cleanup_stale_exports_job.rb delete mode 100644 app/jobs/export_procedure_job.rb delete mode 100644 app/views/instructeur_mailer/notify_procedure_export_available.html.haml diff --git a/app/jobs/cleanup_stale_exports_job.rb b/app/jobs/cleanup_stale_exports_job.rb deleted file mode 100644 index 9344d4f14..000000000 --- a/app/jobs/cleanup_stale_exports_job.rb +++ /dev/null @@ -1,26 +0,0 @@ -class CleanupStaleExportsJob < ApplicationJob - queue_as :cron - - def perform(*args) - attachments = ActiveStorage::Attachment.where( - "name in ('csv_export_file', 'ods_export_file', 'xlsx_export_file') and created_at < ?", - Procedure::MAX_DUREE_CONSERVATION_EXPORT.ago - ) - attachments.each do |attachment| - procedure = Procedure.find(attachment.record_id) - # export can't be queued if it's already attached - #  so we clean the flag up just in case it was not removed during - # the asynchronous generation - case attachment.name - when 'csv_export_file' - procedure.update(csv_export_queued: false) - when 'ods_export_file' - procedure.update(ods_export_queued: false) - when 'xlsx_export_file' - procedure.update(xlsx_export_queued: false) - end - # and we remove the stale attachment - attachment.purge_later - end - end -end diff --git a/app/jobs/export_procedure_job.rb b/app/jobs/export_procedure_job.rb deleted file mode 100644 index 7e935d8ac..000000000 --- a/app/jobs/export_procedure_job.rb +++ /dev/null @@ -1,6 +0,0 @@ -class ExportProcedureJob < ApplicationJob - def perform(procedure, instructeur, export_format) - procedure.prepare_export_download(export_format) - InstructeurMailer.notify_procedure_export_available(instructeur, procedure, export_format).deliver_later - end -end diff --git a/app/mailers/instructeur_mailer.rb b/app/mailers/instructeur_mailer.rb index d132c0005..aa28622d2 100644 --- a/app/mailers/instructeur_mailer.rb +++ b/app/mailers/instructeur_mailer.rb @@ -42,12 +42,4 @@ class InstructeurMailer < ApplicationMailer mail(to: instructeur.email, subject: subject) end - - def notify_procedure_export_available(instructeur, procedure, export_format) - @procedure = procedure - @export_format = export_format - subject = "Votre export de la démarche nº #{procedure.id} est disponible" - - mail(to: instructeur.email, subject: subject) - end end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 081de7cc9..6171d5791 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -1,7 +1,7 @@ require Rails.root.join('lib', 'percentile') class Procedure < ApplicationRecord - self.ignored_columns = ['archived_at'] + self.ignored_columns = ['archived_at', 'csv_export_queued', 'xlsx_export_queued', 'ods_export_queued'] include ProcedureStatsConcern @@ -41,10 +41,6 @@ class Procedure < ApplicationRecord has_one_attached :notice has_one_attached :deliberation - has_one_attached :csv_export_file - has_one_attached :xlsx_export_file - has_one_attached :ods_export_file - accepts_nested_attributes_for :types_de_champ, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true accepts_nested_attributes_for :types_de_champ_private, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true @@ -133,100 +129,11 @@ class Procedure < ApplicationRecord end end - def csv_export_stale? - !csv_export_file.attached? || csv_export_file.created_at < MAX_DUREE_CONSERVATION_EXPORT.ago - end - - def xlsx_export_stale? - !xlsx_export_file.attached? || xlsx_export_file.created_at < MAX_DUREE_CONSERVATION_EXPORT.ago - end - - def ods_export_stale? - !ods_export_file.attached? || ods_export_file.created_at < MAX_DUREE_CONSERVATION_EXPORT.ago - end - - def export_queued?(format) - case format.to_sym - when :csv - return csv_export_queued? - when :xlsx - return xlsx_export_queued? - when :ods - return ods_export_queued? - end - false - end - - def should_generate_export?(format) - case format.to_sym - when :csv - return csv_export_stale? && !csv_export_queued? - when :xlsx - return xlsx_export_stale? && !xlsx_export_queued? - when :ods - return ods_export_stale? && !ods_export_queued? - end - false - end - - def export_file(export_format) - case export_format.to_sym - when :csv - csv_export_file - when :xlsx - xlsx_export_file - when :ods - ods_export_file - end - end - - def queue_export(instructeur, export_format) - case export_format.to_sym - when :csv - update(csv_export_queued: true) - when :xlsx - update(xlsx_export_queued: true) - when :ods - update(ods_export_queued: true) - end - ExportProcedureJob.perform_later(self, instructeur, export_format) - end - - def prepare_export_download(format) - service = ProcedureExportService.new(self, self.dossiers) - filename = export_filename(format) - - case format.to_sym - when :csv - csv_export_file.attach( - io: StringIO.new(service.to_csv), - filename: filename, - content_type: 'text/csv' - ) - update(csv_export_queued: false) - when :xlsx - xlsx_export_file.attach( - io: StringIO.new(service.to_xlsx), - filename: filename, - content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ) - update(xlsx_export_queued: false) - when :ods - ods_export_file.attach( - io: StringIO.new(service.to_ods), - filename: filename, - content_type: 'application/vnd.oasis.opendocument.spreadsheet' - ) - update(ods_export_queued: false) - end - end - def reset! if locked? raise "Can not reset a locked procedure." else groupe_instructeurs.each { |gi| gi.dossiers.destroy_all } - purge_export_files end end @@ -268,14 +175,6 @@ class Procedure < ApplicationRecord procedure.blank? || administrateur.owns?(procedure) end - def purge_export_files - xlsx_export_file.purge_later - ods_export_file.purge_later - csv_export_file.purge_later - - update(csv_export_queued: false, xlsx_export_queued: false, ods_export_queued: false) - end - def locked? publiee? || close? || depubliee? end @@ -594,7 +493,6 @@ class Procedure < ApplicationRecord def hide! discard! dossiers.discard_all - purge_export_files end private @@ -626,7 +524,6 @@ class Procedure < ApplicationRecord def after_close now = Time.zone.now update!(closed_at: now) - purge_export_files end def after_unpublish diff --git a/app/views/instructeur_mailer/notify_procedure_export_available.html.haml b/app/views/instructeur_mailer/notify_procedure_export_available.html.haml deleted file mode 100644 index 678dfd08b..000000000 --- a/app/views/instructeur_mailer/notify_procedure_export_available.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -%p - Bonjour, - -%p - Votre export des dossiers de la démarche nº #{@procedure.id} « #{@procedure.libelle} » au format #{@export_format} est prêt. - -%p - Cliquez sur le lien ci-dessous pour le télécharger : - = link_to('Télécharger l\'export des dossiers', download_export_instructeur_procedure_url(@procedure, :export_format => @export_format)) - -= render partial: "layouts/mailers/signature" diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 1cf7e1b03..9385382c1 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -249,47 +249,5 @@ FactoryBot.define do end end end - - trait :with_csv_export_file do - after(:create) do |procedure, _evaluator| - procedure.csv_export_file.attach(io: StringIO.new("some csv data"), filename: "export.csv", content_type: "text/plain") - procedure.csv_export_file.update(created_at: 5.minutes.ago) - end - end - - trait :with_stale_csv_export_file do - after(:create) do |procedure, _evaluator| - procedure.csv_export_file.attach(io: StringIO.new("some csv data"), filename: "export.csv", content_type: "text/plain") - procedure.csv_export_file.update(created_at: 4.hours.ago) - end - end - - trait :with_ods_export_file do - after(:create) do |procedure, _evaluator| - procedure.ods_export_file.attach(io: StringIO.new("some ods data"), filename: "export.ods", content_type: "text/plain") - procedure.ods_export_file.update(created_at: 5.minutes.ago) - end - end - - trait :with_stale_ods_export_file do - after(:create) do |procedure, _evaluator| - procedure.ods_export_file.attach(io: StringIO.new("some ods data"), filename: "export.ods", content_type: "text/plain") - procedure.ods_export_file.update(created_at: 4.hours.ago) - end - end - - trait :with_xlsx_export_file do - after(:create) do |procedure, _evaluator| - procedure.xlsx_export_file.attach(io: StringIO.new("some xlsx data"), filename: "export.xlsx", content_type: "text/plain") - procedure.xlsx_export_file.update(created_at: 5.minutes.ago) - end - end - - trait :with_stale_xlsx_export_file do - after(:create) do |procedure, _evaluator| - procedure.xlsx_export_file.attach(io: StringIO.new("some xlsx data"), filename: "export.xlsx", content_type: "text/plain") - procedure.xlsx_export_file.update(created_at: 4.hours.ago) - end - end end end diff --git a/spec/mailers/instructeur_mailer_spec.rb b/spec/mailers/instructeur_mailer_spec.rb index ffcda1f25..aafaf85d2 100644 --- a/spec/mailers/instructeur_mailer_spec.rb +++ b/spec/mailers/instructeur_mailer_spec.rb @@ -46,18 +46,4 @@ RSpec.describe InstructeurMailer, type: :mailer do end end end - - describe '#notify_procedure_export_available' do - let(:instructeur) { create(:instructeur) } - let(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) } - let(:dossier) { create(:dossier, procedure: procedure) } - let(:format) { 'xlsx' } - - context 'when the mail is sent' do - subject { described_class.notify_procedure_export_available(instructeur, procedure, format) } - it 'contains a download link' do - expect(subject.body).to include download_export_instructeur_procedure_url(procedure, :export_format => format) - end - end - end end diff --git a/spec/mailers/previews/instructeur_mailer_preview.rb b/spec/mailers/previews/instructeur_mailer_preview.rb index 0a906a7dc..35c2f85a1 100644 --- a/spec/mailers/previews/instructeur_mailer_preview.rb +++ b/spec/mailers/previews/instructeur_mailer_preview.rb @@ -37,10 +37,6 @@ class InstructeurMailerPreview < ActionMailer::Preview InstructeurMailer.send_notifications(instructeur, data) end - def notify_procedure_export_available - InstructeurMailer.notify_procedure_export_available(instructeur, procedure, 'xlsx') - end - private def instructeur diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index c0c949bbd..3b7a9b26c 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -1075,165 +1075,4 @@ describe Procedure do it { is_expected.to be false } end end - - describe '.ods_export_stale?' do - subject { procedure.ods_export_stale? } - - context 'with no ods export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent ods export' do - let(:procedure) { create(:procedure, :with_ods_export_file) } - it { is_expected.to be false } - end - - context 'with an old ods export' do - let(:procedure) { create(:procedure, :with_stale_ods_export_file) } - it { is_expected.to be true } - end - end - - describe '.csv_export_stale?' do - subject { procedure.csv_export_stale? } - - context 'with no csv export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent csv export' do - let(:procedure) { create(:procedure, :with_csv_export_file) } - it { is_expected.to be false } - end - - context 'with an old csv export' do - let(:procedure) { create(:procedure, :with_stale_csv_export_file) } - it { is_expected.to be true } - end - end - - describe '.xlsx_export_stale?' do - subject { procedure.xlsx_export_stale? } - - context 'with no xlsx export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent xlsx export' do - let(:procedure) { create(:procedure, :with_xlsx_export_file) } - it { is_expected.to be false } - end - - context 'with an old xlsx export' do - let(:procedure) { create(:procedure, :with_stale_xlsx_export_file) } - it { is_expected.to be true } - end - end - - describe '.should_generate_export?' do - context 'xlsx' do - subject { procedure.should_generate_export?('xlsx') } - context 'with no export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_xlsx_export_file, xlsx_export_queued: false) } - it { is_expected.to be false } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_xlsx_export_file, xlsx_export_queued: true) } - it { expect(procedure.xlsx_export_queued).to be true } - it { is_expected.to be false } - end - end - - context 'with an old export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_stale_xlsx_export_file, xlsx_export_queued: false) } - it { is_expected.to be true } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_stale_xlsx_export_file, xlsx_export_queued: true) } - it { expect(procedure.xlsx_export_queued).to be true } - it { is_expected.to be false } - end - end - end - - context 'csv' do - subject { procedure.should_generate_export?('csv') } - context 'with no export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_csv_export_file, csv_export_queued: false) } - it { is_expected.to be false } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_csv_export_file, csv_export_queued: true) } - it { expect(procedure.csv_export_queued).to be true } - it { is_expected.to be false } - end - end - - context 'with an old export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_stale_csv_export_file, csv_export_queued: false) } - it { is_expected.to be true } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_stale_csv_export_file, csv_export_queued: true) } - it { expect(procedure.csv_export_queued).to be true } - it { is_expected.to be false } - end - end - end - - context 'ods' do - subject { procedure.should_generate_export?('ods') } - context 'with no export' do - let(:procedure) { create(:procedure) } - it { is_expected.to be true } - end - - context 'with a recent export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_ods_export_file, ods_export_queued: false) } - it { is_expected.to be false } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_ods_export_file, ods_export_queued: true) } - it { expect(procedure.ods_export_queued).to be true } - it { is_expected.to be false } - end - end - - context 'with an old export' do - context 'when its not queued' do - let(:procedure) { create(:procedure, :with_stale_ods_export_file, ods_export_queued: false) } - it { is_expected.to be true } - end - - context 'when its already queued' do - let(:procedure) { create(:procedure, :with_stale_ods_export_file, ods_export_queued: true) } - it { expect(procedure.ods_export_queued).to be true } - it { is_expected.to be false } - end - end - end - end end From 059d80ea34ace26fd6903cfda60adf3a8f010375 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Mon, 17 Feb 2020 16:32:41 +0100 Subject: [PATCH 12/15] #4785 ajout d'une balise 'groupe instructeur' --- .../concerns/tags_substitution_concern.rb | 21 ++++++++++++++++- .../concern/tags_substitution_concern_spec.rb | 23 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 1410f4479..2c7a82266 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -11,6 +11,13 @@ module TagsSubstitutionConcern target: :motivation, available_for_states: Dossier::TERMINE }, + { + libelle: 'groupe instructeur', + description: 'Le groupe instructeur en charge du dossier', + lambda: -> (d) { d.groupe_instructeur.label }, + available?: -> (d) { d.procedure.routee? }, + available_for_states: Dossier::SOUMIS + }, { libelle: 'date de dépôt', description: 'Date du passage en construction du dossier par l’usager', @@ -219,7 +226,19 @@ module TagsSubstitutionConcern def replace_tags_with_values_from_data(text, tags, data) if data.present? tags.reduce(text) do |acc, tag| - replace_tag(acc, tag, data) + # A tag is available by default. + # If it has an :available? lambda, then we check its result to determine if the tag is available + if tag.key?(:available?) + tag_available = instance_exec(data, &tag[:available?]) + else + tag_available = true + end + + if tag_available + replace_tag(acc, tag, data) + else + text + end end else text diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index 288c0075a..cb3c9b352 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -70,6 +70,29 @@ describe TagsSubstitutionConcern, type: :model do end end + context 'when the template use the groupe instructeur tags' do + let(:template) { '--groupe instructeur--' } + let(:state) { Dossier.states.fetch(:en_instruction) } + let!(:dossier) { create(:dossier, procedure: procedure, individual: individual, etablissement: etablissement, state: state) } + context 'and the dossier has a groupe instructeur' do + label = 'Ville de Bordeaux' + before do + gi = procedure.groupe_instructeurs.create(label: label) + gi.dossiers << dossier + dossier.update(groupe_instructeur: gi) + dossier.reload + end + + it { expect(procedure.groupe_instructeurs.size).to eq(2) } + it { expect(procedure.routee?).to eq(true) } + it { is_expected.to eq(label) } + end + + context 'and the dossier has no groupe instructeur' do + it { is_expected.to eq(template) } + end + end + context 'when the procedure has a type de champ named libelleA et libelleB' do let(:types_de_champ) do [ From 48d20935772822ec7570212047e9e9ec8c9fc3f7 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Wed, 19 Feb 2020 15:47:22 +0100 Subject: [PATCH 13/15] tag 'groupe instructeur' uniquement si la procedure est routee --- .../concerns/tags_substitution_concern.rb | 38 +++++++++---------- .../concern/tags_substitution_concern_spec.rb | 4 +- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 2c7a82266..cb2464c93 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -11,13 +11,6 @@ module TagsSubstitutionConcern target: :motivation, available_for_states: Dossier::TERMINE }, - { - libelle: 'groupe instructeur', - description: 'Le groupe instructeur en charge du dossier', - lambda: -> (d) { d.groupe_instructeur.label }, - available?: -> (d) { d.procedure.routee? }, - available_for_states: Dossier::SOUMIS - }, { libelle: 'date de dépôt', description: 'Date du passage en construction du dossier par l’usager', @@ -137,6 +130,15 @@ module TagsSubstitutionConcern } ] + ROUTAGE_TAGS = [ + { + libelle: 'groupe instructeur', + description: 'Le groupe instructeur en charge du dossier', + lambda: -> (d) { d.groupe_instructeur.label }, + available_for_states: Dossier::SOUMIS + } + ] + def tags if procedure.for_individual? identity_tags = INDIVIDUAL_TAGS @@ -144,7 +146,12 @@ module TagsSubstitutionConcern identity_tags = ENTREPRISE_TAGS end - filter_tags(identity_tags + dossier_tags + champ_public_tags + champ_private_tags) + routage_tags = [] + if procedure.routee? + routage_tags = ROUTAGE_TAGS + end + + filter_tags(identity_tags + dossier_tags + champ_public_tags + champ_private_tags + routage_tags) end private @@ -214,6 +221,7 @@ module TagsSubstitutionConcern [champ_public_tags, dossier.champs], [champ_private_tags, dossier.champs_private], [dossier_tags, dossier], + [ROUTAGE_TAGS, dossier], [INDIVIDUAL_TAGS, dossier.individual], [ENTREPRISE_TAGS, dossier.etablissement&.entreprise] ] @@ -226,19 +234,7 @@ module TagsSubstitutionConcern def replace_tags_with_values_from_data(text, tags, data) if data.present? tags.reduce(text) do |acc, tag| - # A tag is available by default. - # If it has an :available? lambda, then we check its result to determine if the tag is available - if tag.key?(:available?) - tag_available = instance_exec(data, &tag[:available?]) - else - tag_available = true - end - - if tag_available - replace_tag(acc, tag, data) - else - text - end + replace_tag(acc, tag, data) end else text diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index cb3c9b352..9488976fd 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -83,13 +83,13 @@ describe TagsSubstitutionConcern, type: :model do dossier.reload end - it { expect(procedure.groupe_instructeurs.size).to eq(2) } it { expect(procedure.routee?).to eq(true) } it { is_expected.to eq(label) } end context 'and the dossier has no groupe instructeur' do - it { is_expected.to eq(template) } + it { expect(procedure.routee?).to eq(false) } + it { is_expected.to eq('défaut') } end end From 5dc5230791a8b3a3e7792987ab8d7232372c9f48 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Tue, 18 Feb 2020 17:18:25 +0100 Subject: [PATCH 14/15] Step1 : add new column to Assign_tos and make sure that the data is saved on form submit --- .../instructeurs/procedures_controller.rb | 1 + app/models/assign_to.rb | 5 +++++ ..._email_notifications_enabled_to_assign_tos.rb | 5 +++++ db/schema.rb | 3 ++- ...ackfill_daily_email_notification_columns.rake | 16 ++++++++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20200218144724_add_daily_email_notifications_enabled_to_assign_tos.rb create mode 100644 lib/tasks/deployment/20200220142710_backfill_daily_email_notification_columns.rake diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 298cc862a..425f78132 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -232,6 +232,7 @@ module Instructeurs def update_email_notifications assign_to.update!(assign_to_params) + assign_to.update!(daily_email_notifications_enabled: params[:assign_to][:email_notifications_enabled]) flash.notice = 'Vos notifications sont enregistrées.' redirect_to instructeur_procedure_path(procedure) end diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index 96bb9713b..e3264ea40 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -3,9 +3,14 @@ class AssignTo < ApplicationRecord belongs_to :groupe_instructeur has_one :procedure_presentation, dependent: :destroy has_one :procedure, through: :groupe_instructeur + before_save :save_to_new_daily_email_column scope :with_email_notifications, -> { where(email_notifications_enabled: true) } + def save_to_new_daily_email_column + self.daily_email_notifications_enabled = email_notifications_enabled + end + def procedure_presentation_or_default_and_errors errors = reset_procedure_presentation_if_invalid [procedure_presentation || build_procedure_presentation, errors] diff --git a/db/migrate/20200218144724_add_daily_email_notifications_enabled_to_assign_tos.rb b/db/migrate/20200218144724_add_daily_email_notifications_enabled_to_assign_tos.rb new file mode 100644 index 000000000..67938c458 --- /dev/null +++ b/db/migrate/20200218144724_add_daily_email_notifications_enabled_to_assign_tos.rb @@ -0,0 +1,5 @@ +class AddDailyEmailNotificationsEnabledToAssignTos < ActiveRecord::Migration[5.2] + def change + add_column :assign_tos, :daily_email_notifications_enabled, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 7417ba719..d6fa3ff97 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_02_11_170134) do +ActiveRecord::Schema.define(version: 2020_02_18_144724) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -103,6 +103,7 @@ ActiveRecord::Schema.define(version: 2020_02_11_170134) do t.boolean "email_notifications_enabled", default: false, null: false t.bigint "groupe_instructeur_id" t.boolean "weekly_email_notifications_enabled", default: true, null: false + t.boolean "daily_email_notifications_enabled", default: false, null: false t.index ["groupe_instructeur_id", "instructeur_id"], name: "unique_couple_groupe_instructeur_instructeur", unique: true t.index ["groupe_instructeur_id"], name: "index_assign_tos_on_groupe_instructeur_id" t.index ["instructeur_id", "procedure_id"], name: "index_assign_tos_on_instructeur_id_and_procedure_id", unique: true diff --git a/lib/tasks/deployment/20200220142710_backfill_daily_email_notification_columns.rake b/lib/tasks/deployment/20200220142710_backfill_daily_email_notification_columns.rake new file mode 100644 index 000000000..919441434 --- /dev/null +++ b/lib/tasks/deployment/20200220142710_backfill_daily_email_notification_columns.rake @@ -0,0 +1,16 @@ +namespace :after_party do + desc 'Deployment task: backfill_daily_email_notification_columns' + task backfill_daily_email_notification_columns: :environment do + puts "Running deploy task 'backfill_daily_email_notification_columns'" + AssignTo.find_each do |assign_to| + columns_to_update = {} + if assign_to.email_notifications_enabled != assign_to.daily_email_notifications_enabled + columns_to_update[:daily_email_notifications_enabled] = assign_to.email_notifications_enabled + end + assign_to.update_columns(columns_to_update) unless columns_to_update.empty? + end + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord.create version: '20200220142710' + end # task :backfill_daily_email_notification_columns +end # namespace :after_party From 4343bb39182be797c823a1eaaa8b7114e6784de2 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Thu, 20 Feb 2020 11:39:33 +0100 Subject: [PATCH 15/15] Revert "openly fail when not delivering mail" This reverts commit 415cc2c2f1d4a7d037bf59da65239a10f1e82581. --- app/mailers/application_mailer.rb | 5 +++++ app/mailers/devise_user_mailer.rb | 5 +++++ spec/mailers/application_mailer_spec.rb | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3504f1a7a..b444548f4 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -3,6 +3,11 @@ class ApplicationMailer < ActionMailer::Base default from: "demarches-simplifiees.fr <#{CONTACT_EMAIL}>" layout 'mailer' + # Don’t retry to send a message if the server rejects the recipient address + rescue_from Net::SMTPSyntaxError do |_error| + message.perform_deliveries = false + end + # Attach the procedure logo to the email (if any). # Returns the attachment url. def attach_logo(procedure) diff --git a/app/mailers/devise_user_mailer.rb b/app/mailers/devise_user_mailer.rb index a19c04768..de07cc1b7 100644 --- a/app/mailers/devise_user_mailer.rb +++ b/app/mailers/devise_user_mailer.rb @@ -4,6 +4,11 @@ class DeviseUserMailer < Devise::Mailer include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url` layout 'mailers/layout' + # Don’t retry to send a message if the server rejects the recipient address + rescue_from Net::SMTPSyntaxError do |_error| + message.perform_deliveries = false + end + def template_paths ['devise_mailer'] end diff --git a/spec/mailers/application_mailer_spec.rb b/spec/mailers/application_mailer_spec.rb index f4464b7ba..9cfa295f9 100644 --- a/spec/mailers/application_mailer_spec.rb +++ b/spec/mailers/application_mailer_spec.rb @@ -3,6 +3,16 @@ RSpec.describe ApplicationMailer, type: :mailer do let(:dossier) { create(:dossier, procedure: build(:simple_procedure)) } subject { DossierMailer.notify_new_draft(dossier) } + describe 'invalid emails are not sent' do + before do + allow_any_instance_of(DossierMailer) + .to receive(:notify_new_draft) + .and_raise(Net::SMTPSyntaxError) + end + + it { expect(subject.message).to be_an_instance_of(ActionMailer::Base::NullMail) } + end + describe 'valid emails are sent' do it { expect(subject.message).not_to be_an_instance_of(ActionMailer::Base::NullMail) } end