ledermann-tmail 1.2.5

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 (164) hide show
  1. data/CHANGES +74 -0
  2. data/LICENSE +21 -0
  3. data/NOTES +7 -0
  4. data/README +179 -0
  5. data/Rakefile +2 -0
  6. data/ext/Makefile +20 -0
  7. data/ext/tmailscanner/tmail/MANIFEST +4 -0
  8. data/ext/tmailscanner/tmail/depend +1 -0
  9. data/ext/tmailscanner/tmail/extconf.rb +33 -0
  10. data/ext/tmailscanner/tmail/tmailscanner.c +614 -0
  11. data/lib/tmail.rb +6 -0
  12. data/lib/tmail/Makefile +18 -0
  13. data/lib/tmail/address.rb +392 -0
  14. data/lib/tmail/attachments.rb +65 -0
  15. data/lib/tmail/base64.rb +46 -0
  16. data/lib/tmail/compat.rb +41 -0
  17. data/lib/tmail/config.rb +67 -0
  18. data/lib/tmail/core_extensions.rb +63 -0
  19. data/lib/tmail/encode.rb +590 -0
  20. data/lib/tmail/header.rb +962 -0
  21. data/lib/tmail/index.rb +9 -0
  22. data/lib/tmail/interface.rb +1162 -0
  23. data/lib/tmail/loader.rb +3 -0
  24. data/lib/tmail/mail.rb +578 -0
  25. data/lib/tmail/mailbox.rb +496 -0
  26. data/lib/tmail/main.rb +6 -0
  27. data/lib/tmail/mbox.rb +3 -0
  28. data/lib/tmail/net.rb +250 -0
  29. data/lib/tmail/obsolete.rb +132 -0
  30. data/lib/tmail/parser.rb +1060 -0
  31. data/lib/tmail/parser.y +416 -0
  32. data/lib/tmail/port.rb +379 -0
  33. data/lib/tmail/quoting.rb +155 -0
  34. data/lib/tmail/require_arch.rb +58 -0
  35. data/lib/tmail/scanner.rb +49 -0
  36. data/lib/tmail/scanner_r.rb +261 -0
  37. data/lib/tmail/stringio.rb +280 -0
  38. data/lib/tmail/utils.rb +361 -0
  39. data/lib/tmail/version.rb +39 -0
  40. data/log/BugTrackingLog.txt +1245 -0
  41. data/log/Changelog.txt +534 -0
  42. data/log/Testlog.txt +2340 -0
  43. data/log/Todo.txt +30 -0
  44. data/meta/MANIFEST +128 -0
  45. data/meta/VERSION +1 -0
  46. data/meta/project.yaml +30 -0
  47. data/meta/unixname +1 -0
  48. data/sample/bench_base64.rb +48 -0
  49. data/sample/data/multipart +23 -0
  50. data/sample/data/normal +29 -0
  51. data/sample/data/sendtest +5 -0
  52. data/sample/data/simple +14 -0
  53. data/sample/data/test +27 -0
  54. data/sample/extract-attachements.rb +33 -0
  55. data/sample/from-check.rb +26 -0
  56. data/sample/multipart.rb +26 -0
  57. data/sample/parse-bench.rb +68 -0
  58. data/sample/parse-test.rb +19 -0
  59. data/sample/sendmail.rb +94 -0
  60. data/setup.rb +1482 -0
  61. data/site/contributing/index.html +183 -0
  62. data/site/css/clean.css +27 -0
  63. data/site/css/layout.css +31 -0
  64. data/site/css/style.css +60 -0
  65. data/site/download/index.html +61 -0
  66. data/site/img/envelope.jpg +0 -0
  67. data/site/img/mailman.gif +0 -0
  68. data/site/img/stamp-sm.jpg +0 -0
  69. data/site/img/stamp.jpg +0 -0
  70. data/site/img/stampborder.jpg +0 -0
  71. data/site/img/tfire.jpg +0 -0
  72. data/site/img/tmail.png +0 -0
  73. data/site/index.html +272 -0
  74. data/site/js/jquery.js +31 -0
  75. data/site/log/Changelog.xsl +33 -0
  76. data/site/log/changelog.xml +1677 -0
  77. data/site/outdated/BUGS +3 -0
  78. data/site/outdated/DEPENDS +1 -0
  79. data/site/outdated/Incompatibilities +89 -0
  80. data/site/outdated/Incompatibilities.ja +102 -0
  81. data/site/outdated/NEWS +9 -0
  82. data/site/outdated/README.ja +73 -0
  83. data/site/outdated/doc.ja/address.html +275 -0
  84. data/site/outdated/doc.ja/basics.html +405 -0
  85. data/site/outdated/doc.ja/config.html +49 -0
  86. data/site/outdated/doc.ja/details.html +146 -0
  87. data/site/outdated/doc.ja/index.html +39 -0
  88. data/site/outdated/doc.ja/mail.html +793 -0
  89. data/site/outdated/doc.ja/mailbox.html +265 -0
  90. data/site/outdated/doc.ja/port.html +95 -0
  91. data/site/outdated/doc.ja/tmail.html +58 -0
  92. data/site/outdated/doc.ja/usage.html +202 -0
  93. data/site/outdated/rdd/address.rrd.m +229 -0
  94. data/site/outdated/rdd/basics.rd.m +275 -0
  95. data/site/outdated/rdd/config.rrd.m +26 -0
  96. data/site/outdated/rdd/details.rd.m +117 -0
  97. data/site/outdated/rdd/index.rhtml.m +54 -0
  98. data/site/outdated/rdd/mail.rrd.m +701 -0
  99. data/site/outdated/rdd/mailbox.rrd.m +228 -0
  100. data/site/outdated/rdd/port.rrd.m +69 -0
  101. data/site/outdated/rdd/tmail.rrd.m +33 -0
  102. data/site/outdated/rdd/usage.rd.m +247 -0
  103. data/site/quickstart/index.html +69 -0
  104. data/site/quickstart/quickstart.html +52 -0
  105. data/site/quickstart/usage.html +193 -0
  106. data/site/reference/address.html +247 -0
  107. data/site/reference/config.html +30 -0
  108. data/site/reference/index.html +101 -0
  109. data/site/reference/mail.html +726 -0
  110. data/site/reference/mailbox.html +245 -0
  111. data/site/reference/port.html +75 -0
  112. data/site/reference/tmail.html +35 -0
  113. data/test/extctrl.rb +6 -0
  114. data/test/fixtures/mailbox +414 -0
  115. data/test/fixtures/mailbox_without_any_from_or_sender +10 -0
  116. data/test/fixtures/mailbox_without_from +11 -0
  117. data/test/fixtures/mailbox_without_return_path +12 -0
  118. data/test/fixtures/raw_attack_email_with_zero_length_whitespace +29 -0
  119. data/test/fixtures/raw_base64_decoded_string +0 -0
  120. data/test/fixtures/raw_base64_email +83 -0
  121. data/test/fixtures/raw_base64_encoded_string +1 -0
  122. data/test/fixtures/raw_email +14 -0
  123. data/test/fixtures/raw_email10 +20 -0
  124. data/test/fixtures/raw_email11 +34 -0
  125. data/test/fixtures/raw_email12 +32 -0
  126. data/test/fixtures/raw_email13 +29 -0
  127. data/test/fixtures/raw_email2 +114 -0
  128. data/test/fixtures/raw_email3 +70 -0
  129. data/test/fixtures/raw_email4 +59 -0
  130. data/test/fixtures/raw_email5 +19 -0
  131. data/test/fixtures/raw_email6 +20 -0
  132. data/test/fixtures/raw_email7 +66 -0
  133. data/test/fixtures/raw_email8 +47 -0
  134. data/test/fixtures/raw_email9 +28 -0
  135. data/test/fixtures/raw_email_multiple_from +30 -0
  136. data/test/fixtures/raw_email_quoted_with_0d0a +14 -0
  137. data/test/fixtures/raw_email_reply +32 -0
  138. data/test/fixtures/raw_email_simple +11 -0
  139. data/test/fixtures/raw_email_with_bad_date +48 -0
  140. data/test/fixtures/raw_email_with_illegal_boundary +58 -0
  141. data/test/fixtures/raw_email_with_mimepart_without_content_type +94 -0
  142. data/test/fixtures/raw_email_with_multipart_mixed_quoted_boundary +50 -0
  143. data/test/fixtures/raw_email_with_nested_attachment +100 -0
  144. data/test/fixtures/raw_email_with_partially_quoted_subject +14 -0
  145. data/test/fixtures/raw_email_with_quoted_illegal_boundary +58 -0
  146. data/test/kcode.rb +14 -0
  147. data/test/temp_test_one.rb +46 -0
  148. data/test/test_address.rb +1216 -0
  149. data/test/test_attachments.rb +131 -0
  150. data/test/test_base64.rb +64 -0
  151. data/test/test_encode.rb +139 -0
  152. data/test/test_header.rb +1021 -0
  153. data/test/test_helper.rb +9 -0
  154. data/test/test_mail.rb +756 -0
  155. data/test/test_mbox.rb +184 -0
  156. data/test/test_port.rb +440 -0
  157. data/test/test_quote.rb +107 -0
  158. data/test/test_scanner.rb +209 -0
  159. data/test/test_utils.rb +36 -0
  160. data/work/script/make +26 -0
  161. data/work/script/rdoc +39 -0
  162. data/work/script/setup +1616 -0
  163. data/work/script/test +30 -0
  164. metadata +297 -0
