mail_view 2.0.0 → 2.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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mail_view (2.0.0)
4
+ mail_view (2.0.1)
5
5
  tilt
6
6
 
7
7
  GEM
@@ -40,8 +40,8 @@ class MailView
40
40
  mail = build_mail(name)
41
41
 
42
42
  # Requested a specific bare MIME part. Render it verbatim.
43
- if sub_type = request.params['part']
44
- if part = find_part(mail, sub_type)
43
+ if part_type = request.params['part']
44
+ if part = find_part(mail, part_type)
45
45
  body = part.body
46
46
  body = body.decoded if body.respond_to?(:decoded)
47
47
  ok body, part.content_type
@@ -51,10 +51,8 @@ class MailView
51
51
 
52
52
  # Otherwise, show our message headers & frame the body.
53
53
  else
54
- part = find_part(mail, format || 'text/*') || mail
55
- part_type = [part.main_type, part.sub_type].compact.join('/')
56
- part_url = "#{request.path}?part=#{Rack::Utils.escape part_type}"
57
- ok email_template.render(Object.new, :name => name, :mail => mail, :part => part, :part_url => part_url)
54
+ part = find_preferred_part(mail, [format, 'text/html', 'text/plain'])
55
+ ok email_template.render(Object.new, :name => name, :mail => mail, :part => part, :part_url => part_body_url(part))
58
56
  end
59
57
  else
60
58
  not_found
@@ -105,15 +103,27 @@ class MailView
105
103
  mail
106
104
  end
107
105
 
106
+ def find_preferred_part(mail, formats)
107
+ found = nil
108
+ formats.find { |f| found = find_part(mail, f) }
109
+ found || mail
110
+ end
111
+
112
+ def part_body_url(part)
113
+ '?part=%s' % Rack::Utils.escape([part.main_type, part.sub_type].compact.join('/'))
114
+ end
115
+
108
116
  def find_part(mail, matching_content_type)
109
117
  if mail.multipart?
110
- all_parts(mail).reverse.find { |part| find_part part, matching_content_type }
111
- elsif mail.content_type.to_s.match matching_content_type
118
+ if matching_content_type.nil? && mail.sub_type == 'alternative'
119
+ mail.parts.last
120
+ else
121
+ found = nil
122
+ mail.parts.find { |part| found = find_part(part, matching_content_type) }
123
+ found
124
+ end
125
+ elsif matching_content_type && mail.content_type.to_s.match(matching_content_type)
112
126
  mail
113
127
  end
114
128
  end
115
-
116
- def all_parts(mail)
117
- mail.respond_to?(:all_parts) ? mail.all_parts : mail.parts
118
- end
119
129
  end
@@ -7,13 +7,12 @@
7
7
  padding: 10px 0 0 0;
8
8
  margin: 0;
9
9
  background: white;
10
- font: 12px/16px "Lucida Grande", sans-serif;
10
+ font: 12px "Lucida Grande", sans-serif;
11
11
  border-bottom: 1px solid #dedede;
12
12
  overflow: hidden;
13
13
  }
14
14
 
15
15
  dl {
16
- float: left;
17
16
  margin: 0 0 10px 0;
18
17
  padding: 0;
19
18
  }
@@ -24,7 +23,6 @@
24
23
  float: left;
25
24
  clear: left;
26
25
  text-align: right;
27
- font-weight: bold;
28
26
  color: #7f7f7f;
29
27
  }
30
28
 
@@ -33,15 +31,6 @@
33
31
  padding: 1px;
34
32
  }
35
33
 
