With this commit we are logging which emails have already received the newsletter This could be important if something goes wrong sending the newsletter, to be able to identify which users have already received the newsletter and be able to skip them We’ve had to add a new action to the Activity model (email) and add paranoia features to be able to deal gracefully with the default `with_hidden` scope in Activities[1] [1] https://github.com/AyuntamientoMadrid/consul/blob/master/app/models/acti vity.rb#L2
158 lines
4.8 KiB
Ruby
158 lines
4.8 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe Newsletter do
|
|
let(:newsletter) { build(:newsletter) }
|
|
|
|
it "is valid" do
|
|
expect(newsletter).to be_valid
|
|
end
|
|
|
|
it 'is not valid without a subject' do
|
|
newsletter.subject = nil
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
it 'is not valid without a segment_recipient' do
|
|
newsletter.segment_recipient = nil
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
it 'is not valid with an inexistent user segment for segment_recipient' do
|
|
newsletter.segment_recipient = 'invalid_user_segment_name'
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
it 'is not valid without a from' do
|
|
newsletter.from = nil
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
it 'is not valid without a body' do
|
|
newsletter.body = nil
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
it 'validates from attribute email format' do
|
|
newsletter.from = "this_is_not_an_email"
|
|
expect(newsletter).not_to be_valid
|
|
end
|
|
|
|
describe '#valid_segment_recipient?' do
|
|
it 'is false when segment_recipient value is invalid' do
|
|
newsletter.update(segment_recipient: 'invalid_segment_name')
|
|
error = 'The user recipients segment is invalid'
|
|
|
|
expect(newsletter).not_to be_valid
|
|
expect(newsletter.errors.messages[:segment_recipient]).to include(error)
|
|
end
|
|
end
|
|
|
|
describe '#list_of_recipient_emails' do
|
|
|
|
before do
|
|
create(:user, newsletter: true, email: 'newsletter_user@consul.dev')
|
|
create(:user, newsletter: false, email: 'no_news_user@consul.dev')
|
|
create(:user, email: 'erased_user@consul.dev').erase
|
|
newsletter.update(segment_recipient: 'all_users')
|
|
end
|
|
|
|
it 'returns list of recipients excluding users with disabled newsletter' do
|
|
expect(newsletter.list_of_recipient_emails.count).to eq(1)
|
|
expect(newsletter.list_of_recipient_emails).to include('newsletter_user@consul.dev')
|
|
expect(newsletter.list_of_recipient_emails).not_to include('no_news_user@consul.dev')
|
|
expect(newsletter.list_of_recipient_emails).not_to include('erased_user@consul.dev')
|
|
end
|
|
end
|
|
|
|
describe "#deliver" do
|
|
let!(:proposals) { Array.new(3) { create(:proposal) } }
|
|
let!(:debate) { create(:debate) }
|
|
|
|
let!(:recipients) { proposals.map(&:author).map(&:email) }
|
|
let!(:newsletter) { create(:newsletter, segment_recipient: "proposal_authors") }
|
|
|
|
before do
|
|
reset_mailer
|
|
Delayed::Worker.delay_jobs = true
|
|
end
|
|
|
|
after do
|
|
Delayed::Worker.delay_jobs = false
|
|
end
|
|
|
|
it "sends an email with the newsletter to every recipient" do
|
|
newsletter.deliver
|
|
|
|
recipients.each do |recipient|
|
|
email = Mailer.newsletter(newsletter, recipient)
|
|
expect(email).to deliver_to(recipient)
|
|
end
|
|
|
|
Delayed::Job.all.map(&:invoke_job)
|
|
expect(ActionMailer::Base.deliveries.count).to eq(3)
|
|
end
|
|
|
|
it "sends emails in batches" do
|
|
allow(newsletter).to receive(:batch_size).and_return(1)
|
|
|
|
newsletter.deliver
|
|
|
|
expect(Delayed::Job.count).to eq(3)
|
|
end
|
|
|
|
it "sends batches in time intervals" do
|
|
allow(newsletter).to receive(:batch_size).and_return(1)
|
|
allow(newsletter).to receive(:batch_interval).and_return(1.second)
|
|
allow(newsletter).to receive(:first_batch_run_at).and_return(Time.current)
|
|
|
|
newsletter.deliver
|
|
|
|
now = newsletter.first_batch_run_at
|
|
first_batch_run_at = now.change(usec: 0)
|
|
second_batch_run_at = (now + 1.second).change(usec: 0)
|
|
third_batch_run_at = (now + 2.seconds).change(usec: 0)
|
|
|
|
expect(Delayed::Job.count).to eq(3)
|
|
expect(Delayed::Job.first.run_at.change(usec: 0)).to eq(first_batch_run_at)
|
|
expect(Delayed::Job.second.run_at.change(usec: 0)).to eq(second_batch_run_at)
|
|
expect(Delayed::Job.third.run_at.change(usec: 0)).to eq(third_batch_run_at)
|
|
end
|
|
|
|
it "logs users that have received the newsletter" do
|
|
newsletter.deliver
|
|
|
|
expect(Activity.count).to eq(3)
|
|
|
|
recipients.each do |email|
|
|
user = User.where(email: email).first
|
|
activity = Activity.where(user: user).first
|
|
|
|
expect(activity.user_id).to eq(user.id)
|
|
expect(activity.action).to eq("email")
|
|
expect(activity.actionable).to eq(newsletter)
|
|
end
|
|
end
|
|
|
|
it "skips invalid emails" do
|
|
Proposal.destroy_all
|
|
|
|
valid_email = "john@gmail.com"
|
|
invalid_email = "john@gmail..com"
|
|
|
|
valid_email_user = create(:user, email: valid_email)
|
|
proposal = create(:proposal, author: valid_email_user)
|
|
|
|
invalid_email_user = create(:user, email: invalid_email)
|
|
proposal = create(:proposal, author: invalid_email_user)
|
|
|
|
newsletter.deliver
|
|
|
|
expect(Activity.count).to eq(1)
|
|
expect(Activity.first.user_id).to eq(valid_email_user.id)
|
|
expect(Activity.first.action).to eq("email")
|
|
expect(Activity.first.actionable).to eq(newsletter)
|
|
end
|
|
|
|
end
|
|
end
|