Skip to content

Commit

Permalink
Add email_spec and speedup/cleanup to spec/mailers (mastodon#27902)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjankowski authored and vmstan committed Dec 14, 2023
1 parent cf6e3d1 commit dff9775
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 155 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ group :test do
# RSpec progress bar formatter
gem 'fuubar', '~> 2.5'

# RSpec helpers for email specs
gem 'email_spec'

# Extra RSpec extenion methods and helpers for sidekiq
gem 'rspec-sidekiq', '~> 4.0'

Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ GEM
elasticsearch-transport (7.13.3)
faraday (~> 1)
multi_json
email_spec (2.2.2)
htmlentities (~> 4.3.3)
launchy (~> 2.1)
mail (~> 2.7)
encryptor (3.0.0)
erubi (1.12.0)
et-orbi (1.2.7)
Expand Down Expand Up @@ -853,6 +857,7 @@ DEPENDENCIES
doorkeeper (~> 5.6)
dotenv-rails (~> 2.8)
ed25519 (~> 1.3)
email_spec
fabrication (~> 2.30)
faker (~> 3.2)
fast_blank (~> 1.0)
Expand Down
97 changes: 45 additions & 52 deletions spec/mailers/admin_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
recipient.user.update(locale: :en)
end

it 'renders the headers' do
expect(mail.subject).to eq("New report for cb6e6126.ngrok.io (##{report.id})")
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the body' do
expect(mail.body.encoded).to eq("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: https://cb6e6126.ngrok.io/admin/reports/#{report.id}\r\n")
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject("New report for cb6e6126.ngrok.io (##{report.id})"))
.and(have_body_text("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: https://cb6e6126.ngrok.io/admin/reports/#{report.id}\r\n"))
end
end

Expand All @@ -33,14 +32,13 @@
recipient.user.update(locale: :en)
end

it 'renders the headers' do
expect(mail.subject).to eq("#{appeal.account.username} is appealing a moderation decision on cb6e6126.ngrok.io")
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the body' do
expect(mail.body.encoded).to match "#{appeal.account.username} is appealing a moderation decision by #{appeal.strike.account.username}"
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject("#{appeal.account.username} is appealing a moderation decision on cb6e6126.ngrok.io"))
.and(have_body_text("#{appeal.account.username} is appealing a moderation decision by #{appeal.strike.account.username}"))
end
end

Expand All @@ -53,14 +51,13 @@
recipient.user.update(locale: :en)
end

it 'renders the headers' do
expect(mail.subject).to eq("New account up for review on cb6e6126.ngrok.io (#{user.account.username})")
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the body' do
expect(mail.body.encoded).to match 'The details of the new account are below. You can approve or reject this application.'
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject("New account up for review on cb6e6126.ngrok.io (#{user.account.username})"))
.and(have_body_text('The details of the new account are below. You can approve or reject this application.'))
end
end

Expand All @@ -75,14 +72,13 @@
recipient.user.update(locale: :en)
end

it 'renders the headers' do
expect(mail.subject).to eq('New trends up for review on cb6e6126.ngrok.io')
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the body' do
expect(mail.body.encoded).to match 'The following items need a review before they can be displayed publicly'
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject('New trends up for review on cb6e6126.ngrok.io'))
.and(have_body_text('The following items need a review before they can be displayed publicly'))
end
end

Expand All @@ -94,14 +90,13 @@
recipient.user.update(locale: :en)
end

it 'renders the headers' do
expect(mail.subject).to eq('New Mastodon versions are available for cb6e6126.ngrok.io!')
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the body' do
expect(mail.body.encoded).to match 'New Mastodon versions have been released, you may want to update!'
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject('New Mastodon versions are available for cb6e6126.ngrok.io!'))
.and(have_body_text('New Mastodon versions have been released, you may want to update!'))
end
end

Expand All @@ -113,18 +108,16 @@
recipient.user.update(locale: :en)
end

it 'renders the headers', :aggregate_failures do
expect(mail.subject).to eq('Critical Mastodon updates are available for cb6e6126.ngrok.io!')
expect(mail.to).to eq [recipient.user_email]
expect(mail.from).to eq ['notifications@localhost']

expect(mail['Importance'].value).to eq 'high'
expect(mail['Priority'].value).to eq 'urgent'
expect(mail['X-Priority'].value).to eq '1'
end

it 'renders the body' do
expect(mail.body.encoded).to match 'New critical versions of Mastodon have been released, you may want to update as soon as possible!'
it 'renders the email' do
expect(mail)
.to be_present
.and(deliver_to(recipient.user_email))
.and(deliver_from('notifications@localhost'))
.and(have_subject('Critical Mastodon updates are available for cb6e6126.ngrok.io!'))
.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'))
end
end
end
115 changes: 58 additions & 57 deletions spec/mailers/notification_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,27 @@
let(:foreign_status) { Fabricate(:status, account: sender, text: 'The body of the foreign status') }
let(:own_status) { Fabricate(:status, account: receiver.account, text: 'The body of the own status') }

shared_examples 'headers' do |type, thread|
it 'renders the to and from headers' do
expect(mail[:to].value).to eq "#{receiver.account.username} <#{receiver.email}>"
expect(mail.from).to eq ['notifications@localhost']
end

