Skip to content
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

Use capture_emails helper to improve email assertions in specs #29245

Merged
merged 2 commits into from
Feb 19, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 17 additions & 8 deletions spec/controllers/admin/disputes/appeals_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,21 @@
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }

it 'redirects back to the strike page and notifies target account about approved appeal', :sidekiq_inline do
subject
emails = capture_emails { subject }

expect(response)
.to redirect_to(disputes_strike_path(appeal.strike))

expect(target_account.reload)
.to_not be_suspended

expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at)))
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(target_account.user.email),
subject: eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at)))
)
end
end

Expand All @@ -55,14 +59,19 @@
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }

it 'redirects back to the strike page and notifies target account about rejected appeal', :sidekiq_inline do
subject
emails = capture_emails { subject }

expect(response)
.to redirect_to(disputes_strike_path(appeal.strike))

expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at)))
expect(emails.size)
.to eq(1)

expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(target_account.user.email),
subject: eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at)))
)
end
end
end
10 changes: 6 additions & 4 deletions spec/controllers/admin/resets_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
describe Admin::ResetsController do
render_views

subject { post :create, params: { account_id: account.id } }

let(:account) { Fabricate(:account) }

before do
Expand All @@ -13,11 +15,11 @@

describe 'POST #create', :sidekiq_inline do
it 'redirects to admin accounts page' do
expect do
post :create, params: { account_id: account.id }
end.to change(Devise.mailer.deliveries, :size).by(2)
emails = capture_emails { subject }

expect(Devise.mailer.deliveries).to have_attributes(
expect(emails.size)
.to eq(2)
expect(emails).to have_attributes(
first: have_attributes(
to: include(account.user.email),
subject: I18n.t('devise.mailer.password_change.subject')
Expand Down
34 changes: 22 additions & 12 deletions spec/controllers/auth/sessions_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,21 @@
end

it 'logs the user in and sends suspicious email and redirects home', :sidekiq_inline do
subject
emails = capture_emails { subject }

expect(response)
.to redirect_to(root_path)

expect(controller.current_user)
.to eq user

expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.suspicious_sign_in.subject'))
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(user.email),
subject: eq(I18n.t('user_mailer.suspicious_sign_in.subject'))
)
end
end

Expand Down Expand Up @@ -260,21 +264,27 @@
end

it 'does not log the user in, sets a flash message, and sends a suspicious sign in email', :sidekiq_inline do
Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
emails = capture_emails do
Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
end
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end

post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }

expect(controller.current_user)
.to be_nil

expect(flash[:alert])
.to match I18n.t('users.rate_limited')

expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.failed_2fa.subject'))
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(user.email),
subject: eq(I18n.t('user_mailer.failed_2fa.subject'))
)
end
end

Expand Down
16 changes: 11 additions & 5 deletions spec/controllers/disputes/appeals_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@
let(:params) { { strike_id: strike.id, appeal: { text: 'Foo' } } }

it 'notifies staff about new appeal and redirects back to strike page', :sidekiq_inline do
subject

expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
emails = capture_emails { subject }

expect(emails.size)
.to eq(1)
expect(emails.first)
.to have_attributes(
to: contain_exactly(admin.email),
subject: eq(I18n.t('admin_mailer.new_appeal.subject', username: current_user.account.acct, instance: Rails.configuration.x.local_domain))
)
expect(response).to redirect_to(disputes_strike_path(strike.id))
end
end
Expand All @@ -31,9 +37,9 @@
let(:params) { { strike_id: strike.id, appeal: { text: '' } } }

it 'does not send email and renders strike show page', :sidekiq_inline do
subject
emails = capture_emails { subject }

expect(ActionMailer::Base.deliveries.size).to eq(0)
expect(emails).to be_empty
expect(response).to render_template('disputes/strikes/show')
end
end
Expand Down
18 changes: 10 additions & 8 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -455,29 +455,31 @@

let!(:user) { Fabricate(:user, confirmed_at: confirmed_at) }

before { ActionMailer::Base.deliveries.clear }

