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,131 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ require 'test_helper'
4
+ require 'tmail'
5
+
6
+ class TestAttachments < Test::Unit::TestCase
7
+
8
+ def test_attachment
9
+ mail = TMail::Mail.new
10
+ mail.mime_version = "1.0"
11
+ mail.set_content_type 'multipart', 'mixed', {'boundary' => 'Apple-Mail-13-196941151'}
12
+ mail.body =<<HERE
13
+ --Apple-Mail-13-196941151
14
+ Content-Transfer-Encoding: quoted-printable
15
+ Content-Type: text/plain;
16
+ charset=ISO-8859-1;
17
+ delsp=yes;
18
+ format=flowed
19
+
20
+ This is the first part.
21
+
22
+ --Apple-Mail-13-196941151
23
+ Content-Type: text/x-ruby-script; name="hello.rb"
24
+ Content-Transfer-Encoding: 7bit
25
+ Content-Disposition: attachment;
26
+ filename="api.rb"
27
+
28
+ puts "Hello, world!"
29
+ gets
30
+
31
+ --Apple-Mail-13-196941151--
32
+ HERE
33
+ assert_equal(true, mail.multipart?)
34
+ assert_equal(1, mail.attachments.length)
35
+ end
36
+
37
+ def test_recursive_multipart_processing
38
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email7")
39
+ mail = TMail::Mail.parse(fixture)
40
+ assert_equal "This is the first part.\n\nAttachment: test.rb\nAttachment: test.pdf\n\n\nAttachment: smime.p7s\n", mail.body
41
+ end
42
+
43
+ def test_decode_encoded_attachment_filename
44
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email8")
45
+ mail = TMail::Mail.parse(fixture)
46
+ attachment = mail.attachments.last
47
+ assert_equal "01 Quien Te Dij\302\212at. Pitbull.mp3", attachment.original_filename unless RUBY_VERSION.match(/1.9/)
48
+ end
49
+
50
+ def test_attachment_with_quoted_filename
51
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email_with_quoted_attachment_filename")
52
+ mail = TMail::Mail.parse(fixture)
53
+ attachment = mail.attachments.last
54
+ str = "Eelanalüüsi päring.jpg"
55
+ assert_equal str, attachment.original_filename
56
+ end
57
+
58
+ def test_assigning_attachment_crashing_due_to_missing_boundary
59
+ mail = TMail::Mail.new
60
+ mail.mime_version = '1.0'
61
+ mail.set_content_type("multipart", "mixed")
62
+
63
+ mailpart=TMail::Mail.new
64
+ mailpart.set_content_type("application", "octet-stream")
65
+ mailpart['Content-Disposition'] = "attachment; filename=mailbox.zip"
66
+
67
+ assert_nothing_raised { mail.parts.push(mailpart) }
68
+ end
69
+
70
+ def test_only_has_attachment
71
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email_only_attachment")
72
+ mail = TMail::Mail.parse(fixture)
73
+ assert_equal(1, mail.attachments.length)
74
+ end
75
+
76
+ def test_content_nil_returned_if_name_of_attachment_type_unquoted
77
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/unquoted_filename_in_attachment")
78
+ mail = TMail::Mail.parse(fixture)
79
+ assert_equal("image/png", mail.attachments.first.content_type)
80
+ end
81
+
82
+ def test_unquoted_apple_mail_content_type
83
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/apple_unquoted_content_type")
84
+ mail = TMail::Mail.parse(fixture)
85
+ assert_equal("application/pdf", mail.attachments.first.content_type)
86
+ end
87
+
88
+ # TMail::Mail.has_attachments? & TMail::Mail.attachments
89
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=23099&group_id=4512&atid=17370
90
+ def test_the_only_part_is_a_word_document
91
+ mail = load_fixture('the_only_part_is_a_word_document.txt')
92
+
93
+ assert_equal('application/msword', mail.content_type)
94
+ assert !mail.multipart?, 'The mail should not be multipart'
95
+ assert mail.attachment?(mail), 'The mail should be considered has an attachment'
96
+
97
+ # The original method TMail::Mail.has_attachments? returns false
98
+ assert mail.has_attachments?, 'PATCH: TMail should consider that this email has an attachment'
99
+
100
+ # The original method TMail::Mail.attachments returns nil
101
+ assert_not_nil mail.attachments, 'PATCH: TMail should return the attachment'
102
+ assert_equal 1, mail.attachments.size, 'PATCH: TMail should detect one attachment'
103
+ assert_instance_of TMail::Attachment, mail.attachments.first, 'The first attachment found should be an instance of TMail::Attachment'
104
+ end
105
+
106
+ # new method TMail::Mail.inline_attachment?
107
+ def test_inline_attachment_should_detect_inline_attachments
108
+ mail = load_fixture('inline_attachment.txt')
109
+
110
+ assert !mail.inline_attachment?(mail.parts[0]), 'The first part is an empty text'
111
+ assert mail.inline_attachment?(mail.parts[1]), 'The second part is an inline attachment'
112
+
113
+ mail = load_fixture('the_only_part_is_a_word_document.txt')
114
+ assert !mail.inline_attachment?(mail), 'The first and only part is an normal attachment'
115
+ end
116
+
117
+ # new method TMail::Mail.text_content_type?
118
+ def test_text_content_type?
119
+ mail = load_fixture('inline_attachment.txt')
120
+
121
+ assert mail.parts[0].text_content_type?, 'The first part of inline_attachment.txt is a text'
122
+ assert !mail.parts[1].text_content_type?, 'The second part of inline_attachment.txt is not a text'
123
+ end
124
+
125
+ protected
126
+
127
+ def load_fixture(name)
128
+ TMail::Mail.load(File.join('test', 'fixtures', name))
129
+ end
130
+
131
+ end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+ require 'tmail/base64'
3
+ require 'test/unit'
4
+
5
+ class TestTMailBase64 < Test::Unit::TestCase
6
+ def try(orig)
7
+ ok = [orig].pack('m').delete("\r\n")
8
+ result = TMail::Base64.encode(orig)
9
+ assert_equal ok, result, "str=#{orig.inspect}"
10
+ assert_equal orig, TMail::Base64.decode(result), "str=#{orig.inspect}"
11
+ end
12
+
13
+ def test_normal
14
+ try ''
15
+ try 'a'
16
+ try 'ab'
17
+ try 'abc'
18
+ try 'abcd'
19
+ try 'abcde'
20
+ try 'abcdef'
21
+ try 'abcdefg'
22
+ try 'abcdefgh'
23
+ try 'abcdefghi'
24
+ try 'abcdefghij'
25
+ try 'abcdefghijk'
26
+ try 'abcdefghijkl'
27
+ try 'abcdefghijklm'
28
+ try 'abcdefghijklmn'
29
+ try 'abcdefghijklmno'
30
+ try 'abcdefghijklmnop'
31
+ try 'abcdefghijklmnopq'
32
+ try 'abcdefghijklmnopqr'
33
+ try 'abcdefghijklmnopqrs'
34
+ try 'abcdefghijklmnopqrst'
35
+ try 'abcdefghijklmnopqrstu'
36
+ try 'abcdefghijklmnopqrstuv'
37
+ try 'abcdefghijklmnopqrstuvw'
38
+ try 'abcdefghijklmnopqrstuvwx'
39
+ try 'abcdefghijklmnopqrstuvwxy'
40
+ try 'abcdefghijklmnopqrstuvwxyz'
41
+ end
42
+
43
+ def test_dangerous_chars
44
+ ["\0", "\001", "\002", "\003", "\0xfd", "\0xfe", "\0xff"].each do |ch|
45
+ 1.upto(96) do |len|
46
+ try ch * len
47
+ end
48
+ end
49
+ end
50
+
51
+ def test_random
52
+ 16.times do
53
+ try make_random_string(96)
54
+ end
55
+ end
56
+
57
+ def make_random_string(len)
58
+ buf = ''
59
+ len.times do
60
+ buf << rand(255)
61
+ end
62
+ buf
63
+ end
64
+ end
@@ -0,0 +1,139 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+ require 'tmail/port'
4
+ require 'tmail/encode'
5
+ require 'nkf'
6
+ require 'test/unit'
7
+
8
+ class TestEncode < Test::Unit::TestCase
9
+
10
+ SRCS = [
11
+ "a cde あいうえおあいうえおあいうえおあいうえおあいうえお", #1
12
+ "a cde あいうえおあいうえおあいうえおあいうえおあいうえ", #2
13
+ "a cde あいうえおあいうえおあいうえおあいうえおあいう", #3
14
+ "a cde あいうえおあいうえおあいうえおあいうえおあい", #4
15
+ "a cde あいうえおあいうえおあいうえおあいうえおあ", #5
16
+ "a cde あいうえおあいうえおあいうえおあいうえお", #6 #
17
+ "a cde あいうえおあいうえおあいうえおあいうえ", #7
18
+ "a cde あいうえおあいうえおあいうえおあいう", #8
19
+ "a cde あいうえおあいうえおあいうえおあい", #9
20
+ "a cde あいうえおあいうえおあいうえおあ", #10
21
+ "a cde あいうえおあいうえおあいうえお", #11
22
+ "a cde あいうえおあいうえおあいうえ", #12
23
+ "a cde あいうえおあいうえおあいう", #13
24
+ "a cde あいうえおあいうえおあい", #14
25
+ "a cde あいうえおあいうえおあ", #15
26
+ "a cde あいうえおあいうえお", #16
27
+ "a cde あいうえおあいうえ", #17
28
+ "a cde あいうえおあいう", #18
29
+ "a cde あいうえおあい", #19
30
+ "a cde あいうえおあ", #20
31
+ "a cde あいうえお", #21
32
+ "a cde あいうえ", #22
33
+ "a cde あいう", #23
34
+ "a cde あい", #24
35
+ "a cde あ", #25
36
+ "aあa aあa aあa aあa aあa aあa" #26
37
+ ]
38
+
39
+ OK = [
40
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCokIiQkJCYkKCQqGyhC?=", #1
41
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCokIiQkJCYkKBsoQg==?=", #2
42
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCokIiQkJCYbKEI=?=", #3
43
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCokIiQkGyhC?=", #4
44
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCokIhsoQg==?=", #5
45
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoJCobKEI=?=", #6
46
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJiQoGyhC?=", #7
47
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQkJhsoQg==?=", #8
48
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=\n\t=?iso-2022-jp?B?GyRCJCQbKEI=?=", #9
49
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqJCIbKEI=?=", #10
50
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKCQqGyhC?=", #11
51
+ "a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYkKBsoQg==?=", #12
52
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkJCYbKEI=?=', #13
53
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIiQkGyhC?=', #14
54
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCokIhsoQg==?=', #15
55
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoJCobKEI=?=', #16
56
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJiQoGyhC?=', #17
57
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQkJhsoQg==?=', #18
58
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiJCQbKEI=?=', #19
59
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKiQiGyhC?=', #20
60
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgkKhsoQg==?=', #21
61
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmJCgbKEI=?=', #22
62
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJCQmGyhC?=', #23
63
+ 'a cde =?iso-2022-jp?B?GyRCJCIkJBsoQg==?=', #24
64
+ 'a cde =?iso-2022-jp?B?GyRCJCIbKEI=?=', #25
65
+ "=?iso-2022-jp?B?YRskQiQiGyhCYSBhGyRCJCIbKEJhIGEbJEIkIhsoQmEgYRskQiQiGyhCYSBh?=\r\n\t=?iso-2022-jp?B?GyRCJCIbKEJhIGEbJEIkIhsoQmE=?=" #26
66
+ ]
67
+
68
+ unless RUBY_VERSION.match(/1.9/)
69
+ def test_s_encode
70
+ SRCS.each_index do |i|
71
+ assert_equal crlf(OK[i]),
72
+ TMail::Encoder.encode(NKF.nkf('-j', SRCS[i]))
73
+ end
74
+ end
75
+ end
76
+
77
+ def crlf( str )
78
+ str.gsub(/\n|\r\n|\r/) { "\r\n" }
79
+ end
80
+
81
+ def test_wrapping_an_email_with_whitespace_at_position_zero
82
+ # This email is a spam mail designed to break mailers... evil.
83
+ mail = TMail::Mail.load("#{File.dirname(__FILE__)}/fixtures/raw_attack_email_with_zero_length_whitespace")
84
+ assert_nothing_raised(Exception) { mail.encoded }
85
+ end
86
+
87
+ # =?utf-8?Q? Nicolas=20Fouch=E9?= is not UTF-8, it's ISO-8859-1 !
88
+ def test_marked_as_utf_8_but_it_is_iso_8859_1
89
+ mail = load_fixture('marked_as_utf_8_but_it_is_iso_8859_1.txt')
90
+
91
+ name = mail.to_addrs.first.name
92
+ assert_equal ' Nicolas Fouché', TMail::Unquoter.unquote_and_convert_to(name, 'utf-8')
93
+
94
+ # Without the patch, TMail raises:
95
+ # Iconv::InvalidCharacter: "\351"
96
+ # method iconv in quoting.rb at line 99
97
+ # method convert_to in quoting.rb at line 99
98
+ # method unquote_quoted_printable_and_convert_to in quoting.rb at line 88
99
+ # method unquote_and_convert_to in quoting.rb at line 72
100
+ # method gsub in quoting.rb at line 63
101
+ # method unquote_and_convert_to in quoting.rb at line 63
102
+ end
103
+
104
+ # =?iso-8859-1?b?77y5772B772O772Q772J772O772HIA==?= =?iso-8859-1?b?77y377yh77yu77yn?= is not ISO-8859-1, it's UTF-8 !
105
+ def test_marked_as_iso_8859_1_but_it_is_utf_8
106
+ mail = load_fixture('marked_as_iso_8859_1_but_it_is_utf_8.txt')
107
+
108
+ name = mail.to_addrs.first.name
109
+ assert_equal 'Yanping WANG', TMail::Unquoter.unquote_and_convert_to(name, 'utf-8')
110
+ # Even GMail could not detect this one :)
111
+
112
+ # Without the patch, TMail returns: "Yanping WANG"
113
+ end
114
+
115
+ # Be sure not to copy/paste the content of the fixture to another file, it could be automatically converted to utf-8
116
+ def test_iso_8859_1_email_without_encoding_and_message_id
117
+ mail = load_fixture('iso_8859_1_email_without_encoding_and_message_id.txt')
118
+
119
+ text = TMail::Unquoter.unquote_and_convert_to(mail.body, 'utf-8')
120
+
121
+ assert(text.include?('é'), 'Text content should include the "é" character')
122
+
123
+ # I'm not very proud of this one, chardet detects iso-8859-2, so I have to force the encoding to iso-8859-1.
124
+ assert(!text.include?('ŕ'), 'Text content should not iso-8859-2, "ŕ" should be "à"')
125
+
126
+ # Without the patch, TMail::Unquoter.unquote_and_convert_to returns:
127
+ # Il semblerait que vous n'ayez pas consult� votre messagerie depuis plus
128
+ # d'un an. Aussi, celle-ci a �t� temporairement desactiv�e.
129
+ # Aucune demande n'est necessaire pour r�activer votre messagerie : la simple
130
+ # consultation de ce message indique que la boite est � nouveau utilisable.
131
+ end
132
+
133
+ protected
134
+
135
+ def load_fixture(name)
136
+ TMail::Mail.load(File.join('test', 'fixtures', name))
137
+ end
138
+
139
+ end
@@ -0,0 +1,1021 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'test_helper'
3
+ require 'tmail'
4
+ require 'tmail/header'
5
+ require 'kcode'
6
+ require 'time'
7
+
8
+ class UnstructuredHeaderTester < Test::Unit::TestCase
9
+ def test_s_new
10
+ %w( Subject SUBJECT sUbJeCt
11
+ X-My-Header ).each do |name|
12
+ h = TMail::HeaderField.new(name, 'This is test header.')
13
+ assert_instance_of TMail::UnstructuredHeader, h,
14
+ 'Header.new: name=' + name.dump
15
+ end
16
+ end
17
+
18
+ def test_to_s
19
+ # I must write more and more test.
20
+ [
21
+ 'This is test header.',
22
+ # "This is \r\n\ttest header"
23
+ # "JAPANESE STRING"
24
+ ''
25
+ ]\
26
+ .each do |str|
27
+ h = TMail::HeaderField.new('Subject', str)
28
+ assert_equal str, h.decoded
29
+ assert_equal str, h.to_s
30
+ end
31
+ end
32
+ end
33
+
34
+ class DateTimeHeaderTester < Test::Unit::TestCase
35
+ def test_s_new
36
+ %w( Date Resent-Date ).each do |name|
37
+ h = TMail::HeaderField.new(name, 'Tue, 4 Dec 2001 10:49:32 +0900')
38
+ assert_instance_of TMail::DateTimeHeader, h, name
39
+ end
40
+ end
41
+
42
+ def test_date
43
+ h = TMail::HeaderField.new('Date', 'Tue, 4 Dec 2001 10:49:32 +0900')
44
+ assert_instance_of Time, h.date
45
+ assert_equal false, h.date.gmt?
46
+ assert_equal Time.parse('Tue, 4 Dec 2001 10:49:32 +0900'), h.date
47
+ end
48
+
49
+ def test_empty__illegal?
50
+ [ [false, 'Tue, 4 Dec 2001 10:49:32 +0900'],
51
+ [false, 'Sat, 15 Dec 2001 12:51:38 +0900'],
52
+ [true, 'Sat, 15 Dec 2001 12:51:38'],
53
+ [true, 'Sat, 15 Dec 2001 12:51'],
54
+ [true, 'Sat,'] ].each do |wrong, str|
55
+
56
+ h = TMail::HeaderField.new('Date', str)
57
+ assert_equal wrong, h.empty?, str
58
+ assert_equal wrong, h.illegal?, str
59
+ end
60
+ end
61
+
62
+ def test_to_s
63
+ h = TMail::HeaderField.new('Date', 'Tue, 4 Dec 2001 10:49:32 +0900')
64
+ time = Time.parse('Tue, 4 Dec 2001 10:49:32 +0900').strftime("%a,%e %b %Y %H:%M:%S %z")
65
+ assert_equal time, h.to_s
66
+ assert_equal h.to_s, h.decoded
67
+ ok = h.to_s
68
+
69
+ h = TMail::HeaderField.new('Date', 'Tue, 4 Dec 2001 01:49:32 +0000')
70
+ assert_equal ok, h.to_s
71
+
72
+ h = TMail::HeaderField.new('Date', 'Tue, 4 Dec 2001 01:49:32 GMT')
73
+ assert_equal ok, h.to_s
74
+ end
75
+ end
76
+
77
+ class AddressHeaderTester < Test::Unit::TestCase
78
+ def test_s_new
79
+ %w( To Cc Bcc From Reply-To
80
+ Resent-To Resent-Cc Resent-Bcc
81
+ Resent-From Resent-Reply-To ).each do |name|
82
+ h = TMail::HeaderField.new(name, 'aamine@loveruby.net')
83
+ assert_instance_of TMail::AddressHeader, h, name
84
+ end
85
+ end
86
+
87
+ def validate_case( str, isempty, to_s, comments, succ )
88
+ h = TMail::HeaderField.new('To', str)
89
+ assert_equal isempty, h.empty?, str.inspect + " (empty?)\n"
90
+ assert_instance_of Array, h.addrs, str.inspect + " (is a)\n"
91
+ assert_equal succ.size, h.addrs.size, str.inspect + " (size)\n"
92
+ h.addrs.each do |a|
93
+ ok = succ.shift
94
+ assert_equal ok[:phrase], a.phrase, str.inspect + " (phrase)\n"
95
+ assert_equal ok[:routes], a.routes, str.inspect + " (routes)\n"
96
+ assert_equal ok[:spec], a.spec, str.inspect + " (spec)\n"
97
+ end
98
+ if comments.first.respond_to? :force_encoding
99
+ encoding = h.comments.first.encoding
100
+ comments.each { |c| c.force_encoding encoding }
101
+ end
102
+ assert_equal comments, h.comments, str.inspect + " (comments)\n"
103
+ to_s.force_encoding(h.to_s.encoding) if to_s.respond_to? :force_encoding
104
+ assert_equal to_s, h.to_s, str.inspect + " (to_s)\n" if to_s
105
+ assert_equal to_s, h.decoded, str.inspect + " (decoded)\n" if to_s
106
+ end
107
+
108
+ def test_ATTRS
109
+ validate_case 'aamine@loveruby.net',
110
+ false,
111
+ 'aamine@loveruby.net',
112
+ [],
113
+ [{ :phrase => nil,
114
+ :routes => [],
115
+ :spec => 'aamine@loveruby.net' }]
116
+
117
+ validate_case 'Minero Aoki <aamine@loveruby.net> (comment)',
118
+ false,
119
+ 'Minero Aoki <aamine@loveruby.net> (comment)',
120
+ ['comment'],
121
+ [{ :phrase => 'Minero Aoki',
122
+ :routes => [],
123
+ :spec => 'aamine@loveruby.net' }]
124
+
125
+ validate_case 'aamine@loveruby.net, , taro@softica.org',
126
+ false,
127
+ 'aamine@loveruby.net, taro@softica.org',
128
+ [],
129
+ [{ :phrase => nil,
130
+ :routes => [],
131
+ :spec => 'aamine@loveruby.net' },
132
+ { :phrase => nil,
133
+ :routes => [],
134
+ :spec => 'taro@softica.org' }]
135
+
136
+ validate_case '',
137
+ true,
138
+ nil,
139
+ [],
140
+ []
141
+
142
+ validate_case '(comment only)',
143
+ true,
144
+ nil,
145
+ ['comment only'],
146
+ []
147
+
148
+ kcode('EUC') {
149
+ validate_case 'hoge@example.jp (=?ISO-2022-JP?B?GyRCJUYlOSVIGyhC?=)',
150
+ false,
151
+ "hoge@example.jp (\245\306\245\271\245\310)",
152
+ ["\245\306\245\271\245\310"],
153
+ [{ :phrase => nil,
154
+ :routes => [],
155
+ :spec => 'hoge@example.jp'}]
156
+ }
157
+ end
158
+ end
159
+
160
+ class SingleAddressHeaderTester < Test::Unit::TestCase
161
+ def test_s_new
162
+ h = TMail::HeaderField.new('Sender', 'aamine@loveruby.net')
163
+ assert_instance_of TMail::SingleAddressHeader, h
164
+ end
165
+
166
+ def test_addr
167
+ h = TMail::HeaderField.new('Sender', 'aamine@loveruby.net')
168
+ assert_not_nil h.addr
169
+ assert_instance_of TMail::Address, h.addr
170
+ assert_equal 'aamine@loveruby.net', h.addr.spec
171
+ assert_equal nil, h.addr.phrase
172
+ assert_equal [], h.addr.routes
173
+ end
174
+
175
+ def test_to_s
176
+ str = 'Minero Aoki <aamine@loveruby.net>, "AOKI, Minero" <aamine@softica.org>'
177
+ h = TMail::HeaderField.new('Sender', str)
178
+ assert_equal 'Minero Aoki <aamine@loveruby.net>', h.to_s
179
+ end
180
+ end
181
+
182
+ class ReturnPathHeaderTester < Test::Unit::TestCase
183
+ def test_s_new
184
+ %w( Return-Path ).each do |name|
185
+ h = TMail::HeaderField.new(name, '<aamine@loveruby.net>')
186
+ assert_instance_of TMail::ReturnPathHeader, h, name
187
+ assert_equal false, h.empty?
188
+ assert_equal false, h.illegal?
189
+ end
190
+ end
191
+
192
+ def test_ATTRS
193
+ h = TMail::HeaderField.new('Return-Path', '<@a,@b,@c:aamine@loveruby.net>')
194
+ assert_not_nil h.addr
195
+ assert_instance_of TMail::Address, h.addr
196
+ assert_equal 'aamine@loveruby.net', h.addr.spec
197
+ assert_equal nil, h.addr.phrase
198
+ assert_equal ['a', 'b', 'c'], h.addr.routes
199
+
200
+ assert_not_nil h.routes
201
+ assert_instance_of Array, h.routes
202
+ assert_equal ['a', 'b', 'c'], h.routes
203
+ assert_equal h.addr.routes, h.routes
204
+
205
+ assert_not_nil h.spec
206
+ assert_instance_of String, h.spec
207
+ assert_equal 'aamine@loveruby.net', h.spec
208
+
209
+ # missing '<' '>'
210
+ h = TMail::HeaderField.new('Return-Path', 'xxxx@yyyy')
211
+ assert_equal 'xxxx@yyyy', h.spec
212
+
213
+ h = TMail::HeaderField.new('Return-Path', '<>')
214
+ assert_instance_of TMail::Address, h.addr
215
+ assert_nil h.addr.local
216
+ assert_nil h.addr.domain
217
+ assert_nil h.addr.spec
218
+ assert_nil h.spec
219
+ end
220
+
221
+ def test_to_s
222
+ body = 'Minero Aoki <@a,@b,@c:aamine@loveruby.net>'
223
+ h = TMail::HeaderField.new('Return-Path', body)
224
+ assert_equal '<@a,@b,@c:aamine@loveruby.net>', h.to_s
225
+ assert_equal h.to_s, h.decoded
226
+
227
+ body = 'aamine@loveruby.net'
228
+ h = TMail::HeaderField.new('Return-Path', body)
229
+ assert_equal '<aamine@loveruby.net>', h.to_s
230
+ assert_equal h.to_s, h.decoded
231
+
232
+ body = '<>'
233
+ h = TMail::HeaderField.new('Return-Path', body)
234
+ assert_equal '<>', h.to_s
235
+ end
236
+ end
237
+
238
+ class MessageIdHeaderTester < Test::Unit::TestCase
239
+ def test_s_new
240
+ %w( Message-Id MESSAGE-ID Message-ID
241
+ Resent-Message-Id Content-Id ).each do |name|
242
+ h = TMail::HeaderField.new(name, '<20020103xg88.k0@mail.loveruby.net>')
243
+ assert_instance_of TMail::MessageIdHeader, h
244
+ end
245
+ end
246
+
247
+ def test_message_id_double_at
248
+ %w( Message-Id MESSAGE-ID Message-ID
249
+ Resent-Message-Id Content-Id ).each do |name|
250
+ h = TMail::HeaderField.new(name, '<20020103xg88.k0@mail@me.loveruby.net>')
251
+ assert_instance_of TMail::MessageIdHeader, h
252
+ end
253
+ end
254
+
255
+ def test_id
256
+ str = '<20020103xg88.k0@mail.loveruby.net>'
257
+ h = TMail::HeaderField.new('Message-Id', str)
258
+ assert_not_nil h.id
259
+ assert_equal str, h.id
260
+
261
+ id = '<20020103xg88.k0@mail.loveruby.net>'
262
+ str = id + ' (comm(ent))'
263
+ h = TMail::HeaderField.new('Message-Id', str)
264
+ assert_not_nil h.id
265
+ assert_equal id, h.id
266
+ end
267
+
268
+ def test_id=
269
+ h = TMail::HeaderField.new('Message-Id', '')
270
+ h.id = str = '<20020103xg88.k0@mail.loveruby.net>'
271
+ assert_not_nil h.id
272
+ assert_equal str, h.id
273
+ end
274
+
275
+ def test_double_at_in_header
276
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email_double_at_in_header")
277
+ str = '<d3b8cf8e49f0448085@0c28713a1@f473e@37signals.com>'
278
+ mail = TMail::Mail.parse(fixture)
279
+ assert_equal str, mail.message_id
280
+ end
281
+ end
282
+
283
+ class ReferencesHeaderTester < Test::Unit::TestCase
284
+ def test_s_new
285
+ str = '<20020103xg88.k0@mail.loveruby.net>'
286
+ %w( References REFERENCES ReFeReNcEs
287
+ In-Reply-To ).each do |name|
288
+ h = TMail::HeaderField.new(name, str)
289
+ assert_instance_of TMail::ReferencesHeader, h, name
290
+ end
291
+ end
292
+
293
+ def test_ATTRS
294
+ id1 = '<20020103xg88.k0@mail.loveruby.net>'
295
+ id2 = '<20011204103415.64DB.GGB03124@nifty.ne.jp>'
296
+ phr = 'message of "Wed, 17 Mar 1999 18:42:07 +0900"'
297
+ str = id1 + ' ' + phr + ' ' + id2
298
+
299
+ h = TMail::HeaderField.new('References', str)
300
+
301
+ ok = [id1, id2]
302
+ h.each_id do |i|
303
+ assert_equal ok.shift, i
304
+ end
305
+ ok = [id1, id2]
306
+ assert_equal ok, h.ids
307
+ h.each_id do |i|
308
+ assert_equal ok.shift, i
309
+ end
310
+
311
+ ok = [phr]
312
+ assert_equal ok, h.phrases
313
+ h.each_phrase do |i|
314
+ assert_equal ok.shift, i
315
+ end
316
+ ok = [phr]
317
+ h.each_phrase do |i|
318
+ assert_equal ok.shift, i
319
+ end
320
+
321
+
322
+ # test 2
323
+ # 'In-Reply-To'
324
+ # 'aamine@dp.u-netsurf.ne.jp's message of "Fri, 8 Jan 1999 03:49:37 +0900"'
325
+ end
326
+
327
+ def test_to_s
328
+ id1 = '<20020103xg88.k0@mail.loveruby.net>'
329
+ id2 = '<20011204103415.64DB.GGB03124@nifty.ne.jp>'
330
+ phr = 'message of "Wed, 17 Mar 1999 18:42:07 +0900"'
331
+ str = id1 + ' ' + phr + ' ' + id2
332
+
333
+ h = TMail::HeaderField.new('References', str)
334
+ assert_equal id1 + ' ' + id2, h.to_s
335
+ end
336
+ end
337
+
338
+ class ReceivedHeaderTester < Test::Unit::TestCase
339
+ HEADER1 = <<EOS
340
+ from helium.ruby-lang.org (helium.ruby-lang.org [210.251.121.214])
341
+ by doraemon.edit.ne.jp (8.12.1/8.12.0) via TCP with ESMTP
342
+ id fB41nwEj007438 for <aamine@mx.edit.ne.jp>;
343
+ Tue, 4 Dec 2001 10:49:58 +0900 (JST)
344
+ EOS
345
+ HEADER2 = <<EOS
346
+ from helium.ruby-lang.org (localhost [127.0.0.1])
347
+ by helium.ruby-lang.org (Postfix) with ESMTP
348
+ id 8F8951AF3F; Tue, 4 Dec 2001 10:49:32 +0900 (JST)
349
+ EOS
350
+ HEADER3 = <<EOS
351
+ from smtp1.dti.ne.jp (smtp1.dti.ne.jp [202.216.228.36])
352
+ by helium.ruby-lang.org (Postfix) with ESMTP id CE3A1C3
353
+ for <ruby-list@ruby-lang.org>; Tue, 4 Dec 2001 10:49:31 +0900 (JST)
354
+ EOS
355
+
356
+ =begin dangerous headers
357
+ # 2-word WITH (this header is also wrong in semantic)
358
+ # I cannot support this.
359
+ Received: by mebius with Microsoft Mail
360
+ id <01BE2B9D.9051EAA0@mebius>; Sat, 19 Dec 1998 22:18:54 -0800
361
+ =end
362
+
363
+ def test_s_new
364
+ %w( Received ).each do |name|
365
+ h = TMail::HeaderField.new(name, HEADER1)
366
+ assert_instance_of TMail::ReceivedHeader, h, name
367
+ end
368
+ end
369
+
370
+ def test_ATTRS
371
+ h = TMail::HeaderField.new('Received', HEADER1)
372
+ assert_instance_of String, h.from
373
+ assert_equal 'helium.ruby-lang.org', h.from
374
+
375
+ assert_instance_of String, h.by
376
+ assert_equal 'doraemon.edit.ne.jp', h.by
377
+
378
+ assert_instance_of String, h.via
379
+ assert_equal 'TCP', h.via
380
+
381
+ assert_instance_of Array, h.with
382
+ assert_equal %w(ESMTP), h.with
383
+
384
+ assert_instance_of String, h.id
385
+ assert_equal 'fB41nwEj007438', h.id
386
+
387
+ assert_instance_of String, h._for
388
+ assert_equal 'aamine@mx.edit.ne.jp', h._for # must be <a> ?
389
+
390
+ assert_instance_of Time, h.date
391
+ time = Time.parse('Tue, 4 Dec 2001 10:49:58 +0900')
392
+ assert_equal time, h.date
393
+
394
+ h = TMail::HeaderField.new('Received', '; Tue, 4 Dec 2001 10:49:58 +0900')
395
+ assert_nil h.from
396
+ assert_nil h.by
397
+ assert_nil h.via
398
+ assert_equal [], h.with
399
+ assert_nil h.id
400
+ assert_nil h._for
401
+ time = Time.parse('Tue, 4 Dec 2001 10:49:58 +0900')
402
+ assert_equal time, h.date
403
+
404
+ # without date
405
+ h = TMail::HeaderField.new('Received', 'by NeXT.Mailer (1.144.2)')
406
+ assert_nil h.from
407
+ assert_equal 'NeXT.Mailer', h.by
408
+ assert_nil h.via
409
+ assert_equal [], h.with
410
+ assert_nil h.id
411
+ assert_nil h._for
412
+ assert_nil h.date
413
+
414
+ # FROM is not a domain
415
+ h = TMail::HeaderField.new('Received',
416
+ 'from someuser@example.com; Tue, 24 Nov 1998 07:59:39 -0500')
417
+ assert_equal 'example.com', h.from
418
+ assert_nil h.by
419
+ assert_nil h.via
420
+ assert_equal [], h.with
421
+ assert_nil h.id
422
+ assert_nil h._for
423
+ time = Time.parse('Tue, 24 Nov 1998 07:59:39 -0500')
424
+ assert_equal time, h.date
425
+
426
+ =begin
427
+ # FOR is not route-addr.
428
+ # item order is wrong.
429
+ h = TMail::HeaderField.new('Received',
430
+ 'from aamine by mail.softica.org with local for list@softica.org id 12Vm3N-00044L-01; Fri, 17 Mar 2000 10:59:53 +0900')
431
+ assert_equal 'aamine', h.from
432
+ assert_equal 'mail.softica.org', h.by
433
+ assert_nil h.via
434
+ assert_equal ['local'], h.with
435
+ assert_equal '12Vm3N-00044L-01', h.id
436
+ assert_equal 'list@softica.org', h._for
437
+ assert_equal Time.local(2000,4,17, 10,59,53), h.date
438
+ =end
439
+
440
+ # word + domain-literal in FROM
441
+
442
+ h = TMail::HeaderField.new('Received',
443
+ 'from localhost [192.168.1.1]; Sat, 19 Dec 1998 22:19:50 PST')
444
+ assert_equal 'localhost', h.from
445
+ assert_nil h.by
446
+ assert_nil h.via
447
+ assert_equal [], h.with
448
+ assert_nil h.id
449
+ assert_nil h._for
450
+ time = Time.parse('Sat, 19 Dec 1998 22:19:50 PST')
451
+ assert_equal time, h.date
452
+
453
+ # addr-spec in BY (must be a domain)
454
+ h = TMail::HeaderField.new('Received',
455
+ 'by aamine@loveruby.net; Wed, 24 Feb 1999 14:34:20 +0900')
456
+ assert_equal 'loveruby.net', h.by
457
+ end
458
+
459
+ def test_to_s
460
+ h = TMail::HeaderField.new('Received', HEADER1)
461
+ time = Time.parse('Tue, 4 Dec 2001 10:49:58 +0900').strftime("%a,%e %b %Y %H:%M:%S %z")
462
+ assert_equal "from helium.ruby-lang.org by doraemon.edit.ne.jp via TCP with ESMTP id fB41nwEj007438 for <aamine@mx.edit.ne.jp>; #{time}", h.to_s
463
+
464
+ [
465
+ 'from harmony.loveruby.net',
466
+ 'by mail.loveruby.net',
467
+ 'via TCP',
468
+ 'with ESMTP',
469
+ 'id LKJHSDFG',
470
+ 'for <aamine@loveruby.net>',
471
+ "; #{time}"
472
+ ]\
473
+ .each do |str|
474
+ h = TMail::HeaderField.new('Received', str)
475
+ assert_equal str, h.to_s, 'ReceivedHeader#to_s: data=' + str.dump
476
+ end
477
+ end
478
+ end
479
+
480
+ class KeywordsHeaderTester < Test::Unit::TestCase
481
+ def test_s_new
482
+ %w( Keywords KEYWORDS KeYwOrDs ).each do |name|
483
+ h = TMail::HeaderField.new(name, 'key, word, is, keyword')
484
+ assert_instance_of TMail::KeywordsHeader, h
485
+ end
486
+ end
487
+
488
+ def test_keys
489
+ h = TMail::HeaderField.new('Keywords', 'key, word, is, keyword')
490
+ assert_instance_of Array, h.keys
491
+ assert_equal %w(key word is keyword), h.keys
492
+ end
493
+ end
494
+
495
+ class EncryptedHeaderTester < Test::Unit::TestCase
496
+ def test_s_new
497
+ %w( Encrypted ).each do |name|
498
+ h = TMail::HeaderField.new(name, 'lot17 solt')
499
+ assert_instance_of TMail::EncryptedHeader, h
500
+ end
501
+ end
502
+
503
+ def test_encrypter
504
+ h = TMail::HeaderField.new('Encrypted', 'lot17 solt')
505
+ assert_equal 'lot17', h.encrypter
506
+ end
507
+
508
+ def test_encrypter=
509
+ h = TMail::HeaderField.new('Encrypted', 'lot17 solt')
510
+ h.encrypter = 'newscheme'
511
+ assert_equal 'newscheme', h.encrypter
512
+ end
513
+
514
+ def test_keyword
515
+ h = TMail::HeaderField.new('Encrypted', 'lot17 solt')
516
+ assert_equal 'solt', h.keyword
517
+ h = TMail::HeaderField.new('Encrypted', 'lot17')
518
+ assert_equal nil, h.keyword
519
+ end
520
+
521
+ def test_keyword=
522
+ h = TMail::HeaderField.new('Encrypted', 'lot17 solt')
523
+ h.keyword = 'newscheme'
524
+ assert_equal 'newscheme', h.keyword
525
+ end
526
+ end
527
+
528
+ class MimeVersionHeaderTester < Test::Unit::TestCase
529
+ def test_s_new
530
+ %w( Mime-Version MIME-VERSION MiMe-VeRsIoN ).each do |name|
531
+ h = TMail::HeaderField.new(name, '1.0')
532
+ assert_instance_of TMail::MimeVersionHeader, h
533
+ end
534
+ end
535
+
536
+ def test_ATTRS
537
+ h = TMail::HeaderField.new('Mime-Version', '1.0')
538
+ assert_equal 1, h.major
539
+ assert_equal 0, h.minor
540
+ assert_equal '1.0', h.version
541
+
542
+ h = TMail::HeaderField.new('Mime-Version', '99.77 (is ok)')
543
+ assert_equal 99, h.major
544
+ assert_equal 77, h.minor
545
+ assert_equal '99.77', h.version
546
+ end
547
+
548
+ def test_major=
549
+ h = TMail::HeaderField.new('Mime-Version', '1.1')
550
+ h.major = 2
551
+ assert_equal 2, h.major
552
+ assert_equal 1, h.minor
553
+ assert_equal 2, h.major
554
+ h.major = 3
555
+ assert_equal 3, h.major
556
+ end
557
+
558
+ def test_minor=
559
+ h = TMail::HeaderField.new('Mime-Version', '2.3')
560
+ assert_equal 3, h.minor
561
+ h.minor = 5
562
+ assert_equal 5, h.minor
563
+ assert_equal 2, h.major
564
+ end
565
+
566
+ def test_to_s
567
+ h = TMail::HeaderField.new('Mime-Version', '1.0 (first version)')
568
+ assert_equal '1.0', h.to_s
569
+ end
570
+
571
+ def test_empty?
572
+ h = TMail::HeaderField.new('Mime-Version', '')
573
+ assert_equal true, h.empty?
574
+ end
575
+ end
576
+
577
+ class ContentTypeHeaderTester < Test::Unit::TestCase
578
+ def test_s_new
579
+ %w( Content-Type CONTENT-TYPE CoNtEnT-TyPe ).each do |name|
580
+ h = TMail::HeaderField.new(name, 'text/plain; charset=iso-2022-jp')
581
+ assert_instance_of TMail::ContentTypeHeader, h, name
582
+ end
583
+ end
584
+
585
+ def test_ATTRS
586
+ h = TMail::HeaderField.new('Content-Type', 'text/plain; charset=iso-2022-jp')
587
+ assert_equal 'text', h.main_type
588
+ assert_equal 'plain', h.sub_type
589
+ assert_equal 1, h.params.size
590
+ assert_equal 'iso-2022-jp', h.params['charset']
591
+
592
+ h = TMail::HeaderField.new('Content-Type', 'Text/Plain; Charset=shift_jis')
593
+ assert_equal 'text', h.main_type
594
+ assert_equal 'plain', h.sub_type
595
+ assert_equal 1, h.params.size
596
+ assert_equal 'shift_jis', h.params['charset']
597
+ end
598
+
599
+ def test_multipart_with_legal_unquoted_boundary
600
+ h = TMail::HeaderField.new('Content-Type', 'multipart/mixed; boundary=dDRMvlgZJXvWKvBx')
601
+ assert_equal 'multipart', h.main_type
602
+ assert_equal 'mixed', h.sub_type
603
+ assert_equal 1, h.params.size
604
+ assert_equal 'dDRMvlgZJXvWKvBx', h.params['boundary']
605
+ end
606
+
607
+ def test_multipart_with_legal_quoted_boundary_should_retain_quotations
608
+ h = TMail::HeaderField.new('Content-Type', 'multipart/mixed; boundary="dDRMvlgZJXvWKvBx"')
609
+ assert_equal 'multipart', h.main_type
610
+ assert_equal 'mixed', h.sub_type
611
+ assert_equal 1, h.params.size
612
+ assert_equal 'dDRMvlgZJXvWKvBx', h.params['boundary']
613
+ end
614
+
615
+ def test_multipart_with_illegal_unquoted_boundary_should_add_quotations
616
+ h = TMail::HeaderField.new('Content-Type', 'multipart/alternative; boundary=----=_=NextPart_000_0093_01C81419.EB75E850')
617
+ assert_equal 'multipart', h.main_type
618
+ assert_equal 'alternative', h.sub_type
619
+ assert_equal 1, h.params.size
620
+ assert_equal '----=_=NextPart_000_0093_01C81419.EB75E850', h.params['boundary']
621
+ end
622
+
623
+ def test_multipart_with_illegal_quoted_boundary_should_retain_quotations
624
+ h = TMail::HeaderField.new('Content-Type', 'multipart/alternative; boundary="----=_=NextPart_000_0093_01C81419.EB75E850"')
625
+ assert_equal 'multipart', h.main_type
626
+ assert_equal 'alternative', h.sub_type
627
+ assert_equal 1, h.params.size
628
+ assert_equal '----=_=NextPart_000_0093_01C81419.EB75E850', h.params['boundary']
629
+ end
630
+
631
+ def test_multipart_with_extra_with_multiple_params
632
+ h = TMail::HeaderField.new('Content-Type', 'multipart/related;boundary=1_4626B816_9F1690;Type="application/smil";Start="<mms.smil.txt>"')
633
+ assert_equal 'multipart', h.main_type
634
+ assert_equal 'related', h.sub_type
635
+ assert_equal 3, h.params.size
636
+ assert_equal '1_4626B816_9F1690', h.params['boundary']
637
+ end
638
+
639
+ def test_main_type=
640
+ h = TMail::HeaderField.new('Content-Type', 'text/plain; charset=iso-2022-jp')
641
+ assert_equal 'text', h.main_type
642
+ h.main_type = 'multipart'
643
+ assert_equal 'multipart', h.main_type
644
+ assert_equal 'multipart', h.main_type
645
+ h.main_type = 'TEXT'
646
+ assert_equal 'text', h.main_type
647
+ end
648
+
649
+ def test_sub_type=
650
+ h = TMail::HeaderField.new('Content-Type', 'text/plain; charset=iso-2022-jp')
651
+ assert_equal 'plain', h.sub_type
652
+ h.sub_type = 'html'
653
+ assert_equal 'html', h.sub_type
654
+ h.sub_type = 'PLAIN'
655
+ assert_equal 'plain', h.sub_type
656
+ end
657
+ end
658
+
659
+ class ContentEncodingHeaderTester < Test::Unit::TestCase
660
+ def test_s_new
661
+ %w( Content-Transfer-Encoding CONTENT-TRANSFER-ENCODING
662
+ COnteNT-TraNSFer-ENCodiNG ).each do |name|
663
+ h = TMail::HeaderField.new(name, 'Base64')
664
+ assert_instance_of TMail::ContentTransferEncodingHeader, h
665
+ end
666
+ end
667
+
668
+ def test_encoding
669
+ h = TMail::HeaderField.new('Content-Transfer-Encoding', 'Base64')
670
+ assert_equal 'base64', h.encoding
671
+
672
+ h = TMail::HeaderField.new('Content-Transfer-Encoding', '7bit')
673
+ assert_equal '7bit', h.encoding
674
+ end
675
+
676
+ def test_encoding=
677
+ h = TMail::HeaderField.new('Content-Transfer-Encoding', 'Base64')
678
+ assert_equal 'base64', h.encoding
679
+ h.encoding = '7bit'
680
+ assert_equal '7bit', h.encoding
681
+ end
682
+
683
+ def test_to_s
684
+ h = TMail::HeaderField.new('Content-Transfer-Encoding', 'Base64')
685
+ assert_equal 'Base64', h.to_s
686
+ assert_equal h.to_s, h.decoded
687
+ assert_equal h.to_s, h.encoded
688
+ end
689
+
690
+ def test_insertion_of_headers_and_encoding_them_short
691
+ mail = TMail::Mail.new
692
+ mail['X-Mail-Header'] = "short bit of data"
693
+ assert_equal("X-Mail-Header: short bit of data\r\n\r\n", mail.encoded)
694
+ end
695
+
696
+ def test_insertion_of_headers_and_encoding_them_more_than_78_char_total_with_whitespace
697
+ mail = TMail::Mail.new
698
+ mail['X-Ruby-Talk'] = "<11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA 4614-95FD-9071A4BDF4A1@grayproductions.net>"
699
+ assert_equal("X-Ruby-Talk: <11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA\r\n\t4614-95FD-9071A4BDF4A1@grayproductions.net>\r\n\r\n", mail.encoded)
700
+ result = TMail::Mail.parse(mail.encoded)
701
+ assert_equal(mail['X-Ruby-Talk'].to_s, result['X-Ruby-Talk'].to_s)
702
+ end
703
+
704
+ def test_insertion_of_headers_and_encoding_them_more_than_78_char_total_with_whitespace
705
+ mail = TMail::Mail.new
706
+ mail['X-Ruby-Talk'] = "<11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA 4614-95FD-9071A4BDF4A1@grayproductions.net11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA 4614-95FD-9071A4BDF4A1@grayproductions.net>"
707
+ assert_equal("X-Ruby-Talk: <11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA\r\n\t4614-95FD-9071A4BDF4A1@grayproductions.net11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA\r\n\t4614-95FD-9071A4BDF4A1@grayproductions.net>\r\n\r\n", mail.encoded)
708
+ result = TMail::Mail.parse(mail.encoded)
709
+ assert_equal(mail['X-Ruby-Talk'].to_s, result['X-Ruby-Talk'].to_s)
710
+ end
711
+
712
+ def test_insertion_of_headers_and_encoding_them_more_than_78_char_total_without_whitespace
713
+ mail = TMail::Mail.new
714
+ mail['X-Ruby-Talk'] = "<11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA-4614-95FD-9071A4BDF4A1@grayproductions.net>"
715
+ assert_equal("X-Ruby-Talk: <11152772-AAFA-4614-95FD-9071A4BDF4A111152772-AAFA-4614-95FD-9071A4BDF4A1@grayproductions.net>\r\n\r\n", mail.encoded)
716
+ result = TMail::Mail.parse(mail.encoded)
717
+ assert_equal(mail['X-Ruby-Talk'].to_s, result['X-Ruby-Talk'].to_s)
718
+ end
719
+
720
+ def test_insertion_of_headers_and_encoding_them_less_than_998_char_total_without_whitespace
721
+ mail = TMail::Mail.new
722
+ text_with_whitespace = ""; 985.times{text_with_whitespace << "a"}
723
+ mail['Reply-To'] = "#{text_with_whitespace}"
724
+ assert_equal("Reply-To: #{text_with_whitespace}\r\n\r\n", mail.encoded)
725
+ result = TMail::Mail.parse(mail.encoded)
726
+ assert_equal(mail['Reply-To'].to_s, result['Reply-To'].to_s)
727
+ end
728
+
729
+ def test_insertion_of_headers_and_encoding_them_more_than_998_char_total_without_whitespace
730
+ mail = TMail::Mail.new
731
+ text_with_whitespace = ""; 1200.times{text_with_whitespace << "a"}
732
+ before_text = ""; 985.times{before_text << "a"}
733
+ after_text = ""; 215.times{after_text << "a"}
734
+ mail['X-Ruby-Talk'] = "#{text_with_whitespace}"
735
+ assert_equal("X-Ruby-Talk: #{before_text}\r\n\t#{after_text}\r\n\r\n", mail.encoded)
736
+ end
737
+
738
+ def test_insertion_of_headers_and_encoding_with_1_more_than_998_char_total_without_whitespace
739
+ mail = TMail::Mail.new
740
+ text_with_whitespace = ""; 996.times{text_with_whitespace << "a"}
741
+ before_text = ""; 995.times{before_text << "a"}
742
+ after_text = ""; 1.times{after_text << "a"}
743
+ mail['X'] = "#{text_with_whitespace}"
744
+ assert_equal("X: #{before_text}\r\n\t#{after_text}\r\n\r\n", mail.encoded)
745
+ end
746
+
747
+ def test_insertion_of_headers_and_encoding_with_exactly_998_char_total_without_whitespace
748
+ mail = TMail::Mail.new
749
+ text_with_whitespace = ""; 995.times{text_with_whitespace << "a"}
750
+ before_text = ""; 995.times{before_text << "a"}
751
+ mail['X'] = "#{text_with_whitespace}"
752
+ assert_equal("X: #{before_text}\r\n\r\n", mail.encoded)
753
+ end
754
+ end
755
+
756
+ class ContentDispositionHeaderTester < Test::Unit::TestCase
757
+ def test_s_new
758
+ %w( Content-Disposition CONTENT-DISPOSITION
759
+ ConTENt-DIsPOsition ).each do |name|
760
+ h = TMail::HeaderField.new(name, 'attachment; filename="README.txt.pif"')
761
+ assert_instance_of TMail::ContentDispositionHeader, h
762
+ end
763
+ end
764
+
765
+ def test_ATTRS
766
+ begin
767
+ _test_ATTRS
768
+ _test_tspecials
769
+ _test_rfc2231_decode
770
+ #_test_rfc2231_encode
771
+ _test_raw_iso2022jp
772
+ _test_raw_eucjp
773
+ _test_raw_sjis unless RUBY_VERSION.match(/1.9/)
774
+ _test_code_conversion unless RUBY_VERSION.match(/1.9/)
775
+ ensure
776
+ TMail.KCODE = 'NONE'
777
+ end
778
+ end
779
+
780
+ def _test_ATTRS
781
+ TMail.KCODE = 'NONE'
782
+
783
+ h = TMail::HeaderField.new('Content-Disposition',
784
+ 'attachment; filename="README.txt.pif"')
785
+ assert_equal 'attachment', h.disposition
786
+ assert_equal 1, h.params.size
787
+ assert_equal 'README.txt.pif', h.params['filename']
788
+
789
+ h = TMail::HeaderField.new('Content-Disposition',
790
+ 'attachment; Filename="README.txt.pif"')
791
+ assert_equal 'attachment', h.disposition
792
+ assert_equal 1, h.params.size
793
+ assert_equal 'README.txt.pif', h.params['filename']
794
+
795
+ h = TMail::HeaderField.new('Content-Disposition',
796
+ 'attachment; filename=')
797
+ assert_equal true, h.empty?
798
+ assert_nil h.params
799
+ assert_nil h['filename']
800
+ end
801
+
802
+ def _test_tspecials
803
+ h = TMail::HeaderField.new('Content-Disposition', 'a; n=a')
804
+ h['n'] = %q|()<>[];:@\\,"/?=|
805
+ assert_equal 'a; n="()<>[];:@\\\\,\"/?="', h.encoded
806
+ end
807
+
808
+ def _test_rfc2231_decode
809
+ TMail.KCODE = 'EUC'
810
+
811
+ h = TMail::HeaderField.new('Content-Disposition',
812
+ "attachment; filename*=iso-2022-jp'ja'%1b$B$Q$i$`%1b%28B")
813
+ assert_equal 'attachment', h.disposition
814
+ assert_equal 1, h.params.size
815
+ expected = "\244\321\244\351\244\340"
816
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
817
+ assert_equal expected, h.params['filename']
818
+ end
819
+
820
+ def _test_rfc2231_encode
821
+ TMail.KCODE = 'EUC'
822
+
823
+ h = TMail::HeaderField.new('Content-Disposition', 'a; n=a')
824
+ h['n'] = "\245\265\245\363\245\327\245\353.txt"
825
+ assert_equal "a; n*=iso-2022-jp'ja'%1B$B%255%25s%25W%25k%1B%28B.txt",
826
+ h.encoded
827
+
828
+ h = TMail::HeaderField.new('Content-Disposition', 'a; n=a')
829
+ h['n'] = "\245\265()<>[];:@\\,\"/?=%*'"
830
+ assert_equal "a;\r\n\tn*=iso-2022-jp'ja'%1B$B%255%1B%28B%28%29%3C%3E%5B%5D%3B%3A%40%5C%2C%22%2F%3F%3D%25%2A%27",
831
+ h.encoded
832
+ end
833
+
834
+ def _test_raw_iso2022jp
835
+ TMail.KCODE = 'EUC'
836
+ # raw iso2022jp string in value (token)
837
+ h = TMail::HeaderField.new('Content-Disposition',
838
+ %Q<attachment; filename=\e$BF|K\\8l\e(B.doc>)
839
+ assert_equal 'attachment', h.disposition
840
+ assert_equal 1, h.params.size
841
+ # assert_equal "\e$BF|K\\8l\e(B.doc", h.params['filename']
842
+
843
+ expected = "\306\374\313\334\270\354.doc"
844
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
845
+
846
+ assert_equal expected, h.params['filename']
847
+
848
+ # raw iso2022jp string in value (quoted string)
849
+ h = TMail::HeaderField.new('Content-Disposition',
850
+ %Q<attachment; filename="\e$BF|K\\8l\e(B.doc">)
851
+ assert_equal 'attachment', h.disposition
852
+ assert_equal 1, h.params.size
853
+ # assert_equal "\e$BF|K\\8l\e(B.doc", h.params['filename']
854
+ assert_equal expected, h.params['filename']
855
+ end
856
+
857
+ def _test_raw_eucjp
858
+ TMail.KCODE = 'EUC'
859
+ # raw EUC-JP string in value (token)
860
+ h = TMail::HeaderField.new('Content-Disposition',
861
+ %Q<attachment; filename=\306\374\313\334\270\354.doc>)
862
+ assert_equal 'attachment', h.disposition
863
+ assert_equal 1, h.params.size
864
+ expected = "\306\374\313\334\270\354.doc"
865
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
866
+ assert_equal expected, h.params['filename']
867
+
868
+ # raw EUC-JP string in value (quoted-string)
869
+ h = TMail::HeaderField.new('Content-Disposition',
870
+ %Q<attachment; filename="\306\374\313\334\270\354.doc">)
871
+ assert_equal 'attachment', h.disposition
872
+ assert_equal 1, h.params.size
873
+ assert_equal expected, h.params['filename']
874
+ end
875
+
876
+ def _test_raw_sjis
877
+ TMail.KCODE = 'SJIS'
878
+ # raw SJIS string in value (token)
879
+ h = TMail::HeaderField.new('Content-Disposition',
880
+ %Q<attachment; filename=\223\372\226{\214\352.doc>)
881
+ assert_equal 'attachment', h.disposition
882
+ assert_equal 1, h.params.size
883
+ expected = "\223\372\226{\214\352.doc"
884
+ expected.force_encoding 'Windows-31J' if expected.respond_to? :force_encoding
885
+ assert_equal expected, h.params['filename']
886
+
887
+ # raw SJIS string in value (quoted-string)
888
+ h = TMail::HeaderField.new('Content-Disposition',
889
+ %Q<attachment; filename="\223\372\226{\214\352.doc">)
890
+ assert_equal 'attachment', h.disposition
891
+ assert_equal 1, h.params.size
892
+ assert_equal expected, h.params['filename']
893
+ end
894
+
895
+ def _test_code_conversion
896
+ # JIS -> TMail.KCODE auto conversion
897
+ TMail.KCODE = 'EUC'
898
+ h = TMail::HeaderField.new('Content-Disposition',
899
+ %Q<attachment; filename=\e$BF|K\\8l\e(B.doc>)
900
+ assert_equal 'attachment', h.disposition
901
+ assert_equal 1, h.params.size
902
+ expected = "\306\374\313\334\270\354.doc"
903
+ expected.force_encoding 'EUC-JP' if expected.respond_to? :force_encoding
904
+ assert_equal expected, h.params['filename']
905
+
906
+ TMail.KCODE = 'SJIS'
907
+ h = TMail::HeaderField.new('Content-Disposition',
908
+ %Q<attachment; filename=\e$BF|K\\8l\e(B.doc>)
909
+ assert_equal 'attachment', h.disposition
910
+ assert_equal 1, h.params.size
911
+ expected = "\223\372\226{\214\352.doc"
912
+ expected.force_encoding 'Windows-31J' if expected.respond_to? :force_encoding
913
+ assert_equal expected, h.params['filename']
914
+ end
915
+
916
+ def test_disposition=
917
+ h = TMail::HeaderField.new('Content-Disposition',
918
+ 'attachment; filename="README.txt.pif"')
919
+ assert_equal 'attachment', h.disposition
920
+ h.disposition = 'virus'
921
+ assert_equal 'virus', h.disposition
922
+ h.disposition = 'AtTaChMeNt'
923
+ assert_equal 'attachment', h.disposition
924
+ end
925
+
926
+ def test_wrong_mail_header
927
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email9")
928
+ assert_raise(TMail::SyntaxError) { TMail::Mail.parse(fixture) }
929
+ end
930
+
931
+ def test_decode_message_with_unknown_charset
932
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email10")
933
+ mail = TMail::Mail.parse(fixture)
934
+ assert_nothing_raised { mail.body }
935
+ end
936
+
937
+ def test_decode_message_with_unquoted_atchar_in_header
938
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email11")
939
+ mail = TMail::Mail.parse(fixture)
940
+ assert_not_nil mail.from
941
+ end
942
+
943
+ def test_new_from_port_should_produce_a_header_object_of_the_correct_class
944
+ p = TMail::FilePort.new("#{File.dirname(__FILE__)}/fixtures/mailbox")
945
+ h = TMail::HeaderField.new_from_port(p, 'Message-Id')
946
+ assert_equal(TMail::MessageIdHeader, h.class)
947
+ end
948
+
949
+ def test_should_return_the_evelope_sender_when_given_from_without_a_colon
950
+ p = TMail::FilePort.new("#{File.dirname(__FILE__)}/fixtures/mailbox")
951
+ h = TMail::HeaderField.new_from_port(p, 'EnvelopeSender')
952
+ assert_equal("mike@envelope_sender.com.au", h.addrs.join)
953
+ end
954
+
955
+ def test_new_from_port_should_produce_a_header_object_that_contains_the_right_data
956
+ p = TMail::FilePort.new("#{File.dirname(__FILE__)}/fixtures/mailbox")
957
+ h = TMail::HeaderField.new_from_port(p, 'From')
958
+ assert_equal("Mikel Lindsaar <mikel@from_address.com>", h.addrs.join)
959
+ end
960
+
961
+ def test_unwrapping_a_long_header_field_using_new_from_port
962
+ p = TMail::FilePort.new("#{File.dirname(__FILE__)}/fixtures/mailbox")
963
+ h = TMail::HeaderField.new_from_port(p, 'Content-Type')
964
+ line = 'multipart/signed; protocol="application/pkcs7-signature"; boundary=Apple-Mail-42-587703407; micalg=sha1'
965
+ assert(line =~ /multipart\/signed/)
966
+ assert(line =~ /protocol="application\/pkcs7-signature"/)
967
+ assert(line =~ /boundary=Apple-Mail-42-587703407/)
968
+ assert(line =~ /micalg=sha1/)
969
+ assert_equal(line.length, 103)
970
+ end
971
+
972
+ def test_returning_nil_if_there_is_no_match
973
+ p = TMail::FilePort.new("#{File.dirname(__FILE__)}/fixtures/mailbox")
974
+ h = TMail::HeaderField.new_from_port(p, 'Received-Long-Header')
975
+ assert_equal(h, nil)
976
+ end
977
+
978
+ def test_multi_address_header_in_tmail
979
+ h = TMail::Mail.new
980
+ h.to = "Mikel@me.com, mikel@you.com"
981
+ assert_equal("To: Mikel@me.com,\r\n\t mikel@you.com\r\n\r\n", h.encoded)
982
+ end
983
+
984
+ def test_adding_custom_message_id
985
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email")
986
+ mail = TMail::Mail.parse(fixture)
987
+ message_id = "<12345@me.com>"
988
+ mail.enforced_message_id = message_id
989
+ mail.ready_to_send
990
+ assert_equal(message_id, mail.message_id)
991
+ end
992
+
993
+ def test_not_adding_custom_message_id
994
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email")
995
+ mail = TMail::Mail.parse(fixture)
996
+ message_id = mail.message_id
997
+ mail.message_id = "<12345@me.com>"
998
+ mail.ready_to_send
999
+ assert_not_equal(message_id, mail.message_id)
1000
+ end
1001
+
1002
+ def test_content_type_does_not_unquote_parameter_values
1003
+ japanese_jis_filename = "¥e$B4A;z¥e(B.jpg"
1004
+ mailsrc =<<ENDSTRING
1005
+ Content-Type: image/jpeg;
1006
+ name="#{japanese_jis_filename}"
1007
+ Content-Transfer-Encoding: Base64
1008
+ Content-Disposition: attachment
1009
+ ENDSTRING
1010
+ result =<<ENDSTRING
1011
+ Content-Type: image/jpeg; name*=iso-2022-jp'ja'%c2%a5e$B4A%3bz%c2%a5e%28B.jpg
1012
+ Content-Transfer-Encoding: Base64
1013
+ Content-Disposition: attachment
1014
+
1015
+ ENDSTRING
1016
+
1017
+ mail = TMail::Mail.parse(mailsrc)
1018
+ assert_equal(result.gsub("\n", "\r\n"), mail.encoded)
1019
+ end
1020
+
1021
+ end