email_spec 0.6.6 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/History.txt +21 -26
  2. data/README.rdoc +5 -3
  3. data/Rakefile +16 -27
  4. data/examples/rails3_root/Gemfile +17 -0
  5. data/examples/rails3_root/Gemfile.lock +138 -0
  6. data/examples/rails3_root/README +5 -0
  7. data/examples/rails3_root/Rakefile +11 -0
  8. data/examples/rails3_root/app/controllers/application_controller.rb +3 -0
  9. data/examples/rails3_root/app/controllers/welcome_controller.rb +16 -0
  10. data/examples/rails3_root/app/helpers/application_helper.rb +2 -0
  11. data/examples/rails3_root/app/mailers/user_mailer.rb +39 -0
  12. data/examples/{rails_root → rails3_root}/app/models/user.rb +0 -0
  13. data/examples/{rails_root/app/views/user_mailer/attachments.erb → rails3_root/app/views/user_mailer/attachments.html.erb} +0 -0
  14. data/examples/{rails_root/app/views/user_mailer/newsletter.erb → rails3_root/app/views/user_mailer/newsletter.html.erb} +0 -0
  15. data/examples/{rails_root/app/views/user_mailer/signup.erb → rails3_root/app/views/user_mailer/signup.html.erb} +1 -0
  16. data/examples/rails3_root/app/views/user_mailer/signup.text.erb +4 -0
  17. data/examples/{rails_root → rails3_root}/app/views/welcome/attachments.html.erb +0 -0
  18. data/examples/{rails_root → rails3_root}/app/views/welcome/confirm.html.erb +0 -0
  19. data/examples/{rails_root → rails3_root}/app/views/welcome/index.html.erb +1 -1
  20. data/examples/{rails_root → rails3_root}/app/views/welcome/newsletter.html.erb +0 -0
  21. data/examples/{rails_root → rails3_root}/app/views/welcome/signup.html.erb +0 -0
  22. data/examples/{rails_root → rails3_root}/attachments/document.pdf +0 -0
  23. data/examples/{rails_root → rails3_root}/attachments/image.png +0 -0
  24. data/examples/rails3_root/config.ru +4 -0
  25. data/examples/rails3_root/config/application.rb +43 -0
  26. data/examples/rails3_root/config/boot.rb +14 -0
  27. data/examples/rails3_root/config/cucumber.yml +8 -0
  28. data/examples/{rails_root → rails3_root}/config/database.yml +0 -0
  29. data/examples/rails3_root/config/environment.rb +6 -0
  30. data/examples/rails3_root/config/environments/development.rb +20 -0
  31. data/examples/rails3_root/config/environments/production.rb +42 -0
  32. data/examples/rails3_root/config/environments/test.rb +30 -0
  33. data/examples/rails3_root/config/initializers/backtrace_silencers.rb +7 -0
  34. data/examples/rails3_root/config/initializers/cookie_verification_secret.rb +7 -0
  35. data/examples/rails3_root/config/initializers/delayed_job.rb +1 -0
  36. data/examples/{rails_root → rails3_root}/config/initializers/inflections.rb +0 -0
  37. data/examples/{rails_root → rails3_root}/config/initializers/mime_types.rb +0 -0
  38. data/examples/rails3_root/config/initializers/notifier_job.rb +1 -0
  39. data/examples/rails3_root/config/initializers/rspec_generator.rb +6 -0
  40. data/examples/rails3_root/config/initializers/session_store.rb +10 -0
  41. data/examples/rails3_root/config/locales/en.yml +5 -0
  42. data/examples/rails3_root/config/routes.rb +7 -0
  43. data/examples/{rails_root → rails3_root}/db/migrate/20090125013728_create_users.rb +0 -0
  44. data/examples/{rails_root → rails3_root}/db/migrate/20090908054656_create_delayed_jobs.rb +0 -0
  45. data/examples/{rails_root → rails3_root}/db/schema.rb +7 -6
  46. data/examples/rails3_root/db/seeds.rb +7 -0
  47. data/examples/rails3_root/doc/README_FOR_APP +2 -0
  48. data/examples/{rails_root → rails3_root}/features/attachments.feature +0 -0
  49. data/examples/{rails_root → rails3_root}/features/delayed_job.feature +0 -0
  50. data/examples/{rails_root → rails3_root}/features/errors.feature +0 -0
  51. data/examples/{sinatra → rails3_root}/features/example.feature +9 -0
  52. data/examples/{rails_root → rails3_root}/features/step_definitions/user_steps.rb +2 -2
  53. data/examples/rails3_root/features/step_definitions/web_steps.rb +219 -0
  54. data/examples/{rails_root → rails3_root}/features/support/env.rb +10 -10
  55. data/examples/rails3_root/features/support/env_ext.rb +2 -0
  56. data/examples/{rails_root → rails3_root}/features/support/paths.rb +2 -2
  57. data/examples/rails3_root/lib/notifier_job.rb +5 -0
  58. data/examples/{rails_root → rails3_root}/lib/tasks/cucumber.rake +6 -0
  59. data/examples/rails3_root/lib/tasks/rspec.rake +69 -0
  60. data/examples/rails3_root/public/404.html +26 -0
  61. data/examples/rails3_root/public/422.html +26 -0
  62. data/examples/rails3_root/public/500.html +26 -0
  63. data/examples/{rails_root → rails3_root}/public/favicon.ico +0 -0
  64. data/examples/{rails_root → rails3_root}/public/images/rails.png +0 -0
  65. data/examples/{rails_root → rails3_root}/public/javascripts/application.js +0 -0
  66. data/examples/{rails_root → rails3_root}/public/javascripts/controls.js +5 -3
  67. data/examples/{rails_root → rails3_root}/public/javascripts/dragdrop.js +7 -6
  68. data/examples/{rails_root → rails3_root}/public/javascripts/effects.js +8 -13
  69. data/examples/{rails_root → rails3_root}/public/javascripts/prototype.js +1573 -1019
  70. data/examples/rails3_root/public/javascripts/rails.js +109 -0
  71. data/examples/{rails_root → rails3_root}/public/robots.txt +0 -0
  72. data/examples/{rails_root → rails3_root}/script/cucumber +0 -0
  73. data/examples/rails3_root/script/rails +9 -0
  74. data/examples/rails3_root/spec/controllers/welcome_controller_spec.rb +20 -0
  75. data/examples/{rails_root → rails3_root}/spec/models/user_mailer_spec.rb +7 -18
  76. data/examples/rails3_root/spec/spec_helper.rb +19 -0
  77. data/examples/sinatra_root/config.ru +4 -0
  78. data/examples/{sinatra → sinatra_root}/features/errors.feature +0 -0
  79. data/examples/{rails_root → sinatra_root}/features/example.feature +0 -0
  80. data/examples/{sinatra → sinatra_root}/features/step_definitions/user_steps.rb +2 -2
  81. data/examples/sinatra_root/features/step_definitions/web_steps.rb +219 -0
  82. data/examples/sinatra_root/features/support/env.rb +21 -0
  83. data/examples/{sinatra → sinatra_root}/features/support/paths.rb +9 -4
  84. data/examples/sinatra_root/lib/example_sinatra_app.rb +35 -0
  85. data/lib/email_spec.rb +2 -2
  86. data/lib/email_spec/deliveries.rb +7 -11
  87. data/lib/email_spec/email_viewer.rb +1 -1
  88. data/lib/email_spec/helpers.rb +7 -7
  89. data/lib/email_spec/mail_ext.rb +11 -0
  90. data/lib/email_spec/matchers.rb +31 -26
  91. data/lib/generators/email_spec/steps/USAGE +5 -0
  92. data/lib/generators/email_spec/steps/steps_generator.rb +14 -0
  93. data/{examples/rails3_root/features/step_definitions → lib/generators/email_spec/steps/templates}/email_steps.rb +0 -0
  94. data/spec/email_spec/helpers_spec.rb +4 -6
  95. data/spec/email_spec/mail_ext_spec.rb +34 -0
  96. data/spec/email_spec/matchers_spec.rb +227 -37
  97. data/spec/spec_helper.rb +14 -2
  98. metadata +174 -207
  99. data/examples/rails_root/Rakefile +0 -13
  100. data/examples/rails_root/app/controllers/application_controller.rb +0 -15
  101. data/examples/rails_root/app/controllers/welcome_controller.rb +0 -16
  102. data/examples/rails_root/app/helpers/application_helper.rb +0 -3
  103. data/examples/rails_root/app/helpers/welcome_helper.rb +0 -2
  104. data/examples/rails_root/app/models/user_mailer.rb +0 -39
  105. data/examples/rails_root/config/boot.rb +0 -110
  106. data/examples/rails_root/config/cucumber.yml +0 -7
  107. data/examples/rails_root/config/environment.rb +0 -28
  108. data/examples/rails_root/config/environments/cucumber.rb +0 -29
  109. data/examples/rails_root/config/environments/development.rb +0 -17
  110. data/examples/rails_root/config/environments/production.rb +0 -28
  111. data/examples/rails_root/config/environments/test.rb +0 -28
  112. data/examples/rails_root/config/initializers/new_rails_defaults.rb +0 -17
  113. data/examples/rails_root/config/routes.rb +0 -45
  114. data/examples/rails_root/doc/README_FOR_APP +0 -5
  115. data/examples/rails_root/features/step_definitions/web_steps.rb +0 -273
  116. data/examples/rails_root/features/support/env_ext.rb +0 -6
  117. data/examples/rails_root/public/404.html +0 -30
  118. data/examples/rails_root/public/422.html +0 -30
  119. data/examples/rails_root/public/500.html +0 -33
  120. data/examples/rails_root/public/dispatch.rb +0 -10
  121. data/examples/rails_root/script/about +0 -4
  122. data/examples/rails_root/script/autospec +0 -5
  123. data/examples/rails_root/script/console +0 -3
  124. data/examples/rails_root/script/dbconsole +0 -3
  125. data/examples/rails_root/script/delayed_job +0 -5
  126. data/examples/rails_root/script/destroy +0 -3
  127. data/examples/rails_root/script/generate +0 -3
  128. data/examples/rails_root/script/performance/benchmarker +0 -3
  129. data/examples/rails_root/script/performance/profiler +0 -3
  130. data/examples/rails_root/script/performance/request +0 -3
  131. data/examples/rails_root/script/plugin +0 -3
  132. data/examples/rails_root/script/process/inspector +0 -3
  133. data/examples/rails_root/script/process/reaper +0 -3
  134. data/examples/rails_root/script/process/spawner +0 -3
  135. data/examples/rails_root/script/runner +0 -3
  136. data/examples/rails_root/script/server +0 -3
  137. data/examples/rails_root/script/spec +0 -5
  138. data/examples/rails_root/script/spec_server +0 -125
  139. data/examples/rails_root/spec/controllers/welcome_controller_spec.rb +0 -15
  140. data/examples/rails_root/spec/model_factory.rb +0 -6
  141. data/examples/rails_root/spec/models/user_spec.rb +0 -5
  142. data/examples/rails_root/spec/rcov.opts +0 -2
  143. data/examples/rails_root/spec/spec.opts +0 -4
  144. data/examples/rails_root/spec/spec_helper.rb +0 -51
  145. data/examples/sinatra/app.rb +0 -33
  146. data/examples/sinatra/features/step_definitions/email_steps.rb +0 -182
  147. data/examples/sinatra/features/step_definitions/web_steps.rb +0 -273
  148. data/examples/sinatra/features/support/env.rb +0 -39
  149. data/examples/sinatra_root/features/step_definitions/email_steps.rb +0 -194
  150. data/lib/email_spec/#helpers.rb# +0 -168
  151. data/spec/spec.opts +0 -4
@@ -0,0 +1,21 @@
1
+ # Generated by cucumber-sinatra. (Tue Jul 27 10:45:23 -0400 2010)
2
+
3
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib/example_sinatra_app.rb')
4
+ require 'capybara'
5
+ require 'capybara/cucumber'
6
+ require 'rspec/core'
7
+ #require 'activesupport'
8
+ require File.expand_path(File.dirname(__FILE__) + '../../../../../lib/email_spec')
9
+ require 'email_spec/cucumber'
10
+
11
+ ExampleSinatraApp.set(:environment, :test)
12
+
13
+ Capybara.app = ExampleSinatraApp
14
+
15
+ class ExampleSinatraAppWorld
16
+ include Capybara
17
+ end
18
+
19
+ World do
20
+ ExampleSinatraAppWorld.new
21
+ end
@@ -1,18 +1,23 @@
1
+ # Taken from the cucumber-rails project.
2
+
1
3
  module NavigationHelpers
2
4
  # Maps a name to a path. Used by the
3
5
  #
4
6
  # When /^I go to (.+)$/ do |page_name|
5
7
  #
6
- # step definition in webrat_steps.rb
8
+ # step definition in web_steps.rb
7
9
  #
8
10
  def path_to(page_name)
9
11
  case page_name
10
12
 
