sup 0.17.0 → 0.18.0
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.
- 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:
|