email_spec 1.6.0 → 2.0.0

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 (118) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +18 -0
  3. data/README.md +30 -28
  4. data/examples/rails4_root/Gemfile +19 -0
  5. data/examples/rails4_root/Gemfile.lock +180 -0
  6. data/examples/rails4_root/README +5 -0
  7. data/examples/rails4_root/Rakefile +11 -0
  8. data/examples/rails4_root/app/controllers/application_controller.rb +3 -0
  9. data/examples/rails4_root/app/controllers/welcome_controller.rb +18 -0
  10. data/examples/rails4_root/app/helpers/application_helper.rb +2 -0
  11. data/examples/rails4_root/app/mailers/user_mailer.rb +39 -0
  12. data/examples/rails4_root/app/models/user.rb +2 -0
  13. data/examples/rails4_root/app/views/user_mailer/email_with_attachment.html.erb +6 -0
  14. data/examples/rails4_root/app/views/user_mailer/newsletter.html.erb +8 -0
  15. data/examples/rails4_root/app/views/user_mailer/signup.html.erb +4 -0
  16. data/examples/rails4_root/app/views/user_mailer/signup.text.erb +4 -0
  17. data/examples/rails4_root/app/views/welcome/attachments.html.erb +0 -0
  18. data/examples/rails4_root/app/views/welcome/confirm.html.erb +1 -0
  19. data/examples/rails4_root/app/views/welcome/index.html.erb +8 -0
  20. data/examples/rails4_root/app/views/welcome/newsletter.html.erb +0 -0
  21. data/examples/rails4_root/app/views/welcome/signup.html.erb +1 -0
  22. data/examples/rails4_root/attachments/document.pdf +0 -0
  23. data/examples/rails4_root/attachments/image.png +0 -0
  24. data/examples/rails4_root/config.ru +4 -0
  25. data/examples/rails4_root/config/application.rb +45 -0
  26. data/examples/rails4_root/config/boot.rb +14 -0
  27. data/examples/rails4_root/config/cucumber.yml +8 -0
  28. data/examples/rails4_root/config/database.yml +25 -0
  29. data/examples/rails4_root/config/environment.rb +6 -0
  30. data/examples/rails4_root/config/environments/development.rb +19 -0
  31. data/examples/rails4_root/config/environments/production.rb +42 -0
  32. data/examples/rails4_root/config/environments/test.rb +32 -0
  33. data/examples/rails4_root/config/initializers/backtrace_silencers.rb +7 -0
  34. data/examples/rails4_root/config/initializers/cookie_verification_secret.rb +7 -0
  35. data/examples/rails4_root/config/initializers/delayed_job.rb +1 -0
  36. data/examples/rails4_root/config/initializers/inflections.rb +10 -0
  37. data/examples/rails4_root/config/initializers/mime_types.rb +5 -0
  38. data/examples/rails4_root/config/initializers/notifier_job.rb +1 -0
  39. data/examples/rails4_root/config/initializers/rspec_generator.rb +6 -0
  40. data/examples/rails4_root/config/initializers/session_store.rb +10 -0
  41. data/examples/rails4_root/config/locales/en.yml +5 -0
  42. data/examples/rails4_root/config/routes.rb +7 -0
  43. data/examples/rails4_root/config/secrets.yml +22 -0
  44. data/examples/rails4_root/db/migrate/20090125013728_create_users.rb +11 -0
  45. data/examples/rails4_root/db/migrate/20090908054656_create_delayed_jobs.rb +20 -0
  46. data/examples/rails4_root/db/migrate/20141119224309_add_queue_to_delayed_jobs.rb +9 -0
  47. data/examples/rails4_root/db/schema.rb +35 -0
  48. data/examples/rails4_root/db/seeds.rb +7 -0
  49. data/examples/rails4_root/db/test.sqlite3 +0 -0
  50. data/examples/rails4_root/doc/README_FOR_APP +2 -0
  51. data/examples/rails4_root/features/attachments.feature +27 -0
  52. data/examples/rails4_root/features/delayed_job.feature +13 -0
  53. data/examples/rails4_root/features/errors.feature +40 -0
  54. data/examples/rails4_root/features/example.feature +93 -0
  55. data/examples/rails4_root/features/step_definitions/email_steps.rb +210 -0
  56. data/examples/rails4_root/features/step_definitions/user_steps.rb +26 -0
  57. data/examples/rails4_root/features/step_definitions/web_steps.rb +219 -0
  58. data/examples/rails4_root/features/support/env.rb +59 -0
  59. data/examples/rails4_root/features/support/env_ext.rb +4 -0
  60. data/examples/rails4_root/features/support/paths.rb +33 -0
  61. data/examples/rails4_root/lib/notifier_job.rb +5 -0
  62. data/examples/rails4_root/lib/tasks/cucumber.rake +65 -0
  63. data/examples/rails4_root/lib/tasks/rspec.rake +69 -0
  64. data/examples/rails4_root/log/development.log +0 -0
  65. data/examples/rails4_root/log/test.log +43813 -0
  66. data/examples/rails4_root/public/404.html +26 -0
  67. data/examples/rails4_root/public/422.html +26 -0
  68. data/examples/rails4_root/public/500.html +26 -0
  69. data/examples/rails4_root/public/favicon.ico +0 -0
  70. data/examples/rails4_root/public/images/rails.png +0 -0
  71. data/examples/rails4_root/public/javascripts/application.js +2 -0
  72. data/examples/rails4_root/public/javascripts/controls.js +965 -0
  73. data/examples/rails4_root/public/javascripts/dragdrop.js +974 -0
  74. data/examples/rails4_root/public/javascripts/effects.js +1123 -0
  75. data/examples/rails4_root/public/javascripts/prototype.js +4874 -0
  76. data/examples/rails4_root/public/javascripts/rails.js +109 -0
  77. data/examples/rails4_root/public/robots.txt +5 -0
  78. data/examples/rails4_root/script/cucumber +10 -0
  79. data/examples/rails4_root/script/delayed_job +5 -0
  80. data/examples/rails4_root/script/rails +9 -0
  81. data/examples/rails4_root/spec/controllers/welcome_controller_spec.rb +20 -0
  82. data/examples/rails4_root/spec/models/user_mailer_spec.rb +47 -0
  83. data/examples/rails4_root/spec/spec_helper.rb +20 -0
  84. data/examples/rails4_root/test/mailers/user_mailer_classic_test.rb +27 -0
  85. data/examples/rails4_root/test/mailers/user_mailer_spec_test.rb +29 -0
  86. data/examples/rails4_root/test/test_helper.rb +10 -0
  87. data/{rails_generators → examples/rails4_root/vendor/plugins/email_spec/rails_generators}/email_spec/email_spec_generator.rb +0 -0
  88. data/{rails_generators → examples/rails4_root/vendor/plugins/email_spec/rails_generators}/email_spec/templates/email_steps.rb +22 -18
  89. data/examples/sinatra_root/Gemfile +15 -0
  90. data/examples/sinatra_root/Gemfile.lock +95 -0
  91. data/examples/sinatra_root/config.ru +4 -0
  92. data/examples/sinatra_root/features/errors.feature +40 -0
  93. data/examples/sinatra_root/features/example.feature +93 -0
  94. data/examples/sinatra_root/features/step_definitions/email_steps.rb +210 -0
  95. data/examples/sinatra_root/features/step_definitions/user_steps.rb +26 -0
  96. data/examples/sinatra_root/features/step_definitions/web_steps.rb +219 -0
  97. data/examples/sinatra_root/features/support/env.rb +21 -0
  98. data/examples/sinatra_root/features/support/paths.rb +29 -0
  99. data/examples/sinatra_root/lib/example_sinatra_app.rb +45 -0
  100. data/features/rails4_app.feature +32 -0
  101. data/features/sinatra_app.feature +14 -0
  102. data/features/step_definitions/app_steps.rb +58 -0
  103. data/features/support/env.rb +16 -0
  104. data/lib/email_spec.rb +1 -1
  105. data/lib/email_spec/deliveries.rb +0 -1
  106. data/lib/email_spec/email_viewer.rb +1 -1
  107. data/lib/email_spec/helpers.rb +16 -5
  108. data/lib/email_spec/matchers.rb +2 -1
  109. data/lib/email_spec/version.rb +3 -0
  110. data/lib/generators/email_spec/steps/templates/email_steps.rb +24 -20
  111. data/spec/email_spec/email_viewer_spec.rb +20 -0
  112. data/spec/email_spec/helpers_spec.rb +316 -0
  113. data/spec/email_spec/mail_ext_spec.rb +34 -0
  114. data/spec/email_spec/matchers_spec.rb +513 -0
  115. data/spec/spec_helper.rb +24 -0
  116. metadata +161 -150
  117. data/lib/email_spec/background_processes.rb +0 -45
  118. data/lib/generators/email_spec/steps/USAGE +0 -5
