Voldemar Duletskiy
Voldemar Duletskiy

Reputation: 981

Action mailer link check in rspec

I have in my rspec test such comparison:

expect(new_mail.body.encoded).to match(url_for(controller:'some_controller',action:'some_action',some_param:some_param))

but it fails because ActionMailer encodes html body to something like this:

   +<a href=3D"http://localhost:3000/some_controller/some_action/wgt1p468ersmkq=
   +gbvmfv5wgmifj13u894dfjrhc0hzczk71pcw3hrk5907iqfolc6onhxvik6apuuwgm1rng7ro=
   +rt8qih43thql3spyp5ajjdugy9jvx0xc5hvpi015z" style=3D"display: inline-block=
   +; background-color: #71B344; color: #FFF; border-radius: 4px; font-weight=
   +: bold; text-decoration: none; padding: 6px 12px; white-space: nowrap">
   +        Go to Your Account
   +      </a>

how to compare expected link and encoded link in mail body?

Upvotes: 5

Views: 3085

Answers (1)

max
max

Reputation: 102001

You can use new_mail.body.to_s instead to get a non encoded version as indicated in a Guide to Rails Testing.

Also you can use Capybara to make assertions on the rendered email (or any html fragment), which is better than just using string matches if you really want to be sure that link is in there:

let(:email){ Capybara::Node::Simple.new(new_mail.body.to_s) }

it "has a link" do
  url = url_for(controller:'some_controller',action:'some_action',some_param:some_param)
  expect(email).to have_link('A link', href: url)
end

Added:

To get the correct part from a multipart email:

def get_message_part(mail, content_type)
  mail.body.parts.find { |p| p.content_type.match content_type }.body.raw_source
end

let(:email) { Capybara::Node::Simple.new(get_message_part(new_mail, /html/)) }

Upvotes: 6

Related Questions