11
- when /the homepage/
13
+ when /the home\s?page/
12
14
  '/'
13
15
 
14
- when /request a newsletter/
15
- "/newsletter/Joe Someone/example@example.com"
16
+ # Add more mappings here.
17
+ # Here is an example that pulls values out of the Regexp:
18
+ #
19
+ # when /^(.*)'s profile page$/i
20
+ # user_profile_path(User.find_by_login($1))
16
21
 
17
22
  else
18
23
  raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
@@ -0,0 +1,35 @@
1
+ require 'sinatra/base'
2
+ require 'pony'
3
+
4
+ class ExampleSinatraApp < Sinatra::Base
5
+ get '/' do
6
+ <<-EOHTML
7
+ <form method="post" action="/signup">
8
+ <label for="Name">Name</label>
9
+ <input type="text" id="Name" name="user[name]">
10
+ <label for="Email">Email</label>
11
+ <input type="text" id="Email" name="user[email]">
12
+ <input type="submit" value="Sign up">
13
+ </form>
14
+ EOHTML
15
+ end
16
+
17
+ post '/signup' do
18
+ user = params[:user]
19
+ body = <<-EOHTML
20
+ Hello #{user['name']}!
21
+
22
+ <a href="http://www.example.com/confirm">Click here to confirm your account!</a>
23
+ EOHTML
24
+ Pony.mail(:from => 'admin@example.com',
25
+ :to => user['email'],
26
+ :subject => 'Account confirmation',
27
+ :body => body
28
+ )
29
+ 'Thanks! Go check your email!'
30
+ end
31
+
32
+ get '/confirm' do
33
+ 'Confirm your new account!'
34
+ end
35
+ end
@@ -5,11 +5,11 @@ end
5
5
 
