adds email digest for proposal notifications
This commit is contained in:
@@ -59,6 +59,14 @@ class Mailer < ApplicationMailer
|
|||||||
end
|
end
|
||||||
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
|
private
|
||||||
|
|
||||||
def with_user(user, &block)
|
def with_user(user, &block)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class User < ActiveRecord::Base
|
|||||||
scope :officials, -> { where("official_level > 0") }
|
scope :officials, -> { where("official_level > 0") }
|
||||||
scope :for_render, -> { includes(:organization) }
|
scope :for_render, -> { includes(:organization) }
|
||||||
scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) }
|
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
|
before_validation :clean_document_number
|
||||||
|
|
||||||
|
|||||||
@@ -11,41 +11,43 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- EACH PROPOSAL NOTIFICATION DO -->
|
<%= @notifications.each do |notification| %>
|
||||||
<table style="width: 100%; border-top: 1px solid #DEE0E3; padding-top: 12px;">
|
<table style="width: 100%; border-top: 1px solid #DEE0E3; padding-top: 12px;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-bottom: 20px; padding-left: 10px;">
|
<td style="padding-bottom: 20px; padding-left: 10px;">
|
||||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 20px;font-weight: bold;line-height: 24px; margin: 0;">
|
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 20px;font-weight: bold;line-height: 24px; margin: 0;">
|
||||||
<%= @notification.title %>
|
<%= link_to notification.notifiable.title, notification_url(notification) %>
|
||||||
</p>
|
</p>
|
||||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; margin-top: 0; color: #cccccc;">
|
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; margin-top: 0; color: #cccccc;">
|
||||||
<%= @notification.proposal.title %> • <%= @notification.proposal.created_at.to_date %> • <%= @notification.proposal.author.name %>
|
<%= notification.notifiable.proposal.title %> •
|
||||||
</p>
|
<%= notification.notifiable.proposal.created_at.to_date %> •
|
||||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
<%= notification.notifiable.proposal.author.name %>
|
||||||
<%= @notification.body %>
|
</p>
|
||||||
</p>
|
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||||
|
<%= notification.notifiable.body %>
|
||||||
|
</p>
|
||||||
|
|
||||||
<table style="width: 100%;">
|
<table style="width: 100%;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding-bottom: 12px;">
|
<td style="padding-bottom: 12px;">
|
||||||
<%= 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 %>
|
<%= 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: "") %>
|
<%= image_tag('icon_mailer_share.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px", alt: "") %>
|
||||||
<%= t('mailers.proposal_notification_digest.share') %>
|
<%= t('mailers.proposal_notification_digest.share') %>
|
||||||
<% end %>
|
<% 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 %>
|
<%= 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: "") %>
|
<%= 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') %>
|
<%= t('mailers.proposal_notification_digest.comment') %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<!-- END -->
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
5
db/migrate/20160613150659_add_email_digest_to_users.rb
Normal file
5
db/migrate/20160613150659_add_email_digest_to_users.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
class AddEmailDigestToUsers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :users, :email_digest, :boolean, default: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -460,6 +460,7 @@ ActiveRecord::Schema.define(version: 20160608174104) do
|
|||||||
t.string "gender", limit: 10
|
t.string "gender", limit: 10
|
||||||
t.datetime "date_of_birth"
|
t.datetime "date_of_birth"
|
||||||
t.boolean "email_on_proposal_notification", default: true
|
t.boolean "email_on_proposal_notification", default: true
|
||||||
|
t.boolean "email_digest", default: true
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
|
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
|
||||||
|
|||||||
14
lib/email_digest.rb
Normal file
14
lib/email_digest.rb
Normal file
@@ -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
|
||||||
9
lib/tasks/emails.rake
Normal file
9
lib/tasks/emails.rake
Normal file
@@ -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
|
||||||
@@ -136,7 +136,7 @@ FactoryGirl.define do
|
|||||||
|
|
||||||
factory :proposal do
|
factory :proposal do
|
||||||
sequence(:title) { |n| "Proposal #{n} title" }
|
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'
|
description 'Proposal description'
|
||||||
question 'Proposal question'
|
question 'Proposal question'
|
||||||
external_url 'http://external_documention.es'
|
external_url 'http://external_documention.es'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
feature 'Direct messages' do
|
feature 'Direct messages' do
|
||||||
|
|
||||||
scenario "Create", :focus do
|
scenario "Create" do
|
||||||
sender = create(:user, :level_two)
|
sender = create(:user, :level_two)
|
||||||
receiver = create(:user, :level_two)
|
receiver = create(:user, :level_two)
|
||||||
|
|
||||||
|
|||||||
@@ -204,4 +204,51 @@ feature 'Emails' do
|
|||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -51,6 +51,53 @@ feature 'Proposal Notifications' do
|
|||||||
expect(page).to have_link("the proposal's page", href: proposal_path(proposal))
|
expect(page).to have_link("the proposal's page", href: proposal_path(proposal))
|
||||||
end
|
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
|
context "Permissions" do
|
||||||
|
|
||||||
scenario "Link to send the message" do
|
scenario "Link to send the message" do
|
||||||
|
|||||||
9
spec/lib/email_digests_spec.rb
Normal file
9
spec/lib/email_digests_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe EmailDigest do
|
||||||
|
|
||||||
|
describe "create" do
|
||||||
|
pending "only send unread notifications"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -196,4 +196,22 @@ module CommonActions
|
|||||||
tag_cloud.tags.map(&:name)
|
tag_cloud.tags.map(&:name)
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user