@@ -0,0 +1,316 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe EmailSpec::Helpers do
4
+ include EmailSpec::Helpers
5
+
6
+ describe "#visit_in_email" do
7
+ it "visits the link in the email" do
8
+ @to = "jimmy_bean@yahoo.com"
9
+ @body = "<a href='/hello'>Hello!</a>"
10
+ @email = Mail::Message.new(:to => @to, :from => "foo@bar.com", :body => @body)
11
+ allow(self).to receive(:mailbox_for).with(@to).and_return([@email])
12
+ expect(open_email(@to, :from => "foo@bar.com")).to eq(@email)
13
+
14
+ expect do
15
+ expect(self).to(receive(:visit).with('/hello'))
16
+ visit_in_email("Hello!")
17
+ end.not_to raise_error
18
+ end
19
+
20
+ it "raises an exception when an email is not found" do
21
+ expect do
22
+ visit_in_email("Hello!", 'jon@example.com')
23
+ end.to raise_error(EmailSpec::CouldNotFindEmailError)
24
+ end
25
+ end
26
+
27
+ describe "#parse_email_for_link" do
28
+ it "properly finds links with text" do
29
+ email = Mail.new(:body => %(<a href="/path/to/page">Click Here</a>))
30
+ expect(parse_email_for_link(email, "Click Here")).to eq("/path/to/page")
31
+ end
32
+
33
+ it "properly finds links with text surrounded by tags" do
34
+ email = Mail.new(:body => %(<a href="/path/to/page"><strong>Click Here</strong></a>))
35
+ expect(parse_email_for_link(email, "Click Here")).to eq("/path/to/page")
36
+ end
37
+
38
+ it "recognizes img alt properties as text" do
39
+ email = Mail.new(:body => %(<a href="/path/to/page"><img src="http://host.com/images/image.gif" alt="an image" /></a>))
40
+ expect(parse_email_for_link(email, "an image")).to eq("/path/to/page")
41
+ end
42
+
43
+ it "causes a spec to fail if the body doesn't contain the text specified to click" do
44
+ email = Mail.new(:body => "")
45
+ expect { parse_email_for_link(email, "non-existent text") }.to raise_error( RSpec::Expectations::ExpectationNotMetError)
46
+ end
47
+ end
48
+
49
+ describe "#set_current_email" do
50
+ it "should cope with a nil email" do
51
+ expect do
52
+ out = set_current_email(nil)
53
+ expect(out).to be_nil
54
+ expect(email_spec_hash[:current_email]).to be_nil
55
+ end.not_to raise_error
56
+ end
57
+
58
+ it "should cope with a real email" do
59
+ email = Mail.new
60
+ expect do
61
+ out = set_current_email(email)
62
+ expect(out).to eq(email)
63
+ expect(email_spec_hash[:current_email]).to eq(email)
64
+ end.not_to raise_error
65
+ end
66
+
67
+ shared_examples_for 'something that sets the current email for recipients' do
68
+ before do
69
+ @email = Mail.new(@recipient_type => 'dave@example.com')
70
+ end
71
+
72
+ it "should record that the email has been read for that recipient" do
73
+ set_current_email(@email)
74
+ expect(email_spec_hash[:read_emails]['dave@example.com']).to include(@email)
75
+ end
76
+
77
+ it "should record that the email has been read for all the recipient of that type" do
78
+ @email.send(@recipient_type) << 'dave_2@example.com'
79
+ set_current_email(@email)
80
+ expect(email_spec_hash[:read_emails]['dave@example.com']).to include(@email)
81
+ expect(email_spec_hash[:read_emails]['dave_2@example.com']).to include(@email)
82
+ end
83
+
84
+ it "should record that the email is the current email for the recipient" do
85
+ set_current_email(@email)
86
+ expect(email_spec_hash[:current_emails]['dave@example.com']).to eq(@email)
87
+ end
88
+
89
+ it "should record that the email is the current email for all the recipients of that type" do
90
+ @email.send(@recipient_type) << 'dave_2@example.com'
91
+ set_current_email(@email)
92
+ expect(email_spec_hash[:current_emails]['dave@example.com']).to eq(@email)
93
+ expect(email_spec_hash[:current_emails]['dave_2@example.com']).to eq(@email)
94
+ end
95
+
96
+ it "should overwrite current email for the recipient with this one" do
97
+ other_mail = Mail.new
98
+ email_spec_hash[:current_emails]['dave@example.com'] = other_mail
99
+ set_current_email(@email)
100
+ expect(email_spec_hash[:current_emails]['dave@example.com']).to eq(@email)
101
+ end
102
+
103
+ it "should overwrite the current email for all the recipients of that type" do
104
+ other_mail = Mail.new
105
+ email_spec_hash[:current_emails]['dave@example.com'] = other_mail
106
+ email_spec_hash[:current_emails]['dave_2@example.com'] = other_mail
107
+ @email.send(@recipient_type) << 'dave_2@example.com'
108
+ set_current_email(@email)
109
+ expect(email_spec_hash[:current_emails]['dave@example.com']).to eq(@email)
110
+ expect(email_spec_hash[:current_emails]['dave_2@example.com']).to eq(@email)
111
+ end
112
+
113
+ it "should not complain when the email has recipients of that type" do
114
+ @email.send(:"#{@recipient_type}=", nil)
115
+ expect { set_current_email(@email) }.not_to raise_error
116
+ end
117
+ end
118
+
119
+ describe "#request_uri(link)" do
120
+ context "without query and anchor" do
121
+ it "returns the path" do
122
+ expect(request_uri('http://www.path.se/to/page')).to eq('/to/page')
123
+ end
124
+ end
125
+
126
+ context "with query and anchor" do
127
+ it "returns the path and query and the anchor" do
128
+ expect(request_uri('http://www.path.se/to/page?q=adam#task')).to eq('/to/page?q=adam#task')
129
+ end
130
+ end
131
+
132
+ context "with anchor" do
133
+ it "returns the path and query and the anchor" do
134
+ expect(request_uri('http://www.path.se/to/page#task')).to eq('/to/page#task')
135
+ end
136
+ end
137
+ end
138
+
139
+ describe 'for mails with recipients in the to address' do
140
+ before do
141
+ @recipient_type = :to
142
+ end
143
+
144
+ it_should_behave_like 'something that sets the current email for recipients'
145
+ end
146
+
147
+ describe 'for mails with recipients in the cc address' do
148
+ before do
149
+ @recipient_type = :cc
150
+ end
151
+
152
+ it_should_behave_like 'something that sets the current email for recipients'
153
+ end
154
+
155
+ describe 'for mails with recipients in the bcc address' do
156
+ before do
157
+ @recipient_type = :bcc
158
+ end
159
+
160
+ it_should_behave_like 'something that sets the current email for recipients'
161
+ end
162
+ end
163
+
164
+ describe '#open_email' do
165
+
166
+ describe 'from' do
167
+
168
+ before do
169
+ @to = "jimmy_bean@yahoo.com"
170
+ @email = Mail::Message.new(:to => @to, :from => "foo@bar.com")
171
+ allow(self).to receive(:mailbox_for).with(@to).and_return([@email])
172
+ end
173
+
174
+ it "should open the email from someone" do
175
+ expect(open_email(@to, :from => "foo@bar.com")).to eq(@email)
176
+ end
177
+
178
+ end
179
+
180
+ describe 'with subject' do
181
+ shared_examples_for 'something that opens the email with subject' do
182
+ before do
183
+ @to = "jimmy_bean@yahoo.com"
184
+ @email = Mail::Message.new(:to => @to, :subject => @subject)
185
+ allow(self).to receive(:mailbox_for).with(@to).and_return([@email])
186
+ end
187
+
188
+ it "should open the email with subject" do
189
+ expect(open_email(@to, :with_subject => @expected)).to eq(@email)
190
+ end
191
+ end
192
+
193
+ describe 'simple string subject' do
194
+ before do
195
+ @subject = 'This is a simple subject'
196
+ @expected = 'a simple'
197
+ end
198
+
199
+ it_should_behave_like 'something that opens the email with subject'
200
+ end
201
+
202
+ describe 'string with regex sensitive characters' do
203
+ before do
204
+ @subject = '[app name] Contains regex characters?'
205
+ @expected = 'regex characters?'
206
+ end
207
+
208
+ it_should_behave_like 'something that opens the email with subject'
209
+ end
210
+
211
+ describe 'regular expression' do
212
+ before do
213
+ @subject = "This is a simple subject"
214
+ @expected = /a simple/
215
+ end
216
+
217
+ it_should_behave_like 'something that opens the email with subject'
218
+ end
219
+ end
220
+
221
+ describe 'with text' do
222
+ shared_examples_for 'something that opens the email with text' do
223
+ before do
224
+ @to = "jimmy_bean@yahoo.com"
225
+ @email = Mail::Message.new(:to => @to, :body => @body)
226
+ allow(self).to receive(:mailbox_for).with(@to).and_return([@email])
227
+ end
228
+
229
+ it "should open the email with text" do
230
+ expect(open_email(@to, :with_text => @text)).to eq(@email)
231
+ end
232
+ end
233
+
234
+ describe 'simple string text' do
235
+ before do
236
+ @body = 'This is an email body that is very simple'
237
+ @text = 'email body'
238
+ end
239
+
240
+ it_should_behave_like 'something that opens the email with text'
241
+ end
242
+
243
+ describe 'string with regex sensitive characters' do
244
+ before do
245
+ @body = 'This is an email body. It contains some [regex] characters?'
246
+ @text = '[regex] characters?'
247
+ end
248
+
249
+ it_should_behave_like 'something that opens the email with text'
250
+ end
251
+
252
+ describe 'regular expression' do
253
+ before do
254
+ @body = 'This is an email body.'
255
+ @text = /an\ email/
256
+ end
257
+
258
+ it_should_behave_like 'something that opens the email with text'
259
+ end
260
+ end
261
+
262
+ describe "when the email isn't found" do
263
+ it "includes the mailbox that was looked in when an address was provided" do
264
+ @email_address = "foo@bar.com"
265
+ expect { open_email(@email_address, :with_subject => "baz") }.to raise_error(EmailSpec::CouldNotFindEmailError) { |error| expect(error.message).to include(@email_address) }
266
+ end
267
+
268
+ it "includes a warning that no mailboxes were searched when no address was provided" do
269
+ allow(subject).to receive(:last_email_address).and_return nil
270
+ expect { open_email(nil, :with_subject => "baz") }.to raise_error(EmailSpec::NoEmailAddressProvided) { |error| expect(error.message).to eq("No email address has been provided. Make sure current_email_address is returning something.") }
271
+ end
272
+
273
+ describe "search by with_subject" do
274
+ before do
275
+ @email_subject = "Subject of 'Nonexistent Email'"
276
+ begin
277
+ open_email("foo@bar.com", :with_subject => @email_subject)
278
+ rescue EmailSpec::CouldNotFindEmailError => e
279
+ @error = e
280
+ end
281
+
282
+ expect(@error).not_to be_nil, "expected an error to get thrown so we could test against it, but didn't catch one"
283
+ end
284
+
285
+ it "includes the subject that wasn't found in the error message" do
286
+ expect(@error.message).to include(@email_subject)
287
+ end
288
+
289
+ it "includes 'with subject' in the error message" do
290
+ expect(@error.message).to include('with subject')
291
+ end
292
+ end
293
+
294
+ describe "search by with_text" do
295
+ before do
296
+ @email_text = "This is a line of text from a 'Nonexistent Email'."
297
+ begin
298
+ open_email("foo@bar.com", :with_text => @email_text)
299
+ rescue EmailSpec::CouldNotFindEmailError => e
300
+ @error = e
301
+ end
302
+
303
+ expect(@error).not_to be_nil, "expected an error to get thrown so we could test against it, but didn't catch one"
304
+ end
305
+
306
+ it "includes the text that wasn't found in the error message" do
307
+ expect(@error.message).to include(@email_text)
308
+ end
309
+
310
+ it "includes 'with text' in the error message" do
311
+ expect(@error.message).to include('with text')
312
+ end
313
+ end
314
+ end
315
+ end
316
+ 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
+ expect(email.default_part.body.to_s).to eq("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
+ expect(email.default_part.body.to_s).to eq("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
+ expect(email.default_part.body.to_s).to eq("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
+ expect(email.default_part.body).to eq(email.default_part_body)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,513 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe EmailSpec::Matchers do
4
+ include EmailSpec::Matchers
5
+
6
+ class MatcherMatch
7
+ def initialize(object_to_test_match)
8
+ @object_to_test_match = object_to_test_match
9
+ end
10
+
11
+ def description
12
+ "match when provided #{@object_to_test_match.inspect}"
13
+ end
14
+
15
+ def matches?(matcher)
16
+ @matcher = matcher
17
+ matcher.matches?(@object_to_test_match)
18
+ end
19
+
20
+ def failure_message
21
+ "expected #{@matcher.inspect} to match when provided #{@object_to_test_match.inspect}, but it did not"
22
+ end
23
+
24
+ def failure_message_when_negated
25
+ "expected #{@matcher.inspect} not to match when provided #{@object_to_test_match.inspect}, but it did"
26
+ end
27
+ alias negative_failure_message failure_message_when_negated
28
+ end
29
+
30
+ def match(object_to_test_match)
31
+ if object_to_test_match.is_a?(Regexp)
32
+ super # delegate to rspec's built in 'match' matcher
33
+ else
34
+ MatcherMatch.new(object_to_test_match)
35
+ end
36
+ end
37
+
38
+ describe "#reply_to" do
39
+ it "should match when the email is set to deliver to the specified address" do
40
+ email = Mail::Message.new(:reply_to => ["test@gmail.com"])
41
+ expect(reply_to("test@gmail.com")).to match(email)
42
+ end
43
+
44
+ it "should match given a name and address" do
45
+ email = Mail::Message.new(:reply_to => ["test@gmail.com"])
46
+ expect(reply_to("David Balatero <test@gmail.com>")).to match(email)
47
+ end
48
+
49
+ it "should give correct failure message when the email is not set to deliver to the specified address" do
50
+ matcher = reply_to("jimmy_bean@yahoo.com")
51
+ message = Mail::Message.new(:reply_to => ['freddy_noe@yahoo.com'])
52
+ allow(message).to receive(:inspect).and_return("email")
53
+ matcher.matches?(message)
54
+ expect(matcher_failure_message(matcher)).to eq(%{expected email to reply to "jimmy_bean@yahoo.com", but it replied to "freddy_noe@yahoo.com"})
55
+ end
56
+
57
+ end
58
+
59
+ describe "#deliver_to" do
60
+ it "should match when the email is set to deliver to the specified address" do
61
+ email = Mail::Message.new(:to => "jimmy_bean@yahoo.com")
62
+
63
+ expect(deliver_to("jimmy_bean@yahoo.com")).to match(email)
64
+ end
65
+
66
+ it "should match when the email is set to deliver to the specified name and address" do
67
+ email = Mail::Message.new(:to => "Jimmy Bean <jimmy_bean@yahoo.com>")
68
+ expect(deliver_to("Jimmy Bean <jimmy_bean@yahoo.com>")).to match(email)
69
+ end
70
+
71
+ it "should match when a list of emails is exact same as all of the email's recipients" do
72
+ email = Mail::Message.new(:to => ["james@yahoo.com", "karen@yahoo.com"])
73
+
74
+ expect(deliver_to("karen@yahoo.com", "james@yahoo.com")).to match(email)
75
+ expect(deliver_to("karen@yahoo.com")).not_to match(email)
76
+ end
77
+
78
+ it "should match when an array of emails is exact same as all of the email's recipients" do
79
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
80
+ email = Mail::Message.new(:to => addresses)
81
+ expect(deliver_to(addresses)).to match(email)
82
+ end
83
+
84
+ it "should match when the names and email addresses match in any order" do
85
+ addresses = ["James <james@yahoo.com>", "Karen <karen@yahoo.com>"]
86
+ email = Mail::Message.new(:to => addresses.reverse)
87
+ expect(deliver_to(addresses)).to match(email)
88
+ end
89
+
90
+ it "should use the passed in objects :email method if not a string" do
91
+ email = Mail::Message.new(:to => "jimmy_bean@yahoo.com")
92
+ user = double("user", :email => "jimmy_bean@yahoo.com")
93
+
94
+ expect(deliver_to(user)).to match(email)
95
+ end
96
+
97
+ it "should not match when the email does not have a recipient" do
98
+ email = Mail::Message.new(:to => nil)
99
+ expect(deliver_to("jimmy_bean@yahoo.com")).not_to match(email)
100
+ end
101
+
102
+ it "should not match when the email addresses match but the names do not" do
103
+ email = Mail::Message.new(:to => "Jimmy Bean <jimmy_bean@yahoo.com>")
104
+ expect(deliver_to("Freddy Noe <jimmy_bean@yahoo.com>")).not_to match(email)
105
+ end
106
+
107
+ it "should not match when the names match but the email addresses do not" do
108
+ email = Mail::Message.new(:to => "Jimmy Bean <jimmy_bean@yahoo.com>")
109
+ expect(deliver_to("Jimmy Bean <freddy_noe@yahoo.com>")).not_to match(email)
110
+ end
111
+
112
+ it "should give correct failure message when the email is not set to deliver to the specified address" do
113
+ matcher = deliver_to("jimmy_bean@yahoo.com")
114
+ message = Mail::Message.new(:to => 'freddy_noe@yahoo.com')
115
+ allow(message).to receive(:inspect).and_return("email")
116
+ matcher.matches?(message)
117
+ expect(matcher_failure_message(matcher)).to eq(%{expected email to deliver to ["jimmy_bean@yahoo.com"], but it delivered to ["freddy_noe@yahoo.com"]})
118
+ end
119
+
120
+ it "should deliver to nobody when the email does not perform deliveries" do
121
+ email = Mail::Message.new(:to => "jimmy_bean@yahoo.com")
122
+ email.perform_deliveries = false
123
+ expect(deliver_to("jimmy_bean@yahoo.com")).not_to match(email)
124
+ end
125
+
126
+ end
127
+
128
+ describe "#deliver_from" do
129
+ it "should match when the email is set to deliver from the specified address" do
130
+ email = Mail::Message.new(:from => "jimmy_bean@yahoo.com")
131
+ expect(deliver_from("jimmy_bean@yahoo.com")).to match(email)
132
+ end
133
+
134
+ it "should match when the email is set to deliver from the specified name and address" do
135
+ email = Mail::Message.new(:from => "Jimmy Bean <jimmy_bean@yahoo.com>")
136
+ expect(deliver_from("Jimmy Bean <jimmy_bean@yahoo.com>")).to match(email)
137
+ end
138
+
139
+ it "should not match when the email does not have a sender" do
140
+ email = Mail::Message.new(:from => nil)
141
+ expect(deliver_from("jimmy_bean@yahoo.com")).not_to match(email)
142
+ end
143
+
144
+ it "should not match when the email addresses match but the names do not" do
145
+ email = Mail::Message.new(:from => "Jimmy Bean <jimmy_bean@yahoo.com>")
146
+ expect(deliver_from("Freddy Noe <jimmy_bean@yahoo.com>")).not_to match(email)
147
+ end
148
+
149
+ it "should not match when the names match but the email addresses do not" do
150
+ email = Mail::Message.new(:from => "Jimmy Bean <jimmy_bean@yahoo.com>")
151
+ expect(deliver_from("Jimmy Bean <freddy_noe@yahoo.com>")).not_to match(email)
152
+ end
153
+
154
+ it "should not match when the email is not set to deliver from the specified address" do
155
+ email = Mail::Message.new(:from => "freddy_noe@yahoo.com")
156
+ expect(deliver_from("jimmy_bean@yahoo.com")).not_to match(email)
157
+ end
158
+
159
+ it "should give correct failure message when the email is not set to deliver from the specified address" do
160
+ matcher = deliver_from("jimmy_bean@yahoo.com")
161
+ matcher.matches?(Mail::Message.new(:from => "freddy_noe@yahoo.com"))
162
+ expect(matcher_failure_message(matcher)).to match(/expected .+ to deliver from "jimmy_bean@yahoo\.com", but it delivered from "freddy_noe@yahoo\.com"/)
163
+ end
164
+
165
+ it "should not deliver from anybody when perform_deliveries is false" do
166
+ email = Mail::Message.new(:from => "freddy_noe@yahoo.com")
167
+ email.perform_deliveries = false
168
+ expect(deliver_from("freddy_noe@yahoo.com")).not_to match(email)
169
+ end
170
+
171
+ end
172
+
173
+ describe "#bcc_to" do
174
+
175
+ it "should match when the email is set to deliver to the specidied address" do
176
+ email = Mail::Message.new(:bcc => "jimmy_bean@yahoo.com")
177
+
178
+ expect(bcc_to("jimmy_bean@yahoo.com")).to match(email)
179
+ end
180
+
181
+ it "should match when a list of emails is exact same as all of the email's recipients" do
182
+ email = Mail::Message.new(:bcc => ["james@yahoo.com", "karen@yahoo.com"])
183
+
184
+ expect(bcc_to("karen@yahoo.com", "james@yahoo.com")).to match(email)
185
+ expect(bcc_to("karen@yahoo.com")).not_to match(email)
186
+ end
187
+
188
+ it "should match when an array of emails is exact same as all of the email's recipients" do
189
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
190
+ email = Mail::Message.new(:bcc => addresses)
191
+ expect(bcc_to(addresses)).to match(email)
192
+ end
193
+
194
+ it "should use the passed in objects :email method if not a string" do
195
+ email = Mail::Message.new(:bcc => "jimmy_bean@yahoo.com")
196
+ user = double("user", :email => "jimmy_bean@yahoo.com")
197
+
198
+ expect(bcc_to(user)).to match(email)
199
+ end
200
+
201
+ it "should bcc to nobody when the email does not perform deliveries" do
202
+ email = Mail::Message.new(:bcc => "jimmy_bean@yahoo.com")
203
+ email.perform_deliveries = false
204
+ expect(bcc_to("jimmy_bean@yahoo.com")).not_to match(email)
205
+ end
206
+
207
+ end
208
+
209
+ describe "#cc_to" do
210
+
211
+ it "should match when the email is set to deliver to the specified address" do
212
+ email = Mail::Message.new(:cc => "jimmy_bean@yahoo.com")
213
+
214
+ expect(cc_to("jimmy_bean@yahoo.com")).to match(email)
215
+ end
216
+
217
+ it "should match when a list of emails is exact same as all of the email's recipients" do
218
+ email = Mail::Message.new(:cc => ["james@yahoo.com", "karen@yahoo.com"])
219
+
220
+ expect(cc_to("karen@yahoo.com", "james@yahoo.com")).to match(email)
221
+ expect(cc_to("karen@yahoo.com")).not_to match(email)
222
+ end
223
+
224
+ it "should match when an array of emails is exact same as all of the email's recipients" do
225
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
226
+ email = Mail::Message.new(:cc => addresses)
227
+ expect(cc_to(addresses)).to match(email)
228
+ end
229
+
230
+ it "should use the passed in objects :email method if not a string" do
231
+ email = Mail::Message.new(:cc => "jimmy_bean@yahoo.com")
232
+ user = double("user", :email => "jimmy_bean@yahoo.com")
233
+
234
+ expect(cc_to(user)).to match(email)
235
+ end
236
+
237
+ it "should cc to nobody when the email does not perform deliveries" do
238
+ email = Mail::Message.new(to: "jimmy_bean@yahoo.com")
239
+ email.perform_deliveries = false
240
+ expect(cc_to("jimmy_bean@yahoo.com")).not_to match(email)
241
+ end
242
+
243
+ end
244
+
245
+ describe "#have_subject" do
246
+
247
+ describe "when regexps are used" do
248
+
249
+ it "should match when the subject matches regexp" do
250
+ email = Mail::Message.new(:subject => ' -- The Subject --')
251
+
252
+ expect(have_subject(/The Subject/)).to match(email)
253
+ expect(have_subject(/foo/)).not_to match(email)
254
+ end
255
+
256
+ it "should have a helpful description" do
257
+ matcher = have_subject(/foo/)
258
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
259
+
260
+ expect(matcher.description).to eq("have subject matching /foo/")
261
+ end
262
+
263
+ it "should offer helpful failing messages" do
264
+ matcher = have_subject(/foo/)
265
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
266
+
267
+ expect(matcher_failure_message(matcher)).to eq('expected the subject to match /foo/, but did not. Actual subject was: "bar"')
268
+ end
269
+
270
+ it "should offer helpful negative failing messages" do
271
+ matcher = have_subject(/b/)
272
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
273
+
274
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected the subject not to match /b/ but "bar" does match it.')
275
+ end
276
+ end
277
+
278
+ describe "when strings are used" do
279
+ it "should match when the subject equals the passed in string exactly" do
280
+ email = Mail::Message.new(:subject => 'foo')
281
+
282
+ expect(have_subject("foo")).to match(email)
283
+ expect(have_subject(" - foo -")).not_to match(email)
284
+ end
285
+
286
+ it "should have a helpful description" do
287
+ matcher = have_subject("foo")
288
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
289
+
290
+ expect(matcher.description).to eq('have subject of "foo"')
291
+ end
292
+
293
+ it "should offer helpful failing messages" do
294
+ matcher = have_subject("foo")
295
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
296
+
297
+ expect(matcher_failure_message(matcher)).to eq('expected the subject to be "foo" but was "bar"')
298
+ end
299
+
300
+ it "should offer helpful negative failing messages" do
301
+ matcher = have_subject("bar")
302
+ matcher.matches?(Mail::Message.new(:subject => "bar"))
303
+
304
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected the subject not to be "bar" but was')
305
+ end
306
+ end
307
+ end
308
+
309
+ describe "#include_email_with_subject" do
310
+
311
+ describe "when regexps are used" do
312
+
313
+ it "should match when any email's subject matches passed in regexp" do
314
+ emails = [Mail::Message.new(:subject => "foobar"), Mail::Message.new(:subject => "bazqux")]
315
+
316
+ expect(include_email_with_subject(/foo/)).to match(emails)
317
+ expect(include_email_with_subject(/quux/)).not_to match(emails)
318
+ end
319
+
320
+ it "should have a helpful description" do
321
+ matcher = include_email_with_subject(/foo/)
322
+ matcher.matches?([])
323
+
324
+ expect(matcher.description).to eq('include email with subject matching /foo/')
325
+ end
326
+
327
+ it "should offer helpful failing messages" do
328
+ matcher = include_email_with_subject(/foo/)
329
+ matcher.matches?([Mail::Message.new(:subject => "bar")])
330
+
331
+ expect(matcher_failure_message(matcher)).to eq('expected at least one email to have a subject matching /foo/, but none did. Subjects were ["bar"]')
332
+ end
333
+
334
+ it "should offer helpful negative failing messages" do
335
+ matcher = include_email_with_subject(/foo/)
336
+ matcher.matches?([Mail::Message.new(:subject => "foo")])
337
+
338
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected no email to have a subject matching /foo/ but found at least one. Subjects were ["foo"]')
339
+ end
340
+ end
341
+
342
+ describe "when strings are used" do
343
+ it "should match when any email's subject equals passed in subject exactly" do
344
+ emails = [Mail::Message.new(:subject => "foobar"), Mail::Message.new(:subject => "bazqux")]
345
+
346
+ expect(include_email_with_subject("foobar")).to match(emails)
347
+ expect(include_email_with_subject("foo")).not_to match(emails)
348
+ end
349
+
350
+ it "should have a helpful description" do
351
+ matcher = include_email_with_subject("foo")
352
+ matcher.matches?([])
353
+
354
+ expect(matcher.description).to eq('include email with subject of "foo"')
355
+ end
356
+
357
+ it "should offer helpful failing messages" do
358
+ matcher = include_email_with_subject("foo")
359
+ matcher.matches?([Mail::Message.new(:subject => "bar")])
360
+
361
+ expect(matcher_failure_message(matcher)).to eq('expected at least one email to have the subject "foo" but none did. Subjects were ["bar"]')
362
+ end
363
+
364
+ it "should offer helpful negative failing messages" do
365
+ matcher = include_email_with_subject("foo")
366
+ matcher.matches?([Mail::Message.new(:subject => "foo")])
367
+
368
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected no email with the subject "foo" but found at least one. Subjects were ["foo"]')
369
+ end
370
+ end
371
+ end
372
+
373
+ describe "#have_body_text" do
374
+ describe "when regexps are used" do
375
+ it "should match when the body matches regexp" do
376
+ email = Mail::Message.new(:body => 'foo bar baz')
377
+
378
+ expect(have_body_text(/bar/)).to match(email)
379
+ expect(have_body_text(/qux/)).not_to match(email)
380
+ end
381
+
382
+ it "should have a helpful description" do
383
+ matcher = have_body_text(/qux/)
384
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
385
+
386
+ expect(matcher.description).to eq('have body matching /qux/')
387
+ end
388
+
389
+ it "should offer helpful failing messages" do
390
+ matcher = have_body_text(/qux/)
391
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
392
+
393
+ expect(matcher_failure_message(matcher)).to eq('expected the body to match /qux/, but did not. Actual body was: "foo bar baz"')
394
+ end
395
+
396
+ it "should offer helpful negative failing messages" do
397
+ matcher = have_body_text(/bar/)
398
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
399
+
400
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected the body not to match /bar/ but "foo bar baz" does match it.')
401
+ end
402
+ end
403
+
404
+ describe "when strings are used" do
405
+ it "should match when the body includes the text" do
406
+ email = Mail::Message.new(:body => 'foo bar baz')
407
+
408
+ expect(have_body_text('bar')).to match(email)
409
+ expect(have_body_text('qux')).not_to match(email)
410
+ end
411
+
412
+ it "should have a helpful description" do
413
+ matcher = have_body_text('qux')
414
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
415
+
416
+ expect(matcher.description).to eq('have body including "qux"')
417
+ end
418
+
419
+ it "should offer helpful failing messages" do
420
+ matcher = have_body_text('qux')
421
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
422
+
423
+ expect(matcher_failure_message(matcher)).to eq('expected the body to contain "qux" but was "foo bar baz"')
424
+ end
425
+
426
+ it "should offer helpful negative failing messages" do
427
+ matcher = have_body_text('bar')
428
+ matcher.matches?(Mail::Message.new(:body => 'foo bar baz'))
429
+
430
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected the body not to contain "bar" but was "foo bar baz"')
431
+ end
432
+ end
433
+
434
+ describe "when dealing with multipart messages" do
435
+ it "should look at the html part" do
436
+ email = Mail.new do
437
+ text_part do
438
+ body "This is text"
439
+ end
440
+ html_part do
441
+ body "This is html"
442
+ end
443
+ end
444
+ expect(have_body_text(/This is html/)).to match(email)
445
+ expect(have_body_text(/This is text/)).not_to match(email)
446
+ end
447
+ end
448
+ end
449
+
450
+ describe "#have_header" do
451
+ describe "when regexps are used" do
452
+ it "should match when header matches passed in regexp" do
453
+ email = Mail::Message.new(:content_type => "text/html")
454
+
455
+ expect(have_header(:content_type, /text/)).to match(email)
456
+ expect(have_header(:foo, /text/)).not_to match(email)
457
+ expect(have_header(:content_type, /bar/)).not_to match(email)
458
+ end
459
+
460
+ it "should have a helpful description" do
461
+ matcher = have_header(:content_type, /bar/)
462
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
463
+
464
+ expect(matcher.description).to eq('have header content_type with value matching /bar/')
465
+ end
466
+
467
+ it "should offer helpful failing messages" do
468
+ matcher = have_header(:content_type, /bar/)
469
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
470
+
471
+ expect(matcher_failure_message(matcher)).to eq('expected the headers to include \'content_type\' with a value matching /bar/ but they were {"content-type"=>"text/html"}')
472
+ end
473
+
474
+ it "should offer helpful negative failing messages" do
475
+ matcher = have_header(:content_type, /text/)
476
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
477
+
478
+ expect(matcher_failure_message_when_negated(matcher)).to eq('expected the headers not to include \'content_type\' with a value matching /text/ but they were {"content-type"=>"text/html"}')
479
+ end
480
+ end
481
+
482
+ describe "when strings are used" do
483
+ it "should match when header equals passed in value exactly" do
484
+ email = Mail::Message.new(:content_type => "text/html")
485
+
486
+ expect(have_header(:content_type, 'text/html')).to match(email)
487
+ expect(have_header(:foo, 'text/html')).not_to match(email)
488
+ expect(have_header(:content_type, 'text')).not_to match(email)
489
+ end
490
+
491
+ it "should have a helpful description" do
492
+ matcher = have_header(:content_type, 'text')
493
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
494
+
495
+ expect(matcher.description).to eq('have header content_type: text')
496
+ end
497
+
498
+ it "should offer helpful failing messages" do
499
+ matcher = have_header(:content_type, 'text')
500
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
501
+
502
+ expect(matcher_failure_message(matcher)).to eq('expected the headers to include \'content_type: text\' but they were {"content-type"=>"text/html"}')
503
+ end
504
+
505
+ it "should offer helpful negative failing messages" do
506
+ matcher = have_header(:content_type, 'text/html')
507
+ matcher.matches?(Mail::Message.new(:content_type => "text/html"))
508
+
509
+ matcher_failure_message_when_negated(matcher) == 'expected the headers not to include \'content_type: text/html\' but they were {:content_type=>"text/html"}'
510
+ end
511
+ end
512
+ end
513
+ end