6
6
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
7
7
 
8
+ require 'rspec'
8
9
  require 'email_spec/background_processes'
9
10
  require 'email_spec/deliveries'
10
11
  require 'email_spec/address_converter'
11
12
  require 'email_spec/email_viewer'
12
13
  require 'email_spec/helpers'
13
14
  require 'email_spec/matchers'
14
-
15
-
15
+ require 'email_spec/mail_ext'
@@ -9,11 +9,7 @@ module EmailSpec
9
9
  end
10
10
 
11
11
  def reset_mailer
12
- if ActionMailer::Base.delivery_method == :cache
13
- mailer.clear_cache
14
- else
15
- deliveries.clear
16
- end
12
+ deliveries.clear
17
13
  end
18
14
 
19
15
  def mailbox_for(address)
@@ -36,12 +32,12 @@ module EmailSpec
36
32
 
37
33
  module ARMailerDeliveries
38
34
  def all_emails
39
- Email.all.map{ |email| parse_to_tmail(email) }
35
+ Email.all.map{ |email| parse_to_mail(email) }
40
36
  end
41
37
 
42
38
  def last_email_sent
43
39
  if email = Email.last
44
- TMail::Mail.parse(email.mail)
40
+ Mail.read(email.mail)
45
41
  else
46
42
  raise("No email has been sent!")
