Add block functionality to HaveSentEmailMatcher so instance variables can be used

This commit is contained in:
Stafford Brunk 2011-05-27 10:50:23 -04:00
parent 6789b932a9
commit 6c222479a5
2 changed files with 101 additions and 20 deletions

View File

@ -12,56 +12,74 @@ module Shoulda # :nodoc:
# from('do-not-reply@example.com').
# with_body(/spam/).
# to('myself@me.com') }
#
# Use values of instance variables
# it {should have_sent_email.to {@user.email} }
def have_sent_email
HaveSentEmailMatcher.new
HaveSentEmailMatcher.new(self)
end
class HaveSentEmailMatcher # :nodoc:
def initialize
def initialize(context)
@context = context
end
def with_subject(email_subject)
def in_context(context)
@context = context
self
end
def with_subject(email_subject = nil, &block)
@email_subject = email_subject
@email_subject_block = block
self
end
def from(sender)
def from(sender = nil, &block)
@sender = sender
@sender_block = block
self
end
def with_body(body)
def with_body(body = nil, &block)
@body = body
@body_block = block
self
end
def to(recipient)
def to(recipient = nil, &block)
@recipient = recipient
@recipient_block = block
self
end
def cc(recipient)
def cc(recipient = nil, &block)
@cc = recipient
@cc_block = block
self
end
def with_cc(recipients)
def with_cc(recipients = nil, &block)
@cc_recipients = recipients
@cc_recipients_block = block
self
end
def bcc(recipient)
def bcc(recipient = nil, &block)
@bcc = recipient
@bcc_block = block
self
end
def with_bcc(recipients)
def with_bcc(recipients = nil, &block)
@bcc_recipients = recipients
@bcc_recipients_block = block
self
end
def matches?(subject)
normalize_blocks
::ActionMailer::Base.deliveries.each do |mail|
@subject_failed = !regexp_or_string_match(mail.subject, @email_subject) if @email_subject
@body_failed = !regexp_or_string_match(mail.body, @body) if @body
@ -123,6 +141,17 @@ module Shoulda # :nodoc:
@subject_failed || @body_failed || @sender_failed || @recipient_failed || @cc_failed || @cc_recipients_failed || @bcc_failed || @bcc_recipients_failed
end
def normalize_blocks
@email_subject = @context.instance_eval(&@email_subject_block) if @email_subject_block
@sender = @context.instance_eval(&@sender_block) if @sender_block
@body = @context.instance_eval(&@body_block) if @body_block
@recipient = @context.instance_eval(&@recipient_block) if @recipient_block
@cc = @context.instance_eval(&@cc_block) if @cc_block
@cc_recipients = @context.instance_eval(&@cc_recipients_block) if @cc_recipients_block
@bcc = @context.instance_eval(&@bcc_block) if @bcc_block
@bcc_recipients = @context.instance_eval(&@bcc_recipients_block) if @bcc_recipients_block
end
def regexp_or_string_match(a_string, a_regexp_or_string)
case a_regexp_or_string
when Regexp
@ -150,5 +179,4 @@ module Shoulda # :nodoc:
end
end
end
end

View File

@ -1,14 +1,67 @@
require 'spec_helper'
describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
def add_mail_to_deliveries
::ActionMailer::Base.deliveries << Mailer.the_email
def add_mail_to_deliveries(params = nil)
::ActionMailer::Base.deliveries << Mailer.the_email(params)
end
context "testing with instance variables" do
before do
@info = {
:from => "do-not-reply@example.com",
:to => "myself@me.com",
:cc => ["you@you.com", "joe@bob.com", "hello@goodbye.com"],
:bcc => ["test@example.com", "sam@bob.com", "goodbye@hello.com"],
:subject => "This is spam",
:body => "Every email is spam." }
define_mailer :mailer, [:the_email] do
def the_email(params)
mail params
end
end
add_mail_to_deliveries(@info)
end
after { ::ActionMailer::Base.deliveries.clear }
it "should send an e-mail based on subject" do
should have_sent_email.with_subject{ @info[:subject] }
end
it "should send an e-mail based on recipient" do
should have_sent_email.to{ @info[:to] }
end
it "should send an e-mail based on sender" do
should have_sent_email.from{ @info[:from] }
end
it "should send an e-mail based on cc" do
should have_sent_email.cc{ @info[:cc][0] }
end
it "should send an e-mail based on cc list" do
should have_sent_email.with_cc{ @info[:cc] }
end
it "should send an e-mail based on bcc" do
should have_sent_email.bcc{ @info[:bcc][0] }
end
it "should send an e-mail based on bcc list" do
should have_sent_email.with_bcc{ @info[:bcc] }
end
it "should send an e-mail based on body" do
should have_sent_email.with_body{ @info[:body] }
end
end
context "an email" do
before do
define_mailer :mailer, [:the_email] do
def the_email
def the_email(params)
mail :from => "do-not-reply@example.com",
:to => "myself@me.com",
:subject => "This is spam",
@ -56,42 +109,42 @@ describe Shoulda::Matchers::ActionMailer::HaveSentEmailMatcher do
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email to/
end
it "accepts sent e-mail based on cc string" do
should have_sent_email.cc('joe@bob.com')
matcher = have_sent_email.cc('you@example.com')
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email cc/
end
it "accepts sent-email based on cc regex" do
should have_sent_email.cc(/@bob\.com/)
matcher = have_sent_email.cc(/us@/)
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email cc/
end
it "accepts sent e-mail based on cc list" do
should have_sent_email.with_cc(['you@you.com', 'joe@bob.com'])
matcher = have_sent_email.with_cc(['you@example.com'])
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email with cc/
end
it "accepts sent e-mail based on bcc string" do
should have_sent_email.bcc("goodbye@hello.com")
matcher = have_sent_email.bcc("test@hello.com")
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email bcc/
end
it "accepts sent e-mail based on bcc regex" do
should have_sent_email.bcc(/@example\.com/)
matcher = have_sent_email.bcc(/you@/)
matcher.matches?(nil)
matcher.failure_message.should =~ /Expected sent email bcc/
end
it "accepts sent e-mail based on bcc list" do
should have_sent_email.with_bcc(['sam@bob.com', 'test@example.com'])
matcher = have_sent_email.with_bcc(['you@you.com', 'joe@bob.com'])