Replace email_spec gem with built-in matchers (#38079)

This commit is contained in:
Matt Jankowski
2026-03-05 09:42:21 -05:00
committed by GitHub
parent 5d4271a3cc
commit 4e3866dbaf
18 changed files with 231 additions and 241 deletions

View File

@@ -129,9 +129,6 @@ group :test do
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
gem 'rspec-github', '~> 3.0', require: false
# RSpec helpers for email specs
gem 'email_spec'
# Extra RSpec extension methods and helpers for sidekiq
gem 'rspec-sidekiq', '~> 5.0'

View File

@@ -224,10 +224,6 @@ GEM
base64
faraday (>= 1, < 3)
multi_json
email_spec (2.3.0)
htmlentities (~> 4.3.3)
launchy (>= 2.1, < 4.0)
mail (~> 2.7)
email_validator (2.2.4)
activemodel
erb (6.0.2)
@@ -977,7 +973,6 @@ DEPENDENCIES
discard (~> 1.2)
doorkeeper (~> 5.6)
dotenv
email_spec
fabrication
faker (~> 3.2)
faraday-httpclient

View File

@@ -14,12 +14,16 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_report.subject', instance: Rails.configuration.x.local_domain, id: report.id)))
.and(have_body_text("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: #{admin_report_url(report)}\r\n"))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_report.subject', instance: Rails.configuration.x.local_domain, id: report.id)
)
expect(mail.body)
.to match('Mike,')
.and match('John has reported Mike')
.and match("View: #{admin_report_url(report)}")
end
end
@@ -33,12 +37,14 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_appeal.subject', instance: Rails.configuration.x.local_domain, username: appeal.account.username)))
.and(have_body_text("#{appeal.account.username} is appealing a moderation decision by #{appeal.strike.account.username}"))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_appeal.subject', instance: Rails.configuration.x.local_domain, username: appeal.account.username)
)
expect(mail.body)
.to match("#{appeal.account.username} is appealing a moderation decision by #{appeal.strike.account.username}")
end
end
@@ -52,12 +58,14 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_pending_account.subject', instance: Rails.configuration.x.local_domain, username: user.account.username)))
.and(have_body_text('The details of the new account are below. You can approve or reject this application.'))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_pending_account.subject', instance: Rails.configuration.x.local_domain, username: user.account.username)
)
expect(mail.body)
.to match('The details of the new account are below. You can approve or reject this application.')
end
end
@@ -76,15 +84,17 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_trends.subject', instance: Rails.configuration.x.local_domain)))
.and(have_body_text('The following items need a review before they can be displayed publicly'))
.and(have_body_text(ActivityPub::TagManager.instance.url_for(status)))
.and(have_body_text(link.title))
.and(have_body_text(tag.display_name))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_trends.subject', instance: Rails.configuration.x.local_domain)
)
expect(mail.body)
.to match('The following items need a review before they can be displayed publicly')
.and match(ActivityPub::TagManager.instance.url_for(status))
.and match(link.title)
.and match(tag.display_name)
end
end
@@ -97,12 +107,14 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_software_updates.subject', instance: Rails.configuration.x.local_domain)))
.and(have_body_text('New Mastodon versions have been released, you may want to update!'))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_software_updates.subject', instance: Rails.configuration.x.local_domain)
)
expect(mail.body)
.to match('New Mastodon versions have been released, you may want to update!')
end
end
@@ -115,15 +127,18 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.new_critical_software_updates.subject', instance: Rails.configuration.x.local_domain)
)
expect(mail.body)
.to match('New critical versions of Mastodon have been released, you may want to update as soon as possible!')
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.new_critical_software_updates.subject', instance: Rails.configuration.x.local_domain)))
.and(have_body_text('New critical versions of Mastodon have been released, you may want to update as soon as possible!'))
.and(have_header('Importance', 'high'))
.and(have_header('Priority', 'urgent'))
.and(have_header('X-Priority', '1'))
.to have_header('Importance', 'high')
.and have_header('Priority', 'urgent')
.and have_header('X-Priority', '1')
end
end
@@ -136,12 +151,14 @@ RSpec.describe AdminMailer do
end
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject(I18n.t('admin_mailer.auto_close_registrations.subject', instance: Rails.configuration.x.local_domain)))
.and(have_body_text('have been automatically switched'))
expect { mail.deliver }
.to send_email(
to: recipient.user_email,
from: 'notifications@localhost',
subject: I18n.t('admin_mailer.auto_close_registrations.subject', instance: Rails.configuration.x.local_domain)
)
expect(mail.body)
.to match('have been automatically switched')
end
end
end

