sup 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/HACKING +42 -0
- data/History.txt +8 -0
- data/Rakefile +12 -0
- data/ReleaseNotes +4 -0
- data/bin/sup-sync +1 -1
- data/bin/sup-tweak-labels +6 -1
- data/contrib/colorpicker.rb +100 -0
- data/contrib/completion/_sup.zsh +114 -0
- data/devel/console.sh +3 -0
- data/devel/count-loc.sh +3 -0
- data/devel/load-index.rb +9 -0
- data/devel/profile.rb +12 -0
- data/devel/start-console.rb +5 -0
- data/doc/FAQ.txt +119 -0
- data/doc/Hooks.txt +79 -0
- data/doc/Philosophy.txt +69 -0
- data/lib/sup/colormap.rb +6 -0
- data/lib/sup/modes/thread_index_mode.rb +12 -1
- data/lib/sup/modes/thread_view_mode.rb +20 -0
- data/lib/sup/version.rb +1 -1
- data/sup.gemspec +55 -0
- data/test/dummy_source.rb +61 -0
- data/test/gnupg_test_home/gpg.conf +1 -0
- data/test/gnupg_test_home/pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
- data/test/gnupg_test_home/receiver_secring.gpg +0 -0
- data/test/gnupg_test_home/receiver_trustdb.gpg +0 -0
- data/test/gnupg_test_home/secring.gpg +0 -0
- data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -0
- data/test/gnupg_test_home/trustdb.gpg +0 -0
- data/test/integration/test_label_service.rb +18 -0
- data/test/messages/bad-content-transfer-encoding-1.eml +8 -0
- data/test/messages/binary-content-transfer-encoding-2.eml +21 -0
- data/test/messages/missing-line.eml +9 -0
- data/test/test_crypto.rb +109 -0
- data/test/test_header_parsing.rb +168 -0
- data/test/test_helper.rb +7 -0
- data/test/test_message.rb +532 -0
- data/test/test_messages_dir.rb +147 -0
- data/test/test_yaml_migration.rb +85 -0
- data/test/test_yaml_regressions.rb +17 -0
- data/test/unit/service/test_label_service.rb +19 -0
- data/test/unit/test_horizontal_selector.rb +40 -0
- data/test/unit/util/test_query.rb +46 -0
- data/test/unit/util/test_string.rb +57 -0
- data/test/unit/util/test_uri.rb +19 -0
- metadata +81 -36
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
From: foo@example.org
|
2
|
+
MIME-Version: 1.0
|
3
|
+
Content-type: multipart/report; boundary="======11647==82899======"; report-type="spam-notification"
|
4
|
+
Subject: Important
|
5
|
+
|
6
|
+
This is a multi-part message in MIME format...
|
7
|
+
|
8
|
+
--======11647==82899======
|
9
|
+
Content-Type: text/plain; charset="ISO-8859-1"
|
10
|
+
Content-Disposition: inline
|
11
|
+
Content-Transfer-Encoding: quoted-printable
|
12
|
+
|
13
|
+
|
14
|
+
--======11647==82899======
|
15
|
+
Content-Type: message/rfc822
|
16
|
+
Content-Disposition: attachment
|
17
|
+
Content-Transfer-Encoding: binary
|
18
|
+
|
19
|
+
|
20
|
+
--======11647==82899======--
|
21
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
From: foo@aol.com
|
2
|
+
To: foo@test.com
|
3
|
+
Subject: Encoding bug
|
4
|
+
Content-Type: text/plain; charset="iso-8859-1"
|
5
|
+
Content-Transfer-Encoding: quoted-printable
|
6
|
+
|
7
|
+
This is =91 a test: the first line seems to disappear from the mail body but is
|
8
|
+
still visible in the thread view.
|
9
|
+
|
data/test/test_crypto.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# tests for sup's crypto libs
|
2
|
+
#
|
3
|
+
# Copyright Clint Byrum <clint@ubuntu.com> 2011. All Rights Reserved.
|
4
|
+
# Copyright Sup Developers 2013.
|
5
|
+
#
|
6
|
+
# This program is free software; you can redistribute it and/or
|
7
|
+
# modify it under the terms of the GNU General Public License
|
8
|
+
# as published by the Free Software Foundation; either version 2
|
9
|
+
# of the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program; if not, write to the Free Software
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19
|
+
# 02110-1301, USA.
|
20
|
+
|
21
|
+
require 'test_helper'
|
22
|
+
require 'sup'
|
23
|
+
require 'stringio'
|
24
|
+
require 'tmpdir'
|
25
|
+
|
26
|
+
module Redwood
|
27
|
+
|
28
|
+
class TestCryptoManager < ::Minitest::Unit::TestCase
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@from_email = 'sup-test-1@foo.bar'
|
32
|
+
@to_email = 'sup-test-2@foo.bar'
|
33
|
+
# Use test gnupg setup
|
34
|
+
@orig_gnupghome = ENV['GNUPGHOME']
|
35
|
+
ENV['GNUPGHOME'] = File.join(File.dirname(__FILE__), 'gnupg_test_home')
|
36
|
+
|
37
|
+
@path = Dir.mktmpdir
|
38
|
+
Redwood::HookManager.init File.join(@path, 'hooks')
|
39
|
+
|
40
|
+
am = {:default=> {:name => "test", :email=> 'sup-test-1@foo.bar'}}
|
41
|
+
Redwood::AccountManager.init am
|
42
|
+
|
43
|
+
Redwood::CryptoManager.init
|
44
|
+
|
45
|
+
if not CryptoManager.have_crypto?
|
46
|
+
warn "No crypto set up, crypto will not be tested. Reason: #{CryptoManager.not_working_reason}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def teardown
|
51
|
+
CryptoManager.deinstantiate!
|
52
|
+
AccountManager.deinstantiate!
|
53
|
+
HookManager.deinstantiate!
|
54
|
+
FileUtils.rm_r @path
|
55
|
+
|
56
|
+
ENV['GNUPGHOME'] = @orig_gnupghome
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_sign
|
60
|
+
if CryptoManager.have_crypto? then
|
61
|
+
signed = CryptoManager.sign @from_email,@to_email,"ABCDEFG"
|
62
|
+
assert_instance_of RMail::Message, signed
|
63
|
+
assert_equal "ABCDEFG", signed.body[0]
|
64
|
+
assert signed.body[1].body.length > 0 , "signature length must be > 0"
|
65
|
+
assert (signed.body[1].body.include? "-----BEGIN PGP SIGNATURE-----") , "Expecting PGP armored data"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_encrypt
|
70
|
+
if CryptoManager.have_crypto? then
|
71
|
+
encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
|
72
|
+
assert_instance_of RMail::Message, encrypted
|
73
|
+
assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_sign_and_encrypt
|
78
|
+
if CryptoManager.have_crypto? then
|
79
|
+
encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
|
80
|
+
assert_instance_of RMail::Message, encrypted
|
81
|
+
assert (encrypted.body[1].body.include? "-----BEGIN PGP MESSAGE-----") , "Expecting PGP armored data"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_decrypt
|
86
|
+
if CryptoManager.have_crypto? then
|
87
|
+
encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
|
88
|
+
assert_instance_of RMail::Message, encrypted
|
89
|
+
assert_instance_of String, (encrypted.body[1].body)
|
90
|
+
decrypted = CryptoManager.decrypt encrypted.body[1], true
|
91
|
+
assert_instance_of Array, decrypted
|
92
|
+
assert_instance_of Chunk::CryptoNotice, decrypted[0]
|
93
|
+
assert_instance_of Chunk::CryptoNotice, decrypted[1]
|
94
|
+
assert_instance_of RMail::Message, decrypted[2]
|
95
|
+
assert_equal "ABCDEFG" , decrypted[2].body
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_verify
|
100
|
+
if CryptoManager.have_crypto?
|
101
|
+
signed = CryptoManager.sign @from_email, @to_email, "ABCDEFG"
|
102
|
+
assert_instance_of RMail::Message, signed
|
103
|
+
assert_instance_of String, (signed.body[1].body)
|
104
|
+
CryptoManager.verify signed.body[0], signed.body[1], true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'sup'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
include Redwood
|
8
|
+
|
9
|
+
class TestMBoxParsing < Minitest::Unit::TestCase
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@path = Dir.mktmpdir
|
13
|
+
@mbox = File.join(@path, 'test_mbox')
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
FileUtils.rm_r @path
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_normal_headers
|
21
|
+
h = Source.parse_raw_email_header StringIO.new(<<EOS)
|
22
|
+
From: Bob <bob@bob.com>
|
23
|
+
To: Sally <sally@sally.com>
|
24
|
+
EOS
|
25
|
+
|
26
|
+
assert_equal "Bob <bob@bob.com>", h["from"]
|
27
|
+
assert_equal "Sally <sally@sally.com>", h["to"]
|
28
|
+
assert_nil h["message-id"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_multiline
|
32
|
+
h = Source.parse_raw_email_header StringIO.new(<<EOS)
|
33
|
+
From: Bob <bob@bob.com>
|
34
|
+
Subject: one two three
|
35
|
+
four five six
|
36
|
+
To: Sally <sally@sally.com>
|
37
|
+
References: <seven>
|
38
|
+
<eight>
|
39
|
+
Seven: Eight
|
40
|
+
EOS
|
41
|
+
|
42
|
+
assert_equal "one two three four five six", h["subject"]
|
43
|
+
assert_equal "Sally <sally@sally.com>", h["to"]
|
44
|
+
assert_equal "<seven> <eight>", h["references"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_ignore_spacing
|
48
|
+
variants = [
|
49
|
+
"Subject:one two three end\n",
|
50
|
+
"Subject: one two three end\n",
|
51
|
+
"Subject: one two three end \n",
|
52
|
+
]
|
53
|
+
variants.each do |s|
|
54
|
+
h = Source.parse_raw_email_header StringIO.new(s)
|
55
|
+
assert_equal "one two three end", h["subject"]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_message_id_ignore_spacing
|
60
|
+
variants = [
|
61
|
+
"Message-Id: <one@bob.com> \n",
|
62
|
+
"Message-Id:<one@bob.com> \n",
|
63
|
+
]
|
64
|
+
variants.each do |s|
|
65
|
+
h = Source.parse_raw_email_header StringIO.new(s)
|
66
|
+
assert_equal "<one@bob.com>", h["message-id"]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_blank_lines
|
71
|
+
h = Source.parse_raw_email_header StringIO.new("")
|
72
|
+
assert_equal nil, h["message-id"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_empty_headers
|
76
|
+
variants = [
|
77
|
+
"Message-Id: \n",
|
78
|
+
"Message-Id:\n",
|
79
|
+
]
|
80
|
+
variants.each do |s|
|
81
|
+
h = Source.parse_raw_email_header StringIO.new(s)
|
82
|
+
assert_equal "", h["message-id"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_detect_end_of_headers
|
87
|
+
h = Source.parse_raw_email_header StringIO.new(<<EOS)
|
88
|
+
From: Bob <bob@bob.com>
|
89
|
+
|
90
|
+
To: a dear friend
|
91
|
+
EOS
|
92
|
+
assert_equal "Bob <bob@bob.com>", h["from"]
|
93
|
+
assert_nil h["to"]
|
94
|
+
|
95
|
+
h = Source.parse_raw_email_header StringIO.new(<<EOS)
|
96
|
+
From: Bob <bob@bob.com>
|
97
|
+
\r
|
98
|
+
To: a dear friend
|
99
|
+
EOS
|
100
|
+
assert_equal "Bob <bob@bob.com>", h["from"]
|
101
|
+
assert_nil h["to"]
|
102
|
+
|
103
|
+
h = Source.parse_raw_email_header StringIO.new(<<EOS)
|
104
|
+
From: Bob <bob@bob.com>
|
105
|
+
\r\n\r
|
106
|
+
To: a dear friend
|
107
|
+
EOS
|
108
|
+
assert_equal "Bob <bob@bob.com>", h["from"]
|
109
|
+
assert_nil h["to"]
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_from_line_splitting
|
113
|
+
l = MBox.new mbox_for_string(<<EOS)
|
114
|
+
From sup-talk-bounces@rubyforge.org Mon Apr 27 12:56:18 2009
|
115
|
+
From: Bob <bob@bob.com>
|
116
|
+
To: a dear friend
|
117
|
+
|
118
|
+
Hello there friend. How are you?
|
119
|
+
|
120
|
+
From sea to shining sea
|
121
|
+
|
122
|
+
From bob@bob.com I get only spam.
|
123
|
+
|
124
|
+
From bob@bob.com
|
125
|
+
|
126
|
+
From bob@bob.com
|
127
|
+
|
128
|
+
(that second one has spaces at the endj
|
129
|
+
|
130
|
+
This is the end of the email.
|
131
|
+
EOS
|
132
|
+
offset = l.next_offset 0
|
133
|
+
assert_equal 61, offset
|
134
|
+
offset = l.next_offset 61
|
135
|
+
assert_nil offset
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_more_from_line_splitting
|
139
|
+
l = MBox.new mbox_for_string(<<EOS)
|
140
|
+
From sup-talk-bounces@rubyforge.org Mon Apr 27 12:56:18 2009
|
141
|
+
From: Bob <bob@bob.com>
|
142
|
+
To: a dear friend
|
143
|
+
|
144
|
+
Hello there friend. How are you?
|
145
|
+
|
146
|
+
From bob@bob.com Mon Apr 27 12:56:19 2009
|
147
|
+
From: Bob <bob@bob.com>
|
148
|
+
To: a dear friend
|
149
|
+
|
150
|
+
Hello again! Would you like to buy my products?
|
151
|
+
EOS
|
152
|
+
offset = l.next_offset 0
|
153
|
+
refute_nil offset
|
154
|
+
|
155
|
+
offset = l.next_offset offset
|
156
|
+
refute_nil offset
|
157
|
+
|
158
|
+
offset = l.next_offset offset
|
159
|
+
assert_nil offset
|
160
|
+
end
|
161
|
+
|
162
|
+
def mbox_for_string content
|
163
|
+
File.open(@mbox, 'w') do |f|
|
164
|
+
f.write content
|
165
|
+
end
|
166
|
+
"mbox://#{@mbox}"
|
167
|
+
end
|
168
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,532 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'sup'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
require 'dummy_source'
|
8
|
+
|
9
|
+
# override File.exists? to make it work with StringIO for testing.
|
10
|
+
# FIXME: do aliasing to avoid breaking this when sup moves from
|
11
|
+
# File.exists? to File.exist?
|
12
|
+
|
13
|
+
class File
|
14
|
+
|
15
|
+
def File.exists? file
|
16
|
+
# puts "fake File::exists?"
|
17
|
+
|
18
|
+
if file.is_a?(StringIO)
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
# use the different function
|
22
|
+
File.exist?(file)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
module Redwood
|
28
|
+
|
29
|
+
class TestMessage < ::Minitest::Unit::TestCase
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@path = Dir.mktmpdir
|
33
|
+
Redwood::HookManager.init File.join(@path, 'hooks')
|
34
|
+
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
Redwood::HookManager.deinstantiate!
|
38
|
+
FileUtils.rm_r @path
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_simple_message
|
42
|
+
|
43
|
+
message = <<EOS
|
44
|
+
Return-path: <fake_sender@example.invalid>
|
45
|
+
Envelope-to: fake_receiver@localhost
|
46
|
+
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
47
|
+
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
48
|
+
(envelope-from <fake_sender@example.invalid>)
|
49
|
+
id 1J1S8R-0006lA-MJ
|
50
|
+
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
51
|
+
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
52
|
+
Mailing-List: contact example-help@example.invalid; run by ezmlm
|
53
|
+
Precedence: bulk
|
54
|
+
List-Id: <example.list-id.example.invalid>
|
55
|
+
List-Post: <mailto:example@example.invalid>
|
56
|
+
List-Help: <mailto:example-help@example.invalid>
|
57
|
+
List-Unsubscribe: <mailto:example-unsubscribe@example.invalid>
|
58
|
+
List-Subscribe: <mailto:example-subscribe@example.invalid>
|
59
|
+
Delivered-To: mailing list example@example.invalid
|
60
|
+
Delivered-To: moderator for example@example.invalid
|
61
|
+
From: Fake Sender <fake_sender@example.invalid>
|
62
|
+
To: Fake Receiver <fake_receiver@localhost>
|
63
|
+
Subject: Re: Test message subject
|
64
|
+
Message-ID: <20071209194819.GA25972@example.invalid>
|
65
|
+
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
66
|
+
MIME-Version: 1.0
|
67
|
+
Content-Type: text/plain; charset=us-ascii
|
68
|
+
Content-Disposition: inline
|
69
|
+
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
70
|
+
User-Agent: Sup/0.3
|
71
|
+
|
72
|
+
Test message!
|
73
|
+
EOS
|
74
|
+
|
75
|
+
source = DummySource.new("sup-test://test_simple_message")
|
76
|
+
source.messages = [ message ]
|
77
|
+
source_info = 0
|
78
|
+
|
79
|
+
sup_message = Message.build_from_source(source, source_info)
|
80
|
+
sup_message.load_from_source!
|
81
|
+
|
82
|
+
# see how well parsing the header went
|
83
|
+
|
84
|
+
to = sup_message.to
|
85
|
+
# "to" is an Array containing person items
|
86
|
+
|
87
|
+
# there should be only one item
|
88
|
+
assert_equal(1, to.length)
|
89
|
+
|
90
|
+
# sup doesn't do capitalized letters in email addresses
|
91
|
+
assert_equal("fake_receiver@localhost", to[0].email)
|
92
|
+
assert_equal("Fake Receiver", to[0].name)
|
93
|
+
|
94
|
+
from = sup_message.from
|
95
|
+
# "from" is just a simple person item
|
96
|
+
|
97
|
+
assert_equal("fake_sender@example.invalid", from.email)
|
98
|
+
assert_equal("Fake Sender", from.name)
|
99
|
+
|
100
|
+
subj = sup_message.subj
|
101
|
+
assert_equal("Re: Test message subject", subj)
|
102
|
+
|
103
|
+
list_subscribe = sup_message.list_subscribe
|
104
|
+
assert_equal("<mailto:example-subscribe@example.invalid>", list_subscribe)
|
105
|
+
|
106
|
+
list_unsubscribe = sup_message.list_unsubscribe
|
107
|
+
assert_equal("<mailto:example-unsubscribe@example.invalid>", list_unsubscribe)
|
108
|
+
|
109
|
+
list_address = sup_message.list_address
|
110
|
+
assert_equal("example@example.invalid", list_address.email)
|
111
|
+
assert_equal("example", list_address.name)
|
112
|
+
|
113
|
+
date = sup_message.date
|
114
|
+
assert_equal(Time.parse("Sun, 9 Dec 2007 21:48:19 +0200"), date)
|
115
|
+
|
116
|
+
id = sup_message.id
|
117
|
+
assert_equal("20071209194819.GA25972@example.invalid", id)
|
118
|
+
|
119
|
+
refs = sup_message.refs
|
120
|
+
assert_equal(1, refs.length)
|
121
|
+
assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", refs[0])
|
122
|
+
|
123
|
+
replytos = sup_message.replytos
|
124
|
+
assert_equal(1, replytos.length)
|
125
|
+
assert_equal("E1J1Rvb-0006k2-CE@localhost.localdomain", replytos[0])
|
126
|
+
|
127
|
+
cc = sup_message.cc
|
128
|
+
# there are no ccs
|
129
|
+
assert_equal(0, cc.length)
|
130
|
+
|
131
|
+
bcc = sup_message.bcc
|
132
|
+
# there are no bccs
|
133
|
+
assert_equal(0, bcc.length)
|
134
|
+
|
135
|
+
recipient_email = sup_message.recipient_email
|
136
|
+
assert_equal("fake_receiver@localhost", recipient_email)
|
137
|
+
|
138
|
+
message_source = sup_message.source
|
139
|
+
assert_equal(message_source, source)
|
140
|
+
|
141
|
+
message_source_info = sup_message.source_info
|
142
|
+
assert_equal(message_source_info, source_info)
|
143
|
+
|
144
|
+
# read the message body chunks
|
145
|
+
|
146
|
+
chunks = sup_message.load_from_source!
|
147
|
+
|
148
|
+
# there should be only one chunk
|
149
|
+
assert_equal(1, chunks.length)
|
150
|
+
|
151
|
+
lines = chunks[0].lines
|
152
|
+
|
153
|
+
# there should be only one line
|
154
|
+
assert_equal(1, lines.length)
|
155
|
+
|
156
|
+
assert_equal("Test message!", lines[0])
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_multipart_message
|
161
|
+
|
162
|
+
message = <<EOS
|
163
|
+
From fake_receiver@localhost Sun Dec 09 22:33:37 +0200 2007
|
164
|
+
Subject: Re: Test message subject
|
165
|
+
From: Fake Receiver <fake_receiver@localhost>
|
166
|
+
To: Fake Sender <fake_sender@example.invalid>
|
167
|
+
References: <E1J1Rvb-0006k2-CE@localhost.localdomain> <20071209194819.GA25972example.invalid>
|
168
|
+
In-Reply-To: <20071209194819.GA25972example.invalid>
|
169
|
+
Date: Sun, 09 Dec 2007 22:33:37 +0200
|
170
|
+
Message-Id: <1197232243-sup-2663example.invalid>
|
171
|
+
User-Agent: Sup/0.3
|
172
|
+
Content-Type: multipart/mixed; boundary="=-1197232418-506707-26079-6122-2-="
|
173
|
+
MIME-Version: 1.0
|
174
|
+
|
175
|
+
|
176
|
+
--=-1197232418-506707-26079-6122-2-=
|
177
|
+
Content-Type: text/plain; charset=utf-8
|
178
|
+
Content-Disposition: inline
|
179
|
+
|
180
|
+
Excerpts from Fake Sender's message of Sun Dec 09 21:48:19 +0200 2007:
|
181
|
+
> Test message!
|
182
|
+
|
183
|
+
Thanks for the message!
|
184
|
+
--=-1197232418-506707-26079-6122-2-=
|
185
|
+
Content-Disposition: attachment; filename="HACKING"
|
186
|
+
Content-Type: application/octet-stream; name="HACKING"
|
187
|
+
Content-Transfer-Encoding: base64
|
188
|
+
|
189
|
+
UnVubmluZyBTdXAgbG9jYWxseQotLS0tLS0tLS0tLS0tLS0tLS0tCkludm9r
|
190
|
+
ZSBpdCBsaWtlIHRoaXM6CgpydWJ5IC1JIGxpYiAtdyBiaW4vc3VwCgpZb3Un
|
191
|
+
bGwgaGF2ZSB0byBpbnN0YWxsIGFsbCBnZW1zIG1lbnRpb25lZCBpbiB0aGUg
|
192
|
+
UmFrZWZpbGUgKGxvb2sgZm9yIHRoZSBsaW5lCnNldHRpbmcgcC5leHRyYV9k
|
193
|
+
ZXBzKS4gSWYgeW91J3JlIG9uIGEgRGViaWFuIG9yIERlYmlhbi1iYXNlZCBz
|
194
|
+
eXN0ZW0gKGUuZy4KVWJ1bnR1KSwgeW91J2xsIGhhdmUgdG8gbWFrZSBzdXJl
|
195
|
+
IHlvdSBoYXZlIGEgY29tcGxldGUgUnVieSBpbnN0YWxsYXRpb24sCmVzcGVj
|
196
|
+
aWFsbHkgbGlic3NsLXJ1YnkuCgpDb2Rpbmcgc3RhbmRhcmRzCi0tLS0tLS0t
|
197
|
+
LS0tLS0tLS0KCi0gRG9uJ3Qgd3JhcCBjb2RlIHVubGVzcyBpdCByZWFsbHkg
|
198
|
+
YmVuZWZpdHMgZnJvbSBpdC4gVGhlIGRheXMgb2YKICA4MC1jb2x1bW4gZGlz
|
199
|
+
cGxheXMgYXJlIGxvbmcgb3Zlci4gQnV0IGRvIHdyYXAgY29tbWVudHMgYW5k
|
200
|
+
IG90aGVyCiAgdGV4dCBhdCB3aGF0ZXZlciBFbWFjcyBtZXRhLVEgZG9lcy4K
|
201
|
+
LSBJIGxpa2UgcG9ldHJ5IG1vZGUuCi0gVXNlIHt9IGZvciBvbmUtbGluZXIg
|
202
|
+
YmxvY2tzIGFuZCBkby9lbmQgZm9yIG11bHRpLWxpbmUgYmxvY2tzLgoK
|
203
|
+
|
204
|
+
--=-1197232418-506707-26079-6122-2-=
|
205
|
+
Content-Disposition: attachment; filename="Manifest.txt"
|
206
|
+
Content-Type: text/plain; name="Manifest.txt"
|
207
|
+
Content-Transfer-Encoding: quoted-printable
|
208
|
+
|
209
|
+
HACKING
|
210
|
+
History.txt
|
211
|
+
LICENSE
|
212
|
+
Manifest.txt
|
213
|
+
README.txt
|
214
|
+
Rakefile
|
215
|
+
bin/sup
|
216
|
+
bin/sup-add
|
217
|
+
bin/sup-config
|
218
|
+
bin/sup-dump
|
219
|
+
bin/sup-recover-sources
|
220
|
+
bin/sup-sync
|
221
|
+
bin/sup-sync-back
|
222
|
+
|
223
|
+
--=-1197232418-506707-26079-6122-2-=--
|
224
|
+
EOS
|
225
|
+
source = DummySource.new("sup-test://test_multipart_message")
|
226
|
+
source.messages = [ message ]
|
227
|
+
source_info = 0
|
228
|
+
|
229
|
+
sup_message = Message.build_from_source(source, source_info)
|
230
|
+
sup_message.load_from_source!
|
231
|
+
|
232
|
+
# read the message body chunks
|
233
|
+
|
234
|
+
chunks = sup_message.load_from_source!
|
235
|
+
|
236
|
+
# this time there should be four chunks: first the quoted part of
|
237
|
+
# the message, then the non-quoted part, then the two attachments
|
238
|
+
assert_equal(4, chunks.length)
|
239
|
+
|
240
|
+
assert_equal(chunks[0].class, Redwood::Chunk::Quote)
|
241
|
+
assert_equal(chunks[1].class, Redwood::Chunk::Text)
|
242
|
+
assert_equal(chunks[2].class, Redwood::Chunk::Attachment)
|
243
|
+
assert_equal(chunks[3].class, Redwood::Chunk::Attachment)
|
244
|
+
|
245
|
+
# further testing of chunks will happen in test_message_chunks.rb
|
246
|
+
# (possibly not yet implemented)
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_broken_message_1
|
251
|
+
|
252
|
+
# an example of a broken message, missing "to" and "from" fields
|
253
|
+
|
254
|
+
message = <<EOS
|
255
|
+
Return-path: <fake_sender@example.invalid>
|
256
|
+
Envelope-to: fake_receiver@localhost
|
257
|
+
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
258
|
+
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
259
|
+
(envelope-from <fake_sender@example.invalid>)
|
260
|
+
id 1J1S8R-0006lA-MJ
|
261
|
+
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
262
|
+
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
263
|
+
Subject: Re: Test message subject
|
264
|
+
Message-ID: <20071209194819.GA25972@example.invalid>
|
265
|
+
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
266
|
+
MIME-Version: 1.0
|
267
|
+
Content-Type: text/plain; charset=us-ascii
|
268
|
+
Content-Disposition: inline
|
269
|
+
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
270
|
+
User-Agent: Sup/0.3
|
271
|
+
|
272
|
+
Test message!
|
273
|
+
EOS
|
274
|
+
|
275
|
+
source = DummySource.new("sup-test://test_broken_message_1")
|
276
|
+
source.messages = [ message ]
|
277
|
+
source_info = 0
|
278
|
+
|
279
|
+
sup_message = Message.build_from_source(source, source_info)
|
280
|
+
sup_message.load_from_source!
|
281
|
+
|
282
|
+
to = sup_message.to
|
283
|
+
|
284
|
+
# there should no items, since the message doesn't have any
|
285
|
+
# recipients -- still not nil
|
286
|
+
assert_equal(0, to.length)
|
287
|
+
|
288
|
+
# from will have bogus values
|
289
|
+
from = sup_message.from
|
290
|
+
# very basic email address check
|
291
|
+
assert_match(/\w+@\w+\.\w{2,4}/, from.email)
|
292
|
+
refute_nil(from.name)
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_broken_message_2
|
297
|
+
|
298
|
+
# an example of a broken message, no body at all
|
299
|
+
|
300
|
+
message = <<EOS
|
301
|
+
Return-path: <fake_sender@example.invalid>
|
302
|
+
From: Fake Sender <fake_sender@example.invalid>
|
303
|
+
To: Fake Receiver <fake_receiver@localhost>
|
304
|
+
Envelope-to: fake_receiver@localhost
|
305
|
+
Delivery-date: Sun, 09 Dec 2007 21:48:19 +0200
|
306
|
+
Received: from fake_sender by localhost.localdomain with local (Exim 4.67)
|
307
|
+
(envelope-from <fake_sender@example.invalid>)
|
308
|
+
id 1J1S8R-0006lA-MJ
|
309
|
+
for fake_receiver@localhost; Sun, 09 Dec 2007 21:48:19 +0200
|
310
|
+
Date: Sun, 9 Dec 2007 21:48:19 +0200
|
311
|
+
Subject: Re: Test message subject
|
312
|
+
Message-ID: <20071209194819.GA25972@example.invalid>
|
313
|
+
References: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
314
|
+
MIME-Version: 1.0
|
315
|
+
Content-Type: text/plain; charset=us-ascii
|
316
|
+
Content-Disposition: inline
|
317
|
+
In-Reply-To: <E1J1Rvb-0006k2-CE@localhost.localdomain>
|
318
|
+
User-Agent: Sup/0.3
|
319
|
+
EOS
|
320
|
+
|
321
|
+
source = DummySource.new("sup-test://test_broken_message_1")
|
322
|
+
source.messages = [ message ]
|
323
|
+
source_info = 0
|
324
|
+
|
325
|
+
sup_message = Message.build_from_source(source, source_info)
|
326
|
+
sup_message.load_from_source!
|
327
|
+
|
328
|
+
# read the message body chunks: no errors should reach this level
|
329
|
+
|
330
|
+
chunks = sup_message.load_from_source!
|
331
|
+
|
332
|
+
# the chunks list should be empty
|
333
|
+
|
334
|
+
assert_equal(0, chunks.length)
|
335
|
+
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_multipart_message_2
|
339
|
+
|
340
|
+
message = <<EOS
|
341
|
+
Return-path: <vim-mac-return-3938-fake_receiver=localhost@vim.org>
|
342
|
+
Envelope-to: fake_receiver@localhost
|
343
|
+
Delivery-date: Wed, 14 Jun 2006 19:22:54 +0300
|
344
|
+
Received: from localhost ([127.0.0.1] helo=localhost.localdomain)
|
345
|
+
by localhost.localdomain with esmtp (Exim 4.60)
|
346
|
+
(envelope-from <vim-mac-return-3938-fake_receiver=localhost@vim.org>)
|
347
|
+
id 1FqXk3-0006jM-48
|
348
|
+
for fake_receiver@localhost; Wed, 14 Jun 2006 18:57:15 +0300
|
349
|
+
Received: from pop.gmail.com
|
350
|
+
by localhost.localdomain with POP3 (fetchmail-6.3.2)
|
351
|
+
for <fake_receiver@localhost> (single-drop); Wed, 14 Jun 2006 18:57:15 +0300 (EEST)
|
352
|
+
X-Gmail-Received: 8ee0fe5f895736974c042c8eaf176014b1ba7b88
|
353
|
+
Delivered-To: fake_receiver@localhost
|
354
|
+
Received: by 10.49.8.16 with SMTP id l16cs11327nfi;
|
355
|
+
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
356
|
+
Received: by 10.66.224.8 with SMTP id w8mr2172862ugg;
|
357
|
+
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
358
|
+
Received: from foobar.math.fu-berlin.de (foobar.math.fu-berlin.de [160.45.45.151])
|
359
|
+
by mx.gmail.com with SMTP id j3si553645ugd.2006.03.26.19.31.56;
|
360
|
+
Sun, 26 Mar 2006 19:31:56 -0800 (PST)
|
361
|
+
Received-SPF: neutral (gmail.com: 160.45.45.151 is neither permitted nor denied by best guess record for domain of vim-mac-return-3938-fake_receiver=localhost@vim.org)
|
362
|
+
Message-Id: <44275cac.74a494f1.315a.ffff825cSMTPIN_ADDED@mx.gmail.com>
|
363
|
+
Received: (qmail 24265 invoked by uid 200); 27 Mar 2006 02:32:39 -0000
|
364
|
+
Mailing-List: contact vim-mac-help@vim.org; run by ezmlm
|
365
|
+
Precedence: bulk
|
366
|
+
Delivered-To: mailing list vim-mac@vim.org
|
367
|
+
Received: (qmail 7913 invoked from network); 26 Mar 2006 23:37:34 -0000
|
368
|
+
Received: from cpe-138-217-96-243.vic.bigpond.net.au (HELO vim.org) (138.217.96.243)
|
369
|
+
by foobar.math.fu-berlin.de with SMTP; 26 Mar 2006 23:37:34 -0000
|
370
|
+
From: fake_sender@example.invalid
|
371
|
+
To: vim-mac@vim.org
|
372
|
+
Subject: Mail Delivery (failure vim-mac@vim.org)
|
373
|
+
Date: Mon, 27 Mar 2006 10:29:39 +1000
|
374
|
+
MIME-Version: 1.0
|
375
|
+
Content-Type: multipart/related;
|
376
|
+
type="multipart/alternative";
|
377
|
+
boundary="----=_NextPart_000_001B_01C0CA80.6B015D10"
|
378
|
+
X-Priority: 3
|
379
|
+
X-MSMail-Priority: Normal
|
380
|
+
|
381
|
+
------=_NextPart_000_001B_01C0CA80.6B015D10
|
382
|
+
Content-Type: multipart/alternative;
|
383
|
+
boundary="----=_NextPart_001_001C_01C0CA80.6B015D10"
|
384
|
+
|
385
|
+
------=_NextPart_001_001C_01C0CA80.6B015D10
|
386
|
+
Content-Type: text/plain;
|
387
|
+
charset="iso-8859-1"
|
388
|
+
Content-Transfer-Encoding: quoted-printable
|
389
|
+
|
390
|
+
------=_NextPart_001_001C_01C0CA80.6B015D10
|
391
|
+
Content-Type: text/html;
|
392
|
+
charset="iso-8859-1"
|
393
|
+
Content-Transfer-Encoding: quoted-printable
|
394
|
+
|
395
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
396
|
+
<HTML><HEAD>
|
397
|
+
<META content=3D"text/html; charset=3Diso-8859-1" =
|
398
|
+
http-equiv=3DContent-Type>
|
399
|
+
<META content=3D"MSHTML 5.00.2920.0" name=3DGENERATOR>
|
400
|
+
<STYLE></STYLE>
|
401
|
+
</HEAD>
|
402
|
+
<BODY bgColor=3D#ffffff>If the message will not displayed automatically,<br>
|
403
|
+
follow the link to read the delivered message.<br><br>
|
404
|
+
Received message is available at:<br>
|
405
|
+
<a href=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0>www.vim.org/inbox/vim-mac/read.php?sessionid-18559</a>
|
406
|
+
<iframe
|
407
|
+
src=3Dcid:031401Mfdab4$3f3dL780$73387018@57W81fa70Re height=3D0 width=3D0></iframe>
|
408
|
+
<DIV> </DIV></BODY></HTML>
|
409
|
+
|
410
|
+
------=_NextPart_001_001C_01C0CA80.6B015D10--
|
411
|
+
|
412
|
+
------=_NextPart_000_001B_01C0CA80.6B015D10--
|
413
|
+
|
414
|
+
|
415
|
+
EOS
|
416
|
+
source = DummySource.new("sup-test://test_multipart_message_2")
|
417
|
+
source.messages = [ message ]
|
418
|
+
source_info = 0
|
419
|
+
|
420
|
+
sup_message = Message.build_from_source(source, source_info)
|
421
|
+
sup_message.load_from_source!
|
422
|
+
|
423
|
+
# read the message body chunks
|
424
|
+
|
425
|
+
sup_message.load_from_source!
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_blank_header_lines
|
429
|
+
|
430
|
+
message = <<EOS
|
431
|
+
Return-Path: <monitor-list-bounces@widget.com>
|
432
|
+
X-Original-To: nobody@localhost
|
433
|
+
Delivered-To: nobody@localhost.eng.widget.com
|
434
|
+
Received: from localhost (localhost.localdomain [127.0.0.1])
|
435
|
+
by soquel.eng.widget.com (Postfix) with ESMTP id 609BC13C0DB1
|
436
|
+
for <nobody@localhost>; Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
|
437
|
+
MIME-Version: 1.0
|
438
|
+
Received: from pa-excas-vip.widget.com [10.16.67.200]
|
439
|
+
by localhost with IMAP (fetchmail-6.2.5)
|
440
|
+
for nobody@localhost (single-drop); Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
|
441
|
+
Received: from pa-exht01.widget.com (10.113.81.167) by pa-excaht11.widget.com
|
442
|
+
(10.113.81.197) with Microsoft SMTP Server (TLS) id 8.1.311.2; Thu, 19 Mar
|
443
|
+
2009 13:42:30 -0700
|
444
|
+
Received: from mailman2.widget.com (10.16.64.159) by pa-exht01.widget.com
|
445
|
+
(10.113.81.167) with Microsoft SMTP Server id 8.1.336.0; Thu, 19 Mar 2009
|
446
|
+
13:42:30 -0700
|
447
|
+
Received: by mailman2.widget.com (Postfix) id 47095AE30856; Thu, 19 Mar 2009
|
448
|
+
13:42:29 -0700 (PDT)
|
449
|
+
Received: from countchocula.widget.com (localhost.localdomain [127.0.0.1]) by
|
450
|
+
mailman2.widget.com (Postfix) with ESMTP id 5F782ABC5948; Thu, 19 Mar 2009
|
451
|
+
13:42:28 -0700 (PDT)
|
452
|
+
Received: from mailhost4.widget.com (mailhost4.widget.com [10.16.67.124]) by
|
453
|
+
mailman2.widget.com (Postfix) with ESMTP id 6CDCCABC5948 for
|
454
|
+
<monitor-list@mailman2.widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
|
455
|
+
Received: by mailhost4.widget.com (Postfix) id 2364AC9AC4; Thu, 19 Mar 2009
|
456
|
+
13:42:26 -0700 (PDT)
|
457
|
+
Received: from pa-exht01.widget.com (pa-exht01.widget.com [10.113.81.167]) by
|
458
|
+
mailhost4.widget.com (Postfix) with ESMTP id 17A68C9AC3 for
|
459
|
+
<monitor-list@widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
|
460
|
+
Received: from PA-EXMBX04.widget.com ([10.113.81.142]) by pa-exht01.widget.com
|
461
|
+
([10.113.81.167]) with mapi; Thu, 19 Mar 2009 13:42:26 -0700
|
462
|
+
From: Some User <someuser@widget.com>
|
463
|
+
To: "monitor-list@widget.com" <monitor-list@widget.com>
|
464
|
+
Sender: "monitor-list-bounces@widget.com" <monitor-list-bounces@widget.com>
|
465
|
+
Date: Thu, 19 Mar 2009 13:42:25 -0700
|
466
|
+
Subject: Looking for a mac
|
467
|
+
Thread-Topic: Looking for a mac
|
468
|
+
Thread-Index: AQHJqNM1xIqqjNRWuUCUBaxzPFK5eQ==
|
469
|
+
Message-ID:
|
470
|
+
<D3C12B2AD838B44DA9D6B2CA334246D011E72A73A4@PA-EXMBX04.widget.com>
|
471
|
+
List-Help: <mailto:monitor-list-request@widget.com?subject=help>
|
472
|
+
List-Subscribe: <http://mailman2.widget.com/mailman/listinfo/monitor-list>,
|
473
|
+
<mailto:monitor-list-request@widget.com?subject=subscribe>
|
474
|
+
List-Unsubscribe:
|
475
|
+
<http://mailman2.widget.com/mailman/listinfo/monitor-list>,
|
476
|
+
<mailto:monitor-list-request@widget.com?subject=unsubscribe>
|
477
|
+
Accept-Language: en-US
|
478
|
+
Content-Language: en-US
|
479
|
+
X-MS-Exchange-Organization-AuthAs: Anonymous
|
480
|
+
X-MS-Exchange-Organization-AuthSource: pa-exht01.widget.com
|
481
|
+
X-MS-Has-Attach:
|
482
|
+
X-Auto-Response-Suppress: All
|
483
|
+
X-MS-TNEF-Correlator:
|
484
|
+
acceptlanguage: en-US
|
485
|
+
delivered-to: monitor-list@widget.com
|
486
|
+
errors-to: monitor-list-bounces@widget.com
|
487
|
+
list-id: engineering monitor related <monitor-list.widget.com>
|
488
|
+
x-mailman-version: 2.1.8
|
489
|
+
x-beenthere: monitor-list@widget.com
|
490
|
+
x-original-to: monitor-list@mailman2.widget.com
|
491
|
+
list-post: <mailto:monitor-list@widget.com>
|
492
|
+
list-archive: <http://mailman2.widget.com/pipermail/monitor-list>
|
493
|
+
Content-Type: text/plain; charset="us-ascii"
|
494
|
+
Content-Transfer-Encoding: quoted-printable
|
495
|
+
|
496
|
+
Hi all,
|
497
|
+
|
498
|
+
Just wondering if anybody can lend me a mac to reproduce PR 384931 ?
|
499
|
+
Thanks.
|
500
|
+
|
501
|
+
Michael=
|
502
|
+
EOS
|
503
|
+
|
504
|
+
source = DummySource.new("sup-test://test_blank_header_lines")
|
505
|
+
source.messages = [ message ]
|
506
|
+
source_info = 0
|
507
|
+
|
508
|
+
sup_message = Message.build_from_source(source, source_info)
|
509
|
+
sup_message.load_from_source!
|
510
|
+
|
511
|
+
# See how well parsing the message ID went.
|
512
|
+
id = sup_message.id
|
513
|
+
assert_equal("D3C12B2AD838B44DA9D6B2CA334246D011E72A73A4@PA-EXMBX04.widget.com", id)
|
514
|
+
|
515
|
+
# Look at another header field whose first line was blank.
|
516
|
+
list_unsubscribe = sup_message.list_unsubscribe
|
517
|
+
assert_equal("<http://mailman2.widget.com/mailman/listinfo/monitor-list>,\n \t" +
|
518
|
+
"<mailto:monitor-list-request@widget.com?subject=unsubscribe>",
|
519
|
+
list_unsubscribe)
|
520
|
+
|
521
|
+
end
|
522
|
+
|
523
|
+
# TODO: test different error cases, malformed messages etc.
|
524
|
+
|
525
|
+
# TODO: test different quoting styles, see that they are all divided
|
526
|
+
# to chunks properly
|
527
|
+
|
528
|
+
end
|
529
|
+
|
530
|
+
end
|
531
|
+
|
532
|
+
# vim:noai:ts=2:sw=2:
|