36
- nav {
37
- float: right;
38
- margin: 0;
39
- }
40
-
41
- nav a {
42
- color: #09c;
43
- }
44
-
45
34
  iframe {
46
35
  border: 0;
47
36
  width: 100%;
@@ -53,11 +42,16 @@
53
42
  <body>
54
43
  <header>
55
44
  <dl>
56
- <% if mail.respond_to?(:smtp_envelope_from) && mail.from != mail.smtp_envelope_from %>
45
+ <% if mail.respond_to?(:smtp_envelope_from) && Array(mail.from) != Array(mail.smtp_envelope_from) %>
57
46
  <dt>SMTP-From:</dt>
58
47
  <dd><%= mail.smtp_envelope_from %></dd>
59
48
  <% end %>
60
49
 
50
+ <% if mail.respond_to?(:smtp_envelope_to) && mail.to != mail.smtp_envelope_to %>
51
+ <dt>SMTP-To:</dt>
52
+ <dd><%= mail.smtp_envelope_to %></dd>
53
+ <% end %>
54
+
61
55
  <dt>From:</dt>
62
56
  <dd><%= Rack::Utils.escape_html(mail.header['from'].to_s) %></dd>
63
57
 
@@ -66,41 +60,39 @@
66
60
  <dd><%= Rack::Utils.escape_html(mail.header['reply-to'].to_s) %></dd>
67
61
  <% end %>
68
62
 
69
- <dt>Subject:</dt>
70
- <dd><strong><%= mail.subject %></strong></dd>
63
+ <dt>To:</dt>
64
+ <dd><%= Rack::Utils.escape_html(mail.header['to'].to_s) %></dd>
65
+
66
+ <% if mail.cc %>
67
+ <dt>CC:</dt>
68
+ <dd><%= Rack::Utils.escape_html(mail.header['cc'].to_s) %></dd>
69
+ <% end %>
71
70
 
72
71
  <dt>Date:</dt>
73
72
  <dd><%= Time.now.strftime("%b %e, %Y %I:%M:%S %p %Z") %></dd>
74
73
 
75
- <% if mail.respond_to?(:smtp_envelope_to) && mail.to != mail.smtp_envelope_to %>
76
- <dt>SMTP-To:</dt>
77
- <dd><%= mail.smtp_envelope_to %></dd>
74
+ <dt>Subject:</dt>
75
+ <dd><strong><%= mail.subject %></strong></dd>
76
+
77
+ <% unless mail.attachments.nil? || mail.attachments.empty? %>
78
+ <dt>Attachments:</dt>
79
+ <dd>
80
+ <%= Rack::Utils.escape_html mail.attachments.map { |a| a.respond_to?(:original_filename) ? a.original_filename : a.filename }.inspect %>
81
+ </dd>
78
82
  <% end %>
79
83
 
80
- <dt>To:</dt>
81
- <dd><%= Rack::Utils.escape_html(mail.header['to'].to_s) %></dd>
84
+ <% if mail.multipart? %>
85
+ <dd>
86
+ <select onchange="top.messageBody.location=this.options[this.selectedIndex].value;">
87
+ <option value="?part=text%2Fhtml">View as HTML email</option>
88
+ <option value="?part=text%2Fplain">View as plain-text email</option>
89
+ </select>
90
+ </dd>
91
+ <% end %>
82
92
  </dl>
83
-
84
- <% if mail.multipart? %>
85
- <nav>
86
- <% if part.content_type && part.content_type.match(/text\/html/) %>
87
- <a href="<%= name %>.txt">View plain text version</a>
88
- <% else %>
89
- <a href="<%= name %>.html">View HTML version</a>
90
- <% end %>
91
- </nav>
92
- <% end %>
93
-
94
- <% unless mail.attachments.nil? || mail.attachments.empty? %>
95
- <ul>
96
- <% mail.attachments.each do |attachment| %>
97
- <%= Rack::Utils.escape_html(attachment.respond_to?(:original_filename) ? attachment.original_filename : attachment.filename) %>
98
- <% end %>
99
- </ul>
100
- <% end %>
101
93
  </header>
102
94
 
103
- <iframe seamless src="<%= part_url %>"></iframe>
95
+ <iframe seamless name="messageBody" src="<%= part_url %>"></iframe>
104
96
 
105
97
  </body>
106
98
  </html>
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'mail_view'
3
- s.version = '2.0.0'
3
+ s.version = '2.0.1'
4
4
  s.author = 'Josh Peek'
5
5
  s.email = 'josh@joshpeek.com'
6
6
  s.summary = 'Visual email testing'
@@ -14,6 +14,7 @@ class TestMailView < Test::Unit::TestCase
14
14
  Mail.new do
15
15
  to 'josh@37signals.com'
16
16
  body 'Hello'
17
+ yield self if block_given?
17
18
  end
18
19
  end
19
20
 
@@ -47,6 +48,8 @@ class TestMailView < Test::Unit::TestCase
47
48
  Mail.new do
48
49
  to 'josh@37signals.com'
49
50
 
51
+ yield self if block_given?
52
+
50
53
  text_part do
51
54
  body 'This is plain text'
52
55
  end
@@ -70,20 +73,20 @@ class TestMailView < Test::Unit::TestCase
70
73
  text_part do
71
74
  body 'This is plain text'
72
75
  end
73
-
74
76
  end
75
77
  end
76
78
 
77
79
  def multipart_mixed_with_text_and_attachment
78
- add_attachment_to plain_text_message
80
+ plain_text_message { |mail| add_attachments_to mail }
79
81
  end
80
82
 
81
83
  def multipart_mixed_with_multipart_alternative_and_attachment
82
- add_attachment_to multipart_alternative
84
+ multipart_alternative { |mail| add_attachments_to mail }
83
85
  end
84
86
 
85
- def add_attachment_to(mail)
86
- mail.attachments['checkbox.png'] = 'stub'
87
+ def add_attachments_to(mail)
88
+ mail.add_file :filename => 'checkbox.png', :content => 'stub'
89
+ mail.add_file :filename => 'foo.vcf', :content => 'stub'
87
90
  mail
88
91
  end
89
92
 
@@ -128,8 +131,8 @@ class TestMailView < Test::Unit::TestCase
128
131
  Preview
129
132
  end
130
133
 
131
- def iframe_src_match(action)
132
- /<iframe[^>]* src="#{Regexp.escape(action)}"[^>]*><\/iframe>/
134
+ def iframe_src_match(content_type)
135
+ /<iframe[^>]* src="\?part=#{Regexp.escape(Rack::Utils.escape(content_type))}"[^>]*><\/iframe>/
133
136
  end
134
137
 
135
138
  def unescaped_body
@@ -168,10 +171,10 @@ class TestMailView < Test::Unit::TestCase
168
171
  def test_plain_text_message
169
172
  get '/plain_text_message'
170
173
  assert last_response.ok?
171
- body_path = '/plain_text_message?part='
172
- assert_match iframe_src_match(body_path), last_response.body
174
+ assert_match iframe_src_match(''), last_response.body
175
+ assert_no_match %r(View as), last_response.body
173
176
 
174
- get body_path
177
+ get '/plain_text_message?part='
175
178
  assert last_response.ok?
176
179
  assert_match 'Hello', last_response.body
177
180
  end
@@ -179,10 +182,10 @@ class TestMailView < Test::Unit::TestCase
179
182
  def test_mounted_plain_text_message
180
183
  get '/plain_text_message', {}, 'SCRIPT_NAME' => '/boom'
181
184
  assert last_response.ok?
182
- body_path = '/boom/plain_text_message?part='
183
- assert_match iframe_src_match(body_path), last_response.body
185
+ assert_match iframe_src_match(''), last_response.body
186
+ assert_no_match %r(View as), last_response.body
184
187
 
185
- get body_path
188
+ get '/boom/plain_text_message?part='
186
189
  assert last_response.ok?
187
190
  assert_equal 'Hello', last_response.body
188
191
  end
@@ -197,10 +200,10 @@ class TestMailView < Test::Unit::TestCase
197
200
  def test_html_message
198
201
  get '/html_message'
199
202
  assert last_response.ok?
200
- body_path = '/html_message?part=text%2Fhtml'
201
- assert_match iframe_src_match(body_path), last_response.body
203
+ assert_match iframe_src_match('text/html'), last_response.body
204
+ assert_no_match %r(View as), last_response.body
202
205
 
203
- get body_path
206
+ get '/html_message?part=text%2Fhtml'
204
207
  assert last_response.ok?
205
208
  assert_equal '<h1>Hello</h1>', last_response.body
206
209
  end
@@ -208,10 +211,10 @@ class TestMailView < Test::Unit::TestCase
208
211
  def test_nested_multipart_message
209
212
  get '/nested_multipart_message'
210
213
  assert last_response.ok?
211
- body_path = '/nested_multipart_message?part=text%2Fhtml'
212
- assert_match iframe_src_match(body_path), last_response.body
214
+ assert_match iframe_src_match('text/html'), last_response.body
215
+ assert_match %r(View as), last_response.body
213
216
 
214
- get body_path
217
+ get '/nested_multipart_message?part=text%2Fhtml'
215
218
  assert last_response.ok?
216
219
  assert_equal '<h1>Hello</h1>', last_response.body
217
220
  end
@@ -219,11 +222,10 @@ class TestMailView < Test::Unit::TestCase
219
222
  def test_multipart_alternative
220
223
  get '/multipart_alternative'
221
224
  assert last_response.ok?
222
- body_path = '/multipart_alternative?part=text%2Fhtml'
223
- assert_match iframe_src_match(body_path), last_response.body
224
- assert_match 'View plain text version', last_response.body
225
+ assert_match iframe_src_match('text/html'), last_response.body
226
+ assert_match 'View as', last_response.body
225
227
 
226
- get body_path
228
+ get '/multipart_alternative?part=text%2Fhtml'
227
229
  assert last_response.ok?
228
230
  assert_equal '<h1>This is HTML</h1>', last_response.body
229
231
  end
@@ -231,11 +233,10 @@ class TestMailView < Test::Unit::TestCase
231
233
  def test_multipart_alternative_as_html
232
234
  get '/multipart_alternative.html'
233
235
  assert last_response.ok?
234
- body_path = '/multipart_alternative.html?part=text%2Fhtml'
235
- assert_match iframe_src_match(body_path), last_response.body
236
- assert_match 'View plain text version', last_response.body
236
+ assert_match iframe_src_match('text/html'), last_response.body
237
+ assert_match 'View as', last_response.body
237
238
 
238
- get body_path
239
+ get '/multipart_alternative.html?part=text%2Fhtml'
239
240
  assert last_response.ok?
240
241
  assert_equal '<h1>This is HTML</h1>', last_response.body
241
242
  end
@@ -243,11 +244,10 @@ class TestMailView < Test::Unit::TestCase
243
244
  def test_multipart_alternative_as_text
244
245
  get '/multipart_alternative.txt'
245
246
  assert last_response.ok?
246
- body_path = '/multipart_alternative.txt?part=text%2Fplain'
247
- assert_match iframe_src_match(body_path), last_response.body
248
- assert_match 'View HTML version', last_response.body
247
+ assert_match iframe_src_match('text/plain'), last_response.body
248
+ assert_match 'View as', last_response.body
249
249
 
250
- get body_path
250
+ get '/multipart_alternative.txt?part=text%2Fplain'
251
251
  assert last_response.ok?
252
252
  assert_equal 'This is plain text', last_response.body
253
253
  end
@@ -255,11 +255,10 @@ class TestMailView < Test::Unit::TestCase
255
255
  def test_multipart_alternative_text_as_default
256
256
  get '/multipart_alternative_text_default'
257
257
  assert last_response.ok?
258
- body_path = '/multipart_alternative_text_default?part=text%2Fplain'
259
- assert_match iframe_src_match(body_path), last_response.body
260
- assert_match 'View HTML version', last_response.body
258
+ assert_match iframe_src_match('text/plain'), last_response.body
259
+ assert_match 'View as', last_response.body
261
260
 
262
- get body_path
261
+ get '/multipart_alternative_text_default?part=text%2Fplain'
263
262
  assert last_response.ok?
264
263
  assert_equal 'This is plain text', last_response.body
265
264
  end
@@ -267,13 +266,11 @@ class TestMailView < Test::Unit::TestCase
267
266
  def test_multipart_mixed_with_text_and_attachment
268
267
  get '/multipart_mixed_with_text_and_attachment'
269
268
  assert last_response.ok?
270
- body_path = '/multipart_mixed_with_text_and_attachment?part='
271
- assert_match iframe_src_match(body_path), last_response.body
272
- assert_no_match %r(View HTML version), last_response.body
273
- assert_no_match %r(View plain text version), last_response.body
269
+ assert_match iframe_src_match('text/plain'), last_response.body
270
+ #assert_no_match %r(View as), last_response.body
274
271
  assert_match 'checkbox.png', last_response.body
275
272
 
276
- get body_path
273
+ get '/multipart_mixed_with_text_and_attachment?part=text%2Fplain'
277
274
  assert last_response.ok?
278
275
  assert_equal 'Hello', last_response.body
279
276
  end
@@ -281,12 +278,11 @@ class TestMailView < Test::Unit::TestCase
281
278
  def test_multipart_mixed_with_multipart_alternative_and_attachment
282
279
  get '/multipart_mixed_with_multipart_alternative_and_attachment'
283
280
  assert last_response.ok?
284
- body_path = '/multipart_mixed_with_multipart_alternative_and_attachment?part=text%2Fhtml'
285
- assert_match iframe_src_match(body_path), last_response.body
286
- assert_match 'View plain text version', last_response.body
281
+ assert_match iframe_src_match('text/html'), last_response.body
282
+ assert_match 'View as', last_response.body
287
283
  assert_match 'checkbox.png', last_response.body
288
284
 
289
- get body_path
285
+ get '/multipart_mixed_with_multipart_alternative_and_attachment?part=text%2Fhtml'
290
286
  assert last_response.ok?
291
287
  assert_equal '<h1>This is HTML</h1>', last_response.body
292
288
  end
@@ -294,12 +290,11 @@ class TestMailView < Test::Unit::TestCase
294
290
  def test_multipart_mixed_with_multipart_alternative_and_attachment_preferring_plain_text
295
291
  get '/multipart_mixed_with_multipart_alternative_and_attachment.txt'
296
292
  assert last_response.ok?
297
- body_path = '/multipart_mixed_with_multipart_alternative_and_attachment.txt?part=text%2Fplain'
298
- assert_match iframe_src_match(body_path), last_response.body
299
- assert_match 'View HTML version', last_response.body
293
+ assert_match iframe_src_match('text/plain'), last_response.body
294
+ assert_match 'View as', last_response.body
300
295
  assert_match 'checkbox.png', last_response.body
301
296
 
302
- get body_path
297
+ get '/multipart_mixed_with_multipart_alternative_and_attachment.txt?part=text%2Fplain'
303
298
  assert last_response.ok?
304
299
  assert_equal 'This is plain text', last_response.body
305
300
  end
@@ -315,10 +310,9 @@ class TestMailView < Test::Unit::TestCase
315
310
  def test_tmail_html_message
316
311
  get '/tmail_html_message'
317
312
  assert last_response.ok?
318
- body_path = '/tmail_html_message?part=text%2Fhtml'
319
- assert_match iframe_src_match(body_path), last_response.body
313
+ assert_match iframe_src_match('text/html'), last_response.body
320
314
 
321
- get body_path
315
+ get '/tmail_html_message?part=text%2Fhtml'
322
316
  assert last_response.ok?
323
317
  assert_equal '<h1>Hello</h1>', last_response.body
324
318
  end
@@ -327,8 +321,8 @@ class TestMailView < Test::Unit::TestCase
327
321
  get '/tmail_multipart_alternative'
328
322
  assert last_response.ok?
329
323
  body_path = '/tmail_multipart_alternative?part=text%2Fhtml'
330
- assert_match iframe_src_match(body_path), last_response.body
331
- assert_match 'View plain text version', last_response.body
324
+ assert_match iframe_src_match('text/html'), last_response.body
325
+ assert_match 'View as', last_response.body
332
326
 
333
327
  get body_path
334
328
  assert last_response.ok?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: