test/test_message.rb in sup-1.0 vs test/test_message.rb in sup-1.1
- old
+ new
@@ -19,14 +19,12 @@
Redwood::HookManager.deinstantiate!
FileUtils.rm_r @path
end
def test_simple_message
- message = fixture('simple-message.eml')
-
source = DummySource.new("sup-test://test_simple_message")
- source.messages = [ message ]
+ source.messages = [ fixture_path('simple-message.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -97,14 +95,12 @@
assert_equal("Test message!", lines.first)
end
def test_multipart_message
- message = fixture('multi-part.eml')
-
source = DummySource.new("sup-test://test_multipart_message")
- source.messages = [ message ]
+ source.messages = [ fixture_path('multi-part.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -124,14 +120,12 @@
# (possibly not yet implemented)
end
def test_broken_message_1
- message = fixture('missing-from-to.eml')
-
source = DummySource.new("sup-test://test_broken_message_1")
- source.messages = [ message ]
+ source.messages = [ fixture_path('missing-from-to.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -148,14 +142,12 @@
refute_nil(from.name)
end
def test_broken_message_2
- message = fixture('no-body.eml')
-
source = DummySource.new("sup-test://test_broken_message_1")
- source.messages = [ message ]
+ source.messages = [ fixture_path('no-body.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -165,36 +157,33 @@
assert_empty(chunks)
end
def test_multipart_message_2
- message = fixture('multi-part-2.eml')
-
source = DummySource.new("sup-test://test_multipart_message_2")
- source.messages = [ message ]
+ source.messages = [ fixture_path('multi-part-2.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
chunks = sup_message.load_from_source! # read the message body chunks
- # TODO: Add more asserts
+ assert_equal(1, chunks.length)
+ assert(chunks[0].is_a? Redwood::Chunk::Attachment)
end
def test_text_attachment_decoding
- message = fixture('text-attachments-with-charset.eml')
-
source = DummySource.new("sup-test://test_text_attachment_decoding")
- source.messages = [ message ]
+ source.messages = [ fixture_path('text-attachments-with-charset.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
chunks = sup_message.load_from_source!
- assert_equal(5, chunks.length)
+ assert_equal(7, chunks.length)
assert(chunks[0].is_a? Redwood::Chunk::Text)
## The first attachment declares charset=us-ascii
assert(chunks[1].is_a? Redwood::Chunk::Attachment)
assert_equal(["This is ASCII"], chunks[1].lines)
## The second attachment declares charset=koi8-r and has some Cyrillic
@@ -205,17 +194,22 @@
assert_equal(["\u{1f602}"], chunks[3].lines)
## The fourth attachment declares no charset and has a non-ASCII byte,
## which will be replaced with U+FFFD REPLACEMENT CHARACTER
assert(chunks[4].is_a? Redwood::Chunk::Attachment)
assert_equal(["Embedded\ufffdgarbage"], chunks[4].lines)
+ ## The fifth attachment has an invalid charset, which should still
+ ## be handled gracefully
+ assert(chunks[5].is_a? Redwood::Chunk::Attachment)
+ assert_equal(["Example invalid charset"], chunks[5].lines)
+ ## The sixth attachment is UTF-7 encoded
+ assert(chunks[6].is_a? Redwood::Chunk::Attachment)
+ assert_equal(["This is ✨UTF-7✨"], chunks[6].lines)
end
def test_mailing_list_header
- message = fixture('mailing-list-header.eml')
-
source = DummySource.new("sup-test://test_mailing_list_header")
- source.messages = [ message ]
+ source.messages = [ fixture_path('mailing-list-header.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -225,14 +219,12 @@
assert_equal("openembedded-devel@lists.openembedded.org", sup_message.list_address.email)
assert_equal("openembedded-devel", sup_message.list_address.name)
end
def test_blank_header_lines
- message = fixture('blank-header-fields.eml')
-
source = DummySource.new("sup-test://test_blank_header_lines")
- source.messages = [ message ]
+ source.messages = [ fixture_path('blank-header-fields.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
sup_message.load_from_source!
@@ -246,15 +238,117 @@
"<mailto:monitor-list-request@widget.com?subject=unsubscribe>",
list_unsubscribe)
end
- def test_malicious_attachment_names
- message = fixture('malicious-attachment-names.eml')
+ def test_rfc2047_header_encoding
+ source = DummySource.new("sup-test://test_rfc2047_header_encoding")
+ source.messages = [ fixture_path("rfc2047-header-encoding.eml") ]
+ source_info = 0
+ sup_message = Message.build_from_source(source, source_info)
+ sup_message.load_from_source!
+
+ assert_equal("Hans Martin Djupvik, Ingrid Bø, Ирина Сидорова, " +
+ "Jesper Berg, Frida Engø " +
+ "bad: =?UTF16?q?badcharsetname?==?US-ASCII?b?/w?=" +
+ "=?UTF-7?Q?=41=6D=65=72=69=63=61=E2=80=99=73?=",
+ sup_message.subj)
+ end
+
+ def test_nonascii_header
+ ## Spammers sometimes send invalid high bytes in the headers.
+ ## They will be replaced with U+FFFD REPLACEMENT CHARACTER.
+ source = DummySource.new("sup-test://test_nonascii_header")
+ source.messages = [ fixture_path("non-ascii-header.eml") ]
+ source_info = 0
+
+ sup_message = Message.build_from_source(source, source_info)
+ sup_message.load_from_source!
+
+ assert_equal("SPAM \ufffd", sup_message.from.name)
+ assert_equal("spammer@example.com", sup_message.from.email)
+ assert_equal("spam \ufffd spam", sup_message.subj)
+ end
+
+ def test_utf8_header
+ ## UTF-8 is allowed in header values according to RFC6532.
+ source = DummySource.new("sup-test://test_utf8_header")
+ source.messages = [ fixture_path("utf8-header.eml") ]
+ source_info = 0
+
+ sup_message = Message.build_from_source(source, source_info)
+ sup_message.load_from_source!
+
+ assert_equal(Encoding::UTF_8, sup_message.subj.encoding)
+ assert_equal("LibraryThing: State of the Thing — January", sup_message.subj)
+ end
+
+ def test_nonascii_header_in_nested_message
+ source = DummySource.new("sup-test://test_nonascii_header_in_nested_message")
+ source.messages = [ fixture_path("non-ascii-header-in-nested-message.eml") ]
+ source_info = 0
+
+ sup_message = Message.build_from_source(source, source_info)
+ chunks = sup_message.load_from_source!
+
+ assert_equal(3, chunks.length)
+
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
+
+ assert(chunks[1].is_a? Redwood::Chunk::EnclosedMessage)
+ assert_equal(4, chunks[1].lines.length)
+ assert_equal("From: SPAM \ufffd <spammer@example.com>", chunks[1].lines[0])
+ assert_equal("To: enclosed <enclosed@example.invalid>", chunks[1].lines[1])
+ assert_equal("Subject: spam \ufffd spam", chunks[1].lines[3])
+
+ assert(chunks[2].is_a? Redwood::Chunk::Text)
+ assert_equal(1, chunks[2].lines.length)
+ assert_equal("This is a spam.", chunks[2].lines[0])
+ end
+
+ def test_embedded_message
+ source = DummySource.new("sup-test://test_embedded_message")
+ source.messages = [ fixture_path("embedded-message.eml") ]
+ source_info = 0
+
+ sup_message = Message.build_from_source(source, source_info)
+
+ chunks = sup_message.load_from_source!
+ assert_equal(3, chunks.length)
+
+ assert_equal("sender@example.com", sup_message.from.email)
+ assert_equal("Sender", sup_message.from.name)
+ assert_equal(1, sup_message.to.length)
+ assert_equal("recipient@example.invalid", sup_message.to[0].email)
+ assert_equal("recipient", sup_message.to[0].name)
+ assert_equal("Email with embedded message", sup_message.subj)
+
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
+ assert_equal("Example outer message.", chunks[0].lines[0])
+ assert_equal("Example second line.", chunks[0].lines[1])
+
+ assert(chunks[1].is_a? Redwood::Chunk::EnclosedMessage)
+ assert_equal(4, chunks[1].lines.length)
+ assert_equal("From: Embed sender <embed@example.com>", chunks[1].lines[0])
+ assert_equal("To: rcpt2 <rcpt2@example.invalid>", chunks[1].lines[1])
+ assert_equal("Date: ", chunks[1].lines[2][0..5])
+ assert_equal(
+ Time.rfc2822("Wed, 15 Jul 2020 12:34:56 +0000"),
+ Time.rfc2822(chunks[1].lines[2][6..-1])
+ )
+ assert_equal("Subject: Embedded subject line", chunks[1].lines[3])
+
+ assert(chunks[2].is_a? Redwood::Chunk::Text)
+ assert_equal(2, chunks[2].lines.length)
+ assert_equal("Example embedded message.", chunks[2].lines[0])
+ assert_equal("Second line.", chunks[2].lines[1])
+ end
+
+ def test_malicious_attachment_names
source = DummySource.new("sup-test://test_blank_header_lines")
- source.messages = [ message ]
+ source.messages = [ fixture_path('malicious-attachment-names.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
chunks = sup_message.load_from_source!
@@ -274,13 +368,11 @@
# Zimbra does an Outlook-style "Original Message" delimiter and then *also*
# prefixes each quoted line with a > marker. That's okay until the sender
# tries to do the right thing and reply after the quote.
# In this case we want to just look at the > markers when determining where
# the quoted chunk ends.
- message = fixture('zimbra-quote-with-bottom-post.eml')
-
source = DummySource.new("sup-test://test_zimbra_quote_with_bottom_post")
- source.messages = [ message ]
+ source.messages = [ fixture_path('zimbra-quote-with-bottom-post.eml') ]
source_info = 0
sup_message = Message.build_from_source(source, source_info)
chunks = sup_message.load_from_source!