sa-tmail 1.2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) 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 +34 -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/lib/vendor/rchardet-1.3/COPYING +504 -0
  41. data/lib/vendor/rchardet-1.3/README +12 -0
  42. data/lib/vendor/rchardet-1.3/lib/rchardet.rb +67 -0
  43. data/lib/vendor/rchardet-1.3/lib/rchardet/big5freq.rb +927 -0
  44. data/lib/vendor/rchardet-1.3/lib/rchardet/big5prober.rb +42 -0
  45. data/lib/vendor/rchardet-1.3/lib/rchardet/chardistribution.rb +237 -0
  46. data/lib/vendor/rchardet-1.3/lib/rchardet/charsetgroupprober.rb +112 -0
  47. data/lib/vendor/rchardet-1.3/lib/rchardet/charsetprober.rb +75 -0
  48. data/lib/vendor/rchardet-1.3/lib/rchardet/codingstatemachine.rb +64 -0
  49. data/lib/vendor/rchardet-1.3/lib/rchardet/constants.rb +42 -0
  50. data/lib/vendor/rchardet-1.3/lib/rchardet/escprober.rb +90 -0
  51. data/lib/vendor/rchardet-1.3/lib/rchardet/escsm.rb +244 -0
  52. data/lib/vendor/rchardet-1.3/lib/rchardet/eucjpprober.rb +88 -0
  53. data/lib/vendor/rchardet-1.3/lib/rchardet/euckrfreq.rb +596 -0
  54. data/lib/vendor/rchardet-1.3/lib/rchardet/euckrprober.rb +42 -0
  55. data/lib/vendor/rchardet-1.3/lib/rchardet/euctwfreq.rb +430 -0
  56. data/lib/vendor/rchardet-1.3/lib/rchardet/euctwprober.rb +42 -0
  57. data/lib/vendor/rchardet-1.3/lib/rchardet/gb2312freq.rb +474 -0
  58. data/lib/vendor/rchardet-1.3/lib/rchardet/gb2312prober.rb +42 -0
  59. data/lib/vendor/rchardet-1.3/lib/rchardet/hebrewprober.rb +289 -0
  60. data/lib/vendor/rchardet-1.3/lib/rchardet/jisfreq.rb +570 -0
  61. data/lib/vendor/rchardet-1.3/lib/rchardet/jpcntx.rb +229 -0
  62. data/lib/vendor/rchardet-1.3/lib/rchardet/langbulgarianmodel.rb +229 -0
  63. data/lib/vendor/rchardet-1.3/lib/rchardet/langcyrillicmodel.rb +330 -0
  64. data/lib/vendor/rchardet-1.3/lib/rchardet/langgreekmodel.rb +227 -0
  65. data/lib/vendor/rchardet-1.3/lib/rchardet/langhebrewmodel.rb +202 -0
  66. data/lib/vendor/rchardet-1.3/lib/rchardet/langhungarianmodel.rb +226 -0
  67. data/lib/vendor/rchardet-1.3/lib/rchardet/langthaimodel.rb +201 -0
  68. data/lib/vendor/rchardet-1.3/lib/rchardet/latin1prober.rb +147 -0
  69. data/lib/vendor/rchardet-1.3/lib/rchardet/mbcharsetprober.rb +89 -0
  70. data/lib/vendor/rchardet-1.3/lib/rchardet/mbcsgroupprober.rb +47 -0
  71. data/lib/vendor/rchardet-1.3/lib/rchardet/mbcssm.rb +542 -0
  72. data/lib/vendor/rchardet-1.3/lib/rchardet/sbcharsetprober.rb +124 -0
  73. data/lib/vendor/rchardet-1.3/lib/rchardet/sbcsgroupprober.rb +58 -0
  74. data/lib/vendor/rchardet-1.3/lib/rchardet/sjisprober.rb +88 -0
  75. data/lib/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb +166 -0
  76. data/lib/vendor/rchardet-1.3/lib/rchardet/utf8prober.rb +87 -0
  77. data/log/BugTrackingLog.txt +1245 -0
  78. data/log/Changelog.txt +534 -0
  79. data/log/Testlog.txt +2340 -0
  80. data/log/Todo.txt +30 -0
  81. data/meta/MANIFEST +128 -0
  82. data/meta/VERSION +1 -0
  83. data/meta/project.yaml +30 -0
  84. data/meta/unixname +1 -0
  85. data/sample/bench_base64.rb +48 -0
  86. data/sample/data/multipart +23 -0
  87. data/sample/data/normal +29 -0
  88. data/sample/data/sendtest +5 -0
  89. data/sample/data/simple +14 -0
  90. data/sample/data/test +27 -0
  91. data/sample/extract-attachements.rb +33 -0
  92. data/sample/from-check.rb +26 -0
  93. data/sample/multipart.rb +26 -0
  94. data/sample/parse-bench.rb +68 -0
  95. data/sample/parse-test.rb +19 -0
  96. data/sample/sendmail.rb +94 -0
  97. data/setup.rb +1482 -0
  98. data/site/contributing/index.html +183 -0
  99. data/site/css/clean.css +27 -0
  100. data/site/css/layout.css +31 -0
  101. data/site/css/style.css +60 -0
  102. data/site/download/index.html +61 -0
  103. data/site/img/envelope.jpg +0 -0
  104. data/site/img/mailman.gif +0 -0
  105. data/site/img/stamp-sm.jpg +0 -0
  106. data/site/img/stamp.jpg +0 -0
  107. data/site/img/stampborder.jpg +0 -0
  108. data/site/img/tfire.jpg +0 -0
  109. data/site/img/tmail.png +0 -0
  110. data/site/index.html +272 -0
  111. data/site/js/jquery.js +31 -0
  112. data/site/log/Changelog.xsl +33 -0
  113. data/site/log/changelog.xml +1677 -0
  114. data/site/outdated/BUGS +3 -0
  115. data/site/outdated/DEPENDS +1 -0
  116. data/site/outdated/Incompatibilities +89 -0
  117. data/site/outdated/Incompatibilities.ja +102 -0
  118. data/site/outdated/NEWS +9 -0
  119. data/site/outdated/README.ja +73 -0
  120. data/site/outdated/doc.ja/address.html +275 -0
  121. data/site/outdated/doc.ja/basics.html +405 -0
  122. data/site/outdated/doc.ja/config.html +49 -0
  123. data/site/outdated/doc.ja/details.html +146 -0
  124. data/site/outdated/doc.ja/index.html +39 -0
  125. data/site/outdated/doc.ja/mail.html +793 -0
  126. data/site/outdated/doc.ja/mailbox.html +265 -0
  127. data/site/outdated/doc.ja/port.html +95 -0
  128. data/site/outdated/doc.ja/tmail.html +58 -0
  129. data/site/outdated/doc.ja/usage.html +202 -0
  130. data/site/outdated/rdd/address.rrd.m +229 -0
  131. data/site/outdated/rdd/basics.rd.m +275 -0
  132. data/site/outdated/rdd/config.rrd.m +26 -0
  133. data/site/outdated/rdd/details.rd.m +117 -0
  134. data/site/outdated/rdd/index.rhtml.m +54 -0
  135. data/site/outdated/rdd/mail.rrd.m +701 -0
  136. data/site/outdated/rdd/mailbox.rrd.m +228 -0
  137. data/site/outdated/rdd/port.rrd.m +69 -0
  138. data/site/outdated/rdd/tmail.rrd.m +33 -0
  139. data/site/outdated/rdd/usage.rd.m +247 -0
  140. data/site/quickstart/index.html +69 -0
  141. data/site/quickstart/quickstart.html +52 -0
  142. data/site/quickstart/usage.html +193 -0
  143. data/site/reference/address.html +247 -0
  144. data/site/reference/config.html +30 -0
  145. data/site/reference/index.html +101 -0
  146. data/site/reference/mail.html +726 -0
  147. data/site/reference/mailbox.html +245 -0
  148. data/site/reference/port.html +75 -0
  149. data/site/reference/tmail.html +35 -0
  150. data/test/extctrl.rb +6 -0
  151. data/test/fixtures/mailbox +414 -0
  152. data/test/fixtures/mailbox_without_any_from_or_sender +10 -0
  153. data/test/fixtures/mailbox_without_from +11 -0
  154. data/test/fixtures/mailbox_without_return_path +12 -0
  155. data/test/fixtures/raw_attack_email_with_zero_length_whitespace +29 -0
  156. data/test/fixtures/raw_base64_decoded_string +0 -0
  157. data/test/fixtures/raw_base64_email +83 -0
  158. data/test/fixtures/raw_base64_encoded_string +1 -0
  159. data/test/fixtures/raw_email +14 -0
  160. data/test/fixtures/raw_email10 +20 -0
  161. data/test/fixtures/raw_email11 +34 -0
  162. data/test/fixtures/raw_email12 +32 -0
  163. data/test/fixtures/raw_email13 +29 -0
  164. data/test/fixtures/raw_email2 +114 -0
  165. data/test/fixtures/raw_email3 +70 -0
  166. data/test/fixtures/raw_email4 +59 -0
  167. data/test/fixtures/raw_email5 +19 -0
  168. data/test/fixtures/raw_email6 +20 -0
  169. data/test/fixtures/raw_email7 +66 -0
  170. data/test/fixtures/raw_email8 +47 -0
  171. data/test/fixtures/raw_email9 +28 -0
  172. data/test/fixtures/raw_email_multiple_from +30 -0
  173. data/test/fixtures/raw_email_quoted_with_0d0a +14 -0
  174. data/test/fixtures/raw_email_reply +32 -0
  175. data/test/fixtures/raw_email_simple +11 -0
  176. data/test/fixtures/raw_email_with_bad_date +48 -0
  177. data/test/fixtures/raw_email_with_illegal_boundary +58 -0
  178. data/test/fixtures/raw_email_with_mimepart_without_content_type +94 -0
  179. data/test/fixtures/raw_email_with_multipart_mixed_quoted_boundary +50 -0
  180. data/test/fixtures/raw_email_with_nested_attachment +100 -0
  181. data/test/fixtures/raw_email_with_partially_quoted_subject +14 -0
  182. data/test/fixtures/raw_email_with_quoted_illegal_boundary +58 -0
  183. data/test/kcode.rb +14 -0
  184. data/test/temp_test_one.rb +46 -0
  185. data/test/test_address.rb +1216 -0
  186. data/test/test_attachments.rb +131 -0
  187. data/test/test_base64.rb +64 -0
  188. data/test/test_encode.rb +139 -0
  189. data/test/test_header.rb +1021 -0
  190. data/test/test_helper.rb +9 -0
  191. data/test/test_mail.rb +756 -0
  192. data/test/test_mbox.rb +184 -0
  193. data/test/test_port.rb +440 -0
  194. data/test/test_quote.rb +107 -0
  195. data/test/test_scanner.rb +209 -0
  196. data/test/test_utils.rb +36 -0
  197. data/work/script/make +26 -0
  198. data/work/script/rdoc +39 -0
  199. data/work/script/setup +1616 -0
  200. data/work/script/test +30 -0
  201. metadata +309 -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'
@@ -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