diff --git a/src/calls/calls_tests.rs b/src/calls/calls_tests.rs index 946cd6aeb..c84b21f78 100644 --- a/src/calls/calls_tests.rs +++ b/src/calls/calls_tests.rs @@ -4,6 +4,7 @@ use crate::config::Config; use crate::constants::DC_CHAT_ID_TRASH; use crate::message::MessageState; use crate::receive_imf::receive_imf; +use crate::test_utils; use crate::test_utils::{TestContext, TestContextManager}; struct CallSetup { @@ -634,20 +635,23 @@ async fn test_forward_call() -> Result<()> { async fn test_end_text_call() -> Result<()> { let mut tcm = TestContextManager::new(); let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - let received1 = receive_imf( - alice, - b"From: bob@example.net\n\ - To: alice@example.org\n\ - Message-ID: \n\ - Date: Sun, 22 Mar 2020 22:37:57 +0000\n\ - Chat-Version: 1.0\n\ - \n\ - Hello\n", - false, + let encrypted_message = test_utils::encrypt_raw_message( + bob, + &[alice], + b"From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Message-ID: \r\n\ + Date: Sun, 22 Mar 2020 22:37:57 +0000\r\n\ + Chat-Version: 1.0\r\n\ + \r\n\ + Hello\r\n", ) - .await? - .unwrap(); + .await?; + let received1 = receive_imf(alice, encrypted_message.as_bytes(), false) + .await? + .unwrap(); assert_eq!(received1.msg_ids.len(), 1); let msg = Message::load_from_db(alice, received1.msg_ids[0]) .await @@ -656,21 +660,23 @@ async fn test_end_text_call() -> Result<()> { // Receiving "Call ended" message that refers // to the text message does not result in an error. - let received2 = receive_imf( - alice, - b"From: bob@example.net\n\ - To: alice@example.org\n\ - Message-ID: \n\ - Date: Sun, 22 Mar 2020 23:37:57 +0000\n\ - In-Reply-To: \n\ - Chat-Version: 1.0\n\ - Chat-Content: call-ended\n\ - \n\ - Call ended\n", - false, + let encrypted_message2 = test_utils::encrypt_raw_message( + bob, + &[alice], + b"From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Message-ID: \r\n\ + Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\ + In-Reply-To: \r\n\ + Chat-Version: 1.0\r\n\ + Chat-Content: call-ended\r\n\ + \r\n\ + Call ended\r\n", ) - .await? - .unwrap(); + .await?; + let received2 = receive_imf(alice, encrypted_message2.as_bytes(), false) + .await? + .unwrap(); assert_eq!(received2.msg_ids.len(), 1); assert_eq!(received2.chat_id, DC_CHAT_ID_TRASH); diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index 162768059..bdd54f31f 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -11,6 +11,7 @@ use crate::message::{Message, MessengerMessage, delete_msgs}; use crate::mimeparser::{self, MimeMessage}; use crate::receive_imf::receive_imf; use crate::securejoin::{get_securejoin_qr, join_securejoin}; +use crate::test_utils; use crate::test_utils::{ AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, E2EE_INFO_MSGS, TestContext, TestContextManager, TimeShiftFalsePositiveNote, sync, @@ -1159,46 +1160,51 @@ async fn test_archive() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_unarchive_if_muted() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let bob = &tcm.bob().await; - async fn msg_from_bob(t: &TestContext, num: u32) -> Result<()> { - receive_imf( - t, + let msg_from_bob = async |num: u32| { + let encrypted_message = test_utils::encrypt_raw_message( + bob, + &[t], format!( - "From: bob@example.net\n\ - To: alice@example.org\n\ - Message-ID: <{num}@example.org>\n\ - Chat-Version: 1.0\n\ - Date: Sun, 22 Mar 2022 19:37:57 +0000\n\ - \n\ - hello\n" + "From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Message-ID: <{num}@example.org>\r\n\ + Chat-Version: 1.0\r\n\ + Date: Sun, 22 Mar 2022 19:37:57 +0000\r\n\ + \r\n\ + hello\r\n" ) .as_bytes(), - false, ) - .await?; - Ok(()) - } + .await + .unwrap(); + receive_imf(t, encrypted_message.as_bytes(), false) + .await + .unwrap(); + }; - msg_from_bob(&t, 1).await?; + msg_from_bob(1).await; let chat_id = t.get_last_msg().await.get_chat_id(); - chat_id.accept(&t).await?; - chat_id.set_visibility(&t, ChatVisibility::Archived).await?; - assert_eq!(get_archived_cnt(&t).await?, 1); + chat_id.accept(t).await?; + chat_id.set_visibility(t, ChatVisibility::Archived).await?; + assert_eq!(get_archived_cnt(t).await?, 1); // not muted chat is unarchived on receiving a message - msg_from_bob(&t, 2).await?; - assert_eq!(get_archived_cnt(&t).await?, 0); + msg_from_bob(2).await; + assert_eq!(get_archived_cnt(t).await?, 0); // forever muted chat is not unarchived on receiving a message - chat_id.set_visibility(&t, ChatVisibility::Archived).await?; - set_muted(&t, chat_id, MuteDuration::Forever).await?; - msg_from_bob(&t, 3).await?; - assert_eq!(get_archived_cnt(&t).await?, 1); + chat_id.set_visibility(t, ChatVisibility::Archived).await?; + set_muted(t, chat_id, MuteDuration::Forever).await?; + msg_from_bob(3).await; + assert_eq!(get_archived_cnt(t).await?, 1); // otherwise muted chat is not unarchived on receiving a message set_muted( - &t, + t, chat_id, MuteDuration::Until( SystemTime::now() @@ -1207,12 +1213,12 @@ async fn test_unarchive_if_muted() -> Result<()> { ), ) .await?; - msg_from_bob(&t, 4).await?; - assert_eq!(get_archived_cnt(&t).await?, 1); + msg_from_bob(4).await; + assert_eq!(get_archived_cnt(t).await?, 1); // expired mute will unarchive the chat set_muted( - &t, + t, chat_id, MuteDuration::Until( SystemTime::now() @@ -1221,20 +1227,20 @@ async fn test_unarchive_if_muted() -> Result<()> { ), ) .await?; - msg_from_bob(&t, 5).await?; - assert_eq!(get_archived_cnt(&t).await?, 0); + msg_from_bob(5).await; + assert_eq!(get_archived_cnt(t).await?, 0); // no unarchiving on sending to muted chat or on adding info messages to muted chat - chat_id.set_visibility(&t, ChatVisibility::Archived).await?; - set_muted(&t, chat_id, MuteDuration::Forever).await?; - send_text_msg(&t, chat_id, "out".to_string()).await?; - add_info_msg(&t, chat_id, "info").await?; - assert_eq!(get_archived_cnt(&t).await?, 1); + chat_id.set_visibility(t, ChatVisibility::Archived).await?; + set_muted(t, chat_id, MuteDuration::Forever).await?; + send_text_msg(t, chat_id, "out".to_string()).await?; + add_info_msg(t, chat_id, "info").await?; + assert_eq!(get_archived_cnt(t).await?, 1); // finally, unarchive on sending to not muted chat - set_muted(&t, chat_id, MuteDuration::NotMuted).await?; - send_text_msg(&t, chat_id, "out2".to_string()).await?; - assert_eq!(get_archived_cnt(&t).await?, 0); + set_muted(t, chat_id, MuteDuration::NotMuted).await?; + send_text_msg(t, chat_id, "out2".to_string()).await?; + assert_eq!(get_archived_cnt(t).await?, 0); Ok(()) } @@ -1873,45 +1879,38 @@ async fn test_lookup_self_by_contact_id() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_marknoticed_chat() -> Result<()> { - let t = TestContext::new_alice().await; - let chat = t.create_chat_with_contact("bob", "bob@example.org").await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let chat = alice.create_chat(bob).await; - receive_imf( - &t, - b"From: bob@example.org\n\ - To: alice@example.org\n\ - Message-ID: <1@example.org>\n\ - Chat-Version: 1.0\n\ - Date: Fri, 23 Apr 2021 10:00:57 +0000\n\ - \n\ - hello\n", - false, - ) - .await?; + let bob_chat_id = bob.create_chat_id(alice).await; + let sent = bob.send_text(bob_chat_id, "hello").await; + alice.recv_msg(&sent).await; - let chats = Chatlist::try_load(&t, 0, None, None).await?; + let chats = Chatlist::try_load(alice, 0, None, None).await?; assert_eq!(chats.len(), 1); assert_eq!(chats.get_chat_id(0)?, chat.id); - assert_eq!(chat.id.get_fresh_msg_cnt(&t).await?, 1); - assert_eq!(t.get_fresh_msgs().await?.len(), 1); + assert_eq!(chat.id.get_fresh_msg_cnt(alice).await?, 1); + assert_eq!(alice.get_fresh_msgs().await?.len(), 1); - let msgs = get_chat_msgs(&t, chat.id).await?; - assert_eq!(msgs.len(), 1); - let msg_id = match msgs.first().unwrap() { + let msgs = get_chat_msgs(alice, chat.id).await?; + assert_eq!(msgs.len(), 2); + let msg_id = match msgs.last().unwrap() { ChatItem::Message { msg_id } => *msg_id, _ => MsgId::new_unset(), }; - let msg = message::Message::load_from_db(&t, msg_id).await?; + let msg = message::Message::load_from_db(alice, msg_id).await?; assert_eq!(msg.state, MessageState::InFresh); - marknoticed_chat(&t, chat.id).await?; + marknoticed_chat(alice, chat.id).await?; - let chats = Chatlist::try_load(&t, 0, None, None).await?; + let chats = Chatlist::try_load(alice, 0, None, None).await?; assert_eq!(chats.len(), 1); - let msg = message::Message::load_from_db(&t, msg_id).await?; + let msg = message::Message::load_from_db(alice, msg_id).await?; assert_eq!(msg.state, MessageState::InNoticed); - assert_eq!(chat.id.get_fresh_msg_cnt(&t).await?, 0); - assert_eq!(t.get_fresh_msgs().await?.len(), 0); + assert_eq!(chat.id.get_fresh_msg_cnt(alice).await?, 0); + assert_eq!(alice.get_fresh_msgs().await?.len(), 0); Ok(()) } @@ -1970,40 +1969,43 @@ async fn test_contact_request_fresh_messages() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_contact_request_archive() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - receive_imf( - &t, - b"From: bob@example.org\n\ - To: alice@example.org\n\ - Message-ID: <2@example.org>\n\ - Chat-Version: 1.0\n\ - Date: Sun, 22 Mar 2021 19:37:57 +0000\n\ - \n\ - hello\n", - false, - ) - .await?; + let bob_chat_id = bob.create_chat_id(alice).await; + let bob_sent_text = bob.send_text(bob_chat_id, "hello").await; + alice.recv_msg(&bob_sent_text).await; - let chats = Chatlist::try_load(&t, 0, None, None).await?; + let chats = Chatlist::try_load(alice, 0, None, None).await?; assert_eq!(chats.len(), 1); let chat_id = chats.get_chat_id(0)?; - assert!(Chat::load_from_db(&t, chat_id).await?.is_contact_request()); - assert_eq!(get_archived_cnt(&t).await?, 0); + assert!( + Chat::load_from_db(alice, chat_id) + .await? + .is_contact_request() + ); + assert_eq!(get_archived_cnt(alice).await?, 0); // archive request without accepting or blocking - chat_id.set_visibility(&t, ChatVisibility::Archived).await?; + chat_id + .set_visibility(alice, ChatVisibility::Archived) + .await?; - let chats = Chatlist::try_load(&t, 0, None, None).await?; + let chats = Chatlist::try_load(alice, 0, None, None).await?; assert_eq!(chats.len(), 1); let chat_id = chats.get_chat_id(0)?; assert!(chat_id.is_archived_link()); - assert_eq!(get_archived_cnt(&t).await?, 1); + assert_eq!(get_archived_cnt(alice).await?, 1); - let chats = Chatlist::try_load(&t, DC_GCL_ARCHIVED_ONLY, None, None).await?; + let chats = Chatlist::try_load(alice, DC_GCL_ARCHIVED_ONLY, None, None).await?; assert_eq!(chats.len(), 1); let chat_id = chats.get_chat_id(0)?; - assert!(Chat::load_from_db(&t, chat_id).await?.is_contact_request()); + assert!( + Chat::load_from_db(alice, chat_id) + .await? + .is_contact_request() + ); Ok(()) } @@ -4695,8 +4697,9 @@ async fn test_sync_delete_chat() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_sync_adhoc_grp() -> Result<()> { - let alice0 = &TestContext::new_alice().await; - let alice1 = &TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice0 = &tcm.alice().await; + let alice1 = &tcm.alice().await; for a in [alice0, alice1] { a.set_config_bool(Config::SyncMsgs, true).await?; } diff --git a/src/contact/contact_tests.rs b/src/contact/contact_tests.rs index b821301ce..47312f4db 100644 --- a/src/contact/contact_tests.rs +++ b/src/contact/contact_tests.rs @@ -998,33 +998,18 @@ async fn test_selfavatar_changed_event() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_last_seen() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - let (contact_id, _) = Contact::add_or_lookup( - &alice, - "Bob", - &ContactAddress::new("bob@example.net")?, - Origin::ManuallyCreated, - ) - .await?; - let contact = Contact::get_by_id(&alice, contact_id).await?; + let contact = alice.add_or_lookup_contact(bob).await; assert_eq!(contact.last_seen(), 0); - let mime = br#"Subject: Hello -Message-ID: message@example.net -To: Alice -From: Bob -Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no -Chat-Version: 1.0 -Date: Sun, 22 Mar 2020 22:37:55 +0000 - -Hi."#; - receive_imf(&alice, mime, false).await?; - let msg = alice.get_last_msg().await; + let msg = tcm.send_recv(bob, alice, "Hi.").await; let timestamp = msg.get_timestamp(); assert!(timestamp > 0); - let contact = Contact::get_by_id(&alice, contact_id).await?; + let contact = Contact::get_by_id(alice, contact.id).await?; assert_eq!(contact.last_seen(), timestamp); Ok(()) diff --git a/src/context/context_tests.rs b/src/context/context_tests.rs index b2de005a7..7b8a036dc 100644 --- a/src/context/context_tests.rs +++ b/src/context/context_tests.rs @@ -8,7 +8,7 @@ use crate::chatlist::Chatlist; use crate::constants::Chattype; use crate::message::Message; use crate::receive_imf::receive_imf; -use crate::test_utils::{E2EE_INFO_MSGS, TestContext}; +use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager}; use crate::tools::{SystemTime, create_outgoing_rfc724_mid}; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -385,49 +385,40 @@ async fn test_search_msgs() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_search_unaccepted_requests() -> Result<()> { - let t = TestContext::new_alice().await; - receive_imf( - &t, - b"From: BobBar \n\ - To: alice@example.org\n\ - Subject: foo\n\ - Message-ID: \n\ - Chat-Version: 1.0\n\ - Date: Tue, 25 Oct 2022 13:37:00 +0000\n\ - \n\ - hello bob, foobar test!\n", - false, - ) - .await?; - let chat_id = t.get_last_msg().await.get_chat_id(); - let chat = Chat::load_from_db(&t, chat_id).await?; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let bob = &tcm.bob().await; + bob.set_config(Config::Displayname, Some("BobBar")).await?; + let msg = tcm.send_recv(bob, t, "hello bob, foobar test!").await; + let chat_id = msg.get_chat_id(); + let chat = Chat::load_from_db(t, chat_id).await?; assert_eq!(chat.get_type(), Chattype::Single); assert!(chat.is_contact_request()); + assert_eq!(Chatlist::try_load(t, 0, None, None).await?.len(), 1); - assert_eq!(Chatlist::try_load(&t, 0, None, None).await?.len(), 1); assert_eq!( - Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(), + Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(), 1 ); assert_eq!(t.search_msgs(None, "foobar").await?.len(), 1); assert_eq!(t.search_msgs(Some(chat_id), "foobar").await?.len(), 1); - chat_id.block(&t).await?; + chat_id.block(t).await?; - assert_eq!(Chatlist::try_load(&t, 0, None, None).await?.len(), 0); + assert_eq!(Chatlist::try_load(t, 0, None, None).await?.len(), 0); assert_eq!( - Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(), + Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(), 0 ); assert_eq!(t.search_msgs(None, "foobar").await?.len(), 0); assert_eq!(t.search_msgs(Some(chat_id), "foobar").await?.len(), 0); - let contact_ids = get_chat_contacts(&t, chat_id).await?; - Contact::unblock(&t, *contact_ids.first().unwrap()).await?; + let contact_ids = get_chat_contacts(t, chat_id).await?; + Contact::unblock(t, *contact_ids.first().unwrap()).await?; - assert_eq!(Chatlist::try_load(&t, 0, None, None).await?.len(), 1); + assert_eq!(Chatlist::try_load(t, 0, None, None).await?.len(), 1); assert_eq!( - Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(), + Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(), 1 ); assert_eq!(t.search_msgs(None, "foobar").await?.len(), 1); diff --git a/src/e2ee.rs b/src/e2ee.rs index 9a1f639bf..0ca08e1be 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -42,12 +42,25 @@ impl EncryptHelper { compress: bool, seipd_version: SeipdVersion, ) -> Result { - let sign_key = load_self_secret_key(context).await?; - let mut raw_message = Vec::new(); let cursor = Cursor::new(&mut raw_message); mail_to_encrypt.clone().write_part(cursor).ok(); + let ctext = self + .encrypt_raw(context, keyring, raw_message, compress, seipd_version) + .await?; + Ok(ctext) + } + + pub async fn encrypt_raw( + self, + context: &Context, + keyring: Vec, + raw_message: Vec, + compress: bool, + seipd_version: SeipdVersion, + ) -> Result { + let sign_key = load_self_secret_key(context).await?; let ctext = pgp::pk_encrypt(raw_message, keyring, sign_key, compress, seipd_version).await?; diff --git a/src/ephemeral/ephemeral_tests.rs b/src/ephemeral/ephemeral_tests.rs index 693c1b872..d42747d6e 100644 --- a/src/ephemeral/ephemeral_tests.rs +++ b/src/ephemeral/ephemeral_tests.rs @@ -9,6 +9,7 @@ use crate::download::DownloadState; use crate::location; use crate::message::markseen_msgs; use crate::receive_imf::receive_imf; +use crate::test_utils; use crate::test_utils::{TestContext, TestContextManager}; use crate::timesmearing::MAX_SECONDS_TO_LEND_FROM_FUTURE; use crate::{ @@ -557,50 +558,54 @@ async fn test_delete_expired_imap_messages() -> Result<()> { // Regression test for a bug in the timer rollback protection. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_ephemeral_timer_references() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; // Message with Message-ID and no timer is received. - receive_imf( - &alice, - b"From: Bob \n\ - To: Alice \n\ - Chat-Version: 1.0\n\ - Subject: Subject\n\ - Message-ID: \n\ - Date: Sun, 22 Mar 2020 00:10:00 +0000\n\ - \n\ - hello\n", - false, + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[alice], + b"From: Bob \r\n\ + To: Alice \r\n\ + Chat-Version: 1.0\r\n\ + Subject: Subject\r\n\ + Message-ID: \r\n\ + Date: Sun, 22 Mar 2020 00:10:00 +0000\r\n\ + \r\n\ + hello\r\n", ) .await?; + receive_imf(alice, encrypted_msg.as_bytes(), false).await?; let msg = alice.get_last_msg().await; let chat_id = msg.chat_id; - assert_eq!(chat_id.get_ephemeral_timer(&alice).await?, Timer::Disabled); + assert_eq!(chat_id.get_ephemeral_timer(alice).await?, Timer::Disabled); // Message with Message-ID is received. - receive_imf( - &alice, - b"From: Bob \n\ - To: Alice \n\ - Chat-Version: 1.0\n\ - Subject: Subject\n\ - Message-ID: \n\ - Date: Sun, 22 Mar 2020 00:11:00 +0000\n\ - Ephemeral-Timer: 60\n\ - \n\ - second message\n", - false, + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[alice], + b"From: Bob \r\n\ + To: Alice \r\n\ + Chat-Version: 1.0\r\n\ + Subject: Subject\r\n\ + Message-ID: \r\n\ + Date: Sun, 22 Mar 2020 00:11:00 +0000\r\n\ + Ephemeral-Timer: 60\r\n\ + \r\n\ + second message\r\n", ) .await?; + receive_imf(alice, encrypted_msg.as_bytes(), false).await?; assert_eq!( - chat_id.get_ephemeral_timer(&alice).await?, + chat_id.get_ephemeral_timer(alice).await?, Timer::Enabled { duration: 60 } ); let msg = alice.get_last_msg().await; // Message is deleted when its timer expires. - msg.id.trash(&alice, false).await?; + msg.id.trash(alice, false).await?; // Message with Message-ID , referencing and // , is received. The message is not in the @@ -614,25 +619,26 @@ async fn test_ephemeral_timer_references() -> Result<()> { // // The message also contains a quote of the first message to test that only References: // header and not In-Reply-To: is consulted by the rollback protection. - receive_imf( - &alice, - b"From: Bob \n\ - To: Alice \n\ - Chat-Version: 1.0\n\ - Subject: Subject\n\ - Message-ID: \n\ - Date: Sun, 22 Mar 2020 00:12:00 +0000\n\ - References: \n\ - In-Reply-To: \n\ - \n\ - > hello\n", - false, + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[alice], + b"From: Bob \r\n\ + To: Alice \r\n\ + Chat-Version: 1.0\r\n\ + Subject: Subject\r\n\ + Message-ID: \r\n\ + Date: Sun, 22 Mar 2020 00:12:00 +0000\r\n\ + References: \r\n\ + In-Reply-To: \r\n\ + \r\n\ + > hello\r\n", ) .await?; + receive_imf(alice, encrypted_msg.as_bytes(), false).await?; let msg = alice.get_last_msg().await; assert_eq!( - msg.chat_id.get_ephemeral_timer(&alice).await?, + msg.chat_id.get_ephemeral_timer(alice).await?, Timer::Disabled ); diff --git a/src/html.rs b/src/html.rs index bc4e4bfbc..5c64ee665 100644 --- a/src/html.rs +++ b/src/html.rs @@ -287,6 +287,7 @@ impl MsgId { mod tests { use super::*; use crate::chat::{self, Chat, forward_msgs, save_msgs}; + use crate::constants; use crate::contact::ContactId; use crate::message::{MessengerMessage, Viewtype}; @@ -520,31 +521,29 @@ test some special html-characters as < > and & but also " and &#x #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_html_save_msg() -> Result<()> { + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; // Alice receives a non-delta html-message - let alice = TestContext::new_alice().await; let chat = alice .create_chat_with_contact("", "sender@testrun.org") .await; let raw = include_bytes!("../test-data/message/text_alt_plain_html.eml"); - receive_imf(&alice, raw, false).await?; + receive_imf(alice, raw, false).await?; let msg = alice.get_last_msg_in(chat.get_id()).await; // Alice saves the message let self_chat = alice.get_self_chat().await; - save_msgs(&alice, &[msg.id]).await?; + save_msgs(alice, &[msg.id]).await?; let saved_msg = alice.get_last_msg_in(self_chat.get_id()).await; assert_ne!(saved_msg.id, msg.id); - assert_eq!( - saved_msg.get_original_msg_id(&alice).await?.unwrap(), - msg.id - ); + assert_eq!(saved_msg.get_original_msg_id(alice).await?.unwrap(), msg.id); assert!(!saved_msg.is_forwarded()); // UI should not flag "saved messages" as "forwarded" assert_ne!(saved_msg.get_from_id(), ContactId::SELF); assert_eq!(saved_msg.get_from_id(), msg.get_from_id()); assert_eq!(saved_msg.is_dc_message, MessengerMessage::No); assert!(saved_msg.get_text().contains("this is plain")); assert!(saved_msg.has_html()); - let html = saved_msg.get_id().get_html(&alice).await?.unwrap(); + let html = saved_msg.get_id().get_html(alice).await?.unwrap(); assert!(html.contains("this is html")); Ok(()) @@ -618,18 +617,19 @@ test some special html-characters as < > and & but also " and &#x #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_cp1252_html() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; receive_imf( - &t, + alice, include_bytes!("../test-data/message/cp1252-html.eml"), false, ) .await?; - let msg = t.get_last_msg().await; + let msg = alice.get_last_msg().await; assert_eq!(msg.viewtype, Viewtype::Text); assert!(msg.text.contains("foo bar ä ö ü ß")); assert!(msg.has_html()); - let html = msg.get_id().get_html(&t).await?.unwrap(); + let html = msg.get_id().get_html(alice).await?.unwrap(); println!("{html}"); assert!(html.contains("foo bar ä ö ü ß")); Ok(()) diff --git a/src/location.rs b/src/location.rs index ac0ff2a47..85ce22c38 100644 --- a/src/location.rs +++ b/src/location.rs @@ -871,6 +871,7 @@ mod tests { use crate::config::Config; use crate::message::MessageState; use crate::receive_imf::receive_imf; + use crate::test_utils; use crate::test_utils::{ExpectedEvents, TestContext, TestContextManager}; use crate::tools::SystemTime; @@ -939,12 +940,15 @@ mod tests { /// Tests that location.kml is hidden. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn receive_location_kml() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - receive_imf( - &alice, + let encrypted_message = test_utils::encrypt_raw_message( + bob, + &[alice], br#"Subject: Hello -Message-ID: hello@example.net +Message-ID: To: Alice From: Bob Date: Mon, 20 Dec 2021 00:00:00 +0000 @@ -952,14 +956,15 @@ Chat-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no Text message."#, - false, ) .await?; + receive_imf(alice, encrypted_message.as_bytes(), false).await?; let received_msg = alice.get_last_msg().await; assert_eq!(received_msg.text, "Text message."); - receive_imf( - &alice, + let encrypted_message = test_utils::encrypt_raw_message( + bob, + &[alice], br#"Subject: locations MIME-Version: 1.0 To: @@ -986,16 +991,14 @@ Content-Disposition: attachment; filename="location.kml" ---U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#, - false, - ) - .await?; +--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#).await?; + receive_imf(alice, encrypted_message.as_bytes(), false).await?; // Received location message is not visible, last message stays the same. let received_msg2 = alice.get_last_msg().await; assert_eq!(received_msg2.id, received_msg.id); - let locations = get_range(&alice, None, None, 0, 0).await?; + let locations = get_range(alice, None, None, 0, 0).await?; assert_eq!(locations.len(), 1); Ok(()) } @@ -1003,10 +1006,13 @@ Content-Disposition: attachment; filename="location.kml" /// Tests that `location.kml` is not hidden and not seen if it contains a message. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn receive_visible_location_kml() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - receive_imf( - &alice, + let encrypted_message = test_utils::encrypt_raw_message( + bob, + &[alice], br#"Subject: locations MIME-Version: 1.0 To: @@ -1034,16 +1040,15 @@ Content-Disposition: attachment; filename="location.kml" ---U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#, - false, - ) - .await?; +--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#).await?; + + receive_imf(alice, encrypted_message.as_bytes(), false).await?; let received_msg = alice.get_last_msg().await; assert_eq!(received_msg.text, "Text message."); assert_eq!(received_msg.state, MessageState::InFresh); - let locations = get_range(&alice, None, None, 0, 0).await?; + let locations = get_range(alice, None, None, 0, 0).await?; assert_eq!(locations.len(), 1); Ok(()) } diff --git a/src/message/message_tests.rs b/src/message/message_tests.rs index dc63f86a1..0293465e3 100644 --- a/src/message/message_tests.rs +++ b/src/message/message_tests.rs @@ -139,23 +139,14 @@ async fn test_unencrypted_quote_encrypted_message() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_chat_id() { // Alice receives a message that pops up as a contact request - let alice = TestContext::new_alice().await; - receive_imf( - &alice, - b"From: Bob \n\ - To: alice@example.org\n\ - Chat-Version: 1.0\n\ - Message-ID: <123@example.com>\n\ - Date: Fri, 29 Jan 2021 21:37:55 +0000\n\ - \n\ - hello\n", - false, - ) - .await - .unwrap(); + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let chat_id = bob.create_chat_id(alice).await; + let sent = bob.send_text(chat_id, "hello").await; + let msg = alice.recv_msg(&sent).await; // check chat-id of this message - let msg = alice.get_last_msg().await; assert!(!msg.get_chat_id().is_special()); assert_eq!(msg.get_text(), "hello".to_string()); } @@ -465,7 +456,8 @@ async fn test_get_state() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_is_bot() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; // Alice receives an auto-generated non-chat message. // @@ -473,7 +465,7 @@ async fn test_is_bot() -> Result<()> { // in which case the message should be marked as bot-generated, // but the contact should not. receive_imf( - &alice, + alice, b"From: Claire \n\ To: alice@example.org\n\ Message-ID: <789@example.com>\n\ @@ -487,12 +479,12 @@ async fn test_is_bot() -> Result<()> { let msg = alice.get_last_msg().await; assert_eq!(msg.get_text(), "hello".to_string()); assert!(msg.is_bot()); - let contact = Contact::get_by_id(&alice, msg.from_id).await?; + let contact = Contact::get_by_id(alice, msg.from_id).await?; assert!(!contact.is_bot()); // Alice receives a message from Bob the bot. receive_imf( - &alice, + alice, b"From: Bob \n\ To: alice@example.org\n\ Chat-Version: 1.0\n\ @@ -507,12 +499,12 @@ async fn test_is_bot() -> Result<()> { let msg = alice.get_last_msg().await; assert_eq!(msg.get_text(), "hello".to_string()); assert!(msg.is_bot()); - let contact = Contact::get_by_id(&alice, msg.from_id).await?; + let contact = Contact::get_by_id(alice, msg.from_id).await?; assert!(contact.is_bot()); // Alice receives a message from Bob who is not the bot anymore. receive_imf( - &alice, + alice, b"From: Bob \n\ To: alice@example.org\n\ Chat-Version: 1.0\n\ @@ -526,7 +518,7 @@ async fn test_is_bot() -> Result<()> { let msg = alice.get_last_msg().await; assert_eq!(msg.get_text(), "hello again".to_string()); assert!(!msg.is_bot()); - let contact = Contact::get_by_id(&alice, msg.from_id).await?; + let contact = Contact::get_by_id(alice, msg.from_id).await?; assert!(!contact.is_bot()); Ok(()) diff --git a/src/mimefactory/mimefactory_tests.rs b/src/mimefactory/mimefactory_tests.rs index f47dfc086..a47b613e8 100644 --- a/src/mimefactory/mimefactory_tests.rs +++ b/src/mimefactory/mimefactory_tests.rs @@ -19,6 +19,7 @@ use crate::headerdef::HeaderDef; use crate::message; use crate::mimeparser::MimeMessage; use crate::receive_imf::receive_imf; +use crate::test_utils; use crate::test_utils::{TestContext, TestContextManager, get_chat_msg}; use crate::tools::SystemTime; @@ -132,14 +133,13 @@ async fn test_subject_from_mua() { // 1.: Receive a mail from an MUA assert_eq!( msg_to_subject_str( - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: Bob \n\ - To: alice@example.org\n\ - Subject: Antw: Chat: hello\n\ - Message-ID: <2222@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n" + b"From: Bob \r\n\ + To: alice@example.org\r\n\ + Subject: Antw: Chat: hello\r\n\ + Message-ID: <2222@example.net>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n" ) .await, "Re: Chat: hello" @@ -147,14 +147,13 @@ async fn test_subject_from_mua() { assert_eq!( msg_to_subject_str( - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: Bob \n\ - To: alice@example.org\n\ - Subject: Infos: 42\n\ - Message-ID: <2222@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n" + b"From: Bob \r\n\ + To: alice@example.org\r\n\ + Subject: Infos: 42\r\n\ + Message-ID: <2222@example.net>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n" ) .await, "Re: Infos: 42" @@ -166,15 +165,14 @@ async fn test_subject_from_dc() { // 2. Receive a message from Delta Chat assert_eq!( msg_to_subject_str( - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: bob@example.com\n\ - To: alice@example.org\n\ - Subject: Chat: hello\n\ - Chat-Version: 1.0\n\ - Message-ID: <2223@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n" + b"From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Subject: Chat: hello\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: <2223@example.net>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n" ) .await, "Re: Chat: hello" @@ -199,29 +197,27 @@ async fn test_subject_outgoing() { async fn test_subject_unicode() { // 4. Receive messages with unicode characters and make sure that we do not panic (we do not care about the result) msg_to_subject_str( - "Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: bob@example.com\n\ - To: alice@example.org\n\ - Subject: äääää\n\ - Chat-Version: 1.0\n\ - Message-ID: <2893@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n" + "From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Subject: äääää\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: <2893@example.com>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n" .as_bytes(), ) .await; msg_to_subject_str( - "Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: bob@example.com\n\ - To: alice@example.org\n\ - Subject: aäääää\n\ - Chat-Version: 1.0\n\ - Message-ID: <2893@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n" + "From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Subject: aäääää\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: <2893@example.com>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n" .as_bytes(), ) .await; @@ -230,54 +226,54 @@ async fn test_subject_unicode() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_subject_mdn() { // 5. Receive an mdn (read receipt) and make sure the mdn's subject is not used - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let bob = &tcm.bob().await; receive_imf( - &t, - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: alice@example.org\n\ - To: bob@example.com\n\ - Subject: Hello, Bob\n\ - Chat-Version: 1.0\n\ - Message-ID: <2893@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n", + t, + b"From: alice@example.org\r\n\ + To: bob@example.net\r\n\ + Subject: Hello, Bob\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: <2893@example.com>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n", false, ) .await .unwrap(); let mut new_msg = incoming_msg_to_reply_msg( - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: bob@example.com\n\ - To: alice@example.org\n\ - Subject: message opened\n\ - Date: Sun, 22 Mar 2020 23:37:57 +0000\n\ - Chat-Version: 1.0\n\ - Message-ID: \n\ - Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\n\ - \n\ - \n\ - --SNIPP\n\ - Content-Type: text/plain; charset=utf-8\n\ - \n\ - Read receipts do not guarantee sth. was read.\n\ - \n\ - \n\ - --SNIPP\n\ - Content-Type: message/disposition-notification\n\ - \n\ - Reporting-UA: Delta Chat 1.28.0\n\ - Original-Recipient: rfc822;bob@example.com\n\ - Final-Recipient: rfc822;bob@example.com\n\ - Original-Message-ID: <2893@example.com>\n\ - Disposition: manual-action/MDN-sent-automatically; displayed\n\ - \n", &t).await; - chat::send_msg(&t, new_msg.chat_id, &mut new_msg) + b"From: bob@example.net\r\n\ + To: alice@example.org\r\n\ + Subject: message opened\r\n\ + Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: \r\n\ + Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\r\n\ + \r\n\ + \r\n\ + --SNIPP\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + \r\n\ + Read receipts do not guarantee sth. was read.\r\n\ + \r\n\ + \r\n\ + --SNIPP\r\n\ + Content-Type: message/disposition-notification\r\n\ + \r\n\ + Reporting-UA: Delta Chat 1.28.0\r\n\ + Original-Recipient: rfc822;bob@example.com\r\n\ + Final-Recipient: rfc822;bob@example.com\r\n\ + Original-Message-ID: <2893@example.com>\r\n\ + Disposition: manual-action/MDN-sent-automatically; displayed\r\n\ + \r\n", t, bob).await; + chat::send_msg(t, new_msg.chat_id, &mut new_msg) .await .unwrap(); - let mf = MimeFactory::from_msg(&t, new_msg).await.unwrap(); + let mf = MimeFactory::from_msg(t, new_msg).await.unwrap(); // The subject string should not be "Re: message opened" - assert_eq!("Re: Hello, Bob", mf.subject_str(&t).await.unwrap()); + assert_eq!("Re: Hello, Bob", mf.subject_str(t).await.unwrap()); } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -294,9 +290,9 @@ async fn test_mdn_create_encrypted() -> Result<()> { .await?; bob.set_config_bool(Config::MdnsEnabled, true).await?; + // MDN for unencrypted message is not encrypted. let mut msg = Message::new(Viewtype::Text); - msg.param.set_int(Param::SkipAutocrypt, 1); - let chat_alice = alice.create_chat(&bob).await.id; + let chat_alice = alice.create_email_chat(&bob).await.id; let sent = alice.send_msg(chat_alice, &mut msg).await; let rcvd = bob.recv_msg(&sent).await; @@ -311,13 +307,13 @@ async fn test_mdn_create_encrypted() -> Result<()> { let bob_alice_contact = bob.add_or_lookup_contact(&alice).await; assert_eq!(bob_alice_contact.get_authname(), "Alice Exampleorg"); + // MDN for encrypted message is encrypted. let rcvd = tcm.send_recv(&alice, &bob, "Heyho").await; message::markseen_msgs(&bob, vec![rcvd.id]).await?; let mimefactory = MimeFactory::from_mdn(&bob, rcvd.from_id, rcvd.rfc724_mid, vec![]).await?; let rendered_msg = mimefactory.render(&bob).await?; - // When encrypted, the MDN should be encrypted as well assert!(rendered_msg.is_encrypted); assert!(!rendered_msg.message.contains("Bob Examplenet")); assert!(!rendered_msg.message.contains("Alice Exampleorg")); @@ -417,7 +413,7 @@ async fn first_subject_str(t: TestContext) -> String { mf.subject_str(&t).await.unwrap() } -// In `imf_raw`, From has to be bob@example.com, To has to be alice@example.org +// In `imf_raw`, From has to be bob@example.net, To has to be alice@example.org async fn msg_to_subject_str(imf_raw: &[u8]) -> String { let subject_str = msg_to_subject_str_inner(imf_raw, false, false, false).await; @@ -465,48 +461,62 @@ async fn msg_to_subject_str_inner( reply: bool, message_arrives_inbetween: bool, ) -> String { - let t = TestContext::new_alice().await; - let mut new_msg = incoming_msg_to_reply_msg(imf_raw, &t).await; - let incoming_msg = get_chat_msg(&t, new_msg.chat_id, 0, 1).await; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let bob = &tcm.bob().await; + let mut new_msg = incoming_msg_to_reply_msg(imf_raw, t, bob).await; + let incoming_msg = get_chat_msg(t, new_msg.chat_id, 1, 2).await; if delete_original_msg { - incoming_msg.id.trash(&t, false).await.unwrap(); + incoming_msg.id.trash(t, false).await.unwrap(); } if message_arrives_inbetween { - receive_imf( - &t, - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: Bob \n\ - To: alice@example.org\n\ - Subject: Some other, completely unrelated subject\n\ - Message-ID: <3cl4@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - Some other, completely unrelated content\n", - false, + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[t], + b"From: Bob \r\n\ + To: alice@example.org\r\n\ + Subject: Some other, completely unrelated subject\r\n\ + Message-ID: <3cl4@example.com>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + Some other, completely unrelated content\r\n", ) .await .unwrap(); + receive_imf(t, encrypted_msg.as_bytes(), false) + .await + .unwrap(); let arrived_msg = t.get_last_msg().await; assert_eq!(arrived_msg.chat_id, incoming_msg.chat_id); } if reply { - new_msg.set_quote(&t, Some(&incoming_msg)).await.unwrap(); + new_msg.set_quote(t, Some(&incoming_msg)).await.unwrap(); } - chat::send_msg(&t, new_msg.chat_id, &mut new_msg) + chat::send_msg(t, new_msg.chat_id, &mut new_msg) .await .unwrap(); - let mf = MimeFactory::from_msg(&t, new_msg).await.unwrap(); - mf.subject_str(&t).await.unwrap() + let mf = MimeFactory::from_msg(t, new_msg).await.unwrap(); + mf.subject_str(t).await.unwrap() } // Creates a `Message` that replies "Hi" to the incoming email in `imf_raw`. -async fn incoming_msg_to_reply_msg(imf_raw: &[u8], context: &Context) -> Message { - receive_imf(context, imf_raw, false).await.unwrap(); +async fn incoming_msg_to_reply_msg( + imf_raw: &[u8], + context: &TestContext, + from: &TestContext, +) -> Message { + let encrypted_msg = test_utils::encrypt_raw_message(from, &[context], imf_raw) + .await + .unwrap(); + + receive_imf(context, encrypted_msg.as_bytes(), false) + .await + .unwrap(); let chats = Chatlist::try_load(context, 0, None, None).await.unwrap(); @@ -522,30 +532,31 @@ async fn incoming_msg_to_reply_msg(imf_raw: &[u8], context: &Context) -> Message #[tokio::test(flavor = "multi_thread", worker_threads = 2)] // This test could still be extended async fn test_render_reply() { - let t = TestContext::new_alice().await; - let context = &t; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let charlie = &tcm.charlie().await; let mut msg = incoming_msg_to_reply_msg( - b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: Charlie \n\ - To: alice@example.org\n\ - Subject: Chat: hello\n\ - Chat-Version: 1.0\n\ - Message-ID: <2223@example.com>\n\ - Date: Sun, 22 Mar 2020 22:37:56 +0000\n\ - \n\ - hello\n", - context, + b"From: Charlie \r\n\ + To: alice@example.org\r\n\ + Subject: Chat: hello\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: <2223@example.com>\r\n\ + Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\ + \r\n\ + hello\r\n", + t, + charlie, ) .await; - chat::send_msg(&t, msg.chat_id, &mut msg).await.unwrap(); + chat::send_msg(t, msg.chat_id, &mut msg).await.unwrap(); - let mimefactory = MimeFactory::from_msg(&t, msg).await.unwrap(); + let mimefactory = MimeFactory::from_msg(t, msg).await.unwrap(); let recipients = mimefactory.recipients(); - assert_eq!(recipients, vec!["charlie@example.com"]); + assert_eq!(recipients, vec!["charlie@example.net"]); - let rendered_msg = mimefactory.render(context).await.unwrap(); + let rendered_msg = mimefactory.render(t).await.unwrap(); let mail = mailparse::parse_mail(rendered_msg.message.as_bytes()).unwrap(); assert_eq!( @@ -557,7 +568,7 @@ async fn test_render_reply() { "1.0" ); - let _mime_msg = MimeMessage::from_bytes(context, rendered_msg.message.as_bytes()) + let _mime_msg = MimeMessage::from_bytes(t, rendered_msg.message.as_bytes()) .await .unwrap(); } diff --git a/src/mimeparser/mimeparser_tests.rs b/src/mimeparser/mimeparser_tests.rs index ee67f48eb..476853fdb 100644 --- a/src/mimeparser/mimeparser_tests.rs +++ b/src/mimeparser/mimeparser_tests.rs @@ -12,7 +12,7 @@ use crate::{ message::{MessageState, MessengerMessage}, receive_imf::receive_imf, securejoin::QrInvite, - test_utils::{TestContext, TestContextManager}, + test_utils::{self, TestContext, TestContextManager}, tools::time, }; @@ -1503,96 +1503,89 @@ Some reply // Test that WantsMdn parameter is not set on outgoing messages. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_outgoing_wants_mdn() -> Result<()> { - let alice = TestContext::new_alice().await; - let bob = TestContext::new_bob().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let alice2 = &tcm.alice().await; + let bob = &tcm.bob().await; - let raw = br"Date: Thu, 28 Jan 2021 00:26:57 +0000 -Chat-Version: 1.0\n\ -Message-ID: -To: Bob -From: Alice -Subject: subject -Chat-Disposition-Notification-To: alice@example.org - -Message. -"; + let chat_id = alice.create_chat(bob).await.id; + let sent = alice.send_text(chat_id, "Message.").await; // Bob receives message. - receive_imf(&bob, raw, false).await?; - let msg = bob.get_last_msg().await; + let bob_msg = bob.recv_msg(&sent).await; // Message is incoming. - assert!(msg.param.get_bool(Param::WantsMdn).unwrap()); + assert!(bob_msg.param.get_bool(Param::WantsMdn).unwrap()); // Alice receives copy-to-self. - receive_imf(&alice, raw, false).await?; - let msg = alice.get_last_msg().await; + let alice2_msg = alice2.recv_msg(&sent).await; // Message is outgoing, don't send read receipt to self. - assert!(msg.param.get_bool(Param::WantsMdn).is_none()); + assert!(alice2_msg.param.get_bool(Param::WantsMdn).is_none()); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_ignore_read_receipt_to_self() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; // Alice receives BCC-self copy of a message sent to Bob. - receive_imf( - &alice, - "Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: alice@example.org\n\ - To: bob@example.net\n\ - Subject: foo\n\ - Message-ID: first@example.com\n\ - Chat-Version: 1.0\n\ - Chat-Disposition-Notification-To: alice@example.org\n\ - Date: Sun, 22 Mar 2020 22:37:57 +0000\n\ - \n\ - hello\n" + let encrypted_message = test_utils::encrypt_raw_message( + alice, + &[bob], + "From: alice@example.org\r\n\ + To: bob@example.net\r\n\ + Subject: foo\r\n\ + Message-ID: first@example.com\r\n\ + Chat-Version: 1.0\r\n\ + Chat-Disposition-Notification-To: alice@example.org\r\n\ + Date: Sun, 22 Mar 2020 22:37:57 +0000\r\n\ + \r\n\ + hello\r\n" .as_bytes(), - false, ) .await?; + receive_imf(alice, encrypted_message.as_bytes(), false).await?; let msg = alice.get_last_msg().await; assert_eq!(msg.state, MessageState::OutDelivered); - // Due to a bug in the old version running on the other device, Alice receives a read - // receipt from self. - receive_imf( - &alice, - "Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\ - From: alice@example.org\n\ - To: alice@example.org\n\ - Subject: message opened\n\ - Date: Sun, 22 Mar 2020 23:37:57 +0000\n\ - Chat-Version: 1.0\n\ - Message-ID: second@example.com\n\ - Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\n\ - \n\ - \n\ - --SNIPP\n\ - Content-Type: text/plain; charset=utf-8\n\ - \n\ - Read receipts do not guarantee sth. was read.\n\ - \n\ - \n\ - --SNIPP\n\ - Content-Type: message/disposition-notification\n\ - \n\ - Original-Recipient: rfc822;bob@example.com\n\ - Final-Recipient: rfc822;bob@example.com\n\ - Original-Message-ID: \n\ - Disposition: manual-action/MDN-sent-automatically; displayed\n\ - \n\ - \n\ - --SNIPP--" - .as_bytes(), - false, - ) - .await?; + // Alice receives a read receipt from self. + // + // This should mark the message as seen, i.e. not counted as fresh, + // but not "read" (having double checkmark in the UI). + let encrypted_message = test_utils::encrypt_raw_message( + alice, + &[alice], + "From: alice@example.org\r\n\ + To: alice@example.org\r\n\ + Subject: message opened\r\n\ + Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\ + Chat-Version: 1.0\r\n\ + Message-ID: second@example.com\r\n\ + Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\r\n\ + \r\n\ + \r\n\ + --SNIPP\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + \r\n\ + Read receipts do not guarantee sth. was read.\r\n\ + \r\n\ + \r\n\ + --SNIPP\r\n\ + Content-Type: message/disposition-notification\r\n\ + \r\n\ + Original-Recipient: rfc822;bob@example.com\r\n\ + Final-Recipient: rfc822;bob@example.com\r\n\ + Original-Message-ID: \r\n\ + Disposition: manual-action/MDN-sent-automatically; displayed\r\n\ + \r\n\ + \r\n\ + --SNIPP--".as_bytes()).await?; + receive_imf(alice, encrypted_message.as_bytes(), false).await?; // Check that the state has not changed to `MessageState::OutMdnRcvd`. - let msg = Message::load_from_db(&alice, msg.id).await?; + let msg = Message::load_from_db(alice, msg.id).await?; assert_eq!(msg.state, MessageState::OutDelivered); Ok(()) @@ -1604,7 +1597,8 @@ async fn test_ignore_read_receipt_to_self() -> Result<()> { /// recognize it as MDN nevertheless to avoid displaying it in the chat as normal message. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_ms_exchange_mdn() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let t = tcm.alice().await; let original = include_bytes!("../../test-data/message/ms_exchange_report_original_message.eml"); @@ -1700,17 +1694,24 @@ Content-Disposition: reaction\n\ #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_jpeg_as_application_octet_stream() -> Result<()> { - let context = TestContext::new_alice().await; - let raw = include_bytes!("../../test-data/message/jpeg-as-application-octet-stream.eml"); + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let encrypted_msg = test_utils::encrypt_raw_message( + alice, + &[bob], + include_bytes!("../../test-data/message/jpeg-as-application-octet-stream.eml"), + ) + .await?; - let msg = MimeMessage::from_bytes(&context.ctx, &raw[..]) + let msg = MimeMessage::from_bytes(bob, encrypted_msg.as_bytes()) .await .unwrap(); assert_eq!(msg.parts.len(), 1); assert_eq!(msg.parts[0].typ, Viewtype::Image); - receive_imf(&context, &raw[..], false).await?; - let msg = context.get_last_msg().await; + receive_imf(alice, encrypted_msg.as_bytes(), false).await?; + let msg = alice.get_last_msg().await; assert_eq!(msg.get_viewtype(), Viewtype::Image); Ok(()) @@ -2065,19 +2066,24 @@ async fn test_receive_signed_only() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_huge_image_becomes_file() -> Result<()> { - let t = TestContext::new_alice().await; - let msg_id = receive_imf( - &t, + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[alice], include_bytes!("../../test-data/message/image_huge_64M.eml"), - false, ) - .await? - .unwrap() - .msg_ids[0]; - let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap(); + .await?; + + let msg_id = receive_imf(alice, encrypted_msg.as_bytes(), false) + .await? + .unwrap() + .msg_ids[0]; + let msg = Message::load_from_db(alice, msg_id).await.unwrap(); // Huge image should be treated as file: assert_eq!(msg.viewtype, Viewtype::File); - assert!(msg.get_file(&t).is_some()); + assert!(msg.get_file(alice).is_some()); assert_eq!(msg.get_filename().unwrap(), "huge_image.png"); assert_eq!(msg.get_filemime().unwrap(), "image/png"); // File has no width or height @@ -2088,19 +2094,24 @@ async fn test_huge_image_becomes_file() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_4k_image_stays_image() -> Result<()> { - let t = TestContext::new_alice().await; - let msg_id = receive_imf( - &t, + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let encrypted_msg = test_utils::encrypt_raw_message( + bob, + &[alice], include_bytes!("../../test-data/message/image_4k.eml"), - false, ) - .await? - .unwrap() - .msg_ids[0]; - let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap(); + .await?; + + let msg_id = receive_imf(alice, encrypted_msg.as_bytes(), false) + .await? + .unwrap() + .msg_ids[0]; + let msg = Message::load_from_db(alice, msg_id).await.unwrap(); // 4K image should be treated as image: assert_eq!(msg.viewtype, Viewtype::Image); - assert!(msg.get_file(&t).is_some()); + assert!(msg.get_file(alice).is_some()); assert_eq!(msg.get_filename().unwrap(), "4k_image.png"); assert_eq!(msg.get_filemime().unwrap(), "image/png"); assert_eq!(msg.param.get_int(Param::Width).unwrap_or_default(), 3840); diff --git a/src/reaction.rs b/src/reaction.rs index b459a132e..76170a04b 100644 --- a/src/reaction.rs +++ b/src/reaction.rs @@ -335,18 +335,17 @@ impl Chat { #[cfg(test)] mod tests { - use deltachat_contact_tools::ContactAddress; - use super::*; use crate::chat::{forward_msgs, get_chat_msgs, marknoticed_chat, send_text_msg}; use crate::chatlist::Chatlist; use crate::config::Config; - use crate::contact::{Contact, Origin}; + use crate::contact::Contact; use crate::key::{load_self_public_key, load_self_secret_key}; use crate::message::{MessageState, Viewtype, delete_msgs, markseen_msgs}; use crate::pgp::{SeipdVersion, pk_encrypt}; use crate::receive_imf::receive_imf; use crate::sql::housekeeping; + use crate::test_utils; use crate::test_utils::E2EE_INFO_MSGS; use crate::test_utils::TestContext; use crate::test_utils::TestContextManager; @@ -386,59 +385,54 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_receive_reaction() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; // Alice receives BCC-self copy of a message sent to Bob. - receive_imf( - &alice, - "To: bob@example.net\n\ -From: alice@example.org\n\ -Date: Today, 29 February 2021 00:00:00 -800\n\ -Message-ID: 12345@example.org\n\ -Subject: Meeting\n\ -\n\ -Can we chat at 1pm pacific, today?" - .as_bytes(), - false, + let encrypted_message = test_utils::encrypt_raw_message( + alice, + &[alice, bob], + b"To: bob@example.net\r\n\ +From: alice@example.org\r\n\ +Date: Today, 29 February 2021 00:00:00 -800\r\n\ +Message-ID: 12345@example.org\r\n\ +Subject: Meeting\r\n\ +\r\n\ +Can we chat at 1pm pacific, today?", ) .await?; + receive_imf(alice, encrypted_message.as_bytes(), false).await?; let msg = alice.get_last_msg().await; assert_eq!(msg.state, MessageState::OutDelivered); - let reactions = get_msg_reactions(&alice, msg.id).await?; + let reactions = get_msg_reactions(alice, msg.id).await?; let contacts = reactions.contacts(); assert_eq!(contacts.len(), 0); - let bob_id = Contact::add_or_lookup( - &alice, - "", - &ContactAddress::new("bob@example.net")?, - Origin::ManuallyCreated, - ) - .await? - .0; + let bob_id = alice.add_or_lookup_contact_id(bob).await; let bob_reaction = reactions.get(bob_id); assert!(bob_reaction.is_empty()); // Bob has not reacted to message yet. // Alice receives reaction to her message from Bob. - receive_imf( - &alice, - "To: alice@example.org\n\ -From: bob@example.net\n\ -Date: Today, 29 February 2021 00:00:10 -800\n\ -Message-ID: 56789@example.net\n\ -In-Reply-To: 12345@example.org\n\ -Subject: Meeting\n\ -Mime-Version: 1.0 (1.0)\n\ -Content-Type: text/plain; charset=utf-8\n\ -Content-Disposition: reaction\n\ -\n\ + test_utils::receive_encrypted_imf( + alice, + bob, + "To: alice@example.org\r\n\ +From: bob@example.net\r\n\ +Date: Today, 29 February 2021 00:00:10 -800\r\n\ +Message-ID: 56789@example.net\r\n\ +In-Reply-To: 12345@example.org\r\n\ +Subject: Meeting\r\n\ +Mime-Version: 1.0 (1.0)\r\n\ +Content-Type: text/plain; charset=utf-8\r\n\ +Content-Disposition: reaction\r\n\ +\r\n\ \u{1F44D}" .as_bytes(), - false, ) .await?; - let reactions = get_msg_reactions(&alice, msg.id).await?; + let reactions = get_msg_reactions(alice, msg.id).await?; assert_eq!(reactions.to_string(), "👍1"); let contacts = reactions.contacts(); @@ -451,8 +445,9 @@ Content-Disposition: reaction\n\ assert_eq!(bob_reaction.as_str(), "👍"); // Alice receives reaction to her message from Bob with a footer. - receive_imf( - &alice, + test_utils::receive_encrypted_imf( + alice, + bob, "To: alice@example.org\n\ From: bob@example.net\n\ Date: Today, 29 February 2021 00:00:10 -800\n\ @@ -469,16 +464,16 @@ Content-Disposition: reaction\n\ _______________________________________________\n\ Here's my footer -- bob@example.net" .as_bytes(), - false, ) .await?; - let reactions = get_msg_reactions(&alice, msg.id).await?; + let reactions = get_msg_reactions(alice, msg.id).await?; assert_eq!(reactions.to_string(), "😀1"); // Alice receives a message with reaction to her message from Bob. - let msg_bob = receive_imf( - &alice, + let msg_bob = test_utils::receive_encrypted_imf( + alice, + bob, "To: alice@example.org\n\ From: bob@example.net\n\ Date: Today, 29 February 2021 00:00:10 -800\n\ @@ -502,18 +497,16 @@ Content-Disposition: reaction\n\ \n\ --YiEDa0DAkWCtVeE4--" .as_bytes(), - false, ) - .await? - .unwrap(); - let msg_bob = Message::load_from_db(&alice, msg_bob.msg_ids[0]).await?; + .await?; + let msg_bob = Message::load_from_db(alice, msg_bob.msg_ids[0]).await?; assert_eq!(msg_bob.from_id, bob_id); assert_eq!(msg_bob.chat_id, msg.chat_id); assert_eq!(msg_bob.viewtype, Viewtype::Text); assert_eq!(msg_bob.state, MessageState::InFresh); assert_eq!(msg_bob.hidden, false); assert_eq!(msg_bob.text, "Reply + reaction"); - let reactions = get_msg_reactions(&alice, msg.id).await?; + let reactions = get_msg_reactions(alice, msg.id).await?; assert_eq!(reactions.to_string(), "👍1"); Ok(()) diff --git a/src/receive_imf/receive_imf_tests.rs b/src/receive_imf/receive_imf_tests.rs index f1aa32aba..04c292237 100644 --- a/src/receive_imf/receive_imf_tests.rs +++ b/src/receive_imf/receive_imf_tests.rs @@ -15,6 +15,7 @@ use crate::imap::prefetch_should_download; use crate::imex::{ImexMode, imex}; use crate::key; use crate::securejoin::get_securejoin_qr; +use crate::test_utils; use crate::test_utils::{ TestContext, TestContextManager, alice_keypair, get_chat_msg, mark_as_verified, }; @@ -1832,47 +1833,57 @@ async fn test_alias_support_answer_from_dc_chat_group() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_dont_assign_to_trash_by_parent() { - let t = TestContext::new_alice().await; - println!("\n========= Receive a message =========="); - receive_imf( - &t, - b"From: Nu Bar \n\ - To: alice@example.org, bob@example.org\n\ - Subject: Hi\n\ - Message-ID: <4444@example.org>\n\ - \n\ - hello\n", - false, + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let charlie = &tcm.charlie().await; + + tcm.section("Receive a message"); + let encrypted_message = test_utils::encrypt_raw_message( + charlie, + &[alice, bob], + b"From: Charlie \r\n\ + To: alice@example.org, bob@example.org\r\n\ + Subject: Hi\r\n\ + Message-ID: <4444@example.org>\r\n\ + \r\n\ + hello\r\n", ) .await .unwrap(); - let chat_id = t.get_last_msg().await.chat_id; - chat_id.accept(&t).await.unwrap(); - let msg = get_chat_msg(&t, chat_id, 0, 1).await; // Make sure that the message is actually in the chat + receive_imf(alice, encrypted_message.as_bytes(), false) + .await + .unwrap(); + let chat_id = alice.get_last_msg().await.chat_id; + chat_id.accept(alice).await.unwrap(); + let msg = get_chat_msg(alice, chat_id, 0, 1).await; // Make sure that the message is actually in the chat assert!(!msg.chat_id.is_special()); assert_eq!(msg.text, "Hi – hello"); - println!("\n========= Delete the message =========="); - msg.id.trash(&t, false).await.unwrap(); + tcm.section("Delete the message"); + msg.id.trash(alice, false).await.unwrap(); - let msgs = chat::get_chat_msgs(&t.ctx, chat_id).await.unwrap(); + let msgs = chat::get_chat_msgs(alice, chat_id).await.unwrap(); assert_eq!(msgs.len(), 0); - println!("\n========= Receive a message that is a reply to the deleted message =========="); - receive_imf( - &t, - b"From: Nu Bar \n\ - To: alice@example.org, bob@example.org\n\ - Subject: Re: Hi\n\ - Message-ID: <5555@example.org>\n\ - In-Reply-To: <4444@example.org\n\ - \n\ - Reply\n", - false, + tcm.section("Receive a message that is a reply to the deleted message"); + let encrypted_message = test_utils::encrypt_raw_message( + charlie, + &[alice, bob], + b"From: Charlie \r\n\ + To: alice@example.org, bob@example.org\r\n\ + Subject: Re: Hi\r\n\ + Message-ID: <5555@example.org>\r\n\ + In-Reply-To: <4444@example.org\r\n\ + \r\n\ + Reply\r\n", ) .await .unwrap(); - let msg = t.get_last_msg().await; + receive_imf(alice, encrypted_message.as_bytes(), false) + .await + .unwrap(); + let msg = alice.get_last_msg().await; assert!(!msg.chat_id.is_special()); // Esp. check that the chat_id is not TRASH assert_eq!(msg.text, "Reply"); } @@ -1882,10 +1893,11 @@ async fn test_dont_show_all_outgoing_msgs_in_self_chat() { // Regression test for : // Some servers add a `Bcc: ` header, which caused all outgoing messages to // be shown in the self-chat. - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; receive_imf( - &t, + t, b"Bcc: alice@example.org Received: from [127.0.0.1] Subject: s @@ -2222,11 +2234,12 @@ sig thursday", #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_chat_assignment_private_classical_reply() { + let mut tcm = TestContextManager::new(); for outgoing_is_classical in &[true, false] { - let t = TestContext::new_alice().await; + let t = &tcm.alice().await; receive_imf( - &t, + t, format!( r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) Subject: =?utf-8?q?single_reply-to?= @@ -2263,12 +2276,12 @@ Message-ID: " "Hello, I've just created the group \"single reply-to\" for us." } ); - let group_chat = Chat::load_from_db(&t, group_msg.chat_id).await.unwrap(); + let group_chat = Chat::load_from_db(t, group_msg.chat_id).await.unwrap(); assert_eq!(group_chat.typ, Chattype::Group); assert_eq!(group_chat.name, "single reply-to"); receive_imf( - &t, + t, format!( r#"Subject: Re: single reply-to To: "Alice" @@ -2297,7 +2310,7 @@ Private reply"#, let private_msg = t.get_last_msg().await; assert_eq!(private_msg.text, "Private reply"); - let private_chat = Chat::load_from_db(&t, private_msg.chat_id).await.unwrap(); + let private_chat = Chat::load_from_db(t, private_msg.chat_id).await.unwrap(); assert_eq!(private_chat.typ, Chattype::Single); assert_ne!(private_msg.chat_id, group_msg.chat_id); } @@ -2305,16 +2318,16 @@ Private reply"#, #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_chat_assignment_private_chat_reply() { + let mut tcm = TestContextManager::new(); for (outgoing_is_classical, outgoing_has_multiple_recipients) in &[(true, true), (false, true), (false, false)] { - let t = TestContext::new_alice().await; + let t = &tcm.alice().await; receive_imf( - &t, + t, format!( - r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) -Subject: =?utf-8?q?single_reply-to?= + r#"Subject: =?utf-8?q?single_reply-to?= {} Date: Fri, 28 May 2021 10:15:05 +0000 To: Bob , Charlie {} @@ -2352,12 +2365,12 @@ Message-ID: " "Hello, I've just created the group \"single reply-to\" for us." } ); - let group_chat = Chat::load_from_db(&t, group_msg.chat_id).await.unwrap(); + let group_chat = Chat::load_from_db(t, group_msg.chat_id).await.unwrap(); assert_eq!(group_chat.typ, Chattype::Group); assert_eq!(group_chat.name, "single reply-to"); receive_imf( - &t, + t, format!( r#"Subject: =?utf-8?q?Re=3A_single_reply-to?= MIME-Version: 1.0 @@ -2392,7 +2405,7 @@ Sent with my Delta Chat Messenger: https://delta.chat let private_msg = t.get_last_msg().await; assert_eq!(private_msg.text, "Private reply"); - let private_chat = Chat::load_from_db(&t, private_msg.chat_id).await.unwrap(); + let private_chat = Chat::load_from_db(t, private_msg.chat_id).await.unwrap(); assert_eq!(private_chat.typ, Chattype::Single); assert_ne!(private_msg.chat_id, group_msg.chat_id); } @@ -2400,11 +2413,12 @@ Sent with my Delta Chat Messenger: https://delta.chat #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_chat_assignment_nonprivate_classical_reply() { + let mut tcm = TestContextManager::new(); for outgoing_is_classical in &[true, false] { - let t = TestContext::new_alice().await; + let t = &tcm.alice().await; receive_imf( - &t, + t, format!( r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) Subject: =?utf-8?q?single_reply-to?= @@ -2440,13 +2454,13 @@ Message-ID: " "Hello, I've just created the group \"single reply-to\" for us." } ); - let group_chat = Chat::load_from_db(&t, group_msg.chat_id).await.unwrap(); + let group_chat = Chat::load_from_db(t, group_msg.chat_id).await.unwrap(); assert_eq!(group_chat.typ, Chattype::Group); assert_eq!(group_chat.name, "single reply-to"); // =============== Receive another outgoing message and check that it is put into the same chat =============== receive_imf( - &t, + t, format!( r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) Subject: Out subj @@ -2471,13 +2485,13 @@ Outgoing reply to all"#, let reply = t.get_last_msg().await; assert_eq!(reply.text, "Out subj – Outgoing reply to all"); - let reply_chat = Chat::load_from_db(&t, reply.chat_id).await.unwrap(); + let reply_chat = Chat::load_from_db(t, reply.chat_id).await.unwrap(); assert_eq!(reply_chat.typ, Chattype::Group); assert_eq!(reply.chat_id, group_msg.chat_id); // =============== Receive an incoming message and check that it is put into the same chat =============== receive_imf( - &t, + t, br#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) Subject: In subj To: "Bob" , "Claire" @@ -2494,7 +2508,7 @@ Reply to all"#, let reply = t.get_last_msg().await; assert_eq!(reply.text, "In subj – Reply to all"); - let reply_chat = Chat::load_from_db(&t, reply.chat_id).await.unwrap(); + let reply_chat = Chat::load_from_db(t, reply.chat_id).await.unwrap(); assert_eq!(reply_chat.typ, Chattype::Group); assert_eq!(reply.chat_id, group_msg.chat_id); } @@ -2743,7 +2757,9 @@ async fn get_parent_message( #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_get_parent_message() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; let mime = br#"Subject: First Message-ID: first@example.net @@ -2752,8 +2768,8 @@ From: Bob Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no First."#; - receive_imf(&t, mime, false).await?; - let first = t.get_last_msg().await; + test_utils::receive_encrypted_imf(alice, bob, mime).await?; + let first = alice.get_last_msg().await; let mime = br#"Subject: Second Message-ID: second@example.net To: Alice @@ -2761,8 +2777,8 @@ From: Bob Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no First."#; - receive_imf(&t, mime, false).await?; - let second = t.get_last_msg().await; + test_utils::receive_encrypted_imf(alice, bob, mime).await?; + let second = alice.get_last_msg().await; let mime = br#"Subject: Third Message-ID: third@example.net To: Alice @@ -2770,8 +2786,8 @@ From: Bob Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no First."#; - receive_imf(&t, mime, false).await?; - let third = t.get_last_msg().await; + test_utils::receive_encrypted_imf(alice, bob, mime).await?; + let third = alice.get_last_msg().await; let mime = br#"Subject: Message with references. Message-ID: second@example.net @@ -2782,21 +2798,22 @@ References: Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no Message with references."#; - let mime_parser = MimeMessage::from_bytes(&t, &mime[..]).await?; + let encrypted_mime = test_utils::encrypt_raw_message(bob, &[alice], mime).await?; + let mime_parser = MimeMessage::from_bytes(alice, encrypted_mime.as_bytes()).await?; - let parent = get_parent_message(&t, &mime_parser).await?.unwrap(); + let parent = get_parent_message(alice, &mime_parser).await?.unwrap(); assert_eq!(parent.id, first.id); - message::delete_msgs(&t, &[first.id]).await?; - let parent = get_parent_message(&t, &mime_parser).await?.unwrap(); + message::delete_msgs(alice, &[first.id]).await?; + let parent = get_parent_message(alice, &mime_parser).await?.unwrap(); assert_eq!(parent.id, second.id); - message::delete_msgs(&t, &[second.id]).await?; - let parent = get_parent_message(&t, &mime_parser).await?.unwrap(); + message::delete_msgs(alice, &[second.id]).await?; + let parent = get_parent_message(alice, &mime_parser).await?.unwrap(); assert_eq!(parent.id, third.id); - message::delete_msgs(&t, &[third.id]).await?; - let parent = get_parent_message(&t, &mime_parser).await?; + message::delete_msgs(alice, &[third.id]).await?; + let parent = get_parent_message(alice, &mime_parser).await?; assert!(parent.is_none()); Ok(()) @@ -3022,7 +3039,7 @@ async fn test_auto_accept_for_bots() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_auto_accept_group_for_bots() -> Result<()> { let t = TestContext::new_alice().await; - t.set_config(Config::Bot, Some("1")).await.unwrap(); + t.set_config_bool(Config::Bot, true).await.unwrap(); let msg = load_imf_email(&t, GRP_MAIL).await; let chat = chat::Chat::load_from_db(&t, msg.chat_id).await?; @@ -3384,7 +3401,8 @@ async fn test_prefer_encrypt_mutual_if_encrypted() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_forged_from_and_no_valid_signatures() -> Result<()> { - let t = &TestContext::new_bob().await; + let mut tcm = TestContextManager::new(); + let t = &tcm.bob().await; let raw = include_bytes!("../../test-data/message/thunderbird_encrypted_signed.eml"); let received_msg = receive_imf(t, raw, false).await?.unwrap(); @@ -3394,7 +3412,7 @@ async fn test_forged_from_and_no_valid_signatures() -> Result<()> { assert!(!msg.chat_id.is_trash()); assert!(!msg.get_showpadlock()); - let t = &TestContext::new_bob().await; + let t = &tcm.bob().await; let raw = String::from_utf8(raw.to_vec())?.replace("alice@example.org", "clarice@example.org"); let received_msg = receive_imf(t, raw.as_bytes(), false).await?.unwrap(); assert!(received_msg.chat_id.is_trash()); @@ -3508,18 +3526,20 @@ async fn test_messed_up_message_id() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_big_forwarded_with_big_attachment() -> Result<()> { - let t = &TestContext::new_bob().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; let raw = include_bytes!("../../test-data/message/big_forwarded_with_big_attachment.eml"); - let rcvd = receive_imf(t, raw, false).await?.unwrap(); + let rcvd = test_utils::receive_encrypted_imf(bob, alice, raw).await?; assert_eq!(rcvd.msg_ids.len(), 3); - let msg = Message::load_from_db(t, rcvd.msg_ids[0]).await?; + let msg = Message::load_from_db(bob, rcvd.msg_ids[0]).await?; assert_eq!(msg.get_viewtype(), Viewtype::Text); assert_eq!(msg.get_text(), "Hello!"); assert!(!msg.has_html()); - let msg = Message::load_from_db(t, rcvd.msg_ids[1]).await?; + let msg = Message::load_from_db(bob, rcvd.msg_ids[1]).await?; assert_eq!(msg.get_viewtype(), Viewtype::Text); assert!( msg.get_text() @@ -3528,10 +3548,10 @@ async fn test_big_forwarded_with_big_attachment() -> Result<()> { assert!(msg.get_text().ends_with("[...]")); assert!(!msg.has_html()); - let msg = Message::load_from_db(t, rcvd.msg_ids[2]).await?; + let msg = Message::load_from_db(bob, rcvd.msg_ids[2]).await?; assert_eq!(msg.get_viewtype(), Viewtype::File); assert!(msg.has_html()); - let html = msg.id.get_html(t).await?.unwrap(); + let html = msg.id.get_html(bob).await?.unwrap(); let tail = html .split_once("Hello!") .unwrap() @@ -5129,10 +5149,12 @@ async fn test_recv_outgoing_msg_no_intended_recipient_fingerprint() -> Result<() #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_sanitize_filename_in_received() -> Result<()> { - let alice = &TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; let raw = b"Message-ID: Mr.XA6y3og8-az.WGbH9_dNcQx@testr -To: -From: \"=?utf-8?q??=\" +To: +From: \"=?utf-8?q??=\" Content-Type: multipart/mixed; boundary=\"mwkNRwaJw1M5n2xcr2ODfAqvTjcj9Z\" @@ -5151,7 +5173,7 @@ PGh0bWw+PGJvZHk+dGV4dDwvYm9keT5kYXRh --mwkNRwaJw1M5n2xcr2ODfAqvTjcj9Z--"; - let msg = receive_imf(alice, raw, false).await?.unwrap(); + let msg = test_utils::receive_encrypted_imf(alice, bob, raw).await?; let msg = Message::load_from_db(alice, msg.msg_ids[0]).await?; assert_eq!(msg.get_filename().unwrap(), "test.HTML"); diff --git a/src/test_utils.rs b/src/test_utils.rs index ee428675b..d158bc758 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -20,6 +20,7 @@ use pretty_assertions::assert_eq; use tempfile::{TempDir, tempdir}; use tokio::runtime::Handle; use tokio::{fs, task}; +use uuid::Uuid; use crate::chat::{ self, Chat, ChatId, ChatIdBlocked, MessageListOptions, add_to_chat_contacts_table, create_group, @@ -32,13 +33,15 @@ use crate::contact::{ Contact, ContactId, Modifier, Origin, import_vcard, make_vcard, mark_contact_id_as_verified, }; use crate::context::Context; +use crate::e2ee::EncryptHelper; use crate::events::{Event, EventEmitter, EventType, Events}; use crate::key::{self, DcKey, self_fingerprint}; use crate::log::warn; use crate::login_param::EnteredLoginParam; use crate::message::{Message, MessageState, MsgId, update_msg_state}; use crate::mimeparser::{MimeMessage, SystemMessage}; -use crate::receive_imf::receive_imf; +use crate::pgp::SeipdVersion; +use crate::receive_imf::{ReceivedMsg, receive_imf}; use crate::securejoin::{get_securejoin_qr, join_securejoin}; use crate::smtp::msg_has_pending_smtp_job; use crate::stock_str::StockStrings; @@ -831,10 +834,7 @@ ORDER BY id" /// Receive a message using the `receive_imf()` pipeline. This is similar /// to `recv_msg()`, but doesn't assume that the message is shown in the chat. - pub async fn recv_msg_opt( - &self, - msg: &SentMessage<'_>, - ) -> Option { + pub async fn recv_msg_opt(&self, msg: &SentMessage<'_>) -> Option { receive_imf(self, msg.payload().as_bytes(), false) .await .unwrap() @@ -1231,6 +1231,68 @@ ORDER BY id" } } +pub async fn encrypt_raw_message( + context: &Context, + receivers: &[&TestContext], + payload: &[u8], +) -> Result { + let encryption_helper = EncryptHelper::new(context).await?; + let mut encryption_keyring = vec![encryption_helper.public_key.clone()]; + + for receiver in receivers { + encryption_keyring.push(key::load_self_public_key(receiver).await?); + } + + let from = context.get_primary_self_addr().await?; + let compress = false; + + let mut cleartext = format!("Autocrypt: {}", encryption_helper.get_aheader()).into_bytes(); + cleartext.extend_from_slice(b"\r\n"); + cleartext.extend_from_slice(payload); + let encrypted_payload = encryption_helper + .encrypt_raw( + context, + encryption_keyring, + cleartext, + compress, + SeipdVersion::V2, + ) + .await?; + let boundary = Uuid::new_v4(); + + let res = format!( +"Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"{boundary}\"\r +MIME-Version: 1.0\r +From: {from}\r +Subject: [...]\r +\r +\r +--{boundary} +Content-Type: application/pgp-encrypted\r +\r +Version: 1\r +\r +--{boundary}\r +Content-Type: application/octet-stream\r +\r +{encrypted_payload} +--{boundary}--\r +"); + Ok(res) +} + +pub async fn receive_encrypted_imf( + context: &TestContext, + from: &TestContext, + imf_raw: &[u8], +) -> Result { + let encrypted_message = encrypt_raw_message(from, &[context], imf_raw).await?; + let received_msg = receive_imf(context, encrypted_message.as_bytes(), false) + .await? + .unwrap(); + Ok(received_msg) +} + impl Deref for TestContext { type Target = Context; diff --git a/src/tests/verified_chats.rs b/src/tests/verified_chats.rs index 055fe7787..1ee6a0b48 100644 --- a/src/tests/verified_chats.rs +++ b/src/tests/verified_chats.rs @@ -13,6 +13,7 @@ use crate::mimeparser::SystemMessage; use crate::receive_imf::receive_imf; use crate::securejoin::{get_securejoin_qr, join_securejoin}; use crate::stock_str; +use crate::test_utils; use crate::test_utils::{ E2EE_INFO_MSGS, TestContext, TestContextManager, get_chat_msg, mark_as_verified, }; @@ -172,32 +173,32 @@ async fn test_missing_key_reexecute_securejoin() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_degrade_verified_oneonone_chat() -> Result<()> { let mut tcm = TestContextManager::new(); - let alice = tcm.alice().await; - let bob = tcm.bob().await; + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - mark_as_verified(&alice, &bob).await; + mark_as_verified(alice, bob).await; - let alice_chat = alice.create_chat(&bob).await; + let alice_chat = alice.create_chat(bob).await; receive_imf( - &alice, - b"From: Bob \n\ - To: alice@example.org\n\ - Message-ID: <1234-2@example.org>\n\ - \n\ - hello\n", + alice, + b"From: Bob \r\n\ + To: alice@example.org\r\n\ + Message-ID: <1234-2@example.net>\r\n\ + \r\n\ + hello\r\n", false, ) .await?; - let msg0 = get_chat_msg(&alice, alice_chat.id, 0, 1).await; - let enabled = stock_str::messages_e2ee_info_msg(&alice); + let msg0 = get_chat_msg(alice, alice_chat.id, 0, 1).await; + let enabled = stock_str::messages_e2ee_info_msg(alice); assert_eq!(msg0.text, enabled); assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatE2ee); - let email_chat = alice.get_email_chat(&bob).await; - assert!(!email_chat.is_encrypted(&alice).await?); - let email_msg = get_chat_msg(&alice, email_chat.id, 0, 1).await; + let email_chat = alice.get_email_chat(bob).await; + assert!(!email_chat.is_encrypted(alice).await?); + let email_msg = get_chat_msg(alice, email_chat.id, 0, 1).await; assert_eq!(email_msg.text, "hello".to_string()); assert!(!email_msg.is_system_message()); @@ -209,32 +210,32 @@ async fn test_degrade_verified_oneonone_chat() -> Result<()> { /// This test tests that the messages are still in the right order. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_old_message_4() -> Result<()> { - let alice = TestContext::new_alice().await; - let msg_incoming = receive_imf( - &alice, - b"From: Bob \n\ - To: alice@example.org\n\ - Message-ID: <1234-2-3@example.org>\n\ - Date: Sun, 08 Dec 2019 19:00:27 +0000\n\ - \n\ - Thanks, Alice!\n", - true, + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + let msg_incoming = test_utils::receive_encrypted_imf( + alice, + bob, + b"From: Bob \r\n\ + To: alice@example.org\r\n\ + Message-ID: <1234-2-3@example.org>\r\n\ + Date: Sun, 08 Dec 2019 19:00:27 +0000\r\n\ + \r\n\ + Thanks, Alice!\r\n", ) - .await? - .unwrap(); + .await?; - let msg_sent = receive_imf( - &alice, - b"From: alice@example.org\n\ - To: Bob \n\ - Message-ID: <1234-2-4@example.org>\n\ - Date: Sat, 07 Dec 2019 19:00:27 +0000\n\ - \n\ - Happy birthday, Bob!\n", - true, + let msg_sent = test_utils::receive_encrypted_imf( + alice, + alice, + b"From: alice@example.org\r\n\ + To: Bob \r\n\ + Message-ID: <1234-2-4@example.org>\r\n\ + Date: Sat, 07 Dec 2019 19:00:27 +0000\r\n\ + \r\n\ + Happy birthday, Bob!\r\n", ) - .await? - .unwrap(); + .await?; // The "Happy birthday" message should be shown first, and then the "Thanks" message assert!(msg_sent.sort_timestamp < msg_incoming.sort_timestamp); @@ -269,17 +270,17 @@ async fn test_mdn_doesnt_disable_verification() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_outgoing_mua_msg() -> Result<()> { let mut tcm = TestContextManager::new(); - let alice = tcm.alice().await; - let bob = tcm.bob().await; + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - mark_as_verified(&alice, &bob).await; - mark_as_verified(&bob, &alice).await; + mark_as_verified(alice, bob).await; + mark_as_verified(bob, alice).await; - tcm.send_recv_accept(&bob, &alice, "Heyho from DC").await; - assert_verified(&alice, &bob).await; + tcm.send_recv_accept(bob, alice, "Heyho from DC").await; + assert_verified(alice, bob).await; let sent = receive_imf( - &alice, + alice, b"From: alice@example.org\n\ To: bob@example.net\n\ \n\ @@ -288,7 +289,7 @@ async fn test_outgoing_mua_msg() -> Result<()> { ) .await? .unwrap(); - tcm.send_recv(&alice, &bob, "Sending with DC again").await; + tcm.send_recv(alice, bob, "Sending with DC again").await; // Unencrypted message from MUA gets into a separate chat. // PGP chat gets all encrypted messages. @@ -296,7 +297,7 @@ async fn test_outgoing_mua_msg() -> Result<()> { .golden_test_chat(sent.chat_id, "test_outgoing_mua_msg") .await; alice - .golden_test_chat(alice.get_chat(&bob).await.id, "test_outgoing_mua_msg_pgp") + .golden_test_chat(alice.get_chat(bob).await.id, "test_outgoing_mua_msg_pgp") .await; Ok(()) diff --git a/src/update_helper.rs b/src/update_helper.rs index 6d0b25f17..691cc6e3e 100644 --- a/src/update_helper.rs +++ b/src/update_helper.rs @@ -87,8 +87,8 @@ impl Params { mod tests { use super::*; use crate::chat::Chat; - use crate::receive_imf::receive_imf; - use crate::test_utils::TestContext; + use crate::test_utils; + use crate::test_utils::TestContextManager; use crate::tools::time; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -115,37 +115,39 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_out_of_order_subject() -> Result<()> { - let t = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; - receive_imf( - &t, - b"From: Bob Authname \n\ - To: alice@example.org\n\ - Subject: updated subject\n\ - Message-ID: \n\ - Chat-Version: 1.0\n\ - Date: Sun, 22 Mar 2021 23:37:57 +0000\n\ - \n\ - second message\n", - false, + test_utils::receive_encrypted_imf( + alice, + bob, + b"From: Bob Authname \r\n\ + To: alice@example.org\r\n\ + Subject: updated subject\r\n\ + Message-ID: \r\n\ + Chat-Version: 1.0\r\n\ + Date: Sun, 22 Mar 2021 23:37:57 +0000\r\n\ + \r\n\ + second message\r\n", ) .await?; - receive_imf( - &t, - b"From: Bob Authname \n\ - To: alice@example.org\n\ - Subject: original subject\n\ - Message-ID: \n\ - Chat-Version: 1.0\n\ - Date: Sun, 22 Mar 2021 22:37:57 +0000\n\ - \n\ - first message\n", - false, + test_utils::receive_encrypted_imf( + alice, + bob, + b"From: Bob Authname \r\n\ + To: alice@example.org\r\n\ + Subject: original subject\r\n\ + Message-ID: \r\n\ + Chat-Version: 1.0\r\n\ + Date: Sun, 22 Mar 2021 22:37:57 +0000\r\n\ + \r\n\ + first message\r\n", ) .await?; - let msg = t.get_last_msg().await; - let chat = Chat::load_from_db(&t, msg.chat_id).await?; + let msg = alice.get_last_msg().await; + let chat = Chat::load_from_db(alice, msg.chat_id).await?; assert_eq!( chat.param.get(Param::LastSubject).unwrap(), "updated subject" diff --git a/src/webxdc/webxdc_tests.rs b/src/webxdc/webxdc_tests.rs index 85c38c851..918f54f26 100644 --- a/src/webxdc/webxdc_tests.rs +++ b/src/webxdc/webxdc_tests.rs @@ -11,8 +11,8 @@ use crate::chat::{ use crate::chatlist::Chatlist; use crate::config::Config; use crate::ephemeral; -use crate::receive_imf::receive_imf; use crate::securejoin::get_securejoin_qr; +use crate::test_utils; use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager}; use crate::tools::{self, SystemTime}; use crate::{message, sql}; @@ -257,24 +257,26 @@ async fn test_resend_webxdc_instance_and_info() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_receive_webxdc_instance() -> Result<()> { - let t = TestContext::new_alice().await; - receive_imf( - &t, + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; + let bob = &tcm.bob().await; + test_utils::receive_encrypted_imf( + alice, + bob, include_bytes!("../../test-data/message/webxdc_good_extension.eml"), - false, ) .await?; - let instance = t.get_last_msg().await; + let instance = alice.get_last_msg().await; assert_eq!(instance.viewtype, Viewtype::Webxdc); assert_eq!(instance.get_filename().unwrap(), "minimal.xdc"); - receive_imf( - &t, + test_utils::receive_encrypted_imf( + alice, + bob, include_bytes!("../../test-data/message/webxdc_bad_extension.eml"), - false, ) .await?; - let instance = t.get_last_msg().await; + let instance = alice.get_last_msg().await; assert_eq!(instance.viewtype, Viewtype::File); // we require the correct extension, only a mime type is not sufficient assert_eq!(instance.get_filename().unwrap(), "index.html"); @@ -682,13 +684,14 @@ async fn expect_status_update_event(t: &TestContext, instance_id: MsgId) -> Resu #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_send_webxdc_status_update() -> Result<()> { - let alice = TestContext::new_alice().await; + let mut tcm = TestContextManager::new(); + let alice = &tcm.alice().await; alice.set_config_bool(Config::BccSelf, true).await?; - let bob = TestContext::new_bob().await; + let bob = &tcm.bob().await; // Alice sends an webxdc instance and a status update - let alice_chat = alice.create_email_chat(&bob).await; - let alice_instance = send_webxdc_instance(&alice, alice_chat.id).await?; + let alice_chat = alice.create_email_chat(bob).await; + let alice_instance = send_webxdc_instance(alice, alice_chat.id).await?; let sent1 = &alice.pop_sent_msg().await; assert_eq!(alice_instance.viewtype, Viewtype::Webxdc); assert!(!sent1.payload().contains("report-type=status-update")); @@ -697,7 +700,7 @@ async fn test_send_webxdc_status_update() -> Result<()> { .send_webxdc_status_update(alice_instance.id, r#"{"payload" : {"foo":"bar"}}"#) .await?; alice.flush_status_updates().await?; - expect_status_update_event(&alice, alice_instance.id).await?; + expect_status_update_event(alice, alice_instance.id).await?; let sent2 = &alice.pop_sent_msg().await; let alice_update = sent2.load_from_db().await; assert!(alice_update.hidden); @@ -706,10 +709,10 @@ async fn test_send_webxdc_status_update() -> Result<()> { assert_eq!(alice_update.text, BODY_DESCR.to_string()); assert_eq!(alice_update.chat_id, alice_instance.chat_id); assert_eq!( - alice_update.parent(&alice).await?.unwrap().id, + alice_update.parent(alice).await?.unwrap().id, alice_instance.id ); - assert_eq!(alice_chat.id.get_msg_cnt(&alice).await?, 1); + assert_eq!(alice_chat.id.get_msg_cnt(alice).await?, 1); assert!(sent2.payload().contains("report-type=status-update")); assert!(sent2.payload().contains(BODY_DESCR)); assert_eq!( @@ -735,12 +738,12 @@ async fn test_send_webxdc_status_update() -> Result<()> { let bob_chat_id = bob_instance.chat_id; assert_eq!(bob_instance.rfc724_mid, alice_instance.rfc724_mid); assert_eq!(bob_instance.viewtype, Viewtype::Webxdc); - assert_eq!(bob_chat_id.get_msg_cnt(&bob).await?, 1); + assert_eq!(bob_chat_id.get_msg_cnt(bob).await?, 1); let bob_received_update = bob.recv_msg_opt(sent2).await; assert!(bob_received_update.is_none()); - expect_status_update_event(&bob, bob_instance.id).await?; - assert_eq!(bob_chat_id.get_msg_cnt(&bob).await?, 1); + expect_status_update_event(bob, bob_instance.id).await?; + assert_eq!(bob_chat_id.get_msg_cnt(bob).await?, 1); assert_eq!( bob.get_webxdc_status_updates(bob_instance.id, StatusUpdateSerial(0)) @@ -749,19 +752,19 @@ async fn test_send_webxdc_status_update() -> Result<()> { ); // Alice has a second device and also receives messages there - let alice2 = TestContext::new_alice().await; + let alice2 = &tcm.alice().await; alice2.recv_msg(sent1).await; alice2.recv_msg_trash(sent2).await; let alice2_instance = alice2.get_last_msg().await; let alice2_chat_id = alice2_instance.chat_id; assert_eq!(alice2_instance.viewtype, Viewtype::Webxdc); - assert_eq!(alice2_chat_id.get_msg_cnt(&alice2).await?, 1); + assert_eq!(alice2_chat_id.get_msg_cnt(alice2).await?, 1); // To support the second device, Alice has enabled bcc_self and will receive their own messages; // these messages, however, should be ignored alice.recv_msg_opt(sent1).await; alice.recv_msg_opt(sent2).await; - assert_eq!(alice_chat.id.get_msg_cnt(&alice).await?, 1); + assert_eq!(alice_chat.id.get_msg_cnt(alice).await?, 1); assert_eq!( alice .get_webxdc_status_updates(alice_instance.id, StatusUpdateSerial(0)) @@ -983,7 +986,7 @@ async fn test_pop_status_update() -> Result<()> { async fn test_draft_and_send_webxdc_status_update() -> Result<()> { let alice = TestContext::new_alice().await; let bob = TestContext::new_bob().await; - let alice_chat_id = alice.create_email_chat(&bob).await.id; + let alice_chat_id = alice.create_chat(&bob).await.id; // prepare webxdc instance, // status updates are not sent for drafts, therefore send_webxdc_status_update() returns Ok(None) @@ -1030,8 +1033,6 @@ async fn test_draft_and_send_webxdc_status_update() -> Result<()> { let bob_instance = bob.recv_msg(&sent1).await; assert_eq!(bob_instance.viewtype, Viewtype::Webxdc); assert_eq!(bob_instance.get_filename().unwrap(), "minimal.xdc"); - assert!(sent1.payload().contains("Content-Type: application/json")); - assert!(sent1.payload().contains("status-update.json")); assert_eq!( bob.get_webxdc_status_updates(bob_instance.id, StatusUpdateSerial(0)) .await?, diff --git a/test-data/message/image_4k.eml b/test-data/message/image_4k.eml index 7b2e3e777..3f7d00adc 100644 --- a/test-data/message/image_4k.eml +++ b/test-data/message/image_4k.eml @@ -1,28 +1,27 @@ -Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET) -From: Test Sender -Subject: Large image test -To: alice@example.org -Message-ID: -Date: Thu, 17 Dec 2020 15:38:45 +0100 -User-Agent: Test-Agent/1.0 -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="------------BIG_IMAGE_BOUNDARY" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------BIG_IMAGE_BOUNDARY -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: 7bit - -Here is a 4k image - ---------------BIG_IMAGE_BOUNDARY -Content-Type: image/png; - name="4k_image.png" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; - filename="4k_image.png" - -iVBORw0KGgoAAAANSUhEUgAADwAAAAhwCAIAAAAf3FwlAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg== ---------------BIG_IMAGE_BOUNDARY-- +From: Test Sender +Subject: Large image test +To: alice@example.org +Message-ID: +Date: Thu, 17 Dec 2020 15:38:45 +0100 +User-Agent: Test-Agent/1.0 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------BIG_IMAGE_BOUNDARY" +Content-Language: en-US + +This is a multi-part message in MIME format. +--------------BIG_IMAGE_BOUNDARY +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 7bit + +Here is a 4k image + +--------------BIG_IMAGE_BOUNDARY +Content-Type: image/png; + name="4k_image.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="4k_image.png" + +iVBORw0KGgoAAAANSUhEUgAADwAAAAhwCAIAAAAf3FwlAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg== +--------------BIG_IMAGE_BOUNDARY-- diff --git a/test-data/message/image_huge_64M.eml b/test-data/message/image_huge_64M.eml index 6dde8a56f..834e885e2 100644 --- a/test-data/message/image_huge_64M.eml +++ b/test-data/message/image_huge_64M.eml @@ -1,28 +1,27 @@ -Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET) -From: Test Sender -Subject: Large image test -To: alice@example.org -Message-ID: -Date: Thu, 17 Dec 2020 15:38:45 +0100 -User-Agent: Test-Agent/1.0 -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="------------HUGE_IMAGE_BOUNDARY" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------HUGE_IMAGE_BOUNDARY -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: 7bit - -Here is a huge image - ---------------HUGE_IMAGE_BOUNDARY -Content-Type: image/png; - name="huge_image.png" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; - filename="huge_image.png" - -iVBORw0KGgoAAAANSUhEUgAAH0AAAB9ACAIAAACJkzqjAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg== ---------------HUGE_IMAGE_BOUNDARY-- +From: Test Sender +Subject: Large image test +To: alice@example.org +Message-ID: +Date: Thu, 17 Dec 2020 15:38:45 +0100 +User-Agent: Test-Agent/1.0 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------HUGE_IMAGE_BOUNDARY" +Content-Language: en-US + +This is a multi-part message in MIME format. +--------------HUGE_IMAGE_BOUNDARY +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 7bit + +Here is a huge image + +--------------HUGE_IMAGE_BOUNDARY +Content-Type: image/png; + name="huge_image.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="huge_image.png" + +iVBORw0KGgoAAAANSUhEUgAAH0AAAB9ACAIAAACJkzqjAAAAEElEQVR4nAEFAPr/AP////8AAAAFCeiupAAAAABJRU5ErkJggg== +--------------HUGE_IMAGE_BOUNDARY-- diff --git a/test-data/message/jpeg-as-application-octet-stream.eml b/test-data/message/jpeg-as-application-octet-stream.eml index 7596b59c7..1bcab588b 100644 --- a/test-data/message/jpeg-as-application-octet-stream.eml +++ b/test-data/message/jpeg-as-application-octet-stream.eml @@ -1,76 +1,74 @@ -X-Mozilla-Status: 0801 -X-Mozilla-Status2: 10000000 -Content-Type: multipart/mixed; boundary="------------L1v4sF5IlAZ0HirXymXElgpK" -Message-ID: <1e3b3bb0-f34f-71e2-6b86-bce80bef2c6f@example.org> -Date: Thu, 3 Aug 2023 13:31:01 -0300 -MIME-Version: 1.0 -User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 - Thunderbird/102.13.0 -Content-Language: en-US -To: bob@example.net -From: Alice -X-Identity-Key: id3 -Fcc: imap://alice%40example.org@in.example.org/Sent - -This is a multi-part message in MIME format. ---------------L1v4sF5IlAZ0HirXymXElgpK -Content-Type: text/plain; charset=UTF-8; format=flowed -Content-Transfer-Encoding: 7bit - - ---------------L1v4sF5IlAZ0HirXymXElgpK -Content-Type: application/octet-stream; name="rusty_deltachat_logo.jpeg" -Content-Disposition: attachment; filename="rusty_deltachat_logo.jpeg" -Content-Transfer-Encoding: base64 - -/9j/4AAQSkZJRgABAQIAzADMAAD/2wBDAP////////////////////////////////////// -////////////////////////////////////////////////2wBDAf////////////////// -////////////////////////////////////////////////////////////////////wAAR -CAEAAQADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA -AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK -FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG -h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl -5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA -AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk -NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE -hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk -5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwCSiiigAooooAKKKKACiiigAooprHAzQA6i -mhgfY0McA0AAYGnVX6U/efagA3Hdnt6VL15qvS5OMZ4oAUt82R26f596lByM1BSgkcA0APZ+ -eO3X3qSq9PV8DBoAl6UVCzZ+lPQ8fSgB9FFICD0oAWiiigAooooAKKKKACiiigAooooAKKKK -ACiiigApCcDNLTH6UAKGB9j6UjkYx3qKigAooooAKKKKACiiigAooooAKKKKAClBI6UlFACk -k9akTofrUVKCR0oAnoqEuT7fSnp0P1oAfRRRQAUUUUAFFFFABRRRQAUUUUAFIwyDTd496QuM -cUAMBI6GkJJ60UUAFFFFABRSqMmpgAOlAEYQnrxTtg96fSEgdTQAmxfT+dLtX0FJvX1o3r6/ -zoAXavoKTYvp/OlBB6GloAZsHvTSh7HNS0UAQEEdRSVYqNk7j8qAI6KKKACnq2ODTKKAJS47 -CnDkA1AOtWKACiiigAooooAKKKKACimscDOM03zPb9f/AK1ADXGD9eabSk5OTSUAFFFFABRR -RQBMowB7806kXoPpQeh+hoAjZ+w/OmUUUAFFFFABTw/r+dMooAsdaKhDEfT0qUEHkUALRRRQ -BG69x+NR1O33T9KgoAKKKKACnBiBim0UASKSTyeKkpiYwfWn0AFFFFABRRTWbb2zQA4jPFV6 -eX46Y/GmUAFFFFABRRRQAUUUUASIe35VJVepVbPB6/zoAay45HT+VMqxTCgPTg0ARUUpBHWk -oAKKKKAClBI6UlFAEocd+KXevr+hqGigBzNn6U2iigAooooAKKKKAAEjpTgWJxk02pExk+tA -ElFFFABSEZGKCQOtNLjtzQBF0ooooAKKKKACiiigAooooAKKKKAJFfsfz/xqSq9OViPcUATY -z1qMp6flTwQelLQBX6UVOQD1qMoR05/nQAyiiigAooooAKKKKACiiigAooooAKAcdKKKAHBm -+tTUxAMZ70+gBCARioSCDzU+cdahY5PHagBtFFFABRRRQAUUUUAFFFFABRRRQAUUdelPCHvx -QA0EjpUqsD9fSkCD3NOCgdqAFooooAaVB+vrURUj/Gp6KAK9FSMncfl/hUdABRRRQAUUUUAF -FFFABRRRQA4MR0p6tnjHNRgZOKmCgUARsp69R/KmVYqA9Tj1oASiiigAooooAKKKKACiilAJ -4FACVIE9fypwUD6+tOoAQADpS0UhIHJoAWkLAdTUZcnpwKZQBIXHYUB+eelR0UAWKKiRux/C -paACmMueR1/nT6KAK9FSsueR1/nUVABRRRQAUUUUAFFFFACg4OalDA+31qGpFTufyoAazE8d -B6U2pyAetQsMEigBKKKKACiiigAooooABzxU4GBTEHf8qkoAKKKKADpUDHJ/lT3Pb8TUdABR -RRQAUUUUAFTKcj3FQ05Tg/pQBNRRRQAVE4wc9j/OpaQjIIoAgooooAKKKKACiiigBRwQanqv -T03Z9vegB7Nj61DUxUGmMuKAGUUUUAFFFFABRRSr1H1oAmAwAKWiigAooooAgY5JpKKKACii -igAooooAKKKKAJwcgGlpifdp9ABRRRQBCwwx/Om09+o+lMoAKKKKACiiigCRB1qSoAcHNTA5 -GaAFqJ2zwPxqWo9h9aAI6KUjBwaSgAooooAKcv3hTaUdR9aAJ6KKKACkPQ/Q0tFAFeiiigAo -oooAKKKKACiiigCVOh+v9BT6an3adQAUUUUARP1H0plOc5Y/lTaACiiigApVGSBSUdOaAJ8D -0FLSA5GaWgAoooPTjrQBE5yfpTKfsb2ppBBwaAEooooAKKKKAJ1OQDS1Ehwcev8AOpaACiii -gCAjBP1pKe45z60ygAooooAKKKKACiinIMn2FAEoGABS0UUAFITgZpaidsnHYUAMooooAKKK -KACpti+n6moalVs8Hr/OgBwGOBS0UUAFFFFABUb9hUlRlCSTkUAR0U8oQM9aZQAUUUUAFSq2 -eD1/nUVFAFiimK2eD1/nT6AEIyMVCQQcGp6QgHrQBBRTyh7c03afQ0AJRS7T6GnBD34oAaAS -cCpgMDFAAHSloAKKKjZ+w/P/AAoAGbsPxqOiigAooooAKKKKAFUZOKlCgf41EDg5FSBwevFA -D6KKKACiiigAooooAQnAJqCpyMjFIEUds/WgCGinuoHI/KmUAFFFFABTw5HXn+dMooAnBB6G -lqvTgxHegCaiot59BS+Z7frQBJRUfme1JvPsKAJaaXA96iJJ6mkoAcWJ+npTaKKACiiigAoo -ooAKKKKACpVXHJ61FUocYGetAD6KQEHoaWgAooooAKKKKACiiigBj9B9aaEJ68VLRQBAQR1p -KlfoPrTApNADaKUgjrSUAFFFFABRRRQAUUUUAFFFFABRRSkEdRQAlFKBkgVKUGOOKAIaKXBz -ipto9BQBBRQRg4p+w4z39KAGUUUUASouOe5/lT6QHIzS0AFFFFABRRRQAUUUUAFFFFACEA9a -WiigBr/d+lRqufpU1FAEbJgZFR1YqNU557dKAG7W9KbVioip3YHegBoBPQUlTgYGKay55HX+ -dADFXdSshHPWnqMD3p1AESdfwqWkAA6d6WgBgQA5H5U+iigBMDOe9LRRQAm0ZzS0UUARFTu9 -jzmpNoxjFLRQAgGOlLRRQB//2Q== - ---------------L1v4sF5IlAZ0HirXymXElgpK-- +Content-Type: multipart/mixed; boundary="------------L1v4sF5IlAZ0HirXymXElgpK" +Message-ID: <1e3b3bb0-f34f-71e2-6b86-bce80bef2c6f@example.net> +Date: Thu, 3 Aug 2023 13:31:01 -0300 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.13.0 +Content-Language: en-US +To: bob@example.net +From: Alice +X-Identity-Key: id3 +Fcc: imap://alice%40example.org@in.example.org/Sent + +This is a multi-part message in MIME format. +--------------L1v4sF5IlAZ0HirXymXElgpK +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: 7bit + + +--------------L1v4sF5IlAZ0HirXymXElgpK +Content-Type: application/octet-stream; name="rusty_deltachat_logo.jpeg" +Content-Disposition: attachment; filename="rusty_deltachat_logo.jpeg" +Content-Transfer-Encoding: base64 + +/9j/4AAQSkZJRgABAQIAzADMAAD/2wBDAP////////////////////////////////////// +////////////////////////////////////////////////2wBDAf////////////////// +////////////////////////////////////////////////////////////////////wAAR +CAEAAQADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA +AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK +FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG +h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl +5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA +AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk +NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE +hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk +5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwCSiiigAooooAKKKKACiiigAooprHAzQA6i +mhgfY0McA0AAYGnVX6U/efagA3Hdnt6VL15qvS5OMZ4oAUt82R26f596lByM1BSgkcA0APZ+ +eO3X3qSq9PV8DBoAl6UVCzZ+lPQ8fSgB9FFICD0oAWiiigAooooAKKKKACiiigAooooAKKKK +ACiiigApCcDNLTH6UAKGB9j6UjkYx3qKigAooooAKKKKACiiigAooooAKKKKAClBI6UlFACk +k9akTofrUVKCR0oAnoqEuT7fSnp0P1oAfRRRQAUUUUAFFFFABRRRQAUUUUAFIwyDTd496QuM +cUAMBI6GkJJ60UUAFFFFABRSqMmpgAOlAEYQnrxTtg96fSEgdTQAmxfT+dLtX0FJvX1o3r6/ +zoAXavoKTYvp/OlBB6GloAZsHvTSh7HNS0UAQEEdRSVYqNk7j8qAI6KKKACnq2ODTKKAJS47 +CnDkA1AOtWKACiiigAooooAKKKKACimscDOM03zPb9f/AK1ADXGD9eabSk5OTSUAFFFFABRR +RQBMowB7806kXoPpQeh+hoAjZ+w/OmUUUAFFFFABTw/r+dMooAsdaKhDEfT0qUEHkUALRRRQ +BG69x+NR1O33T9KgoAKKKKACnBiBim0UASKSTyeKkpiYwfWn0AFFFFABRRTWbb2zQA4jPFV6 +eX46Y/GmUAFFFFABRRRQAUUUUASIe35VJVepVbPB6/zoAay45HT+VMqxTCgPTg0ARUUpBHWk +oAKKKKAClBI6UlFAEocd+KXevr+hqGigBzNn6U2iigAooooAKKKKAAEjpTgWJxk02pExk+tA +ElFFFABSEZGKCQOtNLjtzQBF0ooooAKKKKACiiigAooooAKKKKAJFfsfz/xqSq9OViPcUATY +z1qMp6flTwQelLQBX6UVOQD1qMoR05/nQAyiiigAooooAKKKKACiiigAooooAKAcdKKKAHBm ++tTUxAMZ70+gBCARioSCDzU+cdahY5PHagBtFFFABRRRQAUUUUAFFFFABRRRQAUUdelPCHvx +QA0EjpUqsD9fSkCD3NOCgdqAFooooAaVB+vrURUj/Gp6KAK9FSMncfl/hUdABRRRQAUUUUAF +FFFABRRRQA4MR0p6tnjHNRgZOKmCgUARsp69R/KmVYqA9Tj1oASiiigAooooAKKKKACiilAJ +4FACVIE9fypwUD6+tOoAQADpS0UhIHJoAWkLAdTUZcnpwKZQBIXHYUB+eelR0UAWKKiRux/C +paACmMueR1/nT6KAK9FSsueR1/nUVABRRRQAUUUUAFFFFACg4OalDA+31qGpFTufyoAazE8d +B6U2pyAetQsMEigBKKKKACiiigAooooABzxU4GBTEHf8qkoAKKKKADpUDHJ/lT3Pb8TUdABR +RRQAUUUUAFTKcj3FQ05Tg/pQBNRRRQAVE4wc9j/OpaQjIIoAgooooAKKKKACiiigBRwQanqv +T03Z9vegB7Nj61DUxUGmMuKAGUUUUAFFFFABRRSr1H1oAmAwAKWiigAooooAgY5JpKKKACii +igAooooAKKKKAJwcgGlpifdp9ABRRRQBCwwx/Om09+o+lMoAKKKKACiiigCRB1qSoAcHNTA5 +GaAFqJ2zwPxqWo9h9aAI6KUjBwaSgAooooAKcv3hTaUdR9aAJ6KKKACkPQ/Q0tFAFeiiigAo +oooAKKKKACiiigCVOh+v9BT6an3adQAUUUUARP1H0plOc5Y/lTaACiiigApVGSBSUdOaAJ8D +0FLSA5GaWgAoooPTjrQBE5yfpTKfsb2ppBBwaAEooooAKKKKAJ1OQDS1Ehwcev8AOpaACiii +gCAjBP1pKe45z60ygAooooAKKKKACiinIMn2FAEoGABS0UUAFITgZpaidsnHYUAMooooAKKK +KACpti+n6moalVs8Hr/OgBwGOBS0UUAFFFFABUb9hUlRlCSTkUAR0U8oQM9aZQAUUUUAFSq2 +eD1/nUVFAFiimK2eD1/nT6AEIyMVCQQcGp6QgHrQBBRTyh7c03afQ0AJRS7T6GnBD34oAaAS +cCpgMDFAAHSloAKKKjZ+w/P/AAoAGbsPxqOiigAooooAKKKKAFUZOKlCgf41EDg5FSBwevFA +D6KKKACiiigAooooAQnAJqCpyMjFIEUds/WgCGinuoHI/KmUAFFFFABTw5HXn+dMooAnBB6G +lqvTgxHegCaiot59BS+Z7frQBJRUfme1JvPsKAJaaXA96iJJ6mkoAcWJ+npTaKKACiiigAoo +ooAKKKKACpVXHJ61FUocYGetAD6KQEHoaWgAooooAKKKKACiiigBj9B9aaEJ68VLRQBAQR1p +KlfoPrTApNADaKUgjrSUAFFFFABRRRQAUUUUAFFFFABRRSkEdRQAlFKBkgVKUGOOKAIaKXBz +ipto9BQBBRQRg4p+w4z39KAGUUUUASouOe5/lT6QHIzS0AFFFFABRRRQAUUUUAFFFFACEA9a +WiigBr/d+lRqufpU1FAEbJgZFR1YqNU557dKAG7W9KbVioip3YHegBoBPQUlTgYGKay55HX+ +dADFXdSshHPWnqMD3p1AESdfwqWkAA6d6WgBgQA5H5U+iigBMDOe9LRRQAm0ZzS0UUARFTu9 +jzmpNoxjFLRQAgGOlLRRQB//2Q== + +--------------L1v4sF5IlAZ0HirXymXElgpK-- diff --git a/test-data/message/webxdc_bad_extension.eml b/test-data/message/webxdc_bad_extension.eml index 4b4458154..e93367c23 100644 --- a/test-data/message/webxdc_bad_extension.eml +++ b/test-data/message/webxdc_bad_extension.eml @@ -1,21 +1,21 @@ -Subject: webxdc object attached -Message-ID: 67890@example.org -Date: Fri, 03 Dec 2021 10:00:27 +0000 -To: alice@example.org -From: bob@example.org -Chat-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BREAK==" - - ---==BREAK== -Content-Type: text/plain; charset=utf-8 - -webxdc with bad extension and bad content. - ---==BREAK== -Content-Type: application/webxdc+zip -Content-Disposition: attachment; filename=index.html - -hey! - ---==BREAK==-- +Subject: webxdc object attached +Message-ID: 67890@example.net +Date: Fri, 03 Dec 2021 10:00:27 +0000 +To: alice@example.org +From: bob@example.net +Chat-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BREAK==" + + +--==BREAK== +Content-Type: text/plain; charset=utf-8 + +webxdc with bad extension and bad content. + +--==BREAK== +Content-Type: application/webxdc+zip +Content-Disposition: attachment; filename=index.html + +hey! + +--==BREAK==-- diff --git a/test-data/message/webxdc_good_extension.eml b/test-data/message/webxdc_good_extension.eml index e95c89287..8b7aba7d1 100644 --- a/test-data/message/webxdc_good_extension.eml +++ b/test-data/message/webxdc_good_extension.eml @@ -1,29 +1,29 @@ -Subject: webxdc object attached -Message-ID: 12345@example.org -Date: Fri, 03 Dec 2021 10:00:27 +0000 -To: alice@example.org -From: bob@example.org -Chat-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BREAK==" - - ---==BREAK== -Content-Type: text/plain; charset=utf-8 - -webxdc with good extension; -the mimetype is ignored then, -content is checked. - ---==BREAK== -Content-Type: text/html -Content-Disposition: attachment; filename=minimal.xdc -Content-Transfer-Encoding: base64 - -UEsDBBQAAgAIAFJqnVOItjSofAAAALwAAAAKABwAaW5kZXguaHRtbFVUCQADG1LMYV1SzGF1eAsAAQ -T1AQAABBQAAACzUXTxdw6JDHBVyCjJzbHjsoFQCgo2SfkplSCGgkJJanGJIphlU5xclFlQAhFWUEjJ -Ty7NTc0r0SsvyixJ1VAqyU8EqlTStIYo1kdWbZOXj6o5uiQjsxhodkWJQnFGfmlOikJefolCUiqIV5 -4XCzUCWZeNPsRNNvoQRwIAUEsBAh4DFAACAAgAUmqdU4i2NKh8AAAAvAAAAAoAGAAAAAAAAQAAAKSB -AAAAAGluZGV4Lmh0bWxVVAUAAxtSzGF1eAsAAQT1AQAABBQAAABQSwUGAAAAAAEAAQBQAAAAwAAAAA -AA - ---==BREAK==-- +Subject: webxdc object attached +Message-ID: 12345@example.net +Date: Fri, 03 Dec 2021 10:00:27 +0000 +To: alice@example.org +From: bob@example.net +Chat-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BREAK==" + + +--==BREAK== +Content-Type: text/plain; charset=utf-8 + +webxdc with good extension; +the mimetype is ignored then, +content is checked. + +--==BREAK== +Content-Type: text/html +Content-Disposition: attachment; filename=minimal.xdc +Content-Transfer-Encoding: base64 + +UEsDBBQAAgAIAFJqnVOItjSofAAAALwAAAAKABwAaW5kZXguaHRtbFVUCQADG1LMYV1SzGF1eAsAAQ +T1AQAABBQAAACzUXTxdw6JDHBVyCjJzbHjsoFQCgo2SfkplSCGgkJJanGJIphlU5xclFlQAhFWUEjJ +Ty7NTc0r0SsvyixJ1VAqyU8EqlTStIYo1kdWbZOXj6o5uiQjsxhodkWJQnFGfmlOikJefolCUiqIV5 +4XCzUCWZeNPsRNNvoQRwIAUEsBAh4DFAACAAgAUmqdU4i2NKh8AAAAvAAAAAoAGAAAAAAAAQAAAKSB +AAAAAGluZGV4Lmh0bWxVVAUAAxtSzGF1eAsAAQT1AQAABBQAAABQSwUGAAAAAAEAAQBQAAAAwAAAAA +AA + +--==BREAK==--