diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 2a81c4bfe..d900fd17d 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -59,6 +59,14 @@ class Mailer < ApplicationMailer end end + def proposal_notification_digest(user) + @notifications = user.notifications.where(notifiable_type: "ProposalNotification") + + with_user(user) do + mail(to: user.email, subject: "Email digest") + end + end + private def with_user(user, &block) diff --git a/app/models/user.rb b/app/models/user.rb index 243781cb3..a3b719859 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -51,6 +51,7 @@ class User < ActiveRecord::Base scope :officials, -> { where("official_level > 0") } scope :for_render, -> { includes(:organization) } scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) } + scope :email_digest, -> { where(email_digest: true) } before_validation :clean_document_number diff --git a/app/views/mailer/proposal_notification_digest.html.erb b/app/views/mailer/proposal_notification_digest.html.erb index 4733d900e..16e96260c 100644 --- a/app/views/mailer/proposal_notification_digest.html.erb +++ b/app/views/mailer/proposal_notification_digest.html.erb @@ -11,41 +11,43 @@ - - - - - + + +
-

- <%= @notification.title %> -

-

- <%= @notification.proposal.title %> • <%= @notification.proposal.created_at.to_date %> • <%= @notification.proposal.author.name %> -

-

- <%= @notification.body %> -

+ <%= @notifications.each do |notification| %> + + + + + + +
+

+ <%= link_to notification.notifiable.title, notification_url(notification) %> +

+

+ <%= notification.notifiable.proposal.title %> •  + <%= notification.notifiable.proposal.created_at.to_date %> •  + <%= notification.notifiable.proposal.author.name %> +

+

+ <%= notification.notifiable.body %> +

