From 5177adb32ac8a28c6b8bde641797d6cccf068661 Mon Sep 17 00:00:00 2001 From: taitus Date: Tue, 5 Feb 2019 18:31:33 +0100 Subject: [PATCH] New rake task for proposals to send new action email Execute rake task every day to detect new actions available for not archived proposals. If there are new actions available for today, send email to proposal's author with information text, new actions available and link to proposal dashboard url. --- app/mailers/dashboard/mailer.rb | 17 ++++ app/models/dashboard/action.rb | 5 +- ...actions_notification_rake_created.html.erb | 73 ++++++++++++++++ ...tions_notification_rake_published.html.erb | 74 +++++++++++++++++ config/locales/en/mailers.yml | 24 ++++++ config/locales/es/mailers.yml | 24 ++++++ config/schedule.rb | 4 + lib/tasks/dashboards.rake | 18 ++++ spec/lib/tasks/dashboards_spec.rb | 83 +++++++++++++++++++ spec/mailers/dashboard/mailer_spec.rb | 83 +++++++++++++++++-- .../previews/dashboard_mailer_preview.rb | 14 ++++ spec/models/dashboard/action_spec.rb | 16 ++-- 12 files changed, 420 insertions(+), 15 deletions(-) create mode 100644 app/views/dashboard/mailer/new_actions_notification_rake_created.html.erb create mode 100644 app/views/dashboard/mailer/new_actions_notification_rake_published.html.erb create mode 100644 lib/tasks/dashboards.rake create mode 100644 spec/lib/tasks/dashboards_spec.rb diff --git a/app/mailers/dashboard/mailer.rb b/app/mailers/dashboard/mailer.rb index 91b0dbd2d..e7cbc9a36 100644 --- a/app/mailers/dashboard/mailer.rb +++ b/app/mailers/dashboard/mailer.rb @@ -6,8 +6,25 @@ class Dashboard::Mailer < ApplicationMailer mail to: proposal.author.email, subject: proposal.title end + def new_actions_notification_rake_published(proposal, new_actions_ids) + @proposal = proposal + @new_actions = get_new_actions(new_actions_ids) + mail to: proposal.author.email, subject: I18n.t("mailers.new_actions_notification_rake_published.subject") + end + + def new_actions_notification_rake_created(proposal, new_actions_ids) + @proposal = proposal + @new_actions = get_new_actions(new_actions_ids) + mail to: proposal.author.email, subject: I18n.t("mailers.new_actions_notification_rake_created.subject") + end + def new_actions_notification_on_create(proposal) @proposal = proposal mail to: proposal.author.email, subject: I18n.t("mailers.new_actions_notification_on_create.subject") end + + private + def get_new_actions(new_actions_ids) + Dashboard::Action.where(id: new_actions_ids) + end end diff --git a/app/models/dashboard/action.rb b/app/models/dashboard/action.rb index 2e9a68f88..e88c5a714 100644 --- a/app/models/dashboard/action.rb +++ b/app/models/dashboard/action.rb @@ -93,7 +93,10 @@ class Dashboard::Action < ActiveRecord::Base actions_for_today = get_actions_for_today(proposal) actions_for_yesterday = get_actions_for_yesterday(proposal) - new_actions = actions_for_today - actions_for_yesterday + actions_for_today_ids = actions_for_today.pluck(:id) + actions_for_yesterday_ids = actions_for_yesterday.pluck(:id) + + actions_for_today_ids - actions_for_yesterday_ids end private diff --git a/app/views/dashboard/mailer/new_actions_notification_rake_created.html.erb b/app/views/dashboard/mailer/new_actions_notification_rake_created.html.erb new file mode 100644 index 000000000..ff6f3d817 --- /dev/null +++ b/app/views/dashboard/mailer/new_actions_notification_rake_created.html.erb @@ -0,0 +1,73 @@ + + +

<%= t("mailers.new_actions_notification_rake_created.hi", name: @proposal.author.name) %>

+ +

+ <%= t("mailers.new_actions_notification_rake_created.introduction", + created_at_day: @proposal.created_at.day, + created_at_month: @proposal.created_at.strftime("%B"), + title: @proposal.title) %> +

+

+ <%= t("mailers.new_actions_notification_rake_created.text_1", + link_to_published: link_to(proposal_dashboard_url(@proposal), + proposal_dashboard_url(@proposal))).html_safe %> +

+

<%= t("mailers.new_actions_notification_rake_created.text_2") %>

+
+

<%= t("mailers.new_actions_notification_rake_created.text_3") %>

+ +
+ + <% first_resource = @new_actions.resources.first %> + <% if first_resource.present? %> + <%= t("mailers.new_actions_notification_rake_created.new_resource") %> + +
+ <% end %> + + <% first_proposed_action = @new_actions.proposed_actions.first %> + <% if first_proposed_action.present? %> +

<%= t("mailers.new_actions_notification_rake_created.text_4") %>

+ +
+ <% end %> + + <% if @new_actions.proposed_actions.count > 1 %> + <% second_proposed_action = @new_actions.proposed_actions.second %> +

<%= t("mailers.new_actions_notification_rake_created.text_5") %>

+ +
+ <% end %> + +

<%= t("mailers.new_actions_notification_rake_created.footer_text") %>

+ +
+ + + + + + +
+ <%= link_to proposal_dashboard_url(@proposal), + style: "font-family: 'Open Sans',arial,sans-serif; background: #3700fd; + border-radius: 6px; color: #fff !important; font-weight: bold; + padding: 17px 20px; text-align: center; text-decoration: none; + font-size: 20px; min-width: 200px; display: inline-block;", + target: "_blank" do %> + <%= t("mailers.new_actions_notification_rake_created.dashboard_button") %> + <% end %> +
+ + diff --git a/app/views/dashboard/mailer/new_actions_notification_rake_published.html.erb b/app/views/dashboard/mailer/new_actions_notification_rake_published.html.erb new file mode 100644 index 000000000..daea3d0a6 --- /dev/null +++ b/app/views/dashboard/mailer/new_actions_notification_rake_published.html.erb @@ -0,0 +1,74 @@ + + +

<%= t("mailers.new_actions_notification_rake_published.hi", name: @proposal.author.name) %>

+

+ <%= t("mailers.new_actions_notification_rake_published.introduction", + published_at_day: @proposal.published_at.day, + published_at_month: @proposal.published_at.strftime("%B"), + title: @proposal.title) %> +

+
+ <% first_resource = @new_actions.resources.first %> + <% if first_resource.present? %> +

<%= t("mailers.new_actions_notification_rake_published.text_1", votes_count: @proposal.cached_votes_up) %>

+
+

<%= t("mailers.new_actions_notification_rake_published.text_2") %>

+
+

<%= t("mailers.new_actions_notification_rake_published.new_resource") %>

+ +
+ <% end %> + + <% limit_to_archive_proposal = @proposal.created_at.to_date + + Setting["months_to_archive_proposals"].to_i.months %> +

+ <%= t("mailers.new_actions_notification_rake_published.text_3", + days_count: (limit_to_archive_proposal - Date.today).to_i, + max_votes_count: Setting["votes_for_proposal_success"]) %> +

+ + <% first_proposed_action = @new_actions.proposed_actions.first %> + <% if first_proposed_action.present? %> +

<%= t("mailers.new_actions_notification_rake_published.text_4") %>

+ +
+ <% end %> + + <% if @new_actions.proposed_actions.count > 1 %> + <% second_proposed_action = @new_actions.proposed_actions.second %> +

<%= t("mailers.new_actions_notification_rake_published.text_5") %>

+ +
+ <% end %> + +

<%= t("mailers.new_actions_notification_rake_published.footer_text") %>

