email_spec 0.6.6 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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