47
43
  end
@@ -55,11 +51,11 @@ module EmailSpec
55
51
  Email.all.select { |email|
56
52
  (email.to && email.to.include?(address)) ||
57
53
  (email.bcc && email.bcc.include?(address)) ||
58
- (email.cc && email.cc.include?(address)) }.map{ |email| parse_to_tmail(email) }
54
+ (email.cc && email.cc.include?(address)) }.map{ |email| parse_to_mail(email) }
59
55
  end
60
56
 
61
- def parse_to_tmail(email)
62
- TMail::Mail.parse(email.mail)
57
+ def parse_to_mail(email)
58
+ Mail.read(email.mail)
63
59
  end
64
60
  end
65
61
 
@@ -70,7 +66,7 @@ module EmailSpec
70
66
  end
71
67
 
72
68
  def self.mail(options)
73
- deliveries << build_tmail(options)
69
+ deliveries << build_mail(options)
74
70
  end
75
71
  end
76
72
  end
@@ -81,7 +81,7 @@ module EmailSpec
81
81
  end
82
82
 
83
83
  def self.tmp_email_filename(extension = '.txt')
84
- "#{RAILS_ROOT}/tmp/email-#{Time.now.to_i}#{extension}"
84
+ "#{Rails.root}/tmp/email-#{Time.now.to_i}#{extension}"
85
85
  end
86
86
  end
87
87
  end
@@ -12,7 +12,7 @@ module EmailSpec
12
12
 
13
13
  def click_email_link_matching(regex, email = current_email)
14
14
  url = links_in_email(email).detect { |link| link =~ regex }
15
- raise "No link found matching #{regex.inspect} in #{email.body}" unless url
15
+ raise "No link found matching #{regex.inspect} in #{email.default_part_body}" unless url
16
16
  request_uri = URI::parse(url).request_uri
17
17
  visit request_uri
18
18
  end
@@ -40,7 +40,7 @@ module EmailSpec
40
40
  def current_email(address=nil)
41
41
  address = convert_address(address)
42
42
  email = address ? email_spec_hash[:current_emails][address] : email_spec_hash[:current_email]
43
- raise Spec::Expectations::ExpectationNotMetError, "Expected an open email but none was found. Did you forget to call open_email?" unless email
43
+ raise RSpec::Expectations::ExpectationNotMetError, "Expected an open email but none was found. Did you forget to call open_email?" unless email
44
44
  email
45
45
  end
46
46
 
@@ -61,14 +61,14 @@ module EmailSpec
61
61
  if opts[:with_subject]
62
62
  mailbox_for(address).find { |m| m.subject =~ Regexp.new(opts[:with_subject]) }
63
63
  elsif opts[:with_text]
64
- mailbox_for(address).find { |m| m.body =~ Regexp.new(opts[:with_text]) }
64
+ mailbox_for(address).find { |m| m.default_part_body =~ Regexp.new(opts[:with_text]) }
65
65
  else
66
66
  mailbox_for(address).first
67
67
  end
68
68
  end
69
69
 
70
70
  def links_in_email(email)
71
- URI.extract(email.body, ['http', 'https'])
71
+ URI.extract(email.default_part_body.to_s, ['http', 'https'])
72
72
  end
73
73
 
74
74
  private
@@ -81,7 +81,7 @@ module EmailSpec
81
81
  email = find_email(address, opts)
82
82
  if email.nil?
83
83
  error = "#{opts.keys.first.to_s.humanize unless opts.empty?} #{('"' + opts.values.first.to_s.humanize + '"') unless opts.empty?}"
84
- raise Spec::Expectations::ExpectationNotMetError, "Could not find email #{error}. \n Found the following emails:\n\n #{all_emails.to_s}"
84
+ raise RSpec::Expectations::ExpectationNotMetError, "Could not find email #{error}. \n Found the following emails:\n\n #{all_emails.to_s}"
85
85
  end
86
86
  email
87
87
  end
@@ -114,7 +114,7 @@ module EmailSpec
114
114
 