- - - - - - -
- <%= link_to "#comments", style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block;" do %> - <%= image_tag('icon_mailer_share.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px", alt: "") %> - <%= t('mailers.proposal_notification_digest.share') %> - <% end %> + + + + - - -
+ <%= link_to proposal_url(notification.notifiable.proposal, anchor: "comments"), style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block;" do %> + <%= image_tag('icon_mailer_share.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px", alt: "") %> + <%= t('mailers.proposal_notification_digest.share') %> + <% end %> - <%= link_to "#social-share", style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block; margin-left: 12px;" do %> - <%= image_tag('icon_mailer_comment.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px; vertical-align: middle;", alt: "") %> - <%= t('mailers.proposal_notification_digest.comment') %> - <% end %> -
-
- + <%= link_to proposal_url(notification.notifiable.proposal, anchor: "social-share"), style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block; margin-left: 12px;" do %> + <%= image_tag('icon_mailer_comment.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px; vertical-align: middle;", alt: "") %> + <%= t('mailers.proposal_notification_digest.comment') %> + <% end %> +
+
+ <% end %> diff --git a/db/migrate/20160613150659_add_email_digest_to_users.rb b/db/migrate/20160613150659_add_email_digest_to_users.rb new file mode 100644 index 000000000..d127af78e --- /dev/null +++ b/db/migrate/20160613150659_add_email_digest_to_users.rb @@ -0,0 +1,5 @@ +class AddEmailDigestToUsers < ActiveRecord::Migration + def change + add_column :users, :email_digest, :boolean, default: true + end +end diff --git a/db/schema.rb b/db/schema.rb index bbd6dda8f..c4fddf324 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160608174104) do +ActiveRecord::Schema.define(version: 20160613150659) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -460,6 +460,7 @@ ActiveRecord::Schema.define(version: 20160608174104) do t.string "gender", limit: 10 t.datetime "date_of_birth" t.boolean "email_on_proposal_notification", default: true + t.boolean "email_digest", default: true end add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree diff --git a/lib/email_digest.rb b/lib/email_digest.rb new file mode 100644 index 000000000..90838f78f --- /dev/null +++ b/lib/email_digest.rb @@ -0,0 +1,14 @@ +class EmailDigest + + def initialize + end + + def create + User.email_digest.each do |user| + if user.notifications.where(notifiable_type: "ProposalNotification").any? + Mailer.proposal_notification_digest(user).deliver_later + end + end + end + +end \ No newline at end of file diff --git a/lib/tasks/emails.rake b/lib/tasks/emails.rake new file mode 100644 index 000000000..6670264a5 --- /dev/null +++ b/lib/tasks/emails.rake @@ -0,0 +1,9 @@ +namespace :emails do + + desc "Sends email digest of proposal notifications to each user" + task digest: :environment do + email_digest = EmailDigest.new + email_digest.create + end + +end diff --git a/spec/factories.rb b/spec/factories.rb index ef9c56c47..4ead8ecac 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -136,7 +136,7 @@ FactoryGirl.define do factory :proposal do sequence(:title) { |n| "Proposal #{n} title" } - summary 'In summary, what we want is...' + sequence(:summary) { |n| "In summary, what we want is... #{n}" } description 'Proposal description' question 'Proposal question' external_url 'http://external_documention.es' diff --git a/spec/features/direct_messages_spec.rb b/spec/features/direct_messages_spec.rb index d9301a29e..142be8cbb 100644 --- a/spec/features/direct_messages_spec.rb +++ b/spec/features/direct_messages_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' feature 'Direct messages' do - scenario "Create", :focus do + scenario "Create" do sender = create(:user, :level_two) receiver = create(:user, :level_two) diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb index ec8ff7b5f..5894d40ed 100644 --- a/spec/features/emails_spec.rb +++ b/spec/features/emails_spec.rb @@ -204,4 +204,51 @@ feature 'Emails' do end end + context "Proposal notification digest" do + + scenario "notifications for proposals that I have supported" do + user = create(:user, email_digest: true) + + proposal1 = create(:proposal) + proposal2 = create(:proposal) + proposal3 = create(:proposal) + + create(:vote, votable: proposal1, voter: user) + create(:vote, votable: proposal2, voter: user) + + reset_mailer + + notification1 = create_proposal_notification(proposal1) + notification2 = create_proposal_notification(proposal2) + notification3 = create_proposal_notification(proposal3) + + email_digest = EmailDigest.new + email_digest.create + + email = open_last_email + expect(email).to have_subject("Email digest") + expect(email).to deliver_to(user.email) + + expect(email).to have_body_text(proposal1.title) + expect(email).to have_body_text(notification1.notifiable.title) + expect(email).to have_body_text(notification1.notifiable.body) + expect(email).to have_body_text(proposal1.author.name) + + expect(email).to have_body_text(/#{notification_path(notification1)}/) + expect(email).to have_body_text(/#{proposal_path(proposal1, anchor: 'comments')}/) + expect(email).to have_body_text(/#{proposal_path(proposal1, anchor: 'social-share')}/) + + expect(email).to have_body_text(proposal2.title) + expect(email).to have_body_text(notification2.notifiable.title) + expect(email).to have_body_text(notification2.notifiable.body) + expect(email).to have_body_text(/#{notification_path(notification2)}/) + expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'comments')}/) + expect(email).to have_body_text(/#{proposal_path(proposal2, anchor: 'social-share')}/) + expect(email).to have_body_text(proposal2.author.name) + + expect(email).to_not have_body_text(proposal3.title) + end + + end + end diff --git a/spec/features/proposal_notifications_spec.rb b/spec/features/proposal_notifications_spec.rb index be8b146fd..7785a1236 100644 --- a/spec/features/proposal_notifications_spec.rb +++ b/spec/features/proposal_notifications_spec.rb @@ -51,6 +51,53 @@ feature 'Proposal Notifications' do expect(page).to have_link("the proposal's page", href: proposal_path(proposal)) end + context "Receivers" do + + scenario "Only send a digest to users that have the option set in their profile" do + user1 = create(:user, email_digest: true) + user2 = create(:user, email_digest: true) + user3 = create(:user, email_digest: false) + + proposal = create(:proposal) + + [user1, user2, user3].each do |user| + create(:vote, votable: proposal, voter: user) + end + + create_proposal_notification(proposal) + + reset_mailer + email_digest = EmailDigest.new + email_digest.create + + expect(unread_emails_for(user1.email).size).to eql parse_email_count(1) + expect(unread_emails_for(user2.email).size).to eql parse_email_count(1) + expect(unread_emails_for(user3.email).size).to eql parse_email_count(0) + end + + scenario "Only send a digest to users that have voted for a proposal" do + user1 = create(:user, email_digest: true) + user2 = create(:user, email_digest: true) + user3 = create(:user, email_digest: true) + + proposal = create(:proposal) + + [user1, user2].each do |user| + create(:vote, votable: proposal, voter: user) + end + + create_proposal_notification(proposal) + + reset_mailer + email_digest = EmailDigest.new + email_digest.create + + expect(unread_emails_for(user1.email).size).to eql parse_email_count(1) + expect(unread_emails_for(user2.email).size).to eql parse_email_count(1) + expect(unread_emails_for(user3.email).size).to eql parse_email_count(0) + end + + end context "Permissions" do scenario "Link to send the message" do diff --git a/spec/lib/email_digests_spec.rb b/spec/lib/email_digests_spec.rb new file mode 100644 index 000000000..6fc6eef53 --- /dev/null +++ b/spec/lib/email_digests_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +describe EmailDigest do + + describe "create" do + pending "only send unread notifications" + end + +end \ No newline at end of file diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index 18a3f9499..39faf03f5 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -196,4 +196,22 @@ module CommonActions tag_cloud.tags.map(&:name) end + def create_proposal_notification(proposal) + login_as(proposal.author) + visit root_path + + click_link "My activity" + + within("#proposal_#{proposal.id}") do + click_link "Send message" + end + + fill_in 'proposal_notification_title', with: "Thank you for supporting my proposal #{proposal.title}" + fill_in 'proposal_notification_body', with: "Please share it with others so we can make it happen! #{proposal.summary}" + click_button "Send message" + + expect(page).to have_content "Your message has been sent correctly." + Notification.last + end + end