Simple custom matcher for emails against a "user" model
RSpec::Matchers.define :have_received_an_email do |expected|
def last_email
@last_email ||= ActionMailer::Base.deliveries.last
end
def inbox_size
ActionMailer::Base.deliveries.size
end
def to
last_email.to[0]
end
def subjects_match?
return true if @expected_subject.nil?
@subject_message = " with subject '#{@expected_subject}'"
if last_email.subject == @expected_subject
true
else
@subject_message << " not '#{last_email.subject}'"
false
end
end
def received_an_email?(email)
inbox_size == 1 && to == email
end
def with_subject(expected_subject)
@expected_subject = expected_subject
self
end
match do |actual|
received_an_email?(actual.email) && subjects_match?
end
failure_message_for_should do |actual|
"expected #{actual.email} to receive an email#{@subject_message}"
end
failure_message_for_should_not do |actual|
"expected #{actual.email} to not receive an email#{@subject_message}, but did"
end
description do
"#{actual.email} should have received an email#{@subject_message}"
end
end
describe "an email" do
let(:user) { Factory(:user) }
before do
SomeMailer.email_user(user).deliver
end
it "should have received an email with subject" do
user.should have_received_an_email.with_subject "Rspec my authoritah!"
end
end