115
115
  # e.g. Click here in <a href="http://confirm">Click here</a>
116
116
  def parse_email_for_anchor_text_link(email, link_text)
117
- if textify_images(email.body) =~ %r{<a[^>]*href=['"]?([^'"]*)['"]?[^>]*?>[^<]*?#{link_text}[^<]*?</a>}
117
+ if textify_images(email.default_part_body) =~ %r{<a[^>]*href=['"]?([^'"]*)['"]?[^>]*?>[^<]*?#{link_text}[^<]*?</a>}
118
118
  URI.split($1)[5..-1].compact!.join("?").gsub("&amp;", "&")
119
119
  # sub correct ampersand after rails switches it (http://dev.rubyonrails.org/ticket/4002)
120
120
  else
@@ -123,7 +123,7 @@ module EmailSpec
123
123
  end
124
124
 
125
125
  def textify_images(email_body)
126
- email_body.gsub(%r{<img[^>]*alt=['"]?([^'"]*)['"]?[^>]*?/>}) { $1 }
126
+ email_body.to_s.gsub(%r{<img[^>]*alt=['"]?([^'"]*)['"]?[^>]*?/>}) { $1 }
127
127
  end
128
128
 
129
129
  def parse_email_count(amount)
@@ -0,0 +1,11 @@
1
+ module EmailSpec::MailExt
2
+ def default_part
3
+ @default_part ||= html_part || text_part || self
4
+ end
5
+
6
+ def default_part_body
7
+ default_part.body
8
+ end
9
+ end
10
+
11
+ Mail::Message.send(:include, EmailSpec::MailExt)
@@ -2,11 +2,11 @@ module EmailSpec
2
2
  module Matchers
3
3
  class ReplyTo
4
4
  def initialize(email)
5
- @expected_reply_to = TMail::Address.parse(email)
5
+ @expected_reply_to = Mail::ReplyToField.new(email).addrs.first
6
6
  end
7
7
 
8
8
  def description
9
- "have reply to as #{@expected_reply_to.address.to_s}"
9
+ "have reply to as #{@expected_reply_to.address}"
10
10
  end
11
11
 
12
12
  def matches?(email)
@@ -21,7 +21,7 @@ module EmailSpec
21
21
  end
22
22
 
23
23
  def negative_failure_message
24
- "expected #{@email.inspect} not to deliver to #{@expected_reply_to.inspect}, but it did"
24
+ "expected #{@email.inspect} not to deliver to #{@expected_reply_to.address.inspect}, but it did"
25
25
  end
26
26
  end
27
27
 
@@ -68,20 +68,20 @@ module EmailSpec
68
68
  class DeliverFrom
69
69
 
70
70
  def initialize(email)
71
- @expected_sender = TMail::Address.parse(email)
71
+ @expected_sender = Mail::FromField.new(email).addrs.first
72
72
  end
73
73
 
74
74
  def description
75
- "be delivered from #{@expected_sender.to_s}"
75
+ "be delivered from #{@expected_sender}"
76
76
  end
77
77
 
78
78
  def matches?(email)
79
79
  @email = email
80
- @actual_sender = (email.from_addrs || []).first
80
+ @actual_sender = (email.header[:from].addrs || []).first
81
81
 
82
82
  !@actual_sender.nil? &&
83
83
  @actual_sender.address == @expected_sender.address &&
84
- @actual_sender.name == @expected_sender.name
84
+ @actual_sender.display_name == @expected_sender.display_name
85
85
  end
86
86
 
87
87
  def failure_message
@@ -132,11 +132,11 @@ module EmailSpec
132
132
  BccTo.new(expected_email_addresses_or_objects_that_respond_to_email.flatten)
133
133
  end
134
134
 
135
- Spec::Matchers.define :have_subject do
135
+ RSpec::Matchers.define :have_subject do
136
136
  match do |given|
137
137
  given_subject = given.subject
138
138
  expected_subject = expected.first
139
-
139
+
140
140
  if expected_subject.is_a?(String)
141
141
  description { "have subject of #{expected_subject.inspect}" }
142
142
  failure_message_for_should { "expected the subject to be #{expected_subject.inspect} but was #{given_subject.inspect}" }
@@ -152,66 +152,71 @@ module EmailSpec
152
152
  end
153
153
  end
154
154
  end
155
-
156
- Spec::Matchers.define :include_email_with_subject do
155
+
156
+ RSpec::Matchers.define :include_email_with_subject do
157
157
  match do |given_emails|
158
158
  expected_subject = expected.first
159
-
159
+
160
160
  if expected_subject.is_a?(String)
161
161
  description { "include email with subject of #{expected_subject.inspect}" }
162
162
  failure_message_for_should { "expected at least one email to have the subject #{expected_subject.inspect} but none did. Subjects were #{given_emails.map(&:subject).inspect}" }
163
163
  failure_message_for_should_not { "expected no email with the subject #{expected_subject.inspect} but found at least one. Subjects were #{given_emails.map(&:subject).inspect}" }
164
-
164
+
165
165
  given_emails.map(&:subject).include?(expected_subject)
166
166
  else
167
167
  description { "include email with subject matching #{expected_subject.inspect}" }
168
168
  failure_message_for_should { "expected at least one email to have a subject matching #{expected_subject.inspect}, but none did. Subjects were #{given_emails.map(&:subject).inspect}" }
169
169
  failure_message_for_should_not { "expected no email to have a subject matching #{expected_subject.inspect} but found at least one. Subjects were #{given_emails.map(&:subject).inspect}" }
170
-
170
+
171
171
  !!(given_emails.any?{ |mail| mail.subject =~ expected_subject })
172
172
  end
173
173
  end
174
174
  end
175
175
 
176
- Spec::Matchers.define :have_body_text do
176
+ RSpec::Matchers.define :have_body_text do
177
177
  match do |given|
178
178
  expected_text = expected.first
179
-
179
+
180
180
  if expected_text.is_a?(String)
181
- normalized_body = given.body.gsub(/\s+/, " ")
181
+ normalized_body = given.default_part_body.to_s.gsub(/\s+/, " ")
182
182
  normalized_expected = expected_text.gsub(/\s+/, " ")
183
183
  description { "have body including #{normalized_expected.inspect}" }
184
184
  failure_message_for_should { "expected the body to contain #{normalized_expected.inspect} but was #{normalized_body.inspect}" }
185
185
  failure_message_for_should_not { "expected the body not to contain #{normalized_expected.inspect} but was #{normalized_body.inspect}" }
186
-
186
+
187
187
  normalized_body.include?(normalized_expected)
188
188
  else
189
- given_body = given.body
189
+ given_body = given.default_part_body.to_s
190
190
  description { "have body matching #{expected_text.inspect}" }
191
191
  failure_message_for_should { "expected the body to match #{expected_text.inspect}, but did not. Actual body was: #{given_body.inspect}" }
192
192
  failure_message_for_should_not { "expected the body not to match #{expected_text.inspect} but #{given_body.inspect} does match it." }
193
-
193
+
194
194
  !!(given_body =~ expected_text)
195
195
  end
196
196
  end
197
197
  end
198
198
 
199
- Spec::Matchers.define :have_header do
199
+ def mail_headers_hash(email_headers)
200
+ email_headers.fields.inject({}) { |hash, field| hash[field.field.class::FIELD_NAME] = field.to_s; hash }
201
+ end
202
+
203
+ RSpec::Matchers.define :have_header do
200
204
  match do |given|
201
205
  given_header = given.header
202
206
  expected_name, expected_value = *expected
203
207
 
204
208
  if expected_value.is_a?(String)
205
209
  description { "have header #{expected_name}: #{expected_value}" }
206
- failure_message_for_should { "expected the headers to include '#{expected_name}: #{expected_value}' but they were #{given_header.inspect}" }
207
- failure_message_for_should_not { "expected the headers not to include '#{expected_name}: #{expected_value}' but they were #{given_header.inspect}" }
208
210
 
211
+ failure_message_for_should { "expected the headers to include '#{expected_name}: #{expected_value}' but they were #{mail_headers_hash(given_header).inspect}" }
212
+ failure_message_for_should_not { "expected the headers not to include '#{expected_name}: #{expected_value}' but they were #{mail_headers_hash(given_header).inspect}" }
213
+
209
214
  given_header[expected_name].to_s == expected_value
210
215
  else
211
216
  description { "have header #{expected_name} with value matching #{expected_value.inspect}" }
212
- failure_message_for_should { "expected the headers to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{given_header.inspect}" }
213
- failure_message_for_should_not { "expected the headers not to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{given_header.inspect}" }
214
-
217
+ failure_message_for_should { "expected the headers to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{mail_headers_hash(given_header).inspect}" }
218
+ failure_message_for_should_not { "expected the headers not to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{mail_headers_hash(given_header).inspect}" }
219
+
215
220
  given_header[expected_name].to_s =~ expected_value
216
221
  end
217
222
  end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Creates email_steps.rb in your cucumber step_definitions.
3
+
4
+ Examples:
5
+ `script/rails generate email_spec:steps`
@@ -0,0 +1,14 @@
1
+ # This generator adds email steps to the step definitions directory
2
+ require 'rails/generators'
3
+
4
+ module EmailSpec
5
+ class StepsGenerator < Rails::Generators::Base
6
+ def generate
7
+ copy_file 'email_steps.rb', 'features/step_definitions/email_steps.rb'
8
+ end
9
+
10
+ def self.source_root
11
+ File.join(File.dirname(__FILE__), 'templates')
12
+ end
13
+ end
14
+ end
@@ -4,20 +4,18 @@ describe EmailSpec::Helpers do
4
4
  include EmailSpec::Helpers
5
5
  describe "#parse_email_for_link" do
6
6
  it "properly finds links with text" do
7
- email = stub(:has_body_text? => true,
8
- :body => %(<a href="/path/to/page">Click Here</a>))
7
+ email = Mail.new(:body => %(<a href="/path/to/page">Click Here</a>))
9
8
  parse_email_for_link(email, "Click Here").should == "/path/to/page"
10
9
  end
11
10
 
12
11
  it "recognizes img alt properties as text" do
13
- email = stub(:has_body_text? => true,
14
- :body => %(<a href="/path/to/page"><img src="http://host.com/images/image.gif" alt="an image" /></a>))
12
+ email = Mail.new(:body => %(<a href="/path/to/page"><img src="http://host.com/images/image.gif" alt="an image" /></a>))
15
13
  parse_email_for_link(email, "an image").should == "/path/to/page"
16
14
  end
17
15
 
18
16
  it "causes a spec to fail if the body doesn't contain the text specified to click" do
19
- email = stub(:has_body_text? => false, :body => "hello")
20
- lambda { parse_email_for_link(email, "non-existent text") }.should raise_error(Spec::Expectations::ExpectationNotMetError)
17
+ email = Mail.new(:body => "")
18
+ lambda { parse_email_for_link(email, "non-existent text") }.should raise_error( RSpec::Expectations::ExpectationNotMetError)
21
19
  end
22
20
  end
23
21
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe EmailSpec::MailExt do
4
+ describe "#default_part" do
5
+ it "prefers html_part over text_part" do
6
+ email = Mail.new do
7
+ text_part { body "This is text" }
8
+ html_part { body "This is html" }
9
+ end
10
+
11
+ email.default_part.body.to_s.should == "This is html"
12
+ end
13
+
14
+ it "returns text_part if html_part not available" do
15
+ email = Mail.new do
16
+ text_part { body "This is text" }
17
+ end
18
+
19
+ email.default_part.body.to_s.should == "This is text"
20
+ end
21
+
22
+ it "returns the email if not multi-part" do
23
+ email = Mail.new { body "This is the body" }
24
+ email.default_part.body.to_s.should == "This is the body"
25
+ end
26
+ end
27
+
28
+ describe "#default_part_body" do
29
+ it "returns default_part.body" do
30
+ email = Mail.new(:body => "hi")
31
+ email.default_part.body.should == email.default_part_body
32
+ end
33
+ end
34
+ end