it 'renders the list headers' do
expect(mail['List-ID'].value).to eq "<#{type}.alice.cb6e6126.ngrok.io>"
expect(mail['List-Unsubscribe'].value).to match(%r{<https://cb6e6126.ngrok.io/unsubscribe\?token=.+>})
expect(mail['List-Unsubscribe'].value).to match("&type=#{type}")
expect(mail['List-Unsubscribe-Post'].value).to eq 'List-Unsubscribe=One-Click'
shared_examples 'standard headers' do |type|
it 'renders the email' do
expect(mail)
.to be_present
.and(have_header('To', "#{receiver.account.username} <#{receiver.email}>"))
.and(have_header('List-ID', "<#{type}.alice.cb6e6126.ngrok.io>"))
.and(have_header('List-Unsubscribe', %r{<https://cb6e6126.ngrok.io/unsubscribe\?token=.+>}))
.and(have_header('List-Unsubscribe', /&type=#{type}/))
.and(have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click'))
.and(deliver_to("#{receiver.account.username} <#{receiver.email}>"))
.and(deliver_from('notifications@localhost'))
end
end

if thread
it 'renders the thread headers' do
expect(mail['In-Reply-To'].value).to match(/<conversation-\d+.\d\d\d\d-\d\d-\d\d@cb6e6126.ngrok.io>/)
expect(mail['References'].value).to match(/<conversation-\d+.\d\d\d\d-\d\d-\d\d@cb6e6126.ngrok.io>/)
end
shared_examples 'thread headers' do
it 'renders the email with conversation thread headers' do
conversation_header_regex = /<conversation-\d+.\d\d\d\d-\d\d-\d\d@cb6e6126.ngrok.io>/
expect(mail)
.to be_present
.and(have_header('In-Reply-To', conversation_header_regex))
.and(have_header('References', conversation_header_regex))
end
end

Expand All @@ -35,15 +38,15 @@
let(:mail) { prepared_mailer_for(receiver.account).mention }

include_examples 'localized subject', 'notification_mailer.mention.subject', name: 'bob'
include_examples 'headers', 'mention', true

it 'renders the subject' do
expect(mail.subject).to eq('You were mentioned by bob')
end

it 'renders the body' do
expect(mail.body.encoded).to match('You were mentioned by bob')
expect(mail.body.encoded).to include 'The body of the foreign status'
include_examples 'standard headers', 'mention'
include_examples 'thread headers'

it 'renders the email' do
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'))
end
end

Expand All @@ -53,14 +56,13 @@
let(:mail) { prepared_mailer_for(receiver.account).follow }

include_examples 'localized subject', 'notification_mailer.follow.subject', name: 'bob'
include_examples 'headers', 'follow', false

it 'renders the subject' do
expect(mail.subject).to eq('bob is now following you')
end
include_examples 'standard headers', 'follow'

it 'renders the body' do
expect(mail.body.encoded).to match('bob is now following you')
it 'renders the email' do
expect(mail)
.to be_present
.and(have_subject('bob is now following you'))
.and(have_body_text('bob is now following you'))
end
end

Expand All @@ -70,15 +72,15 @@
let(:mail) { prepared_mailer_for(own_status.account).favourite }

include_examples 'localized subject', 'notification_mailer.favourite.subject', name: 'bob'
include_examples 'headers', 'favourite', true

it 'renders the subject' do
expect(mail.subject).to eq('bob favorited your post')
end

it 'renders the body' do
expect(mail.body.encoded).to match('Your post was favorited by bob')
expect(mail.body.encoded).to include 'The body of the own status'
include_examples 'standard headers', 'favourite'
include_examples 'thread headers'

it 'renders the email' do
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'))
end
end

Expand All @@ -88,15 +90,15 @@
let(:mail) { prepared_mailer_for(own_status.account).reblog }

include_examples 'localized subject', 'notification_mailer.reblog.subject', name: 'bob'
include_examples 'headers', 'reblog', true

it 'renders the subject' do
expect(mail.subject).to eq('bob boosted your post')
end

it 'renders the body' do
expect(mail.body.encoded).to match('Your post was boosted by bob')
expect(mail.body.encoded).to include 'The body of the own status'
include_examples 'standard headers', 'reblog'
include_examples 'thread headers'

it 'renders the email' do
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'))
end
end

Expand All @@ -106,14 +108,13 @@
let(:mail) { prepared_mailer_for(receiver.account).follow_request }

include_examples 'localized subject', 'notification_mailer.follow_request.subject', name: 'bob'
include_examples 'headers', 'follow_request', false

it 'renders the subject' do
expect(mail.subject).to eq('Pending follower: bob')
end
include_examples 'standard headers', 'follow_request'

it 'renders the body' do
expect(mail.body.encoded).to match('bob has requested to follow you')
it 'renders the email' do
expect(mail)
.to be_present
.and(have_subject('Pending follower: bob'))
.and(have_body_text('bob has requested to follow you'))
end
end

Expand Down
Loading

0 comments on commit dff9775

Please sign in to comment.