@@ -0,0 +1,9 @@
1
+ # Add in the local library for the load path so we get that before any possible
2
+ # gem that is already installed.
3
+ require 'stringio'
4
+ $:.unshift File.dirname(__FILE__) + "/../lib"
5
+ $:.unshift File.dirname(__FILE__) + "/../lib/tmail"
6
+ require 'test/unit'
7
+ require 'extctrl'
8
+ require 'test/unit'
9
+ require 'tmail'
data/test/test_mail.rb ADDED
@@ -0,0 +1,756 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'test_helper'
3
+ require 'tmail'
4
+ require 'kcode'
5
+ require 'time'
6
+
7
+ class TestMail < Test::Unit::TestCase
8
+ include TMail::TextUtils
9
+
10
+ def setup
11
+ @mail = TMail::Mail.new
12
+ end
13
+
14
+ def lf( str )
15
+ str.gsub(/\n|\r\n|\r/) { "\n" }
16
+ end
17
+
18
+ def crlf( str )
19
+ str.gsub(/\n|\r\n|\r/) { "\r\n" }
20
+ end
21
+
22
+ def test_MIME
23
+ # FIXME: test more.
24
+
25
+ kcode('EUC') {
26
+ mail = TMail::Mail.parse('From: hoge@example.jp (=?iso-2022-jp?B?GyRCJUYlOSVIGyhC?=)')
27
+ assert_not_nil mail['From']
28
+
29
+ expected = "\245\306\245\271\245\310"
30
+ if expected.respond_to? :force_encoding
31
+ expected.force_encoding(mail['From'].comments.first.encoding)
32
+ end
33
+ assert_equal [expected], mail['From'].comments
34
+
35
+ expected = "From: hoge@example.jp (\245\306\245\271\245\310)\n\n"
36
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
37
+ assert_equal expected, mail.to_s
38
+ assert_equal expected, mail.decoded
39
+
40
+ expected = "From: hoge@example.jp (=?iso-2022-jp?B?GyRCJUYlOSVIGyhC?=)\r\n\r\n"
41
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
42
+ assert_equal expected, mail.encoded
43
+ }
44
+ end
45
+
46
+ def test_to_s
47
+ time = Time.parse('Tue, 4 Dec 2001 10:49:58 +0900').strftime("%a,%e %b %Y %H:%M:%S %z")
48
+ str =<<EOS
49
+ Date: #{time}
50
+ To: Minero Aoki <aamine@loveruby.net>
51
+ Subject: This is test message.
52
+
53
+ This is body.
54
+ EOS
55
+ str = crlf(str)
56
+ m = TMail::Mail.parse(str)
57
+ # strip to avoid error by body's line terminator.
58
+ assert_equal lf(str).strip, m.decoded.strip
59
+ assert_equal crlf(str).strip, m.encoded.strip
60
+ end
61
+
62
+ def test__empty_return_path
63
+ str = "Return-Path: <>\r\n\r\n"
64
+ assert_equal str, TMail::Mail.parse(str).encoded
65
+ end
66
+
67
+ def test_date
68
+ t = Time.now
69
+ @mail.date = t
70
+ assert_equal t.to_i, @mail.date.to_i # avoid usec comparison
71
+ assert_equal time2str(t), @mail['date'].to_s
72
+
73
+ str = "Date: #{time2str(t)}\n\n"
74
+ assert_equal str, TMail::Mail.parse(str).to_s
75
+ end
76
+
77
+ def test_strftime
78
+ t = Time.now
79
+ fmt = '%A%a%B%b%c%d%H%I%j%M%m%p%S%U%W%w%X%x%Y%y%Z%%'
80
+ @mail.date = t
81
+ assert_equal t.strftime(fmt), @mail.strftime(fmt)
82
+ end
83
+
84
+ def test_to
85
+ addr = 'Minero Aoki <aamine@loveruby.net>'
86
+ @mail.to = addr
87
+ assert_equal 1, @mail['to'].addrs.size
88
+ assert_equal 'aamine@loveruby.net', @mail['to'].addrs[0].spec
89
+ assert_equal 'Minero Aoki', @mail['to'].addrs[0].phrase
90
+
91
+ a = @mail.to_addrs
92
+ assert_equal 1, a.size
93
+ assert_equal 'aamine@loveruby.net', a[0].spec
94
+ assert_equal 'Minero Aoki', a[0].phrase
95
+
96
+ a = @mail.to
97
+ assert_equal 1, a.size
98
+ assert_equal 'aamine@loveruby.net', a[0]
99
+
100
+ addr = TMail::Address.parse('Minero Aoki <aamine@loveruby.net>')
101
+ @mail.to_addrs = addr
102
+ assert_equal 1, @mail['to'].addrs.size
103
+ assert_equal 'aamine@loveruby.net', @mail['to'].addrs[0].spec
104
+ assert_equal 'Minero Aoki', @mail['to'].addrs[0].phrase
105
+
106
+ a = @mail.to_addrs
107
+ assert_equal 1, a.size
108
+ assert_equal 'aamine@loveruby.net', a[0].spec
109
+ assert_equal 'Minero Aoki', a[0].phrase
110
+
111
+ a = @mail.to
112
+ assert_equal 1, a.size
113
+ assert_equal 'aamine@loveruby.net', a[0]
114
+
115
+
116
+ @mail.to = ''
117
+ assert_equal nil, @mail.to
118
+ assert_equal 'DEFAULT VALUE', @mail.to('DEFAULT VALUE')
119
+
120
+ @mail.to = 'undisclosed-recipients: ;'
121
+ a = @mail.to
122
+ assert_equal nil, @mail.to
123
+ assert_equal 'DEFAULT VALUE', @mail.to('DEFAULT VALUE')
124
+
125
+
126
+ str = "\"Aoki, Minero\" <aamine@loveruby.net>\n\n"
127
+ @mail.to_addrs = a = TMail::Address.parse(str)
128
+ assert_equal ['aamine@loveruby.net'], @mail.to
129
+ assert_equal [a], @mail.to_addrs
130
+ assert_equal '"Aoki, Minero" <aamine@loveruby.net>', @mail.to_addrs[0].to_s
131
+ assert_equal '"Aoki, Minero" <aamine@loveruby.net>', @mail['to'].to_s
132
+ end
133
+
134
+ def test_cc
135
+ addr = 'Minero Aoki <aamine@loveruby.net>'
136
+ @mail.cc = addr
137
+ assert_equal 1, @mail['cc'].addrs.size
138
+ assert_equal 'aamine@loveruby.net', @mail['cc'].addrs[0].spec
139
+ assert_equal 'Minero Aoki', @mail['cc'].addrs[0].phrase
140
+
141
+ a = @mail.cc_addrs
142
+ assert_equal 1, a.size
143
+ assert_equal 'aamine@loveruby.net', a[0].spec
144
+ assert_equal 'Minero Aoki', a[0].phrase
145
+
146
+ a = @mail.cc
147
+ assert_equal 1, a.size
148
+ assert_equal 'aamine@loveruby.net', a[0]
149
+
150
+ addr = TMail::Address.parse('Minero Aoki <aamine@loveruby.net>')
151
+ @mail.cc_addrs = addr
152
+ assert_equal 1, @mail['cc'].addrs.size
153
+ assert_equal 'aamine@loveruby.net', @mail['cc'].addrs[0].spec
154
+ assert_equal 'Minero Aoki', @mail['cc'].addrs[0].phrase
155
+
156
+ a = @mail.cc_addrs
157
+ assert_equal 1, a.size
158
+ assert_equal 'aamine@loveruby.net', a[0].spec
159
+ assert_equal 'Minero Aoki', a[0].phrase
160
+
161
+ a = @mail.cc
162
+ assert_equal 1, a.size
163
+ assert_equal 'aamine@loveruby.net', a[0]
164
+
165
+
166
+ @mail.cc = ''
167
+ assert_equal nil, @mail.cc
168
+ assert_equal 'DEFAULT VALUE', @mail.cc('DEFAULT VALUE')
169
+
170
+ @mail.cc = 'undisclosed-recipients: ;'
171
+ a = @mail.cc
172
+ assert_equal nil, @mail.cc
173
+ assert_equal 'DEFAULT VALUE', @mail.cc('DEFAULT VALUE')
174
+ end
175
+
176
+ def test_bcc
177
+ addr = 'Minero Aoki <aamine@loveruby.net>'
178
+ @mail.bcc = addr
179
+ assert_equal 1, @mail['bcc'].addrs.size
180
+ assert_equal 'aamine@loveruby.net', @mail['bcc'].addrs[0].spec
181
+ assert_equal 'Minero Aoki', @mail['bcc'].addrs[0].phrase
182
+
183
+ a = @mail.bcc_addrs
184
+ assert_equal 1, a.size
185
+ assert_equal 'aamine@loveruby.net', a[0].spec
186
+ assert_equal 'Minero Aoki', a[0].phrase
187
+
188
+ a = @mail.bcc
189
+ assert_equal 1, a.size
190
+ assert_equal 'aamine@loveruby.net', a[0]
191
+
192
+ addr = TMail::Address.parse('Minero Aoki <aamine@loveruby.net>')
193
+ @mail.bcc_addrs = addr
194
+ assert_equal 1, @mail['bcc'].addrs.size
195
+ assert_equal 'aamine@loveruby.net', @mail['bcc'].addrs[0].spec
196
+ assert_equal 'Minero Aoki', @mail['bcc'].addrs[0].phrase
197
+
198
+ a = @mail.bcc_addrs
199
+ assert_equal 1, a.size
200
+ assert_equal 'aamine@loveruby.net', a[0].spec
201
+ assert_equal 'Minero Aoki', a[0].phrase
202
+
203
+ a = @mail.bcc
204
+ assert_equal 1, a.size
205
+ assert_equal 'aamine@loveruby.net', a[0]
206
+
207
+
208
+ @mail.bcc = ''
209
+ assert_equal nil, @mail.bcc
210
+ assert_equal 'DEFAULT VALUE', @mail.bcc('DEFAULT VALUE')
211
+
212
+ @mail.bcc = 'undisclosed-recipients: ;'
213
+ a = @mail.bcc
214
+ assert_equal nil, @mail.bcc
215
+ assert_equal 'DEFAULT VALUE', @mail.bcc('DEFAULT VALUE')
216
+ end
217
+
218
+ def test_from
219
+ addr = 'Minero Aoki <aamine@loveruby.net>'
220
+ @mail.from = addr
221
+ assert_equal 1, @mail['from'].addrs.size
222
+ assert_equal 'aamine@loveruby.net', @mail['from'].addrs[0].spec
223
+ assert_equal 'Minero Aoki', @mail['from'].addrs[0].phrase
224
+
225
+ a = @mail.from_addrs
226
+ assert_equal 1, a.size
227
+ assert_equal 'aamine@loveruby.net', a[0].spec
228
+ assert_equal 'Minero Aoki', a[0].phrase
229
+
230
+ a = @mail.from
231
+ assert_equal 1, a.size
232
+ assert_equal 'aamine@loveruby.net', a[0]
233
+
234
+ addr = TMail::Address.parse('Minero Aoki <aamine@loveruby.net>')
235
+ @mail.from_addrs = addr
236
+ assert_equal 1, @mail['from'].addrs.size
237
+ assert_equal 'aamine@loveruby.net', @mail['from'].addrs[0].spec
238
+ assert_equal 'Minero Aoki', @mail['from'].addrs[0].phrase
239
+
240
+ a = @mail.from_addrs
241
+ assert_equal 1, a.size
242
+ assert_equal 'aamine@loveruby.net', a[0].spec
243
+ assert_equal 'Minero Aoki', a[0].phrase
244
+
245
+ a = @mail.from
246
+ assert_equal 1, a.size
247
+ assert_equal 'aamine@loveruby.net', a[0]
248
+
249
+
250
+ @mail.from = ''
251
+ assert_equal nil, @mail.from
252
+ assert_equal 'DEFAULT VALUE', @mail.from('DEFAULT VALUE')
253
+
254
+ @mail.from = 'undisclosed-recipients: ;'
255
+ a = @mail.from
256
+ assert_equal nil, @mail.from
257
+ assert_equal 'DEFAULT VALUE', @mail.from('DEFAULT VALUE')
258
+
259
+ @mail.from = "raasdnil@gmail.com, mikel@me.com"
260
+ assert_equal 2, @mail['from'].addrs.size
261
+ assert_equal 'raasdnil@gmail.com', @mail['from'].addrs[0].spec
262
+ assert_equal 'mikel@me.com', @mail['from'].addrs[1].spec
263
+ end
264
+
265
+ def test_reply_to
266
+ addr = 'Minero Aoki <aamine@loveruby.net>'
267
+ @mail.reply_to = addr
268
+ assert_equal 1, @mail['reply-to'].addrs.size
269
+ assert_equal 'aamine@loveruby.net', @mail['reply-to'].addrs[0].spec
270
+ assert_equal 'Minero Aoki', @mail['reply-to'].addrs[0].phrase
271
+
272
+ a = @mail.reply_to_addrs
273
+ assert_equal 1, a.size
274
+ assert_equal 'aamine@loveruby.net', a[0].spec
275
+ assert_equal 'Minero Aoki', a[0].phrase
276
+
277
+ a = @mail.reply_to
278
+ assert_equal 1, a.size
279
+ assert_equal 'aamine@loveruby.net', a[0]
280
+
281
+ addr = TMail::Address.parse('Minero Aoki <aamine@loveruby.net>')
282
+ @mail.reply_to_addrs = addr
283
+ assert_equal 1, @mail['reply-to'].addrs.size
284
+ assert_equal 'aamine@loveruby.net', @mail['reply-to'].addrs[0].spec
285
+ assert_equal 'Minero Aoki', @mail['reply-to'].addrs[0].phrase
286
+
287
+ a = @mail.reply_to_addrs
288
+ assert_equal 1, a.size
289
+ assert_equal 'aamine@loveruby.net', a[0].spec
290
+ assert_equal 'Minero Aoki', a[0].phrase
291
+
292
+ a = @mail.reply_to
293
+ assert_equal 1, a.size
294
+ assert_equal 'aamine@loveruby.net', a[0]
295
+
296
+
297
+ @mail.reply_to = ''
298
+ assert_equal nil, @mail.reply_to
299
+ assert_equal 'DEFAULT VALUE', @mail.reply_to('DEFAULT VALUE')
300
+
301
+ @mail.reply_to = 'undisclosed-recipients: ;'
302
+ a = @mail.reply_to
303
+ assert_equal nil, @mail.reply_to
304
+ assert_equal 'DEFAULT VALUE', @mail.reply_to('DEFAULT VALUE')
305
+ end
306
+
307
+ def test_reply_to_with_blank_reply_to
308
+ @mail = TMail::Mail.new
309
+ from_addr = TMail::Address.parse("Mikel Lindsaar <mikel@lindsaar.net>")
310
+ @mail.from = from_addr
311
+
312
+ # No reply_to set, should return from address
313
+ assert_equal([from_addr], @mail.reply_addresses)
314
+
315
+ # reply_to and from set, should return reply_to
316
+ reply_addr = TMail::Address.parse("Bob <bob@you.net>")
317
+ @mail.reply_to = reply_addr
318
+ assert_equal([reply_addr], @mail.reply_addresses)
319
+
320
+ # reply_to set but nil, should return from address
321
+ @mail.reply_to = nil
322
+ assert_equal([from_addr], @mail.reply_addresses)
323
+
324
+ # from and reply_to set, but nil, should return empty array
325
+ @mail.from = nil
326
+ assert_equal([], @mail.reply_addresses)
327
+ end
328
+
329
+ def do_test_address_attr( name )
330
+ addr = 'Minero Aoki <aamine@loveruby.net>'
331
+ @mail.__send__( name + '=', addr )
332
+ a = @mail.__send__( name + '_addrs' )
333
+ assert_equal 1, a.size
334
+ assert_equal 'aamine@loveruby.net', a[0].spec
335
+ assert_equal 'Minero Aoki', a[0].phrase
336
+
337
+ a = @mail.__send__( name )
338
+ assert_equal 1, a.size
339
+ assert_equal 'aamine@loveruby.net', a[0]
340
+ end
341
+
342
+ def test_subject
343
+ s = 'This is test subject!'
344
+ @mail.subject = s
345
+ assert_equal s, @mail.subject
346
+ assert_equal s, @mail['subject'].to_s
347
+ end
348
+
349
+ def test_unquote_quoted_printable_subject
350
+ msg = <<EOF
351
+ From: me@example.com
352
+ Subject: =?utf-8?Q?testing_testing_=D6=A4?=
353
+ Content-Type: text/plain; charset=iso-8859-1
354
+
355
+ The body
356
+ EOF
357
+ mail = TMail::Mail.parse(msg)
358
+ expected = "testing testing \326\244"
359
+ expected.force_encoding 'utf-8' if expected.respond_to? :force_encoding
360
+ assert_equal expected, mail.subject
361
+ assert_equal "=?utf-8?Q?testing_testing_=D6=A4?=", mail.quoted_subject
362
+ end
363
+
364
+ def test_unquote_7bit_subject
365
+ msg = <<EOF
366
+ From: me@example.com
367
+ Subject: this == working?
368
+ Content-Type: text/plain; charset=iso-8859-1
369
+
370
+ The body
371
+ EOF
372
+ mail = TMail::Mail.parse(msg)
373
+ assert_equal "this == working?", mail.subject
374
+ assert_equal "this == working?", mail.quoted_subject
375
+ end
376
+
377
+ def test_unquote_7bit_body
378
+ msg = <<EOF
379
+ From: me@example.com
380
+ Subject: subject
381
+ Content-Type: text/plain; charset=iso-8859-1
382
+ Content-Transfer-Encoding: 7bit
383
+
384
+ The=3Dbody
385
+ EOF
386
+ mail = TMail::Mail.parse(msg)
387
+ assert_equal "The=3Dbody", mail.body.strip
388
+ assert_equal "The=3Dbody", mail.quoted_body.strip
389
+ end
390
+
391
+ def test_unquote_quoted_printable_body
392
+ msg = <<EOF
393
+ From: me@example.com
394
+ Subject: subject
395
+ Content-Type: text/plain; charset=iso-8859-1
396
+ Content-Transfer-Encoding: quoted-printable
397
+
398
+ The=3Dbody
399
+ EOF
400
+ mail = TMail::Mail.parse(msg)
401
+ assert_equal "The=body", mail.body.strip
402
+ assert_equal "The=3Dbody", mail.quoted_body.strip
403
+ end
404
+
405
+ def test_unquote_base64_body
406
+ msg = <<EOF
407
+ From: me@example.com
408
+ Subject: subject
409
+ Content-Type: text/plain; charset=iso-8859-1
410
+ Content-Transfer-Encoding: base64
411
+
412
+ VGhlIGJvZHk=
413
+ EOF
414
+ mail = TMail::Mail.parse(msg)
415
+ assert_equal "The body", mail.body.strip
416
+ assert_equal "VGhlIGJvZHk=", mail.quoted_body.strip
417
+ end
418
+
419
+ def test_unquote_base64_body_with_invalid_charset
420
+ msg = <<EOF
421
+ From: "2009-07-02 21:53:01" <sender@example.com>
422
+ Subject: unqoute base64 body with invalid charset
423
+ MIME-Version: 1.0
424
+ charset="gb2312"
425
+ Content-Transfer-Encoding: base64
426
+
427
+ RGVhciBTaXJzLCANCldlIGFyZSBnaXZlbiB0byB1bmRlcnN0YW5kIHRoYXQg
428
+ eW91IGFyZSAgTWFudWZhY3R1cmVyIG9mICBwbHN0aWMgIEJvdHRsZXMNCkFk
429
+ ZKO6IGJsYWggQ2hpbmE=
430
+ EOF
431
+ mail = TMail::Mail.parse(msg)
432
+ assert_equal "Dear Sirs, \r\nWe are given to understand that you are Manufacturer of plstic Bottles\r\nAdd: blah China", mail.body.strip
433
+ end
434
+
435
+ def test_message_id
436
+ assert_nil @mail.message_id
437
+ assert_equal 1, @mail.message_id(1)
438
+
439
+ m = '<very.unique.identity@fully.quorified.domain.name>'
440
+ @mail.message_id = m
441
+ assert_equal m, @mail.message_id
442
+
443
+ @mail.message_id = 'this_is_my_badly_formatted_message_id'
444
+ assert_equal nil, @mail.message_id
445
+ end
446
+
447
+ def test_in_reply_to
448
+ i = '<very.unique.identity@fully.quorified.domain.name>'
449
+ @mail.in_reply_to = i
450
+ a = @mail.in_reply_to
451
+ assert_equal a.size, 1
452
+ assert_equal i, a[0]
453
+
454
+ @mail.in_reply_to = [i]
455
+ a = @mail.in_reply_to
456
+ assert_equal a.size, 1
457
+ assert_equal i, a[0]
458
+ end
459
+
460
+ def test_references
461
+ i = '<very.unique.identity@fully.quorified.domain.name>'
462
+ @mail.references = i
463
+ a = @mail.references
464
+ assert_equal a.size, 1
465
+ assert_equal i, a[0]
466
+
467
+ @mail.references = [i]
468
+ a = @mail.references
469
+ assert_equal a.size, 1
470
+ assert_equal i, a[0]
471
+ end
472
+
473
+ def test_mime_version
474
+ assert_nil @mail.mime_version
475
+ assert_equal 1, @mail.mime_version(1)
476
+
477
+ %w( 1.0 999.999 ).each do |v|
478
+ @mail.mime_version = v
479
+ assert_equal v, @mail.mime_version
480
+ end
481
+ end
482
+
483
+ def test_content_type
484
+ [ 'text/plain', 'application/binary', 'multipart/mixed' ].each do |t|
485
+ @mail.content_type = t
486
+ assert_equal t, @mail.content_type
487
+ assert_equal t.split('/',2)[0], @mail.main_type
488
+ assert_equal t.split('/',2)[1], @mail.sub_type
489
+ end
490
+
491
+ @mail.content_type = 'text/plain; charset=iso-2022-jp'
492
+ @mail.content_type = 'application/postscript'
493
+
494
+ assert_raises(ArgumentError) {
495
+ @mail.content_type = 'text'
496
+ }
497
+ end
498
+
499
+ def test_email_with_part_without_content_type
500
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email_with_mimepart_without_content_type")
501
+ mail = TMail::Mail.parse(fixture)
502
+ assert_equal(3, mail.parts.length)
503
+ end
504
+
505
+ def test_mail_to_s_with_illegal_content_type_boundary_preserves_quotes
506
+ msg = <<EOF
507
+ From: mikel@example.com
508
+ Subject: Hello
509
+ Content-Type: multipart/signed;
510
+ micalg=sha1;
511
+ boundary=Apple-Mail-42-587703407;
512
+ protocol="application/pkcs7-signature"
513
+
514
+ The body
515
+ EOF
516
+
517
+ output = <<EOF
518
+ From: mikel@example.com
519
+ Subject: Hello
520
+ #{if RUBY_VERSION < '1.8.7'
521
+ 'Content-Type: multipart/signed; protocol="application/pkcs7-signature"; boundary=Apple-Mail-42-587703407; micalg=sha1'
522
+ else
523
+ 'Content-Type: multipart/signed; micalg=sha1; boundary=Apple-Mail-42-587703407; protocol="application/pkcs7-signature"'
524
+ end}
525
+
526
+ The body
527
+ EOF
528
+
529
+ mail = TMail::Mail.parse(msg)
530
+ assert_equal(output, mail.to_s)
531
+ end
532
+
533
+ def test_mail_to_s_with_filename_discards_quotes_as_needed
534
+ msg = <<EOF
535
+ From: mikel@example.com
536
+ Subject: =?utf-8?Q?testing_testing_=D6=A4?=
537
+ Content-Disposition: attachment; filename="README.txt.pif"
538
+
539
+ The body
540
+ EOF
541
+ mail = TMail::Mail.parse(msg)
542
+ result =<<EOF
543
+ From: mikel@example.com
544
+ Subject: =?utf-8?Q?testing_testing_=D6=A4?=
545
+ Content-Disposition: attachment; filename=README.txt.pif
546
+
547
+ The body
548
+ EOF
549
+ assert_equal(result, mail.to_s)
550
+
551
+
552
+ msg = <<EOF
553
+ From: mikel@example.com
554
+ Subject: =?utf-8?Q?testing_testing_=D6=A4?=
555
+ Content-Disposition: attachment; filename="READ-=ME.t=xt./pi?f"
556
+
557
+ The body
558
+ EOF
559
+ mail = TMail::Mail.parse(msg)
560
+ result =<<EOF
561
+ From: mikel@example.com
562
+ Subject: =?utf-8?Q?testing_testing_=D6=A4?=
563
+ Content-Disposition: attachment; filename="READ-=ME.t=xt./pi?f"
564
+
565
+ The body
566
+ EOF
567
+ assert_equal(result, mail.to_s)
568
+
569
+ end
570
+
571
+ def test_charset
572
+ c = 'iso-2022-jp'
573
+ @mail.charset = c
574
+ assert_equal c, @mail.charset
575
+ assert_equal 'text', @mail.main_type
576
+ assert_equal 'plain', @mail.sub_type
577
+
578
+ @mail.content_type = 'application/binary'
579
+ @mail.charset = c
580
+ assert_equal c, @mail.charset
581
+ end
582
+
583
+ def test_transfer_encoding
584
+ @mail.transfer_encoding = 'base64'
585
+ assert_equal 'base64', @mail.transfer_encoding
586
+ @mail.transfer_encoding = 'BASE64'
587
+ assert_equal 'base64', @mail.transfer_encoding
588
+ @mail.content_transfer_encoding = '7bit'
589
+ assert_equal '7bit', @mail.content_transfer_encoding
590
+ @mail.encoding = 'binary'
591
+ assert_equal 'binary', @mail.encoding
592
+ end
593
+
594
+ def test_disposition
595
+ @mail['content-disposition'] = 'attachment; filename="test.rb"'
596
+ assert_equal 'attachment', @mail.disposition
597
+ assert_equal 'attachment', @mail.content_disposition
598
+ assert_equal 'test.rb', @mail.disposition_param('filename')
599
+
600
+ @mail.disposition = 'none'
601
+ assert_equal 'none', @mail.disposition
602
+ assert_nil @mail.disposition_param('filename')
603
+ assert_equal 1, @mail.disposition_param('filename', 1)
604
+
605
+ src = '=?iso-2022-jp?B?GyRCRnxLXDhsGyhCLnR4dA==?='
606
+ @mail['content-disposition'] = %Q(attachment; filename="#{src}")
607
+ ok = NKF.nkf('-m -e', src)
608
+ kcode('EUC') {
609
+ assert_equal ok, @mail.disposition_param('filename')
610
+ }
611
+ end
612
+
613
+ def test_set_disposition
614
+ @mail.set_disposition 'attachment', 'filename'=>'sample.rb'
615
+ assert_equal 'attachment', @mail.disposition
616
+ assert_equal 'sample.rb', @mail.disposition_param('filename')
617
+ end
618
+
619
+ def test_receive_attachments
620
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email2")
621
+ mail = TMail::Mail.parse(fixture)
622
+ attachment = mail.attachments.last
623
+ assert_equal "smime.p7s", attachment.original_filename
624
+ assert_equal "application/pkcs7-signature", attachment.content_type
625
+ end
626
+
627
+ def test_body_with_underscores
628
+ m = TMail::Mail.new
629
+ expected = 'something_with_underscores'
630
+ m.encoding = 'quoted-printable'
631
+ quoted_body = [expected].pack('*M')
632
+ m.body = quoted_body
633
+ assert_equal "something_with_underscores=\n", m.quoted_body
634
+ assert_equal expected, m.body
635
+ end
636
+
637
+ def test_nested_attachments_are_recognized_correctly
638
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email_with_nested_attachment")
639
+ assert_equal 2, mail.attachments.length
640
+ assert_equal "image/png", mail.attachments.first.content_type
641
+ assert_equal 1902, mail.attachments.first.length
642
+ assert_equal "application/pkcs7-signature", mail.attachments.last.content_type
643
+ end
644
+
645
+ def test_decode_attachment_without_charset
646
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email3")
647
+ attachment = mail.attachments.last
648
+ assert_equal 1026, attachment.read.length
649
+ end
650
+
651
+ def test_attachment_using_content_location
652
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email12")
653
+ mail = TMail::Mail.parse(fixture)
654
+ assert_equal 1, mail.attachments.length
655
+ assert_equal "Photo25.jpg", mail.attachments.first.original_filename
656
+ end
657
+
658
+ def test_attachment_with_text_type
659
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email13")
660
+ mail = TMail::Mail.parse(fixture)
661
+ assert mail.has_attachments?
662
+ assert_equal 1, mail.attachments.length
663
+ assert_equal "hello.rb", mail.attachments.first.original_filename
664
+ end
665
+
666
+ def test_decode_part_without_content_type
667
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email4")
668
+ mail = TMail::Mail.parse(fixture)
669
+ assert_nothing_raised { mail.body }
670
+ end
671
+
672
+ def test_decode_message_without_content_type
673
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email4")
674
+ assert_nothing_raised { mail.body }
675
+ end
676
+
677
+ def test_decode_message_with_incorrect_charset
678
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email6")
679
+ mail = TMail::Mail.parse(fixture)
680
+ assert_nothing_raised { mail.body }
681
+ end
682
+
683
+ def test_quoting_of_illegal_boundary_when_doing_mail_to_s
684
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email_with_illegal_boundary")
685
+ assert_equal(true, mail.multipart?)
686
+ assert_equal('multipart/alternative; boundary="----=_NextPart_000_0093_01C81419.EB75E850"', mail['content-type'].to_s)
687
+ end
688
+
689
+ def test_quoted_illegal_boundary_when_doing_mail_to_s
690
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email_with_quoted_illegal_boundary")
691
+ assert_equal(true, mail.multipart?)
692
+ assert_equal('multipart/alternative; boundary="----=_NextPart_000_0093_01C81419.EB75E850"', mail['content-type'].to_s)
693
+ end
694
+
695
+ def test_quoted_illegal_boundary_with_multipart_mixed_when_doing_mail_to_s
696
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email_with_multipart_mixed_quoted_boundary")
697
+ assert_equal(true, mail.multipart?)
698
+ assert_equal('multipart/mixed; boundary="----=_Part_2192_32400445.1115745999735"', mail['content-type'].to_s)
699
+ end
700
+
701
+ def test_when_opening_a_base64_encoded_email_and_re_parsing_it_keeps_the_transfer_encoding_correct
702
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_base64_email")
703
+ assert_equal("Base64", mail['Content-Transfer-Encoding'].to_s)
704
+ decoded_mail = TMail::Mail.parse(mail.to_s)
705
+ assert_equal("Base64", decoded_mail['Content-Transfer-Encoding'].to_s)
706
+ end
707
+
708
+ def test_create_reply
709
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email")
710
+ reply = mail.create_reply
711
+ assert_equal(["<d3b8cf8e49f04480850c28713a1f473e@37signals.com>"], reply.in_reply_to)
712
+ assert_equal(["<d3b8cf8e49f04480850c28713a1f473e@37signals.com>"], reply.references)
713
+ assert_equal(TMail::Mail, mail.create_reply.class)
714
+ end
715
+
716
+ def test_create_forward
717
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_email")
718
+ forward = mail.create_forward
719
+ assert_equal(true, forward.multipart?)
720
+ assert_equal(TMail::Mail, forward.class)
721
+ end
722
+
723
+ def test_body
724
+ m = TMail::Mail.new
725
+ expected = 'something_with_underscores'
726
+ m.encoding = 'quoted-printable'
727
+ quoted_body = [expected].pack('*M')
728
+ m.body = quoted_body
729
+ assert_equal "something_with_underscores=\n", m.quoted_body
730
+ assert_equal expected, m.body
731
+ end
732
+
733
+ def test_nested_attachments_are_recognized_correctly
734
+ fixture = File.read("#{File.dirname(__FILE__)}/fixtures/raw_email_with_nested_attachment")
735
+ mail = TMail::Mail.parse(fixture)
736
+ assert_equal 2, mail.attachments.length
737
+ assert_equal "image/png", mail.attachments.first.content_type
738
+ assert_equal 1902, mail.attachments.first.length
739
+ assert_equal "application/pkcs7-signature", mail.attachments.last.content_type
740
+ end
741
+
742
+ def test_preamble_read
743
+ fixture = File.read("#{File.dirname(__FILE__)}/fixtures/raw_email4")
744
+ mail = TMail::Mail.parse(fixture)
745
+ assert_equal 'This is a multi-part message in MIME format.', mail.preamble.strip
746
+ end
747
+
748
+ def test_preamble_write
749
+ mail = TMail::Mail.new
750
+ part = TMail::Mail.parse("Content-Type: text/plain\n\nBlah")
751
+ mail.parts << part
752
+ mail.preamble = 'This is the preamble'
753
+ assert(mail.encoded =~ /\r\n\r\nThis is the preamble\r\n--mimepart/)
754
+ end
755
+
756
+ end