After getting some of my model specs to run without issue, I decided to focus on the my mailer specs, as I new there were many things that had to change.
In the related mailer_spec
Assert_select and assert_select_email instead of have_tag, have_text
The first mailer spec I ran, everything blew up, because I had been using have_tag and have_text as matchers. I could not figure out how to get them to work in Rails 3, so switched to using assert_select and assert_select_email.
However, in rails 3.0, assert_select_email has a couple of problems. First, it assumes that emails will be multipart. This wasn't true in my case. It also assumes that email.body returns a string, which it does not, it returns a Body object.
There is a fix in rails 3.1 for this, so I borrowed that code and created an initializer with the following:
module ActionDispatch module Assertions module SelectorAssertions # this is fixed in Rails 3.1 # in 3.0, if the email has no parts, it would always return true # also, the body needed to be converted to a string, as that is what HTML::Document.new expects def assert_select_email(email = nil, &block) deliveries = email ? [email] : ActionMailer::Base.deliveries assert !deliveries.empty?, "No e-mail in delivery list" for delivery in deliveries for part in (delivery.parts.empty? ? [delivery] : delivery.parts) if part["Content-Type"].to_s =~ /^text\/html\W/ root = HTML::Document.new(part.body.to_s).root assert_select root, ":root", &block end end end end end end end
Unlike the fix rails 3.1 fix (https://github.com/rails/rails/pull/2499), this also allows you to pass in an email object. Without this, if assert_select_email found more than one email in the deliveries list, and one of them didn't match your select criteria, this would fail, even if other emails in the deliveries list matched.
By passing in an email, you don't leave that to chance.
Changing all of the have_tag, with_tag, etc to assert_select statements was a bit of a pain, but it works well now.
Change have_text to have_body_text
Move "deliver_" at the front of the mailer method call to ".deliver" at the end of the mailer method call
In the mailer.rb file
Change @body[:foo] = 'bar' assignments to @foo = 'bar'
To change the @body[:foo] = 'bar' assignment to @foo = 'bar', I used the following in TextMates Find in Project
Find: \@body\[:([a-z_1-9]*)\]
Replace: @$1
Use Regular Expressions: true
No comments:
Post a Comment