+ +
+ + + + + + +
+ <%= link_to proposal_dashboard_url(@proposal), + style: "font-family: 'Open Sans',arial,sans-serif; background: #3700fd; + border-radius: 6px; color: #fff !important; font-weight: bold; + padding: 17px 20px; text-align: center; text-decoration: none; + font-size: 20px; min-width: 200px; display: inline-block;", + target: "_blank" do %> + <%= t("mailers.new_actions_notification_rake_published.dashboard_button") %> + <% end %> +
+ + diff --git a/config/locales/en/mailers.yml b/config/locales/en/mailers.yml index 253d25214..d2ac7287b 100644 --- a/config/locales/en/mailers.yml +++ b/config/locales/en/mailers.yml @@ -77,6 +77,30 @@ en: hi: "Dear user," thanks: "Thank you again for participating." sincerely: "Sincererly" + new_actions_notification_rake_created: + subject: "More news about your citizen proposal in Decide Madrid" + hi: "Hello %{name}," + new_resource: "NEW UNLOCKED RESOURCE" + introduction: "As you know, on the %{created_at_day} day of the %{created_at_month} you created the proposal in draft mode %{title} on the Decide Madrid platform." + text_1: "Whenever you want you can publish on this link: %{link_to_published}. If you're still not sure..." + text_2: "Seize this moment! Learn, add other people with the same interests and prepare the diffusion that you will need when you publish your proposal definitively." + text_3: "And to accompany you in this challenge, here are the news..." + text_4: "Take a look at this NEW recommended ACTION:" + text_5: "The next action we recommend is:" + footer_text: "As always, enter the Proposals Panel and we will tell you in detail how to use these resources and how to get the most out of it." + dashboard_button: "Go ahead, discover them!" + new_actions_notification_rake_published: + subject: "More news about your citizen proposal in Decide Madrid" + hi: "Hello %{name}," + new_resource: "NEW UNLOCKED RESOURCE" + introduction: "As you know, on the %{published_at_day} day of the %{published_at_month} you published the proposal %{title} on the Decide Madrid platform." + text_1: "Well, you've got %{votes_count} support so far Congratulations!" + text_2: "And so, you have a new resource available to help you keep moving forward." + text_3: "You are missing %{days_count} days before your proposal gets the %{max_votes_count} supports and goes to referendum. Cheer up and keep spreading. Are you short of ideas?" + text_4: "NEW RECOMMENDED DIFFUSION ACTION" + text_5: "There's more yet, see the following action:" + footer_text: "As always, enter the Proposals Panel and we will tell you in detail how to use these resources and how to get the most out of it." + dashboard_button: "Go ahead, discover them!" new_actions_notification_on_create: subject: "Your draft citizen proposal in Decide Madrid is created" hi: "Hi %{name}!" diff --git a/config/locales/es/mailers.yml b/config/locales/es/mailers.yml index ef7dfb7b6..5d26c0ac7 100644 --- a/config/locales/es/mailers.yml +++ b/config/locales/es/mailers.yml @@ -77,6 +77,30 @@ es: hi: "Estimado/a usuario/a" thanks: "Gracias de nuevo por tu participación." sincerely: "Atentamente" + new_actions_notification_rake_created: + subject: "Más novedades de tu propuesta ciudadana en Decide Madrid" + hi: "Hola %{name}," + new_resource: "NUEVO RECURSO DESBLOQUEADO" + introduction: "Como sabes, el día %{created_at_day} del %{created_at_month} creaste la propuesta en modo borrador %{title} en la plataforma Decide Madrid." + text_1: "Cuando quieras puedes publicar en este enlace: %{link_to_published}. Si aún no lo tienes claro…" + text_2: "¡aprovecha este momento! Aprende, suma a otras personas con los mismos intereses y prepara la difusión que necesitarás al publicar tu propuesta definitivamente." + text_3: "Y para acompañarte en este reto, aquí van las novedades..." + text_4: "Échale un vistazo a esta NUEVA ACCIÓN recomendada:" + text_5: "La siguiente acción que te recomendamos es:" + footer_text: "Como siempre, entra en el Panel de propuestas y te contamos detalladamente cómo utilizar estos recursos y cómo sacarle el máximo partido." + dashboard_button: "Adelante, ¡descúbrelos!" + new_actions_notification_rake_published: + subject: "Más novedades de tu propuesta ciudadana en Decide Madrid" + hi: "Hola %{name}," + new_resource: "NUEVO RECURSO DESBLOQUEADO" + introduction: "Como sabes, el día %{published_at_day} del %{published_at_month} publicaste la propuesta %{title} en la plataforma Decide Madrid." + text_1: "Pues bien, has conseguido %{votes_count} apoyos hasta este momento ¡Felicidades!" + text_2: "Y por eso, tienes disponible un nuevo recurso para ayudarte a seguir avanzando." + text_3: "Te faltan %{days_count} días para que tu propuesta consiga los %{max_votes_count} apoyos y que vaya a referéndum. Ánimo y sigue difundiendo. ¿Te faltan ideas?" + text_4: "NUEVA ACCIÓN DE DIFUSIÓN RECOMENDADA" + text_5: "Aún hay más, consulta la siguiente acción:" + footer_text: "Como siempre, entra en el Panel de propuestas y te contamos detalladamente cómo utilizar estos recursos y cómo sacarle el máximo partido." + dashboard_button: "Adelante, ¡descúbrelos!" new_actions_notification_on_create: subject: "Tu borrador de propuesta ciudadana en Decide Madrid está creado" hi: "Hola %{name}!" diff --git a/config/schedule.rb b/config/schedule.rb index f4c03fd61..16420a765 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -26,3 +26,7 @@ end every 1.day, at: '5:00 am' do rake "-s sitemap:refresh" end + +every 1.day, at: '7:00 am' do + rake "dashboards:send_notifications" +end diff --git a/lib/tasks/dashboards.rake b/lib/tasks/dashboards.rake new file mode 100644 index 000000000..44a3954f8 --- /dev/null +++ b/lib/tasks/dashboards.rake @@ -0,0 +1,18 @@ +namespace :dashboards do + + desc "Send to user notifications from new actions availability on dashboard" + task send_notifications: :environment do + Proposal.not_archived.each do |proposal| + new_actions_ids = Dashboard::Action.detect_new_actions(proposal) + + if new_actions_ids.present? + if proposal.published? + Dashboard::Mailer.new_actions_notification_rake_published(proposal, new_actions_ids).deliver_later + else + Dashboard::Mailer.new_actions_notification_rake_created(proposal, new_actions_ids).deliver_later + end + end + end + end + +end diff --git a/spec/lib/tasks/dashboards_spec.rb b/spec/lib/tasks/dashboards_spec.rb new file mode 100644 index 000000000..434f2b249 --- /dev/null +++ b/spec/lib/tasks/dashboards_spec.rb @@ -0,0 +1,83 @@ +require "rails_helper" +require "rake" + +describe "Dashboards Rake" do + + describe "#send_notifications" do + + before do + Rake.application.rake_require "tasks/dashboards" + Rake::Task.define_task(:environment) + ActionMailer::Base.deliveries.clear + end + + let :run_rake_task do + Rake::Task["dashboards:send_notifications"].reenable + Rake.application.invoke_task "dashboards:send_notifications" + end + + describe "Not send notifications to proposal author" do + + let!(:action) { create(:dashboard_action, :proposed_action, :active, day_offset: 1) } + let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 1) } + + it "when there are not news actions actived for published proposals" do + create(:proposal) + action.update(published_proposal: true) + resource.update(published_proposal: true) + + expect {run_rake_task}.to change { ActionMailer::Base.deliveries.count }.by(0) + end + + it "when there are not news actions actived for draft proposals" do + create(:proposal, :draft) + action.update(published_proposal: false) + resource.update(published_proposal: false) + + expect {run_rake_task}.to change { ActionMailer::Base.deliveries.count }.by(0) + end + + it "when there are news actions actived for archived proposals" do + create(:proposal, :archived) + action.update(day_offset: 0, published_proposal: true) + resource.update(day_offset: 0, published_proposal: true) + + expect {run_rake_task}.to change { ActionMailer::Base.deliveries.count }.by(0) + end + + end + + describe "Send notifications to proposal author" do + let!(:action) { create(:dashboard_action, :proposed_action, :active, day_offset: 0) } + let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 0) } + + it " when there are news actions actived for published proposals" do + proposal = create(:proposal) + action.update(published_proposal: true) + resource.update(published_proposal: true) + + run_rake_task + email = open_last_email + + expect(email).to deliver_from("CONSUL ") + expect(email).to deliver_to(proposal.author) + expect(email).to have_subject("More news about your citizen proposal in Decide Madrid") + end + + it "when there are news actions actived for draft proposals" do + proposal = create(:proposal, :draft) + action.update(published_proposal: false) + resource.update(published_proposal: false) + + run_rake_task + email = open_last_email + + expect(email).to deliver_from("CONSUL ") + expect(email).to deliver_to(proposal.author) + expect(email).to have_subject("More news about your citizen proposal in Decide Madrid") + end + end + + end + +end diff --git a/spec/mailers/dashboard/mailer_spec.rb b/spec/mailers/dashboard/mailer_spec.rb index d4d3a660e..d407138a0 100644 --- a/spec/mailers/dashboard/mailer_spec.rb +++ b/spec/mailers/dashboard/mailer_spec.rb @@ -2,6 +2,83 @@ require "rails_helper" describe Dashboard::Mailer do + let!(:action) { create(:dashboard_action, :proposed_action, :active, + day_offset: 0, + published_proposal: true) } + let!(:resource) { create(:dashboard_action, :resource, :active, + day_offset: 0, + published_proposal: true) } + + describe "#new_actions_notification rake task" do + + before do + Rake.application.rake_require "tasks/dashboards" + Rake::Task.define_task(:environment) + ActionMailer::Base.deliveries.clear + end + + let :run_rake_task do + Rake::Task["dashboards:send_notifications"].reenable + Rake.application.invoke_task "dashboards:send_notifications" + end + + describe "#new_actions_notification_rake_created" do + let!(:proposal) { create(:proposal, :draft) } + + it "sends emails when detect new actions for draft proposal" do + action.update(published_proposal: false) + resource.update(published_proposal: false) + run_rake_task + + email = open_last_email + + expect(email).to deliver_from("CONSUL ") + expect(email).to deliver_to(proposal.author) + expect(email).to have_subject("More news about your citizen proposal in Decide Madrid") + expect(email).to have_body_text("Hello #{proposal.author.name},") + expect(email).to have_body_text("As you know, on the #{proposal.created_at.day} day of the #{proposal.created_at.strftime("%B")} you created the proposal in draft mode #{proposal.title} on the Decide Madrid platform.") + expect(email).to have_body_text("Whenever you want you can publish on this link:") + expect(email).to have_body_text("Seize this moment! Learn, add other people with the same interests and prepare the diffusion that you will need when you publish your proposal definitively.") + expect(email).to have_body_text("And to accompany you in this challenge, here are the news...") + expect(email).to have_body_text("NEW UNLOCKED RESOURCE") + expect(email).to have_body_text("#{resource.title}") + expect(email).to have_body_text("Take a look at this NEW recommended ACTION:") + expect(email).to have_body_text("#{action.title}") + expect(email).to have_body_text("#{action.description}") + expect(email).to have_body_text("As always, enter the Proposals Panel and we will tell you in detail how to use these resources and how to get the most out of it.") + expect(email).to have_body_text("Go ahead, discover them!") + end + end + + describe "#new_actions_notification_rake_published" do + let!(:proposal) { create(:proposal) } + + it "sends emails when detect new actions for proposal" do + run_rake_task + + email = open_last_email + + expect(email).to deliver_from("CONSUL ") + expect(email).to deliver_to(proposal.author) + expect(email).to have_subject("More news about your citizen proposal in Decide Madrid") + expect(email).to have_body_text("Hello #{proposal.author.name},") + expect(email).to have_body_text("As you know, on the #{proposal.published_at.day} day of the #{proposal.published_at.strftime("%B")} you published the proposal #{proposal.title} on the Decide Madrid platform.") + expect(email).to have_body_text("And so, you have a new resource available to help you keep moving forward.") + expect(email).to have_body_text("NEW UNLOCKED RESOURCE") + expect(email).to have_body_text("#{resource.title}") + + limit_to_archive_proposal = proposal.created_at.to_date + Setting["months_to_archive_proposals"].to_i.months + days_count = (limit_to_archive_proposal - Date.today).to_i + expect(email).to have_body_text("You are missing #{days_count} days before your proposal gets the #{Setting["votes_for_proposal_success"]} supports and goes to referendum. Cheer up and keep spreading. Are you short of ideas?") + expect(email).to have_body_text("NEW RECOMMENDED DIFFUSION ACTION") + expect(email).to have_body_text("#{action.title}") + expect(email).to have_body_text("#{action.description}") + expect(email).to have_body_text("As always, enter the Proposals Panel and we will tell you in detail how to use these resources and how to get the most out of it.") + expect(email).to have_body_text("Go ahead, discover them!") + end + end + end + describe "#new_actions_notification_on_create" do before do @@ -9,12 +86,6 @@ describe Dashboard::Mailer do end let!(:proposal) { build(:proposal, :draft) } - let!(:action) { create(:dashboard_action, :proposed_action, :active, - day_offset: 0, - published_proposal: true) } - let!(:resource) { create(:dashboard_action, :resource, :active, - day_offset: 0, - published_proposal: true) } it "sends emails when detect new actions when create a proposal" do action.update(published_proposal: false) diff --git a/spec/mailers/previews/dashboard_mailer_preview.rb b/spec/mailers/previews/dashboard_mailer_preview.rb index 5e6ce05f4..8cf2f99c3 100644 --- a/spec/mailers/previews/dashboard_mailer_preview.rb +++ b/spec/mailers/previews/dashboard_mailer_preview.rb @@ -4,6 +4,20 @@ class DashboardMailerPreview < ActionMailer::Preview Dashboard::Mailer.forward(proposal) end + # http://localhost:3000/rails/mailers/dashboard_mailer/new_actions_notification_rake_published + def new_actions_notification_rake_published + proposal = Proposal.where(published: true).first + new_actions_ids = Dashboard::Action.limit(1).id + Dashboard::Mailer.new_actions_notification(proposal, [new_actions_ids]) + end + + # http://localhost:3000/rails/mailers/dashboard_mailer/new_actions_notification_rake_created + def new_actions_notification_rake_created + proposal = Proposal.where(published: false).first + new_actions_ids = Dashboard::Action.limit(1).id + Dashboard::Mailer.new_actions_notification(proposal, [new_actions_ids]) + end + # http://localhost:3000/rails/mailers/dashboard_mailer/new_actions_notification_on_create def new_actions_notification_on_create proposal = Proposal.first diff --git a/spec/models/dashboard/action_spec.rb b/spec/models/dashboard/action_spec.rb index ca813cd06..bf9a85110 100644 --- a/spec/models/dashboard/action_spec.rb +++ b/spec/models/dashboard/action_spec.rb @@ -275,8 +275,8 @@ describe Dashboard::Action do let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 0, published_proposal: true) } it "when proposal has been created today and day_offset is valid only for today" do - expect(described_class.detect_new_actions(proposal)).to include(resource) - expect(described_class.detect_new_actions(proposal)).to include(action) + expect(described_class.detect_new_actions(proposal)).to include(resource.id) + expect(described_class.detect_new_actions(proposal)).to include(action.id) end it "when proposal has received a new vote today" do @@ -285,8 +285,8 @@ describe Dashboard::Action do resource.update(required_supports: 0) create(:vote, voter: proposal.author, votable: proposal) - expect(described_class.detect_new_actions(proposal)).to include(action) - expect(described_class.detect_new_actions(proposal)).not_to include(resource) + expect(described_class.detect_new_actions(proposal)).to include(action.id) + expect(described_class.detect_new_actions(proposal)).not_to include(resource.id) end end @@ -298,8 +298,8 @@ describe Dashboard::Action do let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 0, published_proposal: false) } it "when day_offset field is valid for today and invalid for yesterday" do - expect(described_class.detect_new_actions(proposal)).to include(resource) - expect(described_class.detect_new_actions(proposal)).to include(action) + expect(described_class.detect_new_actions(proposal)).to include(resource.id) + expect(described_class.detect_new_actions(proposal)).to include(action.id) end it "when proposal has received a new vote today" do @@ -308,8 +308,8 @@ describe Dashboard::Action do resource.update(required_supports: 2) create(:vote, voter: proposal.author, votable: proposal) - expect(described_class.detect_new_actions(proposal)).to include(action) - expect(described_class.detect_new_actions(proposal)).not_to include(resource) + expect(described_class.detect_new_actions(proposal)).to include(action.id) + expect(described_class.detect_new_actions(proposal)).not_to include(resource.id) end end