mimeparser: preserve quotes in messages with attachments

This commit is contained in:
Alexander Krotov
2020-11-08 05:59:23 +03:00
committed by link2xt
parent bf82dd9c60
commit 66907c17d3
3 changed files with 85 additions and 3 deletions

View File

@@ -1161,8 +1161,8 @@ class TestOnlineAccount:
# Majority prefers encryption now
assert msg5.is_encrypted()
def test_reply_encrypted(self, acfactory, lp):
"""Test that replies to encrypted messages are encrypted."""
def test_quote_encrypted(self, acfactory, lp):
"""Test that replies to encrypted messages with quotes are encrypted."""
ac1, ac2 = acfactory.get_two_online_accounts()
lp.sec("ac1: create chat with ac2")
@@ -1211,6 +1211,39 @@ class TestOnlineAccount:
assert msg_in.quoted_text == quoted_msg.text
assert msg_in.is_encrypted() == quoted_msg.is_encrypted()
def test_quote_attachment(self, tmpdir, acfactory, lp):
"""Test that replies with an attachment and a quote are received correctly."""
ac1, ac2 = acfactory.get_two_online_accounts()
lp.sec("ac1 creates chat with ac2")
chat1 = ac1.create_chat(ac2)
lp.sec("ac1 sends text message to ac2")
chat1.send_text("hi")
lp.sec("ac2 receives contact request from ac1")
received_message = ac2._evtracker.wait_next_messages_changed()
assert received_message.text == "hi"
basename = "attachment.txt"
p = os.path.join(tmpdir.strpath, basename)
with open(p, "w") as f:
f.write("data to send")
lp.sec("ac2 sends a reply to ac1")
chat2 = received_message.create_chat()
reply = Message.new_empty(ac2, "file")
reply.set_text("message reply")
reply.set_file(p)
reply.quote = received_message
chat2.send_msg(reply)
lp.sec("ac1 receives a reply from ac2")
received_reply = ac1._evtracker.wait_next_incoming_message()
assert received_reply.text == "message reply"
assert received_reply.quoted_text == received_message.text
assert open(received_reply.filename).read() == "data to send"
def test_saved_mime_on_received_message(self, acfactory, lp):
ac1, ac2 = acfactory.get_two_online_accounts()

View File

@@ -295,7 +295,8 @@ impl MimeMessage {
/// Squashes mutlipart chat messages with attachment into single-part messages.
///
/// Delta Chat sends attachments, such as images, in two-part messages, with the first message
/// containing an explanation. If such a message is detected, first part can be safely dropped.
/// containing a description. If such a message is detected, text from the first part can be
/// moved to the second part, and the first part dropped.
#[allow(clippy::indexing_slicing)]
fn squash_attachment_parts(&mut self) {
if let [textpart, filepart] = &self.parts[..] {
@@ -315,6 +316,9 @@ impl MimeMessage {
// insert new one
filepart.msg = self.parts[0].msg.clone();
if let Some(quote) = self.parts[0].param.get(Param::Quote) {
filepart.param.set(Param::Quote, quote);
}
// forget the one we use now
self.parts[0].msg = "".to_string();
@@ -2299,4 +2303,22 @@ On 2020-10-25, Bob wrote:
);
assert_eq!(message.parts[0].msg, "A reply.");
}
#[async_std::test]
async fn test_attachment_quote() {
let context = TestContext::new().await;
let raw = include_bytes!("../test-data/message/quote_attach.eml");
let mimeparser = MimeMessage::from_bytes(&context.ctx, &raw[..])
.await
.unwrap();
assert_eq!(mimeparser.get_subject().unwrap(), "Message from Alice");
assert_eq!(mimeparser.parts.len(), 1);
assert_eq!(mimeparser.parts[0].msg, "Reply");
assert_eq!(
mimeparser.parts[0].param.get(Param::Quote).unwrap(),
"Quote"
);
assert_eq!(mimeparser.parts[0].typ, Viewtype::File);
}
}

View File

@@ -0,0 +1,27 @@
Subject: Message from Alice
MIME-Version: 1.0
In-Reply-To: <Mr.7h_HyOuM3Dz.xcp4v8QiQua@testrun.org>
Date: Sun, 08 Nov 2020 01:16:26 +0000
Chat-Version: 1.0
Message-ID: <Mr.126R7OsBKvk.dGGBC5WcsLF@testrun.org>
To: Bob <bob@example.org>
From: Alice <alice@testrun.org>
Content-Type: multipart/mixed; boundary="uWbWY2IyEtJ8wZmp282Na11hxBBXlV"
--uWbWY2IyEtJ8wZmp282Na11hxBBXlV
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
> Quote
Reply
--uWbWY2IyEtJ8wZmp282Na11hxBBXlV
Content-Type: text/plain
Content-Disposition: attachment; filename="attachment.txt"
Content-Transfer-Encoding: base64
ZGF0YSB0byBzZW5k
--uWbWY2IyEtJ8wZmp282Na11hxBBXlV--