Skip to content

send weekly digest email in user's locale #556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions app/jobs/organization_notifier_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Strategy: go throught all organizations and take latest active posts from last week
# posted by active members. Send an email to all active and online members
# with the email notifications enabled with those posts.
# with the email notifications enabled with those posts. Group emails by user's locale.

# Schedule defined in config/schedule.yml file.

Expand All @@ -12,9 +12,23 @@ class OrganizationNotifierJob < ActiveJob::Base
def perform
Organization.all.find_each do |org|
posts = org.posts.active.of_active_members.from_last_week

if posts.present?
OrganizationNotifier.recent_posts(posts).deliver_now
users_by_locale(org).each do |locale, users|
OrganizationNotifier.recent_posts(posts, locale, users).deliver_now
end
end
end
end

private

def users_by_locale(organization)
with_notifications = organization.users.online_active.actives.notifications
org_locales = with_notifications.pluck(:locale).uniq

org_locales.each_with_object({}) do |locale, hash|
hash[locale] = with_notifications.where(locale: locale)
end
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

end
18 changes: 4 additions & 14 deletions app/mailers/organization_notifier.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
class OrganizationNotifier < ActionMailer::Base
default from: "\"TimeOverflow\" <info@timeoverflow.org>"

# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.organization_notifier.recent_posts.subject
#
def recent_posts(posts)
def recent_posts(posts, locale, users)
# last 10 posts of offers and inquiries
@offers = posts.where(type: "Offer").take(10)
@inquiries = posts.where(type: "Inquiry").take(10)

@organization_name = posts.take.organization.name

mail(bcc: emails_newsletter(posts))
end

private

def emails_newsletter(posts)
posts.take.organization.users.online_active.actives.
notifications.pluck(:email)
I18n.with_locale(locale) do
mail(bcc: users.map(&:email))
end
end
end
19 changes: 19 additions & 0 deletions spec/jobs/organization_notifier_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'spec_helper'

RSpec.describe OrganizationNotifierJob, type: :job do
let!(:org) { Fabricate(:organization) }
let!(:user) { Fabricate(:user, locale: :en, sign_in_count: 1) }
let!(:member) { Fabricate(:member, organization: org, user: user) }
let!(:user2) { Fabricate(:user, locale: :ca, sign_in_count: 2) }
let!(:member2) { Fabricate(:member, organization: org, user: user2) }
let!(:offer) { Fabricate(:offer, organization: org, user: user) }
let!(:inquiry) { Fabricate(:inquiry, organization: org, user: user2) }

describe '#perform' do
it "should send emails in user's locale" do
expect {
OrganizationNotifierJob.perform_now
}.to change { ActionMailer::Base.deliveries.count }.by(2)
end
end
end
50 changes: 10 additions & 40 deletions spec/mailers/organization_notifier_spec.rb
Original file line number Diff line number Diff line change
@@ -1,60 +1,30 @@
require "spec_helper"

RSpec.describe OrganizationNotifier do
let (:test_organization) { Fabricate(:organization) }
let! (:offer) { Fabricate(:offer, organization: test_organization) }
let! (:inquiry) { Fabricate(:inquiry, organization: test_organization) }
let (:user) do
Fabricate(:user, sign_in_count: 2, email: "user@example.com")
end
let (:another_user) { Fabricate(:user, sign_in_count: 1) }
let (:yet_another_user) { Fabricate(:user, sign_in_count: 0) }
let! (:member) do
Fabricate(:member,
organization: test_organization,
user: user,
active: true)
end
let! (:another_member) do
Fabricate(:member,
organization: test_organization,
user: another_user,
active: false)
end
let! (:yet_another_member) do
Fabricate(:member,
organization: test_organization,
user: yet_another_user,
active: true)
end

before(:each) do
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
OrganizationNotifier.recent_posts(test_organization.posts).deliver_now
end

after(:each) do
ActionMailer::Base.deliveries.clear
end
let(:test_organization) { Fabricate(:organization) }
let!(:offer) { Fabricate(:offer, organization: test_organization) }
let!(:inquiry) { Fabricate(:inquiry, organization: test_organization) }
let(:user) { Fabricate(:user, email: "user@example.com", locale: :en) }
let(:member) { Fabricate(:member, organization: test_organization, user: user) }

describe "send an email" do
it "should send an email" do
expect(ActionMailer::Base.deliveries.count).to eq(1)
expect {
OrganizationNotifier.recent_posts(test_organization.posts, :en, [user]).deliver_now
}.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end

describe "recent posts" do
let(:mail) { OrganizationNotifier.recent_posts(test_organization.posts) }
let(:mail) { OrganizationNotifier.recent_posts(test_organization.posts, :en, [user]) }

it "receive email only active and online users" do
expect(mail.bcc).to eql(["user@example.com"])
end
it "to should be null" do
expect(mail.to).to be_nil
end
it "assigns @organization_name" do
it "body contains organization name" do
expect(mail.body.encoded).to match(test_organization.name)
end
end
Expand Down