View File

@@ -38,12 +38,15 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.mention.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'You were mentioned by bob'
)
expect(mail.text_part.body)
.to match('You were mentioned by bob')
.and match('The body of the foreign status')
expect(mail)
.to be_present
.and(have_subject('You were mentioned by bob'))
.and(have_body_text('You were mentioned by bob'))
.and(have_body_text('The body of the foreign status'))
.and have_thread_headers
.to have_thread_headers
.and have_standard_headers('mention').for(receiver)
end
@@ -59,12 +62,15 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.quote.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'bob quoted your post'
)
expect(mail.text_part.body)
.to match('Your post was quoted by bob')
.and match('The body of the foreign status')
expect(mail)
.to be_present
.and(have_subject('bob quoted your post'))
.and(have_body_text('Your post was quoted by bob'))
.and(have_body_text('The body of the foreign status'))
.and have_thread_headers
.to have_thread_headers
.and have_standard_headers('quote').for(receiver)
end
@@ -80,11 +86,14 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.follow.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'bob is now following you'
)
expect(mail.text_part.body)
.to match('bob is now following you')
expect(mail)
.to be_present
.and(have_subject('bob is now following you'))
.and(have_body_text('bob is now following you'))
.and have_standard_headers('follow').for(receiver)
.to have_standard_headers('follow').for(receiver)
end
it_behaves_like 'delivery to non functional user'
@@ -98,12 +107,15 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.favourite.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'bob favorited your post'
)
expect(mail.text_part.body)
.to match('Your post was favorited by bob')
.and match('The body of the own status')
expect(mail)
.to be_present
.and(have_subject('bob favorited your post'))
.and(have_body_text('Your post was favorited by bob'))
.and(have_body_text('The body of the own status'))
.and have_thread_headers
.to have_thread_headers
.and have_standard_headers('favourite').for(receiver)
end
@@ -119,12 +131,15 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.reblog.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'bob boosted your post'
)
expect(mail.text_part.body)
.to match('Your post was boosted by bob')
.and match('The body of the own status')
expect(mail)
.to be_present
.and(have_subject('bob boosted your post'))
.and(have_body_text('Your post was boosted by bob'))
.and(have_body_text('The body of the own status'))
.and have_thread_headers
.to have_thread_headers
.and have_standard_headers('reblog').for(receiver)
end
@@ -140,11 +155,14 @@ RSpec.describe NotificationMailer do
it_behaves_like 'localized subject', 'notification_mailer.follow_request.subject', name: 'bob'
it 'renders the email' do
expect { mail.deliver }
.to send_email(
subject: 'Pending follower: bob'
)
expect(mail.text_part.body)
.to match('bob has requested to follow you')
expect(mail)
.to be_present
.and(have_subject('Pending follower: bob'))
.and(have_body_text('bob has requested to follow you'))
.and have_standard_headers('follow_request').for(receiver)
.to have_standard_headers('follow_request').for(receiver)
end
it_behaves_like 'delivery to non functional user'

View File