after { ActionMailer::Base.deliveries.clear }

context 'when user is new' do
let(:confirmed_at) { nil }

it 'confirms user and delivers welcome email', :sidekiq_inline do
subject
emails = capture_emails { subject }

expect(user.confirmed_at).to be_present
expect(ActionMailer::Base.deliveries.count).to eq 1
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(user.email),
subject: eq(I18n.t('user_mailer.welcome.subject'))
)
end
end

context 'when user is not new' do
let(:confirmed_at) { Time.zone.now }

it 'confirms user but does not deliver welcome email' do
subject
emails = capture_emails { subject }

expect(user.confirmed_at).to be_present
expect(ActionMailer::Base.deliveries.count).to eq 0
expect(emails).to be_empty
end
end
end
Expand Down
1 change: 1 addition & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def sign_in(resource, _deprecated = nil, scope: nil)
config.include Devise::Test::ControllerHelpers, type: :view
config.include Devise::Test::IntegrationHelpers, type: :feature
config.include Devise::Test::IntegrationHelpers, type: :request
config.include ActionMailer::TestHelper
config.include Paperclip::Shoulda::Matchers
config.include ActiveSupport::Testing::TimeHelpers
config.include Chewy::Rspec::Helpers
Expand Down
10 changes: 8 additions & 2 deletions spec/requests/api/v1/reports_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

it 'creates a report', :aggregate_failures do
perform_enqueued_jobs do
subject
emails = capture_emails { subject }

expect(response).to have_http_status(200)
expect(body_as_json).to match(
Expand All @@ -49,7 +49,13 @@
expect(target_account.targeted_reports).to_not be_empty
expect(target_account.targeted_reports.first.comment).to eq 'reasons'

expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(admin.email),
subject: eq(I18n.t('admin_mailer.new_report.subject', instance: Rails.configuration.x.local_domain, id: target_account.targeted_reports.first.id))
)
end
end

Expand Down
16 changes: 12 additions & 4 deletions spec/services/notify_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@

describe 'email' do
before do
ActionMailer::Base.deliveries.clear

user.settings.update('notification_emails.follow': enabled)
user.save
end
Expand All @@ -167,15 +165,25 @@
let(:enabled) { true }

it 'sends email', :sidekiq_inline do
expect { subject }.to change(ActionMailer::Base.deliveries, :count).by(1)
emails = capture_emails { subject }

expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(user.email),
subject: eq(I18n.t('notification_mailer.follow.subject', name: sender.acct))
)
end
end

context 'when email notification is disabled' do
let(:enabled) { false }

it "doesn't send email" do
expect { subject }.to_not change(ActionMailer::Base.deliveries, :count).from(0)
emails = capture_emails { subject }

expect(emails).to be_empty
end
end
end
Expand Down
5 changes: 3 additions & 2 deletions spec/services/report_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,14 @@

before do
Fabricate(:report, target_account: target_account)
ActionMailer::Base.deliveries.clear
source_account.user.settings['notification_emails.report'] = true
source_account.user.save
end

it 'does not send an e-mail' do
expect { subject.call }.to_not change(ActionMailer::Base.deliveries, :count).from(0)
emails = capture_emails { subject.call }

expect(emails).to be_empty
end
end
end
11 changes: 8 additions & 3 deletions spec/workers/backup_worker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@
let!(:other_backup) { Fabricate(:backup, user: backup.user) }

it 'sends the backup to the service and removes other backups', :sidekiq_inline do
expect do
worker.perform(backup.id)
end.to change(UserMailer.deliveries, :size).by(1)
emails = capture_emails { worker.perform(backup.id) }

expect(service).to have_received(:call).with(backup)
expect { other_backup.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect(emails.size)
.to eq(1)
expect(emails.first)
mjankowski marked this conversation as resolved.
Show resolved Hide resolved
.to have_attributes(
to: contain_exactly(backup.user.email),
subject: I18n.t('user_mailer.backup_ready.subject')
)
end

context 'when sidekiq retries are exhausted' do
Expand Down