email_spec 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11bdd9e521aecbb968f672214cc109869f111f1ac981b793e1a3c41bcf4691ce
4
- data.tar.gz: 7cd61105485eae764f8786ef4a3e2ccdbd9309f8d020f883177d8d62df7df184
3
+ metadata.gz: 4e0a37bd9d3d9eaa30f18b427930baa52d8b895b50d4d7b831650d621a9c955e
4
+ data.tar.gz: 4193090888bee1123f782507dc6c8496b9bca6ff0aea94612624a48f9d45d65b
5
5
  SHA512:
6
- metadata.gz: 540ed6ea489564623c0ab0c781c70842782b8485307cf70d7396fc0221896ac396cae83a58d72e64586bb879b58a68b3e93b61f24120586657fe9acaea9f9486
7
- data.tar.gz: 57b37098385ff0d8f545e385195693ddf67c04d03d4c37a9219cf4677d36cc2a880e0dea6bca6eed595ac977eb9afd1841062d180e47410ce5ec6fe20c1820fd
6
+ metadata.gz: 97b61a1089f4c29bdcfffca000405a5d66bc2430dca4c9e293090cea5a12ebae9bacc108c3663b9a3961a5f955d59a0870a28c53a19d0782ed9d66ff6cfea15a
7
+ data.tar.gz: b38641514a7ceace6ea75f178865dffd9b910cebbc2eb28fea8c1ea3a7f64786e248900f34dd881f722c251ceb12e5f52f071257cf10b15eb316ad1a2e9e9427
data/Changelog.md CHANGED
@@ -1,6 +1,20 @@
1
+ ## 2.3.0 2024-07-21
2
+
3
+ * [Support the specified name and address for bcc_to and cc_to matchers](https://github.com/email-spec/email-spec/pull/212)
4
+ * [Allow launchy 3.x versions](https://github.com/email-spec/email-spec/pull/226)
5
+ * [Replace deprecated/removed File.exists? alias](https://github.com/email-spec/email-spec/pull/223)
6
+ * [Extend have_body_text matcher to be able to specify which part in multipart to check](https://github.com/email-spec/email-spec/pull/196)
7
+
8
+ ## 2.2.2 2023-06-26
9
+
10
+ * [Defer accommodating different delivery methods to runtime](https://github.com/email-spec/email-spec/pull/224)
11
+
1
12
  ## 2.2.1 2022-09-12
2
13
 
3
- * [Patch for eager loading](https://github.com/email-spec/email-spec/pull/219)
14
+ * [Support to decode part in EmailSpec::MailExt#default_part_body](https://github.com/email-spec/email-spec/pull/211)
15
+ * [Drop rubyforge_project from gemspec](https://github.com/email-spec/email-spec/pull/215)
16
+ * [Avoid eagerly loading ActionMailer::Base](https://github.com/email-spec/email-spec/pull/219)
17
+ * [README: use SVG badges](https://github.com/email-spec/email-spec/pull/217)
4
18
 
5
19
  ## 2.2.0 2018-04-03
6
20
 
data/README.md CHANGED
@@ -302,6 +302,15 @@ expect(email).to have_body_text(/Hi Jojo Binks,/)
302
302
  ```
303
303
 
304
304
 
305
+ You can specify which part in multipart to check with `in_html_part` or
306
+ `in_text_part`.
307
+
308
+ ```ruby
309
+ email = UserMailer.("jojo@yahoo.com", "Jojo Binks")
310
+ expect(email).to have_body_text(/This is html/).in_html_part
311
+ expect(email).to have_body_text(/This is text/).in_text_part
312
+ ```
313
+
305
314
  ##### have_header(key, value)
306
315
 
307
316
  This checks that the expected key/value pair is in the headers of the email.
@@ -0,0 +1,226 @@
1
+ # Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # last_email_address
7
+ # reset_mailer
8
+ # open_last_email
9
+ # visit_in_email
10
+ # unread_emails_for
11
+ # mailbox_for
12
+ # current_email
13
+ # open_email
14
+ # read_emails_for
15
+ # find_email
16
+ #
17
+ # General form for email scenarios are:
18
+ # - clear the email queue (done automatically by email_spec)
19
+ # - execute steps that sends an email
20
+ # - check the user received an/no/[0-9] emails
21
+ # - open the email
22
+ # - inspect the email contents
23
+ # - interact with the email (e.g. click links)
24
+ #
25
+ # The Cucumber steps below are setup in this order.
26
+
27
+ module EmailHelpers
28
+ def current_email_address
29
+ # Replace with your a way to find your current email. e.g @current_user.email
30
+ # last_email_address will return the last email address used by email spec to find an email.
31
+ # Note that last_email_address will be reset after each Scenario.
32
+ last_email_address || "example@example.com"
33
+ end
34
+ end
35
+
36
+ World(EmailHelpers)
37
+
38
+ #
39
+ # Reset the e-mail queue within a scenario.
40
+ # This is done automatically before each scenario.
41
+ #
42
+
43
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
44
+ reset_mailer
45
+ end
46
+
47
+ #
48
+ # Check how many emails have been sent/received
49
+ #
50
+
51
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
52
+ expect(unread_emails_for(address).size).to eql parse_email_count(amount)
53
+ end
54
+
55
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
56
+ expect(mailbox_for(address).size).to eql parse_email_count(amount)
57
+ end
58
+
59
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
60
+ expect(unread_emails_for(address).select { |m| m.subject =~ Regexp.new(Regexp.escape(subject)) }.size).to eql parse_email_count(amount)
61
+ end
62
+
63
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject \/([^"]*?)\/$/ do |address, amount, subject|
64
+ expect(unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size).to eql parse_email_count(amount)
65
+ end
66
+
67
+ Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
68
+ open_email(address, :with_text => expected_body)
69
+ end
70
+
71
+ #
72
+ # Accessing emails
73
+ #
74
+
75
+ # Opens the most recently received email
76
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
77
+ open_email(address)
78
+ end
79
+
80
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
81
+ open_email(address, :with_subject => subject)
82
+ end
83
+
84
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject \/([^"]*?)\/$/ do |address, subject|
85
+ open_email(address, :with_subject => Regexp.new(subject))
86
+ end
87
+
88
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
89
+ open_email(address, :with_text => text)
90
+ end
91
+
92
+ When /^(?:I|they|"([^"]*?)") opens? the email with text \/([^"]*?)\/$/ do |address, text|
93
+ open_email(address, :with_text => Regexp.new(text))
94
+ end
95
+
96
+ #
97
+ # Inspect the Email Contents
98
+ #
99
+
100
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
101
+ expect(current_email).to have_subject(text)
102
+ end
103
+
104
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
105
+ expect(current_email).to have_subject(Regexp.new(text))
106
+ end
107
+
108
+ Then /^(?:I|they) should not see "([^"]*?)" in the email subject$/ do |text|
109
+ expect(current_email).not_to have_subject(text)
110
+ end
111
+
112
+ Then /^(?:I|they) should not see \/([^"]*?)\/ in the email subject$/ do |text|
113
+ expect(current_email).not_to have_subject(Regexp.new(text))
114
+ end
115
+
116
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
117
+ expect(current_email.default_part_body.to_s).to include(text)
118
+ end
119
+
120
+ Then /^(?:I|they) should not see "([^"]*?)" in the email body$/ do |text|
121
+ expect(current_email.default_part_body.to_s).not_to include(text)
122
+ end
123
+
124
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
125
+ expect(current_email.default_part_body.to_s).to match Regexp.new(text)
126
+ end
127
+
128
+ Then /^(?:I|they) should not see \/([^"]*?)\/ in the email body$/ do |text|
129
+ expect(current_email.default_part_body.to_s).not_to match Regexp.new(text)
130
+ end
131
+
132
+ Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
133
+ expect(current_email).to be_delivered_from(text)
134
+ end
135
+
136
+ Then /^(?:I|they) should see the email reply to "([^"]*?)"$/ do |text|
137
+ expect(current_email).to have_reply_to(text)
138
+ end
139
+
140
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
141
+ expect(current_email).to have_header(name, text)
142
+ end
143
+
144
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
145
+ expect(current_email).to have_header(name, Regexp.new(text))
146
+ end
147
+
148
+ Then /^I should see it is a multi\-part email$/ do
149
+ expect(current_email).to be_multipart
150
+ end
151
+
152
+ Then /^(?:I|they) should see "([^"]*?)" in the email html part body$/ do |text|
153
+ expect(current_email.html_part.body.to_s).to include(text)
154
+ end
155
+
156
+ Then /^(?:I|they) should see "([^"]*?)" in the email text part body$/ do |text|
157
+ expect(current_email.text_part.body.to_s).to include(text)
158
+ end
159
+
160
+ #
161
+ # Inspect the Email Attachments
162
+ #
163
+
164
+ Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
165
+ expect(current_email_attachments.size).to eql parse_email_count(amount)
166
+ end
167
+
168
+ Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
169
+ expect(current_email_attachments.select { |a| a.filename == filename }.size).to eql parse_email_count(amount)
170
+ end
171
+
172
+ Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
173
+ expect(current_email_attachments[(index.to_i - 1)].filename).to eql filename
174
+ end
175
+
176
+ Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
177
+ expect(current_email_attachments.select { |a| a.content_type.include?(content_type) }.size).to eql parse_email_count(amount)
178
+ end
179
+
180
+ Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
181
+ expect(current_email_attachments[(index.to_i - 1)].content_type).to include(content_type)
182
+ end
183
+
184
+ Then /^all attachments should not be blank$/ do
185
+ current_email_attachments.each do |attachment|
186
+ expect(attachment.read.size).to_not eql 0
187
+ end
188
+ end
189
+
190
+ Then /^show me a list of email attachments$/ do
191
+ EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
192
+ end
193
+
194
+ #
195
+ # Interact with Email Contents
196
+ #
197
+
198
+ When /^(?:I|they|"([^"]*?)") follows? "([^"]*?)" in the email$/ do |address, link|
199
+ visit_in_email(link, address)
200
+ end
201
+
202
+ When /^(?:I|they) click the first link in the email$/ do
203
+ click_first_link_in_email
204
+ end
205
+
206
+ #
207
+ # Debugging
208
+ # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
209
+ # Patches accepted. ;)
210
+ #
211
+
212
+ Then /^save and open current email$/ do
213
+ EmailSpec::EmailViewer::save_and_open_email(current_email)
214
+ end
215
+
216
+ Then /^save and open all text emails$/ do
217
+ EmailSpec::EmailViewer::save_and_open_all_text_emails
218
+ end
219
+
220
+ Then /^save and open all html emails$/ do
221
+ EmailSpec::EmailViewer::save_and_open_all_html_emails
222
+ end
223
+
224
+ Then /^save and open all raw emails$/ do
225
+ EmailSpec::EmailViewer::save_and_open_all_raw_emails
226
+ end
@@ -0,0 +1,226 @@
1
+ # Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # last_email_address
7
+ # reset_mailer
8
+ # open_last_email
9
+ # visit_in_email
10
+ # unread_emails_for
11
+ # mailbox_for
12
+ # current_email
13
+ # open_email
14
+ # read_emails_for
15
+ # find_email
16
+ #
17
+ # General form for email scenarios are:
18
+ # - clear the email queue (done automatically by email_spec)
19
+ # - execute steps that sends an email
20
+ # - check the user received an/no/[0-9] emails
21
+ # - open the email
22
+ # - inspect the email contents
23
+ # - interact with the email (e.g. click links)
24
+ #
25
+ # The Cucumber steps below are setup in this order.
26
+
27
+ module EmailHelpers
28
+ def current_email_address
29
+ # Replace with your a way to find your current email. e.g @current_user.email
30
+ # last_email_address will return the last email address used by email spec to find an email.
31
+ # Note that last_email_address will be reset after each Scenario.
32
+ last_email_address || "example@example.com"
33
+ end
34
+ end
35
+
36
+ World(EmailHelpers)
37
+
38
+ #
39
+ # Reset the e-mail queue within a scenario.
40
+ # This is done automatically before each scenario.
41
+ #
42
+
43
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
44
+ reset_mailer
45
+ end
46
+
47
+ #
48
+ # Check how many emails have been sent/received
49
+ #
50
+
51
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
52
+ expect(unread_emails_for(address).size).to eql parse_email_count(amount)
53
+ end
54
+
55
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
56
+ expect(mailbox_for(address).size).to eql parse_email_count(amount)
57
+ end
58
+
59
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
60
+ expect(unread_emails_for(address).select { |m| m.subject =~ Regexp.new(Regexp.escape(subject)) }.size).to eql parse_email_count(amount)
61
+ end
62
+
63
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject \/([^"]*?)\/$/ do |address, amount, subject|
64
+ expect(unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size).to eql parse_email_count(amount)
65
+ end
66
+
67
+ Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
68
+ open_email(address, :with_text => expected_body)
69
+ end
70
+
71
+ #
72
+ # Accessing emails
73
+ #
74
+
75
+ # Opens the most recently received email
76
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
77
+ open_email(address)
78
+ end
79
+
80
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
81
+ open_email(address, :with_subject => subject)
82
+ end
83
+
84
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject \/([^"]*?)\/$/ do |address, subject|
85
+ open_email(address, :with_subject => Regexp.new(subject))
86
+ end
87
+
88
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
89
+ open_email(address, :with_text => text)
90
+ end
91
+
92
+ When /^(?:I|they|"([^"]*?)") opens? the email with text \/([^"]*?)\/$/ do |address, text|
93
+ open_email(address, :with_text => Regexp.new(text))
94
+ end
95
+
96
+ #
97
+ # Inspect the Email Contents
98
+ #
99
+
100
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
101
+ expect(current_email).to have_subject(text)
102
+ end
103
+
104
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
105
+ expect(current_email).to have_subject(Regexp.new(text))
106
+ end
107
+
108
+ Then /^(?:I|they) should not see "([^"]*?)" in the email subject$/ do |text|
109
+ expect(current_email).not_to have_subject(text)
110
+ end
111
+
112
+ Then /^(?:I|they) should not see \/([^"]*?)\/ in the email subject$/ do |text|
113
+ expect(current_email).not_to have_subject(Regexp.new(text))
114
+ end
115
+
116
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
117
+ expect(current_email.default_part_body.to_s).to include(text)
118
+ end
119
+
120
+ Then /^(?:I|they) should not see "([^"]*?)" in the email body$/ do |text|
121
+ expect(current_email.default_part_body.to_s).not_to include(text)
122
+ end
123
+
124
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
125
+ expect(current_email.default_part_body.to_s).to match Regexp.new(text)
126
+ end
127
+
128
+ Then /^(?:I|they) should not see \/([^"]*?)\/ in the email body$/ do |text|
129
+ expect(current_email.default_part_body.to_s).not_to match Regexp.new(text)
130
+ end
131
+
132
+ Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
133
+ expect(current_email).to be_delivered_from(text)
134
+ end
135
+
136
+ Then /^(?:I|they) should see the email reply to "([^"]*?)"$/ do |text|
137
+ expect(current_email).to have_reply_to(text)
138
+ end
139
+
140
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
141
+ expect(current_email).to have_header(name, text)
142
+ end
143
+
144
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
145
+ expect(current_email).to have_header(name, Regexp.new(text))
146
+ end
147
+
148
+ Then /^I should see it is a multi\-part email$/ do
149
+ expect(current_email).to be_multipart
150
+ end
151
+
152
+ Then /^(?:I|they) should see "([^"]*?)" in the email html part body$/ do |text|
153
+ expect(current_email.html_part.body.to_s).to include(text)
154
+ end
155
+
156
+ Then /^(?:I|they) should see "([^"]*?)" in the email text part body$/ do |text|
157
+ expect(current_email.text_part.body.to_s).to include(text)
158
+ end
159
+
160
+ #
161
+ # Inspect the Email Attachments
162
+ #
163
+
164
+ Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
165
+ expect(current_email_attachments.size).to eql parse_email_count(amount)
166
+ end
167
+
168
+ Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
169
+ expect(current_email_attachments.select { |a| a.filename == filename }.size).to eql parse_email_count(amount)
170
+ end
171
+
172
+ Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
173
+ expect(current_email_attachments[(index.to_i - 1)].filename).to eql filename
174
+ end
175
+
176
+ Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
177
+ expect(current_email_attachments.select { |a| a.content_type.include?(content_type) }.size).to eql parse_email_count(amount)
178
+ end
179
+
180
+ Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
181
+ expect(current_email_attachments[(index.to_i - 1)].content_type).to include(content_type)
182
+ end
183
+
184
+ Then /^all attachments should not be blank$/ do
185
+ current_email_attachments.each do |attachment|
186
+ expect(attachment.read.size).to_not eql 0
187
+ end
188
+ end
189
+
190
+ Then /^show me a list of email attachments$/ do
191
+ EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
192
+ end
193
+
194
+ #
195
+ # Interact with Email Contents
196
+ #
197
+
198
+ When /^(?:I|they|"([^"]*?)") follows? "([^"]*?)" in the email$/ do |address, link|
199
+ visit_in_email(link, address)
200
+ end
201
+
202
+ When /^(?:I|they) click the first link in the email$/ do
203
+ click_first_link_in_email
204
+ end
205
+
206
+ #
207
+ # Debugging
208
+ # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
209
+ # Patches accepted. ;)
210
+ #
211
+
212
+ Then /^save and open current email$/ do
213
+ EmailSpec::EmailViewer::save_and_open_email(current_email)
214
+ end
215
+
216
+ Then /^save and open all text emails$/ do
217
+ EmailSpec::EmailViewer::save_and_open_all_text_emails
218
+ end
219
+
220
+ Then /^save and open all html emails$/ do
221
+ EmailSpec::EmailViewer::save_and_open_all_html_emails
222
+ end
223
+
224
+ Then /^save and open all raw emails$/ do
225
+ EmailSpec::EmailViewer::save_and_open_all_raw_emails
226
+ end
@@ -6,13 +6,13 @@ Given /^the (\w+) app is setup with the latest email steps$/ do |app_name|
6
6
  'email_steps.rb')
7
7
  latest_specs_path = File.join(root_dir, 'lib', 'generators', 'email_spec',
8
8
  'steps', 'templates','email_steps.rb')
9
- FileUtils.rm(email_specs_path) if File.exists?(email_specs_path)
9
+ FileUtils.rm(email_specs_path) if File.exist?(email_specs_path)
10
10
  FileUtils.cp_r(latest_specs_path, email_specs_path)
11
11
  end
12
12
 
13
13
  Then /^the (\w+) app should have the email steps in place$/ do |app_name|
14
14
  email_specs_path = "#{root_dir}/examples/#{app_name}_root/features/step_definitions/email_steps.rb"
15
- expect(File.exists?(email_specs_path)).to be true
15
+ expect(File.exist?(email_specs_path)).to be true
16
16
  end
17
17
 
18
18
  Then /^I should see the following summary report:$/ do |expected_report|
@@ -22,7 +22,7 @@ end
22
22
  Given /^the (\w+) app is setup with the latest generators$/ do |app_name|
23
23
  app_dir= File.join(root_dir,'examples',"#{app_name}_root")
24
24
  email_specs_path = File.join(app_dir,'features','step_definitions','email_steps.rb')
25
- FileUtils.rm(email_specs_path) if File.exists?(email_specs_path)
25
+ FileUtils.rm(email_specs_path) if File.exist?(email_specs_path)
26
26
 
27
27
  if app_name == 'rails4'
28
28
  #Testing using the gem
@@ -46,7 +46,7 @@ When /^I run "([^\"]*)" in the (\w+) app$/ do |cmd, app_name|
46
46
  app_specific_gemfile = File.join(app_path,'Gemfile')
47
47
  Dir.chdir(app_path) do
48
48
  #hack to fight competing bundles (email specs vs rails4_root's
49
- if File.exists? app_specific_gemfile
49
+ if File.exist? app_specific_gemfile
50
50
  orig_gemfile = ENV['BUNDLE_GEMFILE']
51
51
  ENV['BUNDLE_GEMFILE'] = app_specific_gemfile
52
52
  @output = `#{cmd}`
@@ -1,5 +1,5 @@
1
1
  module EmailSpec
2
- module MailerDeliveries
2
+ module Deliveries
3
3
  def all_emails
4
4
  deliveries
5
5
  end
@@ -9,7 +9,9 @@ module EmailSpec
9
9
  end
10
10
 
11
11
  def reset_mailer
12
- if defined?(ActionMailer) && ActionMailer::Base.delivery_method == :cache
12
+ if defined?(ActionMailer) && ActionMailer::Base.delivery_method == :activerecord
13
+ Email.delete_all
14
+ elsif defined?(ActionMailer) && ActionMailer::Base.delivery_method == :cache
13
15
  mailer.clear_cache
14
16
  else
15
17
  deliveries.clear
@@ -23,36 +25,22 @@ module EmailSpec
23
25
  protected
24
26
 
25
27
  def deliveries
26
- if ActionMailer::Base.delivery_method == :cache
28
+ if defined?(Pony)
29
+ Pony.deliveries
30
+ elsif ActionMailer::Base.delivery_method == :activerecord
31
+ Email.all.map { |email| parse_ar_to_mail(email) }
32
+ elsif ActionMailer::Base.delivery_method == :cache
27
33
  mailer.cached_deliveries
28
34
  else
29
35
  mailer.deliveries
30
36
  end
31
37
  end
32
- end
33
-
34
- module ARMailerDeliveries
35
- def all_emails
36
- Email.all.map{ |email| parse_to_mail(email) }
37
- end
38
38
 
39
- def last_email_sent
40
- if email = Email.last
41
- parse_to_mail(email)
42
- else
43
- raise("No email has been sent!")
44
- end
39
+ def mailer
40
+ ActionMailer::Base
45
41
  end
46
42
 
47
- def reset_mailer
48
- Email.delete_all
49
- end
50
-
51
- def mailbox_for(address)
52
- Email.all.select { |email| email.destinations.include?(address) }.map{ |email| parse_to_mail(email) }
53
- end
54
-
55
- def parse_to_mail(email)
43
+ def parse_ar_to_mail(email)
56
44
  Mail.read(email.mail)
57
45
  end
58
46
  end
@@ -68,24 +56,4 @@ module EmailSpec
68
56
  end
69
57
  end
70
58
  end
71
-
72
- module Deliveries
73
- if defined?(Pony)
74
- def deliveries; Pony::deliveries ; end
75
- include EmailSpec::MailerDeliveries
76
- else
77
- ActiveSupport.on_load(:action_mailer) do
78
- if delivery_method == :activerecord
79
- ::EmailSpec::Helpers.include EmailSpec::ARMailerDeliveries
80
- else
81
- ::EmailSpec::Deliveries.module_eval do
82
- def mailer
83
- ActionMailer::Base
84
- end
85
- end
86
- ::EmailSpec::Helpers.include ::EmailSpec::MailerDeliveries
87
- end
88
- end
89
- end
90
- end
91
59
  end
@@ -0,0 +1,45 @@
1
+ module EmailSpec
2
+ module Extractors
3
+ class Base
4
+ attr_accessor :mail
5
+
6
+ def initialize(mail)
7
+ @mail = mail
8
+ end
9
+
10
+ def call
11
+ part_body ? HTMLEntities.new.decode(part_body) : ''
12
+ end
13
+
14
+ private
15
+
16
+ def part_body
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+
21
+ class DefaultPartBody < Base
22
+ private
23
+
24
+ def part_body
25
+ (mail.html_part || mail.text_part || mail).body
26
+ end
27
+ end
28
+
29
+ class HtmlPartBody < Base
30
+ private
31
+
32
+ def part_body
33
+ mail.html_part ? mail.html_part.body : nil
34
+ end
35
+ end
36
+
37
+ class TextPartBody < Base
38
+ private
39
+
40
+ def part_body
41
+ mail.text_part ? mail.text_part.body : nil
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,5 @@
1
+ require_relative 'extractors'
2
+
1
3
  module EmailSpec
2
4
  module Matchers
3
5
  class EmailMatcher
@@ -128,7 +130,7 @@ module EmailSpec
128
130
 
129
131
  def matches?(email)
130
132
  @email = email
131
- @actual_recipients = address_array{ email.bcc }.sort
133
+ @actual_recipients = address_array { email[:bcc].formatted }.sort
132
134
  @actual_recipients == @expected_email_addresses
133
135
  end
134
136
 
@@ -162,7 +164,7 @@ module EmailSpec
162
164
 
163
165
  def matches?(email)
164
166
  @email = email
165
- @actual_recipients = address_array { email.cc }.sort
167
+ @actual_recipients = address_array { email[:cc].formatted }.sort
166
168
  @actual_recipients == @expected_email_addresses
167
169
  end
168
170
 
@@ -274,6 +276,7 @@ module EmailSpec
274
276
 
275
277
  def initialize(text)
276
278
  @expected_text = text
279
+ @extractor = EmailSpec::Extractors::DefaultPartBody
277
280
  end
278
281
 
279
282
  def description
@@ -284,13 +287,23 @@ module EmailSpec
284
287
  end
285
288
  end
286
289
 
290
+ def in_html_part
291
+ @extractor = EmailSpec::Extractors::HtmlPartBody
292
+ self
293
+ end
294
+
295
+ def in_text_part
296
+ @extractor = EmailSpec::Extractors::TextPartBody
297
+ self
298
+ end
299
+
287
300
  def matches?(email)
288
301
  if @expected_text.is_a?(String)
289
- @given_text = email.default_part_body.to_s.gsub(/\s+/, " ")
302
+ @given_text = @extractor.new(email).call.to_s.gsub(/\s+/, " ")
290
303
  @expected_text = @expected_text.gsub(/\s+/, " ")
291
304
  @given_text.include?(@expected_text)
292
305
  else
293
- @given_text = email.default_part_body.to_s
306
+ @given_text = @extractor.new(email).call.to_s
294
307
  !!(@given_text =~ @expected_text)
295
308
  end
296
309
  end
@@ -358,7 +371,14 @@ module EmailSpec
358
371
  alias negative_failure_message failure_message_when_negated
359
372
 
360
373
  def mail_headers_hash(email_headers)
361
- email_headers.fields.inject({}) { |hash, field| hash[field.field.class::FIELD_NAME] = field.to_s; hash }
374
+ email_headers.fields.inject({}) do |hash, field|
375
+ if field.field.class.const_defined?('FIELD_NAME')
376
+ hash[field.field.class::FIELD_NAME] = field.to_s
377
+ else
378
+ hash[field.field.class::NAME.downcase] = field.to_s
379
+ end
380
+ hash
381
+ end
362
382
  end
363
383
  end
364
384
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EmailSpec
2
- VERSION = '2.2.1'
4
+ VERSION = "2.3.0"
3
5
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support'
3
2
 
4
3
  describe EmailSpec::MailExt do
5
4
  describe "#default_part" do
@@ -40,8 +39,9 @@ describe EmailSpec::MailExt do
40
39
  it "decodes parts before return" do
41
40
  email = Mail.new(:body => "hello\r\nquoted-printable")
42
41
  email.content_transfer_encoding = 'quoted-printable'
43
- expect(email.encoded).to include("hello=0D\nquoted-printable")
44
- expect(email.default_part_body).to eq("hello\r\nquoted-printable")
42
+
43
+ expect(email.encoded).to include("hello\r\nquoted-printable=")
44
+ expect(email.default_part_body).to eq("hello\nquoted-printable")
45
45
  end
46
46
  end
47
47
 
@@ -137,7 +137,7 @@ describe EmailSpec::Matchers do
137
137
  end
138
138
 
139
139
  it "should not match when the email does not have a sender" do
140
- email = Mail::Message.new(:from => nil)
140
+ email = Mail::Message.new(:from => "johnshow@yahoo.com")
141
141
  expect(deliver_from("jimmy_bean@yahoo.com")).not_to match(email)
142
142
  end
143
143
 
@@ -178,6 +178,12 @@ describe EmailSpec::Matchers do
178
178
  expect(bcc_to("jimmy_bean@yahoo.com")).to match(email)
179
179
  end
180
180
 
181
+ it "should match when the email is set to deliver to the specified name and address" do
182
+ email = Mail::Message.new(:bcc => "Jimmy Bean <jimmy_bean@yahoo.com>")
183
+
184
+ expect(bcc_to("Jimmy Bean <jimmy_bean@yahoo.com>")).to match(email)
185
+ end
186
+
181
187
  it "should match when a list of emails is exact same as all of the email's recipients" do
182
188
  email = Mail::Message.new(:bcc => ["james@yahoo.com", "karen@yahoo.com"])
183
189
 
@@ -214,6 +220,12 @@ describe EmailSpec::Matchers do
214
220
  expect(cc_to("jimmy_bean@yahoo.com")).to match(email)
215
221
  end
216
222
 
223
+ it "should match when the email is set to deliver to the specified name and address" do
224
+ email = Mail::Message.new(:cc => "Jimmy Bean <jimmy_bean@yahoo.com>")
225
+
226
+ expect(cc_to("Jimmy Bean <jimmy_bean@yahoo.com>")).to match(email)
227
+ end
228
+
217
229
  it "should match when a list of emails is exact same as all of the email's recipients" do
218
230
  email = Mail::Message.new(:cc => ["james@yahoo.com", "karen@yahoo.com"])
219
231
 
@@ -454,6 +466,106 @@ describe EmailSpec::Matchers do
454
466
  end
455
467
  end
456
468
 
469
+ describe "#have_body_text", ".in_html_part" do
470
+ describe 'when html part is definded in mulitpart' do
471
+ it 'should match when the body matches regexp' do
472
+ email = Mail.new do
473
+ html_part do
474
+ body 'This is html'
475
+ end
476
+ end
477
+
478
+ expect(have_body_text(/This is html/).in_html_part).to match(email)
479
+ end
480
+ end
481
+
482
+ describe 'when text part is definded in mulitpart' do
483
+ it 'should not look at text part' do
484
+ email = Mail.new do
485
+ text_part do
486
+ body 'This is text'
487
+ end
488
+ end
489
+
490
+ expect(have_body_text(/This is text/).in_html_part).not_to match(email)
491
+ end
492
+ end
493
+
494
+ describe 'when html and text parts are definded in mulitpart' do
495
+ it 'should look at html part' do
496
+ email = Mail.new do
497
+ html_part do
498
+ body 'This is html'
499
+ end
500
+ text_part do
501
+ body 'This is text'
502
+ end
503
+ end
504
+
505
+ expect(have_body_text(/This is html/).in_html_part).to match(email)
506
+ expect(have_body_text(/This is text/).in_html_part).not_to match(email)
507
+ end
508
+ end
509
+
510
+ describe 'when nothing is defined in mulitpart' do
511
+ it 'should not look at any parts' do
512
+ email = Mail.new(body: 'This is body')
513
+
514
+ expect(have_body_text(/This is body/).in_html_part).not_to match(email)
515
+ end
516
+ end
517
+ end
518
+
519
+ describe "#have_body_text", ".in_text_part" do
520
+ describe 'when text part is definded in mulitpart' do
521
+ it 'should match when the body matches regexp' do
522
+ email = Mail.new do
523
+ text_part do
524
+ body 'This is text'
525
+ end
526
+ end
527
+
528
+ expect(have_body_text(/This is text/).in_text_part).to match(email)
529
+ end
530
+ end
531
+
532
+ describe 'when text and html parts are definded in mulitpart' do
533
+ it 'should look at text part' do
534
+ email = Mail.new do
535
+ text_part do
536
+ body 'This is text'
537
+ end
538
+
539
+ html_part do
540
+ body 'This is html'
541
+ end
542
+ end
543
+
544
+ expect(have_body_text(/This is text/).in_text_part).to match(email)
545
+ expect(have_body_text(/This is html/).in_text_part).not_to match(email)
546
+ end
547
+ end
548
+
549
+ describe 'when html part is definded in mulitpart' do
550
+ it 'should not look at html part' do
551
+ email = Mail.new do
552
+ html_part do
553
+ body "This is html"
554
+ end
555
+ end
556
+
557
+ expect(have_body_text(/This is html/).in_text_part).not_to match(email)
558
+ end
559
+ end
560
+
561
+ describe 'when nothing is defined in mulitpart' do
562
+ it 'should not look at any parts' do
563
+ email = Mail.new(body: 'This is body')
564
+
565
+ expect(have_body_text(/This is body/).in_text_part).not_to match(email)
566
+ end
567
+ end
568
+ end
457
569
  describe "#have_header" do
458
570
  describe "when regexps are used" do
459
571
  it "should match when header matches passed in regexp" do
data/spec/spec_helper.rb CHANGED
@@ -3,9 +3,6 @@ require 'action_mailer'
3
3
  require 'mail'
4
4
  require File.expand_path(File.dirname(__FILE__) + '/../lib/email_spec.rb')
5
5
 
6
- # Trigger loading ActionMailer::Base
7
- ActionMailer::Base
8
-
9
6
  RSpec.configure do |config|
10
7
  config.include EmailSpec::Helpers
11
8
  config.include EmailSpec::Matchers
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Mabey
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-12 00:00:00.000000000 Z
13
+ date: 2024-07-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: htmlentities
@@ -30,16 +30,22 @@ dependencies:
30
30
  name: launchy
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - "~>"
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: '2.1'
36
+ - - "<"
37
+ - !ruby/object:Gem::Version
38
+ version: '4.0'
36
39
  type: :runtime
37
40
  prerelease: false
38
41
  version_requirements: !ruby/object:Gem::Requirement
39
42
  requirements:
40
- - - "~>"
43
+ - - ">="
41
44
  - !ruby/object:Gem::Version
42
45
  version: '2.1'
46
+ - - "<"
47
+ - !ruby/object:Gem::Version
48
+ version: '4.0'
43
49
  - !ruby/object:Gem::Dependency
44
50
  name: mail
45
51
  requirement: !ruby/object:Gem::Requirement
@@ -82,20 +88,6 @@ dependencies:
82
88
  - - "~>"
83
89
  - !ruby/object:Gem::Version
84
90
  version: 1.3.17
85
- - !ruby/object:Gem::Dependency
86
- name: actionmailer
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: '4.2'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - "~>"
97
- - !ruby/object:Gem::Version
98
- version: '4.2'
99
91
  - !ruby/object:Gem::Dependency
100
92
  name: rack-test
101
93
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +219,7 @@ files:
227
219
  - examples/rails4_root/features/delayed_job.feature
228
220
  - examples/rails4_root/features/errors.feature
229
221
  - examples/rails4_root/features/example.feature
222
+ - examples/rails4_root/features/step_definitions/email_steps.rb
230
223
  - examples/rails4_root/features/step_definitions/user_steps.rb
231
224
  - examples/rails4_root/features/step_definitions/web_steps.rb
232
225
  - examples/rails4_root/features/support/env.rb
@@ -260,6 +253,7 @@ files:
260
253
  - examples/sinatra_root/config.ru
261
254
  - examples/sinatra_root/features/errors.feature
262
255
  - examples/sinatra_root/features/example.feature
256
+ - examples/sinatra_root/features/step_definitions/email_steps.rb
263
257
  - examples/sinatra_root/features/step_definitions/user_steps.rb
264
258
  - examples/sinatra_root/features/step_definitions/web_steps.rb
265
259
  - examples/sinatra_root/features/support/env.rb
@@ -276,6 +270,7 @@ files:
276
270
  - lib/email_spec/deliveries.rb
277
271
  - lib/email_spec/email_viewer.rb
278
272
  - lib/email_spec/errors.rb
273
+ - lib/email_spec/extractors.rb
279
274
  - lib/email_spec/helpers.rb
280
275
  - lib/email_spec/mail_ext.rb
281
276
  - lib/email_spec/matchers.rb
@@ -309,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
309
304
  - !ruby/object:Gem::Version
310
305
  version: '0'
311
306
  requirements: []
312
- rubygems_version: 3.3.21
307
+ rubygems_version: 3.5.10
313
308
  signing_key:
314
309
  specification_version: 4
315
310
  summary: Easily test email in RSpec, Cucumber or Minitest