@@ -8,8 +8,8 @@ RSpec.describe UserMailer do
before { receiver.account.update(memorial: true) }
it 'does not deliver mail' do
emails = capture_emails { mail.deliver_now }
expect(emails).to be_empty
expect { mail.deliver_now }
.to_not send_email
end
end
end
@@ -59,11 +59,10 @@ RSpec.describe UserMailer do
it 'renders confirmation instructions' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.confirmation_instructions.title')))
.and(have_body_text('spec'))
.and(have_body_text(Rails.configuration.x.local_domain))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.confirmation_instructions.title'))
.and match('spec')
.and match(Rails.configuration.x.local_domain)
end
it_behaves_like 'localized subject',
@@ -78,11 +77,10 @@ RSpec.describe UserMailer do
it 'renders reconfirmation instructions' do
receiver.update!(email: 'new-email@example.com', locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.reconfirmation_instructions.title')))
.and(have_body_text('spec'))
.and(have_body_text(Rails.configuration.x.local_domain))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.reconfirmation_instructions.title'))
.and match('spec')
.and match(Rails.configuration.x.local_domain)
end
it_behaves_like 'localized subject',
@@ -97,10 +95,9 @@ RSpec.describe UserMailer do
it 'renders reset password instructions' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.reset_password_instructions.title')))
.and(have_body_text('spec'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.reset_password_instructions.title'))
.and match('spec')
end
it_behaves_like 'localized subject',
@@ -114,9 +111,8 @@ RSpec.describe UserMailer do
it 'renders password change notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.password_change.title')))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.password_change.title'))
end
it_behaves_like 'localized subject',
@@ -130,9 +126,8 @@ RSpec.describe UserMailer do
it 'renders email change notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.email_changed.title')))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.email_changed.title'))
end
it_behaves_like 'localized subject',
@@ -149,10 +144,9 @@ RSpec.describe UserMailer do
it 'renders warning notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('user_mailer.warning.title.suspend', acct: receiver.account.acct)))
.and(have_body_text(strike.text))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.warning.title.suspend', acct: receiver.account.acct))
.and match(strike.text)
end
end
@@ -163,9 +157,8 @@ RSpec.describe UserMailer do
it 'renders webauthn credential deleted notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('devise.mailer.webauthn_credential.deleted.title')))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.webauthn_credential.deleted.title'))
end
it_behaves_like 'localized subject',
@@ -182,9 +175,8 @@ RSpec.describe UserMailer do
it 'renders suspicious sign in notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('user_mailer.suspicious_sign_in.explanation')))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.suspicious_sign_in.explanation'))
end
it_behaves_like 'localized subject',
@@ -200,9 +192,8 @@ RSpec.describe UserMailer do
it 'renders failed 2FA notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('user_mailer.failed_2fa.explanation')))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.failed_2fa.explanation'))
end
it_behaves_like 'localized subject',
@@ -214,10 +205,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.appeal_approved(receiver, appeal) }
it 'renders appeal_approved notification' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at))))
.and(have_body_text(I18n.t('user_mailer.appeal_approved.title')))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at)))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.appeal_approved.title'))
end
end
@@ -226,10 +217,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.appeal_rejected(receiver, appeal) }
it 'renders appeal_rejected notification' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at))))
.and(have_body_text(I18n.t('user_mailer.appeal_rejected.title')))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at)))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.appeal_rejected.title'))
end
end
@@ -237,10 +228,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.two_factor_enabled(receiver) }
it 'renders two_factor_enabled mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.two_factor_enabled.subject')))
.and(have_body_text(I18n.t('devise.mailer.two_factor_enabled.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.two_factor_enabled.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.two_factor_enabled.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -250,10 +241,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.two_factor_disabled(receiver) }
it 'renders two_factor_disabled mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.two_factor_disabled.subject')))
.and(have_body_text(I18n.t('devise.mailer.two_factor_disabled.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.two_factor_disabled.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.two_factor_disabled.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -263,10 +254,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.webauthn_enabled(receiver) }
it 'renders webauthn_enabled mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.webauthn_enabled.subject')))
.and(have_body_text(I18n.t('devise.mailer.webauthn_enabled.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.webauthn_enabled.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.webauthn_enabled.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -276,10 +267,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.webauthn_disabled(receiver) }
it 'renders webauthn_disabled mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.webauthn_disabled.subject')))
.and(have_body_text(I18n.t('devise.mailer.webauthn_disabled.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.webauthn_disabled.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.webauthn_disabled.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -289,10 +280,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.two_factor_recovery_codes_changed(receiver) }
it 'renders two_factor_recovery_codes_changed mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject')))
.and(have_body_text(I18n.t('devise.mailer.two_factor_recovery_codes_changed.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.two_factor_recovery_codes_changed.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -303,10 +294,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.webauthn_credential_added(receiver, credential) }
it 'renders webauthn_credential_added mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('devise.mailer.webauthn_credential.added.subject')))
.and(have_body_text(I18n.t('devise.mailer.webauthn_credential.added.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('devise.mailer.webauthn_credential.added.subject'))
expect(mail.text_part.body)
.to match(I18n.t('devise.mailer.webauthn_credential.added.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -322,10 +313,10 @@ RSpec.describe UserMailer do
end
it 'renders welcome mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.welcome.subject')))
.and(have_body_text(I18n.t('user_mailer.welcome.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.welcome.subject'))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.welcome.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -336,10 +327,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.backup_ready(receiver, backup) }
it 'renders backup_ready mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.backup_ready.subject')))
.and(have_body_text(I18n.t('user_mailer.backup_ready.explanation')))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.backup_ready.subject'))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.backup_ready.explanation'))
end
it_behaves_like 'delivery to memorialized user'
@@ -350,10 +341,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.terms_of_service_changed(receiver, terms) }
it 'renders terms_of_service_changed mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.terms_of_service_changed.subject')))
.and(have_body_text(I18n.t('user_mailer.terms_of_service_changed.changelog')))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.terms_of_service_changed.subject'))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.terms_of_service_changed.changelog'))
end
it_behaves_like 'optional bulk mailer settings'
@@ -364,10 +355,10 @@ RSpec.describe UserMailer do
let(:mail) { described_class.announcement_published(receiver, announcement) }
it 'renders announcement_published mail' do
expect(mail)
.to be_present
.and(have_subject(I18n.t('user_mailer.announcement_published.subject')))
.and(have_body_text(I18n.t('user_mailer.announcement_published.description', domain: local_domain_uri.host)))
expect { mail.deliver }
.to send_email(subject: I18n.t('user_mailer.announcement_published.subject'))
expect(mail.text_part.body)
.to match(I18n.t('user_mailer.announcement_published.description', domain: local_domain_uri.host))
end
it_behaves_like 'optional bulk mailer settings'

