From 6c222479a565664b013c89b4120c47769644fdbd Mon Sep 17 00:00:00 2001 From: Stafford Brunk Date: Fri, 27 May 2011 10:50:23 -0400 Subject: [PATCH] Add block functionality to HaveSentEmailMatcher so instance variables can be used --- .../matchers/action_mailer/have_sent_email.rb | 50 ++++++++++--- .../action_mailer/have_sent_email_spec.rb | 71 ++++++++++++++++--- 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/lib/shoulda/matchers/action_mailer/have_sent_email.rb b/lib/shoulda/matchers/action_mailer/have_sent_email.rb index 26240d45f..e27654f4c 100644 --- a/lib/shoulda/matchers/action_mailer/have_sent_email.rb +++ b/lib/shoulda/matchers/action_mailer/have_sent_email.rb @@ -12,56 +12,74 @@ module ActionMailer # :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 in_context(context) + @context = context + self end - def with_subject(email_subject) + 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 @@ def anything_failed? @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 @@ def match_array_in_array(target_array, match_array) end end end - end diff --git a/spec/shoulda/action_mailer/have_sent_email_spec.rb b/spec/shoulda/action_mailer/have_sent_email_spec.rb index 4cff8165d..818815e79 100644 --- a/spec/shoulda/action_mailer/have_sent_email_spec.rb +++ b/spec/shoulda/action_mailer/have_sent_email_spec.rb @@ -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 @@ def the_email 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'])