Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test email headers using RSpec

I'm using SendGrid's SMTP API in my Rails application to send out emails. However, I'm running into troubles testing the email header ("X-SMTPAPI") using RSpec.

Here's what the email looks like (retrieving from ActionMailer::Base.deliveries):

#<Mail::Message:2189335760, Multipart: false, Headers: 
<Date: Tue, 20 Dec 2011 16:14:25 +0800>, 
<From: "Acme Inc" <[email protected]>>, 
<To: [email protected]>, 
<Message-ID: <[email protected]>>, 
<Subject: Your Acme order>, <Mime-Version: 1.0>, 
<Content-Type: text/plain>, <Content-Transfer-Encoding: 7bit>, 
<X-SMTPAPI: {"sub":{"|last_name|":[Foo],"|first_name|":[Bar]},"to":["[email protected]"]}>> 

Here's my spec code (which failed):

ActionMailer::Base.deliveries.last.to.should include("[email protected]")

I've also tried various method to retrieve the header("X-SMTPAPI") and didn't work either:

mail = ActionMailer::Base.deliveries.last
mail.headers("X-SMTPAPI") #NoMethodError: undefined method `each_pair' for "X-SMTPAPI":String

Help?

Update (answer)

Turns out, I can do this to retrieve the value of the email header:

mail.header['X-SMTPAPI'].value

However, the returned value is in JSON format. Then, all I need to do is to decode it:

sendgrid_header = ActiveSupport::JSON.decode(mail.header['X-SMTPAPI'].value)

which returns a hash, where I can do this:

sendgrid_header["to"] 

to retrieve the array of email addresses.

like image 511
Lim Cheng Soon Avatar asked Dec 20 '11 08:12

Lim Cheng Soon


1 Answers

The email_spec gem has a bunch of matchers that make this easier, you can do stuff like

mail.should have_header('X-SMTPAPI', some_value)
mail.should deliver_to('[email protected]')

And perusing the source to that gem should point you in the right direction if you don't want to use it e.g.

mail.to.addrs

returns you the email addresses (as opposed to stuff like 'Bob ')

and

mail.header['foo']

gets you the field for the foo header (depending on what you're checking you may want to call to_s on it to get the actual field value)

like image 119
Frederick Cheung Avatar answered Oct 16 '22 23:10

Frederick Cheung