View File

@@ -43,7 +43,6 @@ require 'webmock/rspec'
require 'paperclip/matchers'
require 'capybara/rspec'
require 'chewy/rspec'
require 'email_spec/rspec'
require 'pundit/rspec'
require 'test_prof/recipes/rspec/before_all'

View File

@@ -17,8 +17,8 @@ RSpec::Matchers.define :have_thread_headers do
match(notify_expectation_failures: true) do |mail|
expect(mail)
.to be_present
.and(have_header('In-Reply-To', conversation_header_regex))
.and(have_header('References', conversation_header_regex))
.and have_header('In-Reply-To', conversation_header_regex)
.and have_header('References', conversation_header_regex)
end
def conversation_header_regex = /<conversation-\d+.\d\d\d\d-\d\d-\d\d@#{Regexp.quote(Rails.configuration.x.local_domain)}>/
@@ -32,12 +32,21 @@ RSpec::Matchers.define :have_standard_headers do |type|
match(notify_expectation_failures: true) do |mail|
expect(mail)
.to be_present
.and(have_header('To', "#{@user.account.username} <#{@user.email}>"))
.and(have_header('List-ID', "<#{type}.#{@user.account.username}.#{Rails.configuration.x.local_domain}>"))
.and(have_header('List-Unsubscribe', %r{<https://#{Rails.configuration.x.local_domain}/unsubscribe\?token=.+>}))
.and(have_header('List-Unsubscribe', /&type=#{type}/))
.and(have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click'))
.and(deliver_to("#{@user.account.username} <#{@user.email}>"))
.and(deliver_from(Rails.configuration.action_mailer.default_options[:from]))
.and have_header('To', "#{@user.account.username} <#{@user.email}>")
.and have_header('List-ID', "<#{type}.#{@user.account.username}.#{Rails.configuration.x.local_domain}>")
.and have_header('List-Unsubscribe', %r{<https://#{Rails.configuration.x.local_domain}/unsubscribe\?token=.+>})
.and have_header('List-Unsubscribe', /&type=#{type}/)
.and have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click')
expect(mail.to)
.to contain_exactly(@user.email)
expect(mail.from)
.to contain_exactly(Rails.configuration.action_mailer.default_options[:from])
end
end
RSpec::Matchers.define :have_header do |name, value|
match(notify_expectation_failures: true) do |mail|
expect(mail.header[name].value)
.to match(value)
end
end

View File

@@ -22,4 +22,8 @@ module SystemHelpers
def frontend_translations(key)
FRONTEND_TRANSLATIONS[key]
end
def email_links(email)
URI.extract(email.text_part.to_s, %w(http https))
end
end

View File

@@ -14,13 +14,10 @@ RSpec.describe 'Admin Announcement Mail Distributions' do
expect(page)
.to have_title(I18n.t('admin.announcements.preview.title'))
emails = capture_emails do
expect do
expect { click_on I18n.t('admin.terms_of_service.preview.send_to_all', count: 1, display_count: 1) }
.to(change { announcement.reload.notification_sent_at })
end
expect(emails.first)
.to be_present
.and(deliver_to(user.email))
end.to send_email(to: user.email)
expect(page)
.to have_title(I18n.t('admin.announcements.title'))
end

View File

@@ -14,10 +14,8 @@ RSpec.describe 'Admin TermsOfService Tests' do
expect(page)
.to have_title(I18n.t('admin.announcements.preview.title'))
emails = capture_emails { click_on I18n.t('admin.terms_of_service.preview.send_preview', email: user.email) }
expect(emails.first)
.to be_present
.and(deliver_to(user.email))
expect { click_on I18n.t('admin.terms_of_service.preview.send_preview', email: user.email) }
.to send_email(to: user.email)
expect(page)
.to have_title(I18n.t('admin.announcements.title'))
end

View File

@@ -16,11 +16,8 @@ RSpec.describe 'Admin Change Emails' do
.to have_title(I18n.t('admin.accounts.change_email.title', username: user.account.username))
fill_in 'user_unconfirmed_email', with: 'test@host.example'
emails = capture_emails { process_change_email }
expect(emails.first)
.to be_present
.and(deliver_to('test@host.example'))
.and(have_subject(/Confirm email/))
expect { process_change_email }
.to send_email(to: 'test@host.example', subject: /Confirm email/)
expect(page)
.to have_title(user.account.pretty_acct)
end

View File

@@ -36,14 +36,11 @@ RSpec.describe 'Admin Confirmations' do
it 'resends the confirmation mail' do
visit admin_account_path(id: user.account.id)
emails = capture_emails { resend_confirmation }
expect { resend_confirmation }
.to send_email(to: user.email)
expect(page)
.to have_title(I18n.t('admin.accounts.title'))
.and have_content(I18n.t('admin.accounts.resend_confirmation.success'))
expect(emails.first)
.to be_present
.and deliver_to(user.email)
end
end

View File

@@ -8,20 +8,11 @@ RSpec.describe 'Admin::Reset' do
sign_in admin_user
visit admin_account_path(account.id)
emails = capture_emails do
expect do
expect { submit_reset }
.to change(Admin::ActionLog.where(target: account.user), :count).by(1)
end
expect(emails.first)
.to be_present
.and(deliver_to(account.user.email))
.and(have_subject(password_change_subject))
expect(emails.last)
.to be_present
.and(deliver_to(account.user.email))
.and(have_subject(reset_instructions_subject))
.to send_email(to: account.user.email, subject: password_change_subject)
.and send_email(to: account.user.email, subject: reset_instructions_subject)
end.to change(Admin::ActionLog.where(target: account.user), :count).by(1)
expect(page)
.to have_content(account.username)

View File

@@ -14,13 +14,9 @@ RSpec.describe 'Admin TermsOfService Distributions' do
expect(page)
.to have_title(I18n.t('admin.terms_of_service.preview.title'))
emails = capture_emails do
expect { click_on I18n.t('admin.terms_of_service.preview.send_to_all', count: 1, display_count: 1) }
.to(change { terms_of_service.reload.notification_sent_at })
end
expect(emails.first)
.to be_present
.and(deliver_to(user.email))
expect { click_on I18n.t('admin.terms_of_service.preview.send_to_all', count: 1, display_count: 1) }
.to change { terms_of_service.reload.notification_sent_at }
.and send_email(to: user.email)
expect(page)
.to have_title(I18n.t('admin.terms_of_service.title'))
end

View File

@@ -14,10 +14,8 @@ RSpec.describe 'Admin TermsOfService Tests' do
expect(page)
.to have_title(I18n.t('admin.terms_of_service.preview.title'))
emails = capture_emails { click_on I18n.t('admin.terms_of_service.preview.send_preview', email: user.email) }
expect(emails.first)
.to be_present
.and(deliver_to(user.email))
expect { click_on I18n.t('admin.terms_of_service.preview.send_preview', email: user.email) }
.to send_email(to: user.email)
expect(page)
.to have_title(I18n.t('admin.terms_of_service.preview.title'))
end

View File

@@ -50,9 +50,8 @@ RSpec.describe 'Auth Passwords' do
def submit_email_reset
fill_in 'user_email', with: user.email
click_on I18n.t('auth.reset_password')
open_last_email
visit_in_email(I18n.t('devise.mailer.reset_password_instructions.action'))
emails = capture_emails { click_on I18n.t('auth.reset_password') }
visit email_links(emails.first).first
end
def set_new_password

View File

@@ -27,17 +27,9 @@ RSpec.describe 'Dispute Appeals' do
# Valid with text
fill_in 'appeal_text', with: 'It wasnt me this time!'
emails = capture_emails do
expect { submit_form }
.to change(Appeal, :count).by(1)
end
expect(emails)
.to contain_exactly(
have_attributes(
to: contain_exactly(admin.email),
subject: eq(new_appeal_subject)
)
)
expect { submit_form }
.to change(Appeal, :count).by(1)
.and send_email(to: admin.email, subject: new_appeal_subject)
expect(page)
.to have_content(I18n.t('disputes.strikes.appealed_msg'))
end

View File

@@ -24,17 +24,12 @@ RSpec.describe 'Settings TwoFactorAuthenticationMethods' do
# Fill in challenge form
fill_in 'form_challenge_current_password', with: user.password
emails = capture_emails do
expect { click_on I18n.t('challenge.confirm') }
.to change { user.reload.otp_required_for_login }.to(false)
end
expect { click_on I18n.t('challenge.confirm') }
.to change { user.reload.otp_required_for_login }.to(false)
.and send_email(to: user.email, subject: I18n.t('devise.mailer.two_factor_disabled.subject'))
expect(page)
.to have_content(I18n.t('two_factor_authentication.disabled_success'))
expect(emails.first)
.to be_present
.and(deliver_to(user.email))
.and(have_subject(I18n.t('devise.mailer.two_factor_disabled.subject')))
end
end
end