mirror of
https://github.com/chatmail/core.git
synced 2026-05-17 05:46:30 +03:00
test: use encrypted messages in more tests
This change is a preparation for ignoring unencrypted messages by default. New test_utils::encrypt_raw_message and test_utils::receive_encrypted_imf are used to encrypt the messages before "receiving" them with receive_imf.
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::config::Config;
|
|||||||
use crate::constants::DC_CHAT_ID_TRASH;
|
use crate::constants::DC_CHAT_ID_TRASH;
|
||||||
use crate::message::MessageState;
|
use crate::message::MessageState;
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{TestContext, TestContextManager};
|
use crate::test_utils::{TestContext, TestContextManager};
|
||||||
|
|
||||||
struct CallSetup {
|
struct CallSetup {
|
||||||
@@ -634,20 +635,23 @@ async fn test_forward_call() -> Result<()> {
|
|||||||
async fn test_end_text_call() -> Result<()> {
|
async fn test_end_text_call() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
let alice = &tcm.alice().await;
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
let received1 = receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
alice,
|
bob,
|
||||||
b"From: bob@example.net\n\
|
&[alice],
|
||||||
To: alice@example.org\n\
|
b"From: bob@example.net\r\n\
|
||||||
Message-ID: <first@example.net>\n\
|
To: alice@example.org\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:57 +0000\n\
|
Message-ID: <first@example.net>\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Date: Sun, 22 Mar 2020 22:37:57 +0000\r\n\
|
||||||
\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Hello\n",
|
\r\n\
|
||||||
false,
|
Hello\r\n",
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap();
|
let received1 = receive_imf(alice, encrypted_message.as_bytes(), false)
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
assert_eq!(received1.msg_ids.len(), 1);
|
assert_eq!(received1.msg_ids.len(), 1);
|
||||||
let msg = Message::load_from_db(alice, received1.msg_ids[0])
|
let msg = Message::load_from_db(alice, received1.msg_ids[0])
|
||||||
.await
|
.await
|
||||||
@@ -656,21 +660,23 @@ async fn test_end_text_call() -> Result<()> {
|
|||||||
|
|
||||||
// Receiving "Call ended" message that refers
|
// Receiving "Call ended" message that refers
|
||||||
// to the text message does not result in an error.
|
// to the text message does not result in an error.
|
||||||
let received2 = receive_imf(
|
let encrypted_message2 = test_utils::encrypt_raw_message(
|
||||||
alice,
|
bob,
|
||||||
b"From: bob@example.net\n\
|
&[alice],
|
||||||
To: alice@example.org\n\
|
b"From: bob@example.net\r\n\
|
||||||
Message-ID: <second@example.net>\n\
|
To: alice@example.org\r\n\
|
||||||
Date: Sun, 22 Mar 2020 23:37:57 +0000\n\
|
Message-ID: <second@example.net>\r\n\
|
||||||
In-Reply-To: <first@example.net>\n\
|
Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\
|
||||||
Chat-Version: 1.0\n\
|
In-Reply-To: <first@example.net>\r\n\
|
||||||
Chat-Content: call-ended\n\
|
Chat-Version: 1.0\r\n\
|
||||||
\n\
|
Chat-Content: call-ended\r\n\
|
||||||
Call ended\n",
|
\r\n\
|
||||||
false,
|
Call ended\r\n",
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap();
|
let received2 = receive_imf(alice, encrypted_message2.as_bytes(), false)
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
assert_eq!(received2.msg_ids.len(), 1);
|
assert_eq!(received2.msg_ids.len(), 1);
|
||||||
assert_eq!(received2.chat_id, DC_CHAT_ID_TRASH);
|
assert_eq!(received2.chat_id, DC_CHAT_ID_TRASH);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::message::{Message, MessengerMessage, delete_msgs};
|
|||||||
use crate::mimeparser::{self, MimeMessage};
|
use crate::mimeparser::{self, MimeMessage};
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
use crate::securejoin::{get_securejoin_qr, join_securejoin};
|
use crate::securejoin::{get_securejoin_qr, join_securejoin};
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{
|
use crate::test_utils::{
|
||||||
AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, E2EE_INFO_MSGS, TestContext, TestContextManager,
|
AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, E2EE_INFO_MSGS, TestContext, TestContextManager,
|
||||||
TimeShiftFalsePositiveNote, sync,
|
TimeShiftFalsePositiveNote, sync,
|
||||||
@@ -1159,46 +1160,51 @@ async fn test_archive() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_unarchive_if_muted() -> Result<()> {
|
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<()> {
|
let msg_from_bob = async |num: u32| {
|
||||||
receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
t,
|
bob,
|
||||||
|
&[t],
|
||||||
format!(
|
format!(
|
||||||
"From: bob@example.net\n\
|
"From: bob@example.net\r\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\r\n\
|
||||||
Message-ID: <{num}@example.org>\n\
|
Message-ID: <{num}@example.org>\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Date: Sun, 22 Mar 2022 19:37:57 +0000\n\
|
Date: Sun, 22 Mar 2022 19:37:57 +0000\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
hello\n"
|
hello\r\n"
|
||||||
)
|
)
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
Ok(())
|
.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();
|
let chat_id = t.get_last_msg().await.get_chat_id();
|
||||||
chat_id.accept(&t).await?;
|
chat_id.accept(t).await?;
|
||||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
chat_id.set_visibility(t, ChatVisibility::Archived).await?;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 1);
|
assert_eq!(get_archived_cnt(t).await?, 1);
|
||||||
|
|
||||||
// not muted chat is unarchived on receiving a message
|
// not muted chat is unarchived on receiving a message
|
||||||
msg_from_bob(&t, 2).await?;
|
msg_from_bob(2).await;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 0);
|
assert_eq!(get_archived_cnt(t).await?, 0);
|
||||||
|
|
||||||
// forever muted chat is not unarchived on receiving a message
|
// forever muted chat is not unarchived on receiving a message
|
||||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
chat_id.set_visibility(t, ChatVisibility::Archived).await?;
|
||||||
set_muted(&t, chat_id, MuteDuration::Forever).await?;
|
set_muted(t, chat_id, MuteDuration::Forever).await?;
|
||||||
msg_from_bob(&t, 3).await?;
|
msg_from_bob(3).await;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 1);
|
assert_eq!(get_archived_cnt(t).await?, 1);
|
||||||
|
|
||||||
// otherwise muted chat is not unarchived on receiving a message
|
// otherwise muted chat is not unarchived on receiving a message
|
||||||
set_muted(
|
set_muted(
|
||||||
&t,
|
t,
|
||||||
chat_id,
|
chat_id,
|
||||||
MuteDuration::Until(
|
MuteDuration::Until(
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
@@ -1207,12 +1213,12 @@ async fn test_unarchive_if_muted() -> Result<()> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
msg_from_bob(&t, 4).await?;
|
msg_from_bob(4).await;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 1);
|
assert_eq!(get_archived_cnt(t).await?, 1);
|
||||||
|
|
||||||
// expired mute will unarchive the chat
|
// expired mute will unarchive the chat
|
||||||
set_muted(
|
set_muted(
|
||||||
&t,
|
t,
|
||||||
chat_id,
|
chat_id,
|
||||||
MuteDuration::Until(
|
MuteDuration::Until(
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
@@ -1221,20 +1227,20 @@ async fn test_unarchive_if_muted() -> Result<()> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
msg_from_bob(&t, 5).await?;
|
msg_from_bob(5).await;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 0);
|
assert_eq!(get_archived_cnt(t).await?, 0);
|
||||||
|
|
||||||
// no unarchiving on sending to muted chat or on adding info messages to muted chat
|
// no unarchiving on sending to muted chat or on adding info messages to muted chat
|
||||||
chat_id.set_visibility(&t, ChatVisibility::Archived).await?;
|
chat_id.set_visibility(t, ChatVisibility::Archived).await?;
|
||||||
set_muted(&t, chat_id, MuteDuration::Forever).await?;
|
set_muted(t, chat_id, MuteDuration::Forever).await?;
|
||||||
send_text_msg(&t, chat_id, "out".to_string()).await?;
|
send_text_msg(t, chat_id, "out".to_string()).await?;
|
||||||
add_info_msg(&t, chat_id, "info").await?;
|
add_info_msg(t, chat_id, "info").await?;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 1);
|
assert_eq!(get_archived_cnt(t).await?, 1);
|
||||||
|
|
||||||
// finally, unarchive on sending to not muted chat
|
// finally, unarchive on sending to not muted chat
|
||||||
set_muted(&t, chat_id, MuteDuration::NotMuted).await?;
|
set_muted(t, chat_id, MuteDuration::NotMuted).await?;
|
||||||
send_text_msg(&t, chat_id, "out2".to_string()).await?;
|
send_text_msg(t, chat_id, "out2".to_string()).await?;
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 0);
|
assert_eq!(get_archived_cnt(t).await?, 0);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1874,45 +1880,38 @@ async fn test_lookup_self_by_contact_id() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_marknoticed_chat() -> Result<()> {
|
async fn test_marknoticed_chat() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let chat = t.create_chat_with_contact("bob", "bob@example.org").await;
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
let chat = alice.create_chat(bob).await;
|
||||||
|
|
||||||
receive_imf(
|
let bob_chat_id = bob.create_chat_id(alice).await;
|
||||||
&t,
|
let sent = bob.send_text(bob_chat_id, "hello").await;
|
||||||
b"From: bob@example.org\n\
|
alice.recv_msg(&sent).await;
|
||||||
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 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.len(), 1);
|
||||||
assert_eq!(chats.get_chat_id(0)?, chat.id);
|
assert_eq!(chats.get_chat_id(0)?, chat.id);
|
||||||
assert_eq!(chat.id.get_fresh_msg_cnt(&t).await?, 1);
|
assert_eq!(chat.id.get_fresh_msg_cnt(alice).await?, 1);
|
||||||
assert_eq!(t.get_fresh_msgs().await?.len(), 1);
|
assert_eq!(alice.get_fresh_msgs().await?.len(), 1);
|
||||||
|
|
||||||
let msgs = get_chat_msgs(&t, chat.id).await?;
|
let msgs = get_chat_msgs(alice, chat.id).await?;
|
||||||
assert_eq!(msgs.len(), 1);
|
assert_eq!(msgs.len(), 2);
|
||||||
let msg_id = match msgs.first().unwrap() {
|
let msg_id = match msgs.last().unwrap() {
|
||||||
ChatItem::Message { msg_id } => *msg_id,
|
ChatItem::Message { msg_id } => *msg_id,
|
||||||
_ => MsgId::new_unset(),
|
_ => 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);
|
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);
|
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!(msg.state, MessageState::InNoticed);
|
||||||
assert_eq!(chat.id.get_fresh_msg_cnt(&t).await?, 0);
|
assert_eq!(chat.id.get_fresh_msg_cnt(alice).await?, 0);
|
||||||
assert_eq!(t.get_fresh_msgs().await?.len(), 0);
|
assert_eq!(alice.get_fresh_msgs().await?.len(), 0);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1971,40 +1970,43 @@ async fn test_contact_request_fresh_messages() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_contact_request_archive() -> Result<()> {
|
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(
|
let bob_chat_id = bob.create_chat_id(alice).await;
|
||||||
&t,
|
let bob_sent_text = bob.send_text(bob_chat_id, "hello").await;
|
||||||
b"From: bob@example.org\n\
|
alice.recv_msg(&bob_sent_text).await;
|
||||||
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 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.len(), 1);
|
||||||
let chat_id = chats.get_chat_id(0)?;
|
let chat_id = chats.get_chat_id(0)?;
|
||||||
assert!(Chat::load_from_db(&t, chat_id).await?.is_contact_request());
|
assert!(
|
||||||
assert_eq!(get_archived_cnt(&t).await?, 0);
|
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
|
// 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);
|
assert_eq!(chats.len(), 1);
|
||||||
let chat_id = chats.get_chat_id(0)?;
|
let chat_id = chats.get_chat_id(0)?;
|
||||||
assert!(chat_id.is_archived_link());
|
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);
|
assert_eq!(chats.len(), 1);
|
||||||
let chat_id = chats.get_chat_id(0)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -4699,8 +4701,9 @@ async fn test_sync_delete_chat() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_sync_adhoc_grp() -> Result<()> {
|
async fn test_sync_adhoc_grp() -> Result<()> {
|
||||||
let alice0 = &TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let alice1 = &TestContext::new_alice().await;
|
let alice0 = &tcm.alice().await;
|
||||||
|
let alice1 = &tcm.alice().await;
|
||||||
for a in [alice0, alice1] {
|
for a in [alice0, alice1] {
|
||||||
a.set_config_bool(Config::SyncMsgs, true).await?;
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -998,33 +998,18 @@ async fn test_selfavatar_changed_event() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_last_seen() -> Result<()> {
|
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(
|
let contact = alice.add_or_lookup_contact(bob).await;
|
||||||
&alice,
|
|
||||||
"Bob",
|
|
||||||
&ContactAddress::new("bob@example.net")?,
|
|
||||||
Origin::ManuallyCreated,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let contact = Contact::get_by_id(&alice, contact_id).await?;
|
|
||||||
assert_eq!(contact.last_seen(), 0);
|
assert_eq!(contact.last_seen(), 0);
|
||||||
|
|
||||||
let mime = br#"Subject: Hello
|
let msg = tcm.send_recv(bob, alice, "Hi.").await;
|
||||||
Message-ID: message@example.net
|
|
||||||
To: Alice <alice@example.org>
|
|
||||||
From: Bob <bob@example.net>
|
|
||||||
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 timestamp = msg.get_timestamp();
|
let timestamp = msg.get_timestamp();
|
||||||
assert!(timestamp > 0);
|
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);
|
assert_eq!(contact.last_seen(), timestamp);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::chatlist::Chatlist;
|
|||||||
use crate::constants::Chattype;
|
use crate::constants::Chattype;
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::receive_imf::receive_imf;
|
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};
|
use crate::tools::{SystemTime, create_outgoing_rfc724_mid};
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_search_unaccepted_requests() -> Result<()> {
|
async fn test_search_unaccepted_requests() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
receive_imf(
|
let t = &tcm.alice().await;
|
||||||
&t,
|
let bob = &tcm.bob().await;
|
||||||
b"From: BobBar <bob@example.org>\n\
|
bob.set_config(Config::Displayname, Some("BobBar")).await?;
|
||||||
To: alice@example.org\n\
|
let msg = tcm.send_recv(bob, t, "hello bob, foobar test!").await;
|
||||||
Subject: foo\n\
|
let chat_id = msg.get_chat_id();
|
||||||
Message-ID: <msg1234@example.org>\n\
|
let chat = Chat::load_from_db(t, chat_id).await?;
|
||||||
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?;
|
|
||||||
assert_eq!(chat.get_type(), Chattype::Single);
|
assert_eq!(chat.get_type(), Chattype::Single);
|
||||||
assert!(chat.is_contact_request());
|
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!(
|
assert_eq!(
|
||||||
Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(),
|
Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(t.search_msgs(None, "foobar").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);
|
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!(
|
assert_eq!(
|
||||||
Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(),
|
Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
assert_eq!(t.search_msgs(None, "foobar").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);
|
assert_eq!(t.search_msgs(Some(chat_id), "foobar").await?.len(), 0);
|
||||||
|
|
||||||
let contact_ids = get_chat_contacts(&t, chat_id).await?;
|
let contact_ids = get_chat_contacts(t, chat_id).await?;
|
||||||
Contact::unblock(&t, *contact_ids.first().unwrap()).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!(
|
assert_eq!(
|
||||||
Chatlist::try_load(&t, 0, Some("BobBar"), None).await?.len(),
|
Chatlist::try_load(t, 0, Some("BobBar"), None).await?.len(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(t.search_msgs(None, "foobar").await?.len(), 1);
|
assert_eq!(t.search_msgs(None, "foobar").await?.len(), 1);
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::chat::send_msg;
|
use crate::chat::send_msg;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContextManager;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_downloadstate_values() {
|
fn test_downloadstate_values() {
|
||||||
@@ -378,12 +378,14 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_update_download_state() -> Result<()> {
|
async fn test_update_download_state() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let chat = t.create_chat_with_contact("Bob", "bob@example.org").await;
|
let t = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
let chat_id = t.create_chat_id(bob).await;
|
||||||
|
|
||||||
let mut msg = Message::new_text("Hi Bob".to_owned());
|
let mut msg = Message::new_text("Hi Bob".to_owned());
|
||||||
let msg_id = send_msg(&t, chat.id, &mut msg).await?;
|
let msg_id = send_msg(t, chat_id, &mut msg).await?;
|
||||||
let msg = Message::load_from_db(&t, msg_id).await?;
|
let msg = Message::load_from_db(t, msg_id).await?;
|
||||||
assert_eq!(msg.download_state(), DownloadState::Done);
|
assert_eq!(msg.download_state(), DownloadState::Done);
|
||||||
|
|
||||||
for s in &[
|
for s in &[
|
||||||
@@ -393,17 +395,15 @@ mod tests {
|
|||||||
DownloadState::Done,
|
DownloadState::Done,
|
||||||
DownloadState::Done,
|
DownloadState::Done,
|
||||||
] {
|
] {
|
||||||
msg_id.update_download_state(&t, *s).await?;
|
msg_id.update_download_state(t, *s).await?;
|
||||||
let msg = Message::load_from_db(&t, msg_id).await?;
|
let msg = Message::load_from_db(t, msg_id).await?;
|
||||||
assert_eq!(msg.download_state(), *s);
|
assert_eq!(msg.download_state(), *s);
|
||||||
}
|
}
|
||||||
t.sql
|
t.sql
|
||||||
.execute("DELETE FROM msgs WHERE id=?", (msg_id,))
|
.execute("DELETE FROM msgs WHERE id=?", (msg_id,))
|
||||||
.await?;
|
.await?;
|
||||||
// Nothing to do is ok.
|
// Nothing to do is ok.
|
||||||
msg_id
|
msg_id.update_download_state(t, DownloadState::Done).await?;
|
||||||
.update_download_state(&t, DownloadState::Done)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/e2ee.rs
17
src/e2ee.rs
@@ -42,12 +42,25 @@ impl EncryptHelper {
|
|||||||
compress: bool,
|
compress: bool,
|
||||||
seipd_version: SeipdVersion,
|
seipd_version: SeipdVersion,
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let sign_key = load_self_secret_key(context).await?;
|
|
||||||
|
|
||||||
let mut raw_message = Vec::new();
|
let mut raw_message = Vec::new();
|
||||||
let cursor = Cursor::new(&mut raw_message);
|
let cursor = Cursor::new(&mut raw_message);
|
||||||
mail_to_encrypt.clone().write_part(cursor).ok();
|
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<SignedPublicKey>,
|
||||||
|
raw_message: Vec<u8>,
|
||||||
|
compress: bool,
|
||||||
|
seipd_version: SeipdVersion,
|
||||||
|
) -> Result<String> {
|
||||||
|
let sign_key = load_self_secret_key(context).await?;
|
||||||
let ctext =
|
let ctext =
|
||||||
pgp::pk_encrypt(raw_message, keyring, sign_key, compress, seipd_version).await?;
|
pgp::pk_encrypt(raw_message, keyring, sign_key, compress, seipd_version).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::download::DownloadState;
|
|||||||
use crate::location;
|
use crate::location;
|
||||||
use crate::message::markseen_msgs;
|
use crate::message::markseen_msgs;
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{TestContext, TestContextManager};
|
use crate::test_utils::{TestContext, TestContextManager};
|
||||||
use crate::{
|
use crate::{
|
||||||
chat::{self, Chat, ChatItem, create_group, send_text_msg},
|
chat::{self, Chat, ChatItem, create_group, send_text_msg},
|
||||||
@@ -309,20 +310,22 @@ async fn test_ephemeral_timer_rollback() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_ephemeral_delete_msgs() -> Result<()> {
|
async fn test_ephemeral_delete_msgs() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
|
let t = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
let self_chat = t.get_self_chat().await;
|
let self_chat = t.get_self_chat().await;
|
||||||
|
|
||||||
assert_eq!(next_expiration_timestamp(&t).await, None);
|
assert_eq!(next_expiration_timestamp(t).await, None);
|
||||||
|
|
||||||
t.send_text(self_chat.id, "Saved message, which we delete manually")
|
t.send_text(self_chat.id, "Saved message, which we delete manually")
|
||||||
.await;
|
.await;
|
||||||
let msg = t.get_last_msg_in(self_chat.id).await;
|
let msg = t.get_last_msg_in(self_chat.id).await;
|
||||||
msg.id.trash(&t, false).await?;
|
msg.id.trash(t, false).await?;
|
||||||
check_msg_is_deleted(&t, &self_chat, msg.id).await;
|
check_msg_is_deleted(t, &self_chat, msg.id).await;
|
||||||
|
|
||||||
self_chat
|
self_chat
|
||||||
.id
|
.id
|
||||||
.set_ephemeral_timer(&t, Timer::Enabled { duration: 3600 })
|
.set_ephemeral_timer(t, Timer::Enabled { duration: 3600 })
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -330,7 +333,7 @@ async fn test_ephemeral_delete_msgs() -> Result<()> {
|
|||||||
let now = time();
|
let now = time();
|
||||||
let msg = t.send_text(self_chat.id, "Message text").await;
|
let msg = t.send_text(self_chat.id, "Message text").await;
|
||||||
|
|
||||||
check_msg_will_be_deleted(&t, msg.sender_msg_id, &self_chat, now + 3599, time() + 3601)
|
check_msg_will_be_deleted(t, msg.sender_msg_id, &self_chat, now + 3599, time() + 3601)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -342,16 +345,16 @@ async fn test_ephemeral_delete_msgs() -> Result<()> {
|
|||||||
let now = time();
|
let now = time();
|
||||||
let msg = t.send_text(self_chat.id, "Message text").await;
|
let msg = t.send_text(self_chat.id, "Message text").await;
|
||||||
|
|
||||||
check_msg_will_be_deleted(&t, msg.sender_msg_id, &self_chat, now + 3559, time() + 3601)
|
check_msg_will_be_deleted(t, msg.sender_msg_id, &self_chat, now + 3559, time() + 3601)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Send a message to Bob which will be deleted after 1800s because of DeleteDeviceAfter.
|
// Send a message to Bob which will be deleted after 1800s because of DeleteDeviceAfter.
|
||||||
let bob_chat = t.create_chat_with_contact("", "bob@example.net").await;
|
let bob_chat = t.create_chat(bob).await;
|
||||||
let now = time();
|
let now = time();
|
||||||
let msg = t.send_text(bob_chat.id, "Message text").await;
|
let msg = t.send_text(bob_chat.id, "Message text").await;
|
||||||
|
|
||||||
check_msg_will_be_deleted(&t, msg.sender_msg_id, &bob_chat, now + 1799, time() + 1801)
|
check_msg_will_be_deleted(t, msg.sender_msg_id, &bob_chat, now + 1799, time() + 1801)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -359,13 +362,13 @@ async fn test_ephemeral_delete_msgs() -> Result<()> {
|
|||||||
// This tests that the message is deleted at min(ephemeral deletion time, DeleteDeviceAfter deletion time).
|
// This tests that the message is deleted at min(ephemeral deletion time, DeleteDeviceAfter deletion time).
|
||||||
bob_chat
|
bob_chat
|
||||||
.id
|
.id
|
||||||
.set_ephemeral_timer(&t, Timer::Enabled { duration: 60 })
|
.set_ephemeral_timer(t, Timer::Enabled { duration: 60 })
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let now = time();
|
let now = time();
|
||||||
let msg = t.send_text(bob_chat.id, "Message text").await;
|
let msg = t.send_text(bob_chat.id, "Message text").await;
|
||||||
|
|
||||||
check_msg_will_be_deleted(&t, msg.sender_msg_id, &bob_chat, now + 59, time() + 61)
|
check_msg_will_be_deleted(t, msg.sender_msg_id, &bob_chat, now + 59, time() + 61)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -548,50 +551,54 @@ async fn test_delete_expired_imap_messages() -> Result<()> {
|
|||||||
// Regression test for a bug in the timer rollback protection.
|
// Regression test for a bug in the timer rollback protection.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_ephemeral_timer_references() -> Result<()> {
|
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 <first@example.com> and no timer is received.
|
// Message with Message-ID <first@example.com> and no timer is received.
|
||||||
receive_imf(
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
b"From: Bob <bob@example.com>\n\
|
&[alice],
|
||||||
To: Alice <alice@example.org>\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
Chat-Version: 1.0\n\
|
To: Alice <alice@example.org>\r\n\
|
||||||
Subject: Subject\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Message-ID: <first@example.com>\n\
|
Subject: Subject\r\n\
|
||||||
Date: Sun, 22 Mar 2020 00:10:00 +0000\n\
|
Message-ID: <first@example.com>\r\n\
|
||||||
\n\
|
Date: Sun, 22 Mar 2020 00:10:00 +0000\r\n\
|
||||||
hello\n",
|
\r\n\
|
||||||
false,
|
hello\r\n",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_msg.as_bytes(), false).await?;
|
||||||
|
|
||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
let chat_id = msg.chat_id;
|
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 <second@example.com> is received.
|
// Message with Message-ID <second@example.com> is received.
|
||||||
receive_imf(
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
b"From: Bob <bob@example.com>\n\
|
&[alice],
|
||||||
To: Alice <alice@example.org>\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
Chat-Version: 1.0\n\
|
To: Alice <alice@example.org>\r\n\
|
||||||
Subject: Subject\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Message-ID: <second@example.com>\n\
|
Subject: Subject\r\n\
|
||||||
Date: Sun, 22 Mar 2020 00:11:00 +0000\n\
|
Message-ID: <second@example.com>\r\n\
|
||||||
Ephemeral-Timer: 60\n\
|
Date: Sun, 22 Mar 2020 00:11:00 +0000\r\n\
|
||||||
\n\
|
Ephemeral-Timer: 60\r\n\
|
||||||
second message\n",
|
\r\n\
|
||||||
false,
|
second message\r\n",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_msg.as_bytes(), false).await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
chat_id.get_ephemeral_timer(&alice).await?,
|
chat_id.get_ephemeral_timer(alice).await?,
|
||||||
Timer::Enabled { duration: 60 }
|
Timer::Enabled { duration: 60 }
|
||||||
);
|
);
|
||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
|
|
||||||
// Message is deleted when its timer expires.
|
// Message is deleted when its timer expires.
|
||||||
msg.id.trash(&alice, false).await?;
|
msg.id.trash(alice, false).await?;
|
||||||
|
|
||||||
// Message with Message-ID <third@example.com>, referencing <first@example.com> and
|
// Message with Message-ID <third@example.com>, referencing <first@example.com> and
|
||||||
// <second@example.com>, is received. The message <second@example.come> is not in the
|
// <second@example.com>, is received. The message <second@example.come> is not in the
|
||||||
@@ -605,25 +612,26 @@ async fn test_ephemeral_timer_references() -> Result<()> {
|
|||||||
//
|
//
|
||||||
// The message also contains a quote of the first message to test that only References:
|
// 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.
|
// header and not In-Reply-To: is consulted by the rollback protection.
|
||||||
receive_imf(
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
b"From: Bob <bob@example.com>\n\
|
&[alice],
|
||||||
To: Alice <alice@example.org>\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
Chat-Version: 1.0\n\
|
To: Alice <alice@example.org>\r\n\
|
||||||
Subject: Subject\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Message-ID: <third@example.com>\n\
|
Subject: Subject\r\n\
|
||||||
Date: Sun, 22 Mar 2020 00:12:00 +0000\n\
|
Message-ID: <third@example.com>\r\n\
|
||||||
References: <first@example.com> <second@example.com>\n\
|
Date: Sun, 22 Mar 2020 00:12:00 +0000\r\n\
|
||||||
In-Reply-To: <first@example.com>\n\
|
References: <first@example.com> <second@example.com>\r\n\
|
||||||
\n\
|
In-Reply-To: <first@example.com>\r\n\
|
||||||
> hello\n",
|
\r\n\
|
||||||
false,
|
> hello\r\n",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_msg.as_bytes(), false).await?;
|
||||||
|
|
||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
msg.chat_id.get_ephemeral_timer(&alice).await?,
|
msg.chat_id.get_ephemeral_timer(alice).await?,
|
||||||
Timer::Disabled
|
Timer::Disabled
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -635,24 +643,20 @@ async fn test_ephemeral_timer_references() -> Result<()> {
|
|||||||
// successful reconnection.
|
// successful reconnection.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_ephemeral_msg_offline() -> Result<()> {
|
async fn test_ephemeral_msg_offline() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let chat = alice
|
let alice = &tcm.alice().await;
|
||||||
.create_chat_with_contact("Bob", "bob@example.org")
|
let bob = &tcm.bob().await;
|
||||||
.await;
|
let chat = alice.create_chat(bob).await;
|
||||||
let duration = 60;
|
let duration = 60;
|
||||||
chat.id
|
chat.id
|
||||||
.set_ephemeral_timer(&alice, Timer::Enabled { duration })
|
.set_ephemeral_timer(alice, Timer::Enabled { duration })
|
||||||
.await?;
|
.await?;
|
||||||
let mut msg = Message::new_text("hi".to_string());
|
let mut msg = Message::new_text("hi".to_string());
|
||||||
assert!(
|
assert!(chat::send_msg_sync(alice, chat.id, &mut msg).await.is_err());
|
||||||
chat::send_msg_sync(&alice, chat.id, &mut msg)
|
|
||||||
.await
|
|
||||||
.is_err()
|
|
||||||
);
|
|
||||||
let stmt = "SELECT COUNT(*) FROM smtp WHERE msg_id=?";
|
let stmt = "SELECT COUNT(*) FROM smtp WHERE msg_id=?";
|
||||||
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
||||||
let now = time();
|
let now = time();
|
||||||
check_msg_will_be_deleted(&alice, msg.id, &chat, now, now + i64::from(duration) + 1).await?;
|
check_msg_will_be_deleted(alice, msg.id, &chat, now, now + i64::from(duration) + 1).await?;
|
||||||
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
24
src/html.rs
24
src/html.rs
@@ -287,6 +287,7 @@ impl MsgId {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::chat::{self, Chat, forward_msgs, save_msgs};
|
use crate::chat::{self, Chat, forward_msgs, save_msgs};
|
||||||
|
|
||||||
use crate::constants;
|
use crate::constants;
|
||||||
use crate::contact::ContactId;
|
use crate::contact::ContactId;
|
||||||
use crate::message::{MessengerMessage, Viewtype};
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_html_save_msg() -> Result<()> {
|
async fn test_html_save_msg() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
// Alice receives a non-delta html-message
|
// Alice receives a non-delta html-message
|
||||||
let alice = TestContext::new_alice().await;
|
|
||||||
let chat = alice
|
let chat = alice
|
||||||
.create_chat_with_contact("", "sender@testrun.org")
|
.create_chat_with_contact("", "sender@testrun.org")
|
||||||
.await;
|
.await;
|
||||||
let raw = include_bytes!("../test-data/message/text_alt_plain_html.eml");
|
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;
|
let msg = alice.get_last_msg_in(chat.get_id()).await;
|
||||||
|
|
||||||
// Alice saves the message
|
// Alice saves the message
|
||||||
let self_chat = alice.get_self_chat().await;
|
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;
|
let saved_msg = alice.get_last_msg_in(self_chat.get_id()).await;
|
||||||
assert_ne!(saved_msg.id, msg.id);
|
assert_ne!(saved_msg.id, msg.id);
|
||||||
assert_eq!(
|
assert_eq!(saved_msg.get_original_msg_id(alice).await?.unwrap(), msg.id);
|
||||||
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!(!saved_msg.is_forwarded()); // UI should not flag "saved messages" as "forwarded"
|
||||||
assert_ne!(saved_msg.get_from_id(), ContactId::SELF);
|
assert_ne!(saved_msg.get_from_id(), ContactId::SELF);
|
||||||
assert_eq!(saved_msg.get_from_id(), msg.get_from_id());
|
assert_eq!(saved_msg.get_from_id(), msg.get_from_id());
|
||||||
assert_eq!(saved_msg.is_dc_message, MessengerMessage::No);
|
assert_eq!(saved_msg.is_dc_message, MessengerMessage::No);
|
||||||
assert!(saved_msg.get_text().contains("this is plain"));
|
assert!(saved_msg.get_text().contains("this is plain"));
|
||||||
assert!(saved_msg.has_html());
|
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 <b>html</b>"));
|
assert!(html.contains("this is <b>html</b>"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -618,18 +617,19 @@ test some special html-characters as < > and & but also " and &#x
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_cp1252_html() -> Result<()> {
|
async fn test_cp1252_html() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
alice,
|
||||||
include_bytes!("../test-data/message/cp1252-html.eml"),
|
include_bytes!("../test-data/message/cp1252-html.eml"),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let msg = t.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.viewtype, Viewtype::Text);
|
assert_eq!(msg.viewtype, Viewtype::Text);
|
||||||
assert!(msg.text.contains("foo bar ä ö ü ß"));
|
assert!(msg.text.contains("foo bar ä ö ü ß"));
|
||||||
assert!(msg.has_html());
|
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}");
|
println!("{html}");
|
||||||
assert!(html.contains("foo bar ä ö ü ß"));
|
assert!(html.contains("foo bar ä ö ü ß"));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -871,6 +871,7 @@ mod tests {
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::message::MessageState;
|
use crate::message::MessageState;
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{ExpectedEvents, TestContext, TestContextManager};
|
use crate::test_utils::{ExpectedEvents, TestContext, TestContextManager};
|
||||||
use crate::tools::SystemTime;
|
use crate::tools::SystemTime;
|
||||||
|
|
||||||
@@ -939,12 +940,15 @@ mod tests {
|
|||||||
/// Tests that location.kml is hidden.
|
/// Tests that location.kml is hidden.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn receive_location_kml() -> Result<()> {
|
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(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
|
&[alice],
|
||||||
br#"Subject: Hello
|
br#"Subject: Hello
|
||||||
Message-ID: hello@example.net
|
Message-ID: <hello@example.net>
|
||||||
To: Alice <alice@example.org>
|
To: Alice <alice@example.org>
|
||||||
From: Bob <bob@example.net>
|
From: Bob <bob@example.net>
|
||||||
Date: Mon, 20 Dec 2021 00:00:00 +0000
|
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
|
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
||||||
|
|
||||||
Text message."#,
|
Text message."#,
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
let received_msg = alice.get_last_msg().await;
|
let received_msg = alice.get_last_msg().await;
|
||||||
assert_eq!(received_msg.text, "Text message.");
|
assert_eq!(received_msg.text, "Text message.");
|
||||||
|
|
||||||
receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
|
&[alice],
|
||||||
br#"Subject: locations
|
br#"Subject: locations
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
To: <alice@example.org>
|
To: <alice@example.org>
|
||||||
@@ -986,16 +991,14 @@ Content-Disposition: attachment; filename="location.kml"
|
|||||||
</Document>
|
</Document>
|
||||||
</kml>
|
</kml>
|
||||||
|
|
||||||
--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#,
|
--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#).await?;
|
||||||
false,
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Received location message is not visible, last message stays the same.
|
// Received location message is not visible, last message stays the same.
|
||||||
let received_msg2 = alice.get_last_msg().await;
|
let received_msg2 = alice.get_last_msg().await;
|
||||||
assert_eq!(received_msg2.id, received_msg.id);
|
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);
|
assert_eq!(locations.len(), 1);
|
||||||
Ok(())
|
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.
|
/// Tests that `location.kml` is not hidden and not seen if it contains a message.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn receive_visible_location_kml() -> Result<()> {
|
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(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
bob,
|
||||||
|
&[alice],
|
||||||
br#"Subject: locations
|
br#"Subject: locations
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
To: <alice@example.org>
|
To: <alice@example.org>
|
||||||
@@ -1034,16 +1040,15 @@ Content-Disposition: attachment; filename="location.kml"
|
|||||||
</Document>
|
</Document>
|
||||||
</kml>
|
</kml>
|
||||||
|
|
||||||
--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#,
|
--U8BOG8qNXfB0GgLiQ3PKUjlvdIuLRF--"#).await?;
|
||||||
false,
|
|
||||||
)
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
let received_msg = alice.get_last_msg().await;
|
let received_msg = alice.get_last_msg().await;
|
||||||
assert_eq!(received_msg.text, "Text message.");
|
assert_eq!(received_msg.text, "Text message.");
|
||||||
assert_eq!(received_msg.state, MessageState::InFresh);
|
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);
|
assert_eq!(locations.len(), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,28 +56,25 @@ async fn test_get_width_height() {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_quote_basic() {
|
async fn test_quote_basic() {
|
||||||
let d = TestContext::new().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let ctx = &d.ctx;
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
ctx.set_config(Config::ConfiguredAddr, Some("self@example.com"))
|
let chat = alice.create_chat(bob).await;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let chat = d.create_chat_with_contact("", "dest@example.com").await;
|
|
||||||
let mut msg = Message::new_text("Quoted message".to_string());
|
let mut msg = Message::new_text("Quoted message".to_string());
|
||||||
|
|
||||||
// Message has to be sent such that it gets saved to db.
|
// Message has to be sent such that it gets saved to db.
|
||||||
chat::send_msg(ctx, chat.id, &mut msg).await.unwrap();
|
chat::send_msg(alice, chat.id, &mut msg).await.unwrap();
|
||||||
assert!(!msg.rfc724_mid.is_empty());
|
assert!(!msg.rfc724_mid.is_empty());
|
||||||
|
|
||||||
let mut msg2 = Message::new(Viewtype::Text);
|
let mut msg2 = Message::new(Viewtype::Text);
|
||||||
msg2.set_quote(ctx, Some(&msg))
|
msg2.set_quote(alice, Some(&msg))
|
||||||
.await
|
.await
|
||||||
.expect("can't set quote");
|
.expect("can't set quote");
|
||||||
assert_eq!(msg2.quoted_text().unwrap(), msg.get_text());
|
assert_eq!(msg2.quoted_text().unwrap(), msg.get_text());
|
||||||
|
|
||||||
let quoted_msg = msg2
|
let quoted_msg = msg2
|
||||||
.quoted_message(ctx)
|
.quoted_message(alice)
|
||||||
.await
|
.await
|
||||||
.expect("error while retrieving quoted message")
|
.expect("error while retrieving quoted message")
|
||||||
.expect("quoted message not found");
|
.expect("quoted message not found");
|
||||||
@@ -139,23 +136,14 @@ async fn test_unencrypted_quote_encrypted_message() -> Result<()> {
|
|||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_get_chat_id() {
|
async fn test_get_chat_id() {
|
||||||
// Alice receives a message that pops up as a contact request
|
// Alice receives a message that pops up as a contact request
|
||||||
let alice = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
receive_imf(
|
let alice = &tcm.alice().await;
|
||||||
&alice,
|
let bob = &tcm.bob().await;
|
||||||
b"From: Bob <bob@example.com>\n\
|
let chat_id = bob.create_chat_id(alice).await;
|
||||||
To: alice@example.org\n\
|
let sent = bob.send_text(chat_id, "hello").await;
|
||||||
Chat-Version: 1.0\n\
|
let msg = alice.recv_msg(&sent).await;
|
||||||
Message-ID: <123@example.com>\n\
|
|
||||||
Date: Fri, 29 Jan 2021 21:37:55 +0000\n\
|
|
||||||
\n\
|
|
||||||
hello\n",
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// check chat-id of this message
|
// check chat-id of this message
|
||||||
let msg = alice.get_last_msg().await;
|
|
||||||
assert!(!msg.get_chat_id().is_special());
|
assert!(!msg.get_chat_id().is_special());
|
||||||
assert_eq!(msg.get_text(), "hello".to_string());
|
assert_eq!(msg.get_text(), "hello".to_string());
|
||||||
}
|
}
|
||||||
@@ -465,7 +453,8 @@ async fn test_get_state() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_is_bot() -> Result<()> {
|
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.
|
// Alice receives an auto-generated non-chat message.
|
||||||
//
|
//
|
||||||
@@ -473,7 +462,7 @@ async fn test_is_bot() -> Result<()> {
|
|||||||
// in which case the message should be marked as bot-generated,
|
// in which case the message should be marked as bot-generated,
|
||||||
// but the contact should not.
|
// but the contact should not.
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: Claire <claire@example.com>\n\
|
b"From: Claire <claire@example.com>\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\n\
|
||||||
Message-ID: <789@example.com>\n\
|
Message-ID: <789@example.com>\n\
|
||||||
@@ -487,12 +476,12 @@ async fn test_is_bot() -> Result<()> {
|
|||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_text(), "hello".to_string());
|
assert_eq!(msg.get_text(), "hello".to_string());
|
||||||
assert!(msg.is_bot());
|
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());
|
assert!(!contact.is_bot());
|
||||||
|
|
||||||
// Alice receives a message from Bob the bot.
|
// Alice receives a message from Bob the bot.
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: Bob <bob@example.com>\n\
|
b"From: Bob <bob@example.com>\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\n\
|
||||||
Chat-Version: 1.0\n\
|
Chat-Version: 1.0\n\
|
||||||
@@ -507,12 +496,12 @@ async fn test_is_bot() -> Result<()> {
|
|||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_text(), "hello".to_string());
|
assert_eq!(msg.get_text(), "hello".to_string());
|
||||||
assert!(msg.is_bot());
|
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());
|
assert!(contact.is_bot());
|
||||||
|
|
||||||
// Alice receives a message from Bob who is not the bot anymore.
|
// Alice receives a message from Bob who is not the bot anymore.
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: Bob <bob@example.com>\n\
|
b"From: Bob <bob@example.com>\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\n\
|
||||||
Chat-Version: 1.0\n\
|
Chat-Version: 1.0\n\
|
||||||
@@ -526,7 +515,7 @@ async fn test_is_bot() -> Result<()> {
|
|||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_text(), "hello again".to_string());
|
assert_eq!(msg.get_text(), "hello again".to_string());
|
||||||
assert!(!msg.is_bot());
|
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());
|
assert!(!contact.is_bot());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -627,19 +616,15 @@ def hello():
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_delete_msgs_offline() -> Result<()> {
|
async fn test_delete_msgs_offline() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let chat = alice
|
let alice = &tcm.alice().await;
|
||||||
.create_chat_with_contact("Bob", "bob@example.org")
|
let bob = &tcm.bob().await;
|
||||||
.await;
|
let chat_id = alice.create_chat_id(bob).await;
|
||||||
let mut msg = Message::new_text("hi".to_string());
|
let mut msg = Message::new_text("hi".to_string());
|
||||||
assert!(
|
assert!(chat::send_msg_sync(alice, chat_id, &mut msg).await.is_err());
|
||||||
chat::send_msg_sync(&alice, chat.id, &mut msg)
|
|
||||||
.await
|
|
||||||
.is_err()
|
|
||||||
);
|
|
||||||
let stmt = "SELECT COUNT(*) FROM smtp WHERE msg_id=?";
|
let stmt = "SELECT COUNT(*) FROM smtp WHERE msg_id=?";
|
||||||
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
assert!(alice.sql.exists(stmt, (msg.id,)).await?);
|
||||||
delete_msgs(&alice, &[msg.id]).await?;
|
delete_msgs(alice, &[msg.id]).await?;
|
||||||
assert!(!alice.sql.exists(stmt, (msg.id,)).await?);
|
assert!(!alice.sql.exists(stmt, (msg.id,)).await?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use crate::headerdef::HeaderDef;
|
|||||||
use crate::message;
|
use crate::message;
|
||||||
use crate::mimeparser::MimeMessage;
|
use crate::mimeparser::MimeMessage;
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{TestContext, TestContextManager, get_chat_msg};
|
use crate::test_utils::{TestContext, TestContextManager, get_chat_msg};
|
||||||
use crate::tools::SystemTime;
|
use crate::tools::SystemTime;
|
||||||
|
|
||||||
@@ -132,14 +133,13 @@ async fn test_subject_from_mua() {
|
|||||||
// 1.: Receive a mail from an MUA
|
// 1.: Receive a mail from an MUA
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
msg_to_subject_str(
|
msg_to_subject_str(
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
From: Bob <bob@example.com>\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: Antw: Chat: hello\r\n\
|
||||||
Subject: Antw: Chat: hello\n\
|
Message-ID: <2222@example.net>\r\n\
|
||||||
Message-ID: <2222@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n"
|
||||||
hello\n"
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
"Re: Chat: hello"
|
"Re: Chat: hello"
|
||||||
@@ -147,14 +147,13 @@ async fn test_subject_from_mua() {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
msg_to_subject_str(
|
msg_to_subject_str(
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
From: Bob <bob@example.com>\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: Infos: 42\r\n\
|
||||||
Subject: Infos: 42\n\
|
Message-ID: <2222@example.net>\r\n\
|
||||||
Message-ID: <2222@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n"
|
||||||
hello\n"
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
"Re: Infos: 42"
|
"Re: Infos: 42"
|
||||||
@@ -166,15 +165,14 @@ async fn test_subject_from_dc() {
|
|||||||
// 2. Receive a message from Delta Chat
|
// 2. Receive a message from Delta Chat
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
msg_to_subject_str(
|
msg_to_subject_str(
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
b"From: bob@example.net\r\n\
|
||||||
From: bob@example.com\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: Chat: hello\r\n\
|
||||||
Subject: Chat: hello\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <2223@example.net>\r\n\
|
||||||
Message-ID: <2223@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n"
|
||||||
hello\n"
|
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
"Re: Chat: hello"
|
"Re: Chat: hello"
|
||||||
@@ -199,29 +197,27 @@ async fn test_subject_outgoing() {
|
|||||||
async fn test_subject_unicode() {
|
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)
|
// 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(
|
msg_to_subject_str(
|
||||||
"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
"From: bob@example.net\r\n\
|
||||||
From: bob@example.com\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: äääää\r\n\
|
||||||
Subject: äääää\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <2893@example.com>\r\n\
|
||||||
Message-ID: <2893@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n"
|
||||||
hello\n"
|
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
msg_to_subject_str(
|
msg_to_subject_str(
|
||||||
"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
"From: bob@example.net\r\n\
|
||||||
From: bob@example.com\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: aäääää\r\n\
|
||||||
Subject: aäääää\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <2893@example.com>\r\n\
|
||||||
Message-ID: <2893@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n"
|
||||||
hello\n"
|
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -230,54 +226,54 @@ async fn test_subject_unicode() {
|
|||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_subject_mdn() {
|
async fn test_subject_mdn() {
|
||||||
// 5. Receive an mdn (read receipt) and make sure the mdn's subject is not used
|
// 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(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
b"From: alice@example.org\r\n\
|
||||||
From: alice@example.org\n\
|
To: bob@example.net\r\n\
|
||||||
To: bob@example.com\n\
|
Subject: Hello, Bob\r\n\
|
||||||
Subject: Hello, Bob\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <2893@example.com>\r\n\
|
||||||
Message-ID: <2893@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n",
|
||||||
hello\n",
|
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut new_msg = incoming_msg_to_reply_msg(
|
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\
|
b"From: bob@example.net\r\n\
|
||||||
From: bob@example.com\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: message opened\r\n\
|
||||||
Subject: message opened\n\
|
Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 23:37:57 +0000\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <Mr.12345678902@example.com>\r\n\
|
||||||
Message-ID: <Mr.12345678902@example.com>\n\
|
Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\r\n\
|
||||||
Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\n\
|
\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
\n\
|
--SNIPP\r\n\
|
||||||
--SNIPP\n\
|
Content-Type: text/plain; charset=utf-8\r\n\
|
||||||
Content-Type: text/plain; charset=utf-8\n\
|
\r\n\
|
||||||
\n\
|
Read receipts do not guarantee sth. was read.\r\n\
|
||||||
Read receipts do not guarantee sth. was read.\n\
|
\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
\n\
|
--SNIPP\r\n\
|
||||||
--SNIPP\n\
|
Content-Type: message/disposition-notification\r\n\
|
||||||
Content-Type: message/disposition-notification\n\
|
\r\n\
|
||||||
\n\
|
Reporting-UA: Delta Chat 1.28.0\r\n\
|
||||||
Reporting-UA: Delta Chat 1.28.0\n\
|
Original-Recipient: rfc822;bob@example.com\r\n\
|
||||||
Original-Recipient: rfc822;bob@example.com\n\
|
Final-Recipient: rfc822;bob@example.com\r\n\
|
||||||
Final-Recipient: rfc822;bob@example.com\n\
|
Original-Message-ID: <2893@example.com>\r\n\
|
||||||
Original-Message-ID: <2893@example.com>\n\
|
Disposition: manual-action/MDN-sent-automatically; displayed\r\n\
|
||||||
Disposition: manual-action/MDN-sent-automatically; displayed\n\
|
\r\n", t, bob).await;
|
||||||
\n", &t).await;
|
chat::send_msg(t, new_msg.chat_id, &mut new_msg)
|
||||||
chat::send_msg(&t, new_msg.chat_id, &mut new_msg)
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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"
|
// 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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
@@ -294,9 +290,9 @@ async fn test_mdn_create_encrypted() -> Result<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
bob.set_config_bool(Config::MdnsEnabled, true).await?;
|
bob.set_config_bool(Config::MdnsEnabled, true).await?;
|
||||||
|
|
||||||
|
// MDN for unencrypted message is not encrypted.
|
||||||
let mut msg = Message::new(Viewtype::Text);
|
let mut msg = Message::new(Viewtype::Text);
|
||||||
msg.param.set_int(Param::SkipAutocrypt, 1);
|
let chat_alice = alice.create_email_chat(&bob).await.id;
|
||||||
let chat_alice = alice.create_chat(&bob).await.id;
|
|
||||||
let sent = alice.send_msg(chat_alice, &mut msg).await;
|
let sent = alice.send_msg(chat_alice, &mut msg).await;
|
||||||
|
|
||||||
let rcvd = bob.recv_msg(&sent).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;
|
let bob_alice_contact = bob.add_or_lookup_contact(&alice).await;
|
||||||
assert_eq!(bob_alice_contact.get_authname(), "Alice Exampleorg");
|
assert_eq!(bob_alice_contact.get_authname(), "Alice Exampleorg");
|
||||||
|
|
||||||
|
// MDN for encrypted message is encrypted.
|
||||||
let rcvd = tcm.send_recv(&alice, &bob, "Heyho").await;
|
let rcvd = tcm.send_recv(&alice, &bob, "Heyho").await;
|
||||||
message::markseen_msgs(&bob, vec![rcvd.id]).await?;
|
message::markseen_msgs(&bob, vec![rcvd.id]).await?;
|
||||||
|
|
||||||
let mimefactory = MimeFactory::from_mdn(&bob, rcvd.from_id, rcvd.rfc724_mid, vec![]).await?;
|
let mimefactory = MimeFactory::from_mdn(&bob, rcvd.from_id, rcvd.rfc724_mid, vec![]).await?;
|
||||||
let rendered_msg = mimefactory.render(&bob).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.is_encrypted);
|
||||||
assert!(!rendered_msg.message.contains("Bob Examplenet"));
|
assert!(!rendered_msg.message.contains("Bob Examplenet"));
|
||||||
assert!(!rendered_msg.message.contains("Alice Exampleorg"));
|
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()
|
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 {
|
async fn msg_to_subject_str(imf_raw: &[u8]) -> String {
|
||||||
let subject_str = msg_to_subject_str_inner(imf_raw, false, false, false).await;
|
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,
|
reply: bool,
|
||||||
message_arrives_inbetween: bool,
|
message_arrives_inbetween: bool,
|
||||||
) -> String {
|
) -> String {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let mut new_msg = incoming_msg_to_reply_msg(imf_raw, &t).await;
|
let t = &tcm.alice().await;
|
||||||
let incoming_msg = get_chat_msg(&t, new_msg.chat_id, 0, 1).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 {
|
if delete_original_msg {
|
||||||
incoming_msg.id.trash(&t, false).await.unwrap();
|
incoming_msg.id.trash(t, false).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if message_arrives_inbetween {
|
if message_arrives_inbetween {
|
||||||
receive_imf(
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
&t,
|
bob,
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
&[t],
|
||||||
From: Bob <bob@example.com>\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\r\n\
|
||||||
Subject: Some other, completely unrelated subject\n\
|
Subject: Some other, completely unrelated subject\r\n\
|
||||||
Message-ID: <3cl4@example.com>\n\
|
Message-ID: <3cl4@example.com>\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
Some other, completely unrelated content\n",
|
Some other, completely unrelated content\r\n",
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
receive_imf(t, encrypted_msg.as_bytes(), false)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let arrived_msg = t.get_last_msg().await;
|
let arrived_msg = t.get_last_msg().await;
|
||||||
assert_eq!(arrived_msg.chat_id, incoming_msg.chat_id);
|
assert_eq!(arrived_msg.chat_id, incoming_msg.chat_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if reply {
|
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
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mf = MimeFactory::from_msg(&t, new_msg).await.unwrap();
|
let mf = MimeFactory::from_msg(t, new_msg).await.unwrap();
|
||||||
mf.subject_str(&t).await.unwrap()
|
mf.subject_str(t).await.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a `Message` that replies "Hi" to the incoming email in `imf_raw`.
|
// 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 {
|
async fn incoming_msg_to_reply_msg(
|
||||||
receive_imf(context, imf_raw, false).await.unwrap();
|
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();
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
// This test could still be extended
|
// This test could still be extended
|
||||||
async fn test_render_reply() {
|
async fn test_render_reply() {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let context = &t;
|
let t = &tcm.alice().await;
|
||||||
|
let charlie = &tcm.charlie().await;
|
||||||
|
|
||||||
let mut msg = incoming_msg_to_reply_msg(
|
let mut msg = incoming_msg_to_reply_msg(
|
||||||
b"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
b"From: Charlie <charlie@example.net>\r\n\
|
||||||
From: Charlie <charlie@example.com>\n\
|
To: alice@example.org\r\n\
|
||||||
To: alice@example.org\n\
|
Subject: Chat: hello\r\n\
|
||||||
Subject: Chat: hello\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <2223@example.com>\r\n\
|
||||||
Message-ID: <2223@example.com>\n\
|
Date: Sun, 22 Mar 2020 22:37:56 +0000\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:56 +0000\n\
|
\r\n\
|
||||||
\n\
|
hello\r\n",
|
||||||
hello\n",
|
t,
|
||||||
context,
|
charlie,
|
||||||
)
|
)
|
||||||
.await;
|
.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();
|
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();
|
let mail = mailparse::parse_mail(rendered_msg.message.as_bytes()).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -557,7 +568,7 @@ async fn test_render_reply() {
|
|||||||
"1.0"
|
"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
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::{
|
|||||||
message::{MessageState, MessengerMessage},
|
message::{MessageState, MessengerMessage},
|
||||||
receive_imf::receive_imf,
|
receive_imf::receive_imf,
|
||||||
securejoin::QrInvite,
|
securejoin::QrInvite,
|
||||||
test_utils::{TestContext, TestContextManager},
|
test_utils::{self, TestContext, TestContextManager},
|
||||||
tools::time,
|
tools::time,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1503,96 +1503,89 @@ Some reply
|
|||||||
// Test that WantsMdn parameter is not set on outgoing messages.
|
// Test that WantsMdn parameter is not set on outgoing messages.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_outgoing_wants_mdn() -> Result<()> {
|
async fn test_outgoing_wants_mdn() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let bob = TestContext::new_bob().await;
|
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
|
let chat_id = alice.create_chat(bob).await.id;
|
||||||
Chat-Version: 1.0\n\
|
let sent = alice.send_text(chat_id, "Message.").await;
|
||||||
Message-ID: <foobarbaz@example.org>
|
|
||||||
To: Bob <bob@example.org>
|
|
||||||
From: Alice <alice@example.org>
|
|
||||||
Subject: subject
|
|
||||||
Chat-Disposition-Notification-To: alice@example.org
|
|
||||||
|
|
||||||
Message.
|
|
||||||
";
|
|
||||||
|
|
||||||
// Bob receives message.
|
// Bob receives message.
|
||||||
receive_imf(&bob, raw, false).await?;
|
let bob_msg = bob.recv_msg(&sent).await;
|
||||||
let msg = bob.get_last_msg().await;
|
|
||||||
// Message is incoming.
|
// 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.
|
// Alice receives copy-to-self.
|
||||||
receive_imf(&alice, raw, false).await?;
|
let alice2_msg = alice2.recv_msg(&sent).await;
|
||||||
let msg = alice.get_last_msg().await;
|
|
||||||
// Message is outgoing, don't send read receipt to self.
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_ignore_read_receipt_to_self() -> Result<()> {
|
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.
|
// Alice receives BCC-self copy of a message sent to Bob.
|
||||||
receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
alice,
|
||||||
"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
&[bob],
|
||||||
From: alice@example.org\n\
|
"From: alice@example.org\r\n\
|
||||||
To: bob@example.net\n\
|
To: bob@example.net\r\n\
|
||||||
Subject: foo\n\
|
Subject: foo\r\n\
|
||||||
Message-ID: first@example.com\n\
|
Message-ID: first@example.com\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Chat-Version: 1.0\r\n\
|
||||||
Chat-Disposition-Notification-To: alice@example.org\n\
|
Chat-Disposition-Notification-To: alice@example.org\r\n\
|
||||||
Date: Sun, 22 Mar 2020 22:37:57 +0000\n\
|
Date: Sun, 22 Mar 2020 22:37:57 +0000\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
hello\n"
|
hello\r\n"
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.state, MessageState::OutDelivered);
|
assert_eq!(msg.state, MessageState::OutDelivered);
|
||||||
|
|
||||||
// Due to a bug in the old version running on the other device, Alice receives a read
|
// Alice receives a read receipt from self.
|
||||||
// receipt from self.
|
//
|
||||||
receive_imf(
|
// This should mark the message as seen, i.e. not counted as fresh,
|
||||||
&alice,
|
// but not "read" (having double checkmark in the UI).
|
||||||
"Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
From: alice@example.org\n\
|
alice,
|
||||||
To: alice@example.org\n\
|
&[alice],
|
||||||
Subject: message opened\n\
|
"From: alice@example.org\r\n\
|
||||||
Date: Sun, 22 Mar 2020 23:37:57 +0000\n\
|
To: alice@example.org\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Subject: message opened\r\n\
|
||||||
Message-ID: second@example.com\n\
|
Date: Sun, 22 Mar 2020 23:37:57 +0000\r\n\
|
||||||
Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\n\
|
Chat-Version: 1.0\r\n\
|
||||||
\n\
|
Message-ID: second@example.com\r\n\
|
||||||
\n\
|
Content-Type: multipart/report; report-type=disposition-notification; boundary=\"SNIPP\"\r\n\
|
||||||
--SNIPP\n\
|
\r\n\
|
||||||
Content-Type: text/plain; charset=utf-8\n\
|
\r\n\
|
||||||
\n\
|
--SNIPP\r\n\
|
||||||
Read receipts do not guarantee sth. was read.\n\
|
Content-Type: text/plain; charset=utf-8\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
\n\
|
Read receipts do not guarantee sth. was read.\r\n\
|
||||||
--SNIPP\n\
|
\r\n\
|
||||||
Content-Type: message/disposition-notification\n\
|
\r\n\
|
||||||
\n\
|
--SNIPP\r\n\
|
||||||
Original-Recipient: rfc822;bob@example.com\n\
|
Content-Type: message/disposition-notification\r\n\
|
||||||
Final-Recipient: rfc822;bob@example.com\n\
|
\r\n\
|
||||||
Original-Message-ID: <first@example.com>\n\
|
Original-Recipient: rfc822;bob@example.com\r\n\
|
||||||
Disposition: manual-action/MDN-sent-automatically; displayed\n\
|
Final-Recipient: rfc822;bob@example.com\r\n\
|
||||||
\n\
|
Original-Message-ID: <first@example.com>\r\n\
|
||||||
\n\
|
Disposition: manual-action/MDN-sent-automatically; displayed\r\n\
|
||||||
--SNIPP--"
|
\r\n\
|
||||||
.as_bytes(),
|
\r\n\
|
||||||
false,
|
--SNIPP--".as_bytes()).await?;
|
||||||
)
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Check that the state has not changed to `MessageState::OutMdnRcvd`.
|
// 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);
|
assert_eq!(msg.state, MessageState::OutDelivered);
|
||||||
|
|
||||||
Ok(())
|
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.
|
/// recognize it as MDN nevertheless to avoid displaying it in the chat as normal message.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_ms_exchange_mdn() -> Result<()> {
|
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 =
|
let original =
|
||||||
include_bytes!("../../test-data/message/ms_exchange_report_original_message.eml");
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_jpeg_as_application_octet_stream() -> Result<()> {
|
async fn test_jpeg_as_application_octet_stream() -> Result<()> {
|
||||||
let context = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let raw = include_bytes!("../../test-data/message/jpeg-as-application-octet-stream.eml");
|
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
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(msg.parts.len(), 1);
|
assert_eq!(msg.parts.len(), 1);
|
||||||
assert_eq!(msg.parts[0].typ, Viewtype::Image);
|
assert_eq!(msg.parts[0].typ, Viewtype::Image);
|
||||||
|
|
||||||
receive_imf(&context, &raw[..], false).await?;
|
receive_imf(alice, encrypted_msg.as_bytes(), false).await?;
|
||||||
let msg = context.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.get_viewtype(), Viewtype::Image);
|
assert_eq!(msg.get_viewtype(), Viewtype::Image);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -2065,19 +2066,24 @@ async fn test_receive_signed_only() -> Result<()> {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_huge_image_becomes_file() -> Result<()> {
|
async fn test_huge_image_becomes_file() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let msg_id = receive_imf(
|
let alice = &tcm.alice().await;
|
||||||
&t,
|
let bob = &tcm.bob().await;
|
||||||
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
|
bob,
|
||||||
|
&[alice],
|
||||||
include_bytes!("../../test-data/message/image_huge_64M.eml"),
|
include_bytes!("../../test-data/message/image_huge_64M.eml"),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap()
|
|
||||||
.msg_ids[0];
|
let msg_id = receive_imf(alice, encrypted_msg.as_bytes(), false)
|
||||||
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
|
.await?
|
||||||
|
.unwrap()
|
||||||
|
.msg_ids[0];
|
||||||
|
let msg = Message::load_from_db(alice, msg_id).await.unwrap();
|
||||||
// Huge image should be treated as file:
|
// Huge image should be treated as file:
|
||||||
assert_eq!(msg.viewtype, Viewtype::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_filename().unwrap(), "huge_image.png");
|
||||||
assert_eq!(msg.get_filemime().unwrap(), "image/png");
|
assert_eq!(msg.get_filemime().unwrap(), "image/png");
|
||||||
// File has no width or height
|
// 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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_4k_image_stays_image() -> Result<()> {
|
async fn test_4k_image_stays_image() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let msg_id = receive_imf(
|
let alice = &tcm.alice().await;
|
||||||
&t,
|
let bob = &tcm.bob().await;
|
||||||
|
let encrypted_msg = test_utils::encrypt_raw_message(
|
||||||
|
bob,
|
||||||
|
&[alice],
|
||||||
include_bytes!("../../test-data/message/image_4k.eml"),
|
include_bytes!("../../test-data/message/image_4k.eml"),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap()
|
|
||||||
.msg_ids[0];
|
let msg_id = receive_imf(alice, encrypted_msg.as_bytes(), false)
|
||||||
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
|
.await?
|
||||||
|
.unwrap()
|
||||||
|
.msg_ids[0];
|
||||||
|
let msg = Message::load_from_db(alice, msg_id).await.unwrap();
|
||||||
// 4K image should be treated as image:
|
// 4K image should be treated as image:
|
||||||
assert_eq!(msg.viewtype, Viewtype::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_filename().unwrap(), "4k_image.png");
|
||||||
assert_eq!(msg.get_filemime().unwrap(), "image/png");
|
assert_eq!(msg.get_filemime().unwrap(), "image/png");
|
||||||
assert_eq!(msg.param.get_int(Param::Width).unwrap_or_default(), 3840);
|
assert_eq!(msg.param.get_int(Param::Width).unwrap_or_default(), 3840);
|
||||||
|
|||||||
@@ -335,18 +335,17 @@ impl Chat {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use deltachat_contact_tools::ContactAddress;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::chat::{forward_msgs, get_chat_msgs, marknoticed_chat, send_text_msg};
|
use crate::chat::{forward_msgs, get_chat_msgs, marknoticed_chat, send_text_msg};
|
||||||
use crate::chatlist::Chatlist;
|
use crate::chatlist::Chatlist;
|
||||||
use crate::config::Config;
|
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::key::{load_self_public_key, load_self_secret_key};
|
||||||
use crate::message::{MessageState, Viewtype, delete_msgs, markseen_msgs};
|
use crate::message::{MessageState, Viewtype, delete_msgs, markseen_msgs};
|
||||||
use crate::pgp::{SeipdVersion, pk_encrypt};
|
use crate::pgp::{SeipdVersion, pk_encrypt};
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
use crate::sql::housekeeping;
|
use crate::sql::housekeeping;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::E2EE_INFO_MSGS;
|
use crate::test_utils::E2EE_INFO_MSGS;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContext;
|
||||||
use crate::test_utils::TestContextManager;
|
use crate::test_utils::TestContextManager;
|
||||||
@@ -386,59 +385,54 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_receive_reaction() -> Result<()> {
|
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.
|
// Alice receives BCC-self copy of a message sent to Bob.
|
||||||
receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&alice,
|
alice,
|
||||||
"To: bob@example.net\n\
|
&[alice, bob],
|
||||||
From: alice@example.org\n\
|
b"To: bob@example.net\r\n\
|
||||||
Date: Today, 29 February 2021 00:00:00 -800\n\
|
From: alice@example.org\r\n\
|
||||||
Message-ID: 12345@example.org\n\
|
Date: Today, 29 February 2021 00:00:00 -800\r\n\
|
||||||
Subject: Meeting\n\
|
Message-ID: 12345@example.org\r\n\
|
||||||
\n\
|
Subject: Meeting\r\n\
|
||||||
Can we chat at 1pm pacific, today?"
|
\r\n\
|
||||||
.as_bytes(),
|
Can we chat at 1pm pacific, today?",
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
receive_imf(alice, encrypted_message.as_bytes(), false).await?;
|
||||||
let msg = alice.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.state, MessageState::OutDelivered);
|
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();
|
let contacts = reactions.contacts();
|
||||||
assert_eq!(contacts.len(), 0);
|
assert_eq!(contacts.len(), 0);
|
||||||
|
|
||||||
let bob_id = Contact::add_or_lookup(
|
let bob_id = alice.add_or_lookup_contact_id(bob).await;
|
||||||
&alice,
|
|
||||||
"",
|
|
||||||
&ContactAddress::new("bob@example.net")?,
|
|
||||||
Origin::ManuallyCreated,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.0;
|
|
||||||
let bob_reaction = reactions.get(bob_id);
|
let bob_reaction = reactions.get(bob_id);
|
||||||
assert!(bob_reaction.is_empty()); // Bob has not reacted to message yet.
|
assert!(bob_reaction.is_empty()); // Bob has not reacted to message yet.
|
||||||
|
|
||||||
// Alice receives reaction to her message from Bob.
|
// Alice receives reaction to her message from Bob.
|
||||||
receive_imf(
|
test_utils::receive_encrypted_imf(
|
||||||
&alice,
|
alice,
|
||||||
"To: alice@example.org\n\
|
bob,
|
||||||
From: bob@example.net\n\
|
"To: alice@example.org\r\n\
|
||||||
Date: Today, 29 February 2021 00:00:10 -800\n\
|
From: bob@example.net\r\n\
|
||||||
Message-ID: 56789@example.net\n\
|
Date: Today, 29 February 2021 00:00:10 -800\r\n\
|
||||||
In-Reply-To: 12345@example.org\n\
|
Message-ID: 56789@example.net\r\n\
|
||||||
Subject: Meeting\n\
|
In-Reply-To: 12345@example.org\r\n\
|
||||||
Mime-Version: 1.0 (1.0)\n\
|
Subject: Meeting\r\n\
|
||||||
Content-Type: text/plain; charset=utf-8\n\
|
Mime-Version: 1.0 (1.0)\r\n\
|
||||||
Content-Disposition: reaction\n\
|
Content-Type: text/plain; charset=utf-8\r\n\
|
||||||
\n\
|
Content-Disposition: reaction\r\n\
|
||||||
|
\r\n\
|
||||||
\u{1F44D}"
|
\u{1F44D}"
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.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");
|
assert_eq!(reactions.to_string(), "👍1");
|
||||||
|
|
||||||
let contacts = reactions.contacts();
|
let contacts = reactions.contacts();
|
||||||
@@ -451,8 +445,9 @@ Content-Disposition: reaction\n\
|
|||||||
assert_eq!(bob_reaction.as_str(), "👍");
|
assert_eq!(bob_reaction.as_str(), "👍");
|
||||||
|
|
||||||
// Alice receives reaction to her message from Bob with a footer.
|
// Alice receives reaction to her message from Bob with a footer.
|
||||||
receive_imf(
|
test_utils::receive_encrypted_imf(
|
||||||
&alice,
|
alice,
|
||||||
|
bob,
|
||||||
"To: alice@example.org\n\
|
"To: alice@example.org\n\
|
||||||
From: bob@example.net\n\
|
From: bob@example.net\n\
|
||||||
Date: Today, 29 February 2021 00:00:10 -800\n\
|
Date: Today, 29 February 2021 00:00:10 -800\n\
|
||||||
@@ -469,16 +464,16 @@ Content-Disposition: reaction\n\
|
|||||||
_______________________________________________\n\
|
_______________________________________________\n\
|
||||||
Here's my footer -- bob@example.net"
|
Here's my footer -- bob@example.net"
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.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");
|
assert_eq!(reactions.to_string(), "😀1");
|
||||||
|
|
||||||
// Alice receives a message with reaction to her message from Bob.
|
// Alice receives a message with reaction to her message from Bob.
|
||||||
let msg_bob = receive_imf(
|
let msg_bob = test_utils::receive_encrypted_imf(
|
||||||
&alice,
|
alice,
|
||||||
|
bob,
|
||||||
"To: alice@example.org\n\
|
"To: alice@example.org\n\
|
||||||
From: bob@example.net\n\
|
From: bob@example.net\n\
|
||||||
Date: Today, 29 February 2021 00:00:10 -800\n\
|
Date: Today, 29 February 2021 00:00:10 -800\n\
|
||||||
@@ -502,18 +497,16 @@ Content-Disposition: reaction\n\
|
|||||||
\n\
|
\n\
|
||||||
--YiEDa0DAkWCtVeE4--"
|
--YiEDa0DAkWCtVeE4--"
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap();
|
let msg_bob = Message::load_from_db(alice, msg_bob.msg_ids[0]).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.from_id, bob_id);
|
||||||
assert_eq!(msg_bob.chat_id, msg.chat_id);
|
assert_eq!(msg_bob.chat_id, msg.chat_id);
|
||||||
assert_eq!(msg_bob.viewtype, Viewtype::Text);
|
assert_eq!(msg_bob.viewtype, Viewtype::Text);
|
||||||
assert_eq!(msg_bob.state, MessageState::InFresh);
|
assert_eq!(msg_bob.state, MessageState::InFresh);
|
||||||
assert_eq!(msg_bob.hidden, false);
|
assert_eq!(msg_bob.hidden, false);
|
||||||
assert_eq!(msg_bob.text, "Reply + reaction");
|
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");
|
assert_eq!(reactions.to_string(), "👍1");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use crate::imap::prefetch_should_download;
|
|||||||
use crate::imex::{ImexMode, imex};
|
use crate::imex::{ImexMode, imex};
|
||||||
use crate::key;
|
use crate::key;
|
||||||
use crate::securejoin::get_securejoin_qr;
|
use crate::securejoin::get_securejoin_qr;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{
|
use crate::test_utils::{
|
||||||
TestContext, TestContextManager, alice_keypair, get_chat_msg, mark_as_verified,
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_dont_assign_to_trash_by_parent() {
|
async fn test_dont_assign_to_trash_by_parent() {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
println!("\n========= Receive a message ==========");
|
let alice = &tcm.alice().await;
|
||||||
receive_imf(
|
let bob = &tcm.bob().await;
|
||||||
&t,
|
let charlie = &tcm.charlie().await;
|
||||||
b"From: Nu Bar <nu@bar.org>\n\
|
|
||||||
To: alice@example.org, bob@example.org\n\
|
tcm.section("Receive a message");
|
||||||
Subject: Hi\n\
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
Message-ID: <4444@example.org>\n\
|
charlie,
|
||||||
\n\
|
&[alice, bob],
|
||||||
hello\n",
|
b"From: Charlie <charlie@example.net>\r\n\
|
||||||
false,
|
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
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let chat_id = t.get_last_msg().await.chat_id;
|
receive_imf(alice, encrypted_message.as_bytes(), false)
|
||||||
chat_id.accept(&t).await.unwrap();
|
.await
|
||||||
let msg = get_chat_msg(&t, chat_id, 0, 1).await; // Make sure that the message is actually in the chat
|
.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!(!msg.chat_id.is_special());
|
||||||
assert_eq!(msg.text, "Hi – hello");
|
assert_eq!(msg.text, "Hi – hello");
|
||||||
|
|
||||||
println!("\n========= Delete the message ==========");
|
tcm.section("Delete the message");
|
||||||
msg.id.trash(&t, false).await.unwrap();
|
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);
|
assert_eq!(msgs.len(), 0);
|
||||||
|
|
||||||
println!("\n========= Receive a message that is a reply to the deleted message ==========");
|
tcm.section("Receive a message that is a reply to the deleted message");
|
||||||
receive_imf(
|
let encrypted_message = test_utils::encrypt_raw_message(
|
||||||
&t,
|
charlie,
|
||||||
b"From: Nu Bar <nu@bar.org>\n\
|
&[alice, bob],
|
||||||
To: alice@example.org, bob@example.org\n\
|
b"From: Charlie <charlie@example.net>\r\n\
|
||||||
Subject: Re: Hi\n\
|
To: alice@example.org, bob@example.org\r\n\
|
||||||
Message-ID: <5555@example.org>\n\
|
Subject: Re: Hi\r\n\
|
||||||
In-Reply-To: <4444@example.org\n\
|
Message-ID: <5555@example.org>\r\n\
|
||||||
\n\
|
In-Reply-To: <4444@example.org\r\n\
|
||||||
Reply\n",
|
\r\n\
|
||||||
false,
|
Reply\r\n",
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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!(!msg.chat_id.is_special()); // Esp. check that the chat_id is not TRASH
|
||||||
assert_eq!(msg.text, "Reply");
|
assert_eq!(msg.text, "Reply");
|
||||||
}
|
}
|
||||||
@@ -1882,10 +1893,11 @@ async fn test_dont_show_all_outgoing_msgs_in_self_chat() {
|
|||||||
// Regression test for <https://github.com/deltachat/deltachat-android/issues/1940>:
|
// Regression test for <https://github.com/deltachat/deltachat-android/issues/1940>:
|
||||||
// Some servers add a `Bcc: <Self>` header, which caused all outgoing messages to
|
// Some servers add a `Bcc: <Self>` header, which caused all outgoing messages to
|
||||||
// be shown in the self-chat.
|
// be shown in the self-chat.
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
|
let t = &tcm.alice().await;
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
b"Bcc: alice@example.org
|
b"Bcc: alice@example.org
|
||||||
Received: from [127.0.0.1]
|
Received: from [127.0.0.1]
|
||||||
Subject: s
|
Subject: s
|
||||||
@@ -2222,11 +2234,12 @@ sig thursday",
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_chat_assignment_private_classical_reply() {
|
async fn test_chat_assignment_private_classical_reply() {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
for outgoing_is_classical in &[true, false] {
|
for outgoing_is_classical in &[true, false] {
|
||||||
let t = TestContext::new_alice().await;
|
let t = &tcm.alice().await;
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
||||||
Subject: =?utf-8?q?single_reply-to?=
|
Subject: =?utf-8?q?single_reply-to?=
|
||||||
@@ -2263,12 +2276,12 @@ Message-ID: <Gr.eJ_llQIXf0K.buxmrnMmG0Y@gmx.de>"
|
|||||||
"Hello, I've just created the group \"single reply-to\" for us."
|
"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.typ, Chattype::Group);
|
||||||
assert_eq!(group_chat.name, "single reply-to");
|
assert_eq!(group_chat.name, "single reply-to");
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Subject: Re: single reply-to
|
r#"Subject: Re: single reply-to
|
||||||
To: "Alice" <alice@example.org>
|
To: "Alice" <alice@example.org>
|
||||||
@@ -2297,7 +2310,7 @@ Private reply"#,
|
|||||||
|
|
||||||
let private_msg = t.get_last_msg().await;
|
let private_msg = t.get_last_msg().await;
|
||||||
assert_eq!(private_msg.text, "Private reply");
|
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_eq!(private_chat.typ, Chattype::Single);
|
||||||
assert_ne!(private_msg.chat_id, group_msg.chat_id);
|
assert_ne!(private_msg.chat_id, group_msg.chat_id);
|
||||||
}
|
}
|
||||||
@@ -2305,16 +2318,16 @@ Private reply"#,
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_chat_assignment_private_chat_reply() {
|
async fn test_chat_assignment_private_chat_reply() {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
for (outgoing_is_classical, outgoing_has_multiple_recipients) in
|
for (outgoing_is_classical, outgoing_has_multiple_recipients) in
|
||||||
&[(true, true), (false, true), (false, false)]
|
&[(true, true), (false, true), (false, false)]
|
||||||
{
|
{
|
||||||
let t = TestContext::new_alice().await;
|
let t = &tcm.alice().await;
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
r#"Subject: =?utf-8?q?single_reply-to?=
|
||||||
Subject: =?utf-8?q?single_reply-to?=
|
|
||||||
{}
|
{}
|
||||||
Date: Fri, 28 May 2021 10:15:05 +0000
|
Date: Fri, 28 May 2021 10:15:05 +0000
|
||||||
To: Bob <bob@example.com>, Charlie <charlie@example.net>{}
|
To: Bob <bob@example.com>, Charlie <charlie@example.net>{}
|
||||||
@@ -2352,12 +2365,12 @@ Message-ID: <Gr.iy1KCE2y65_.mH2TM52miv9@testrun.org>"
|
|||||||
"Hello, I've just created the group \"single reply-to\" for us."
|
"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.typ, Chattype::Group);
|
||||||
assert_eq!(group_chat.name, "single reply-to");
|
assert_eq!(group_chat.name, "single reply-to");
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Subject: =?utf-8?q?Re=3A_single_reply-to?=
|
r#"Subject: =?utf-8?q?Re=3A_single_reply-to?=
|
||||||
MIME-Version: 1.0
|
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;
|
let private_msg = t.get_last_msg().await;
|
||||||
assert_eq!(private_msg.text, "Private reply");
|
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_eq!(private_chat.typ, Chattype::Single);
|
||||||
assert_ne!(private_msg.chat_id, group_msg.chat_id);
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_chat_assignment_nonprivate_classical_reply() {
|
async fn test_chat_assignment_nonprivate_classical_reply() {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
for outgoing_is_classical in &[true, false] {
|
for outgoing_is_classical in &[true, false] {
|
||||||
let t = TestContext::new_alice().await;
|
let t = &tcm.alice().await;
|
||||||
|
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
||||||
Subject: =?utf-8?q?single_reply-to?=
|
Subject: =?utf-8?q?single_reply-to?=
|
||||||
@@ -2440,13 +2454,13 @@ Message-ID: <Gr.eJ_llQIXf0K.buxmrnMmG0Y@gmx.de>"
|
|||||||
"Hello, I've just created the group \"single reply-to\" for us."
|
"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.typ, Chattype::Group);
|
||||||
assert_eq!(group_chat.name, "single reply-to");
|
assert_eq!(group_chat.name, "single reply-to");
|
||||||
|
|
||||||
// =============== Receive another outgoing message and check that it is put into the same chat ===============
|
// =============== Receive another outgoing message and check that it is put into the same chat ===============
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
format!(
|
format!(
|
||||||
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
r#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
||||||
Subject: Out subj
|
Subject: Out subj
|
||||||
@@ -2471,13 +2485,13 @@ Outgoing reply to all"#,
|
|||||||
|
|
||||||
let reply = t.get_last_msg().await;
|
let reply = t.get_last_msg().await;
|
||||||
assert_eq!(reply.text, "Out subj – Outgoing reply to all");
|
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.typ, Chattype::Group);
|
||||||
assert_eq!(reply.chat_id, group_msg.chat_id);
|
assert_eq!(reply.chat_id, group_msg.chat_id);
|
||||||
|
|
||||||
// =============== Receive an incoming message and check that it is put into the same chat ===============
|
// =============== Receive an incoming message and check that it is put into the same chat ===============
|
||||||
receive_imf(
|
receive_imf(
|
||||||
&t,
|
t,
|
||||||
br#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
br#"Received: from mout.gmx.net (mout.gmx.net [212.227.17.22])
|
||||||
Subject: In subj
|
Subject: In subj
|
||||||
To: "Bob" <bob@example.com>, "Claire" <claire@example.com>
|
To: "Bob" <bob@example.com>, "Claire" <claire@example.com>
|
||||||
@@ -2494,7 +2508,7 @@ Reply to all"#,
|
|||||||
|
|
||||||
let reply = t.get_last_msg().await;
|
let reply = t.get_last_msg().await;
|
||||||
assert_eq!(reply.text, "In subj – Reply to all");
|
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.typ, Chattype::Group);
|
||||||
assert_eq!(reply.chat_id, group_msg.chat_id);
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_get_parent_message() -> Result<()> {
|
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
|
let mime = br#"Subject: First
|
||||||
Message-ID: first@example.net
|
Message-ID: first@example.net
|
||||||
@@ -2752,8 +2768,8 @@ From: Bob <bob@example.net>
|
|||||||
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
||||||
|
|
||||||
First."#;
|
First."#;
|
||||||
receive_imf(&t, mime, false).await?;
|
test_utils::receive_encrypted_imf(alice, bob, mime).await?;
|
||||||
let first = t.get_last_msg().await;
|
let first = alice.get_last_msg().await;
|
||||||
let mime = br#"Subject: Second
|
let mime = br#"Subject: Second
|
||||||
Message-ID: second@example.net
|
Message-ID: second@example.net
|
||||||
To: Alice <alice@example.org>
|
To: Alice <alice@example.org>
|
||||||
@@ -2761,8 +2777,8 @@ From: Bob <bob@example.net>
|
|||||||
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
||||||
|
|
||||||
First."#;
|
First."#;
|
||||||
receive_imf(&t, mime, false).await?;
|
test_utils::receive_encrypted_imf(alice, bob, mime).await?;
|
||||||
let second = t.get_last_msg().await;
|
let second = alice.get_last_msg().await;
|
||||||
let mime = br#"Subject: Third
|
let mime = br#"Subject: Third
|
||||||
Message-ID: third@example.net
|
Message-ID: third@example.net
|
||||||
To: Alice <alice@example.org>
|
To: Alice <alice@example.org>
|
||||||
@@ -2770,8 +2786,8 @@ From: Bob <bob@example.net>
|
|||||||
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
||||||
|
|
||||||
First."#;
|
First."#;
|
||||||
receive_imf(&t, mime, false).await?;
|
test_utils::receive_encrypted_imf(alice, bob, mime).await?;
|
||||||
let third = t.get_last_msg().await;
|
let third = alice.get_last_msg().await;
|
||||||
|
|
||||||
let mime = br#"Subject: Message with references.
|
let mime = br#"Subject: Message with references.
|
||||||
Message-ID: second@example.net
|
Message-ID: second@example.net
|
||||||
@@ -2782,21 +2798,22 @@ References: <second@example.net> <nonexistent@example.net> <first@example.net>
|
|||||||
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no
|
||||||
|
|
||||||
Message with references."#;
|
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);
|
assert_eq!(parent.id, first.id);
|
||||||
|
|
||||||
message::delete_msgs(&t, &[first.id]).await?;
|
message::delete_msgs(alice, &[first.id]).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, second.id);
|
assert_eq!(parent.id, second.id);
|
||||||
|
|
||||||
message::delete_msgs(&t, &[second.id]).await?;
|
message::delete_msgs(alice, &[second.id]).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, third.id);
|
assert_eq!(parent.id, third.id);
|
||||||
|
|
||||||
message::delete_msgs(&t, &[third.id]).await?;
|
message::delete_msgs(alice, &[third.id]).await?;
|
||||||
let parent = get_parent_message(&t, &mime_parser).await?;
|
let parent = get_parent_message(alice, &mime_parser).await?;
|
||||||
assert!(parent.is_none());
|
assert!(parent.is_none());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -3022,7 +3039,7 @@ async fn test_auto_accept_for_bots() -> Result<()> {
|
|||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_auto_accept_group_for_bots() -> Result<()> {
|
async fn test_auto_accept_group_for_bots() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
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 msg = load_imf_email(&t, GRP_MAIL).await;
|
||||||
|
|
||||||
let chat = chat::Chat::load_from_db(&t, msg.chat_id).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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_forged_from_and_no_valid_signatures() -> Result<()> {
|
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 raw = include_bytes!("../../test-data/message/thunderbird_encrypted_signed.eml");
|
||||||
let received_msg = receive_imf(t, raw, false).await?.unwrap();
|
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.chat_id.is_trash());
|
||||||
assert!(!msg.get_showpadlock());
|
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 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();
|
let received_msg = receive_imf(t, raw.as_bytes(), false).await?.unwrap();
|
||||||
assert!(received_msg.chat_id.is_trash());
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_big_forwarded_with_big_attachment() -> Result<()> {
|
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 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);
|
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_viewtype(), Viewtype::Text);
|
||||||
assert_eq!(msg.get_text(), "Hello!");
|
assert_eq!(msg.get_text(), "Hello!");
|
||||||
assert!(!msg.has_html());
|
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_eq!(msg.get_viewtype(), Viewtype::Text);
|
||||||
assert!(
|
assert!(
|
||||||
msg.get_text()
|
msg.get_text()
|
||||||
@@ -3528,10 +3548,10 @@ async fn test_big_forwarded_with_big_attachment() -> Result<()> {
|
|||||||
assert!(msg.get_text().ends_with("[...]"));
|
assert!(msg.get_text().ends_with("[...]"));
|
||||||
assert!(!msg.has_html());
|
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_eq!(msg.get_viewtype(), Viewtype::File);
|
||||||
assert!(msg.has_html());
|
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
|
let tail = html
|
||||||
.split_once("Hello!")
|
.split_once("Hello!")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -5133,10 +5153,12 @@ async fn test_recv_outgoing_msg_no_intended_recipient_fingerprint() -> Result<()
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_sanitize_filename_in_received() -> Result<()> {
|
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
|
let raw = b"Message-ID: Mr.XA6y3og8-az.WGbH9_dNcQx@testr
|
||||||
To: <tmp_5890965001269692@testrun.org>
|
To: <alice@example.org>
|
||||||
From: \"=?utf-8?q??=\" <tmp_6272287793210918@testrun.org>
|
From: \"=?utf-8?q??=\" <bob@example.net>
|
||||||
Content-Type: multipart/mixed; boundary=\"mwkNRwaJw1M5n2xcr2ODfAqvTjcj9Z\"
|
Content-Type: multipart/mixed; boundary=\"mwkNRwaJw1M5n2xcr2ODfAqvTjcj9Z\"
|
||||||
|
|
||||||
|
|
||||||
@@ -5155,7 +5177,7 @@ PGh0bWw+PGJvZHk+dGV4dDwvYm9keT5kYXRh
|
|||||||
|
|
||||||
--mwkNRwaJw1M5n2xcr2ODfAqvTjcj9Z--";
|
--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?;
|
let msg = Message::load_from_db(alice, msg.msg_ids[0]).await?;
|
||||||
|
|
||||||
assert_eq!(msg.get_filename().unwrap(), "test.HTML");
|
assert_eq!(msg.get_filename().unwrap(), "test.HTML");
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use pretty_assertions::assert_eq;
|
|||||||
use tempfile::{TempDir, tempdir};
|
use tempfile::{TempDir, tempdir};
|
||||||
use tokio::runtime::Handle;
|
use tokio::runtime::Handle;
|
||||||
use tokio::{fs, task};
|
use tokio::{fs, task};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::chat::{
|
use crate::chat::{
|
||||||
self, Chat, ChatId, ChatIdBlocked, MessageListOptions, add_to_chat_contacts_table, create_group,
|
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,
|
Contact, ContactId, Modifier, Origin, import_vcard, make_vcard, mark_contact_id_as_verified,
|
||||||
};
|
};
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::e2ee::EncryptHelper;
|
||||||
use crate::events::{Event, EventEmitter, EventType, Events};
|
use crate::events::{Event, EventEmitter, EventType, Events};
|
||||||
use crate::key::{self, DcKey, self_fingerprint};
|
use crate::key::{self, DcKey, self_fingerprint};
|
||||||
use crate::log::warn;
|
use crate::log::warn;
|
||||||
use crate::login_param::EnteredLoginParam;
|
use crate::login_param::EnteredLoginParam;
|
||||||
use crate::message::{Message, MessageState, MsgId, update_msg_state};
|
use crate::message::{Message, MessageState, MsgId, update_msg_state};
|
||||||
use crate::mimeparser::{MimeMessage, SystemMessage};
|
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::securejoin::{get_securejoin_qr, join_securejoin};
|
||||||
use crate::smtp::msg_has_pending_smtp_job;
|
use crate::smtp::msg_has_pending_smtp_job;
|
||||||
use crate::stock_str::StockStrings;
|
use crate::stock_str::StockStrings;
|
||||||
@@ -831,10 +834,7 @@ ORDER BY id"
|
|||||||
|
|
||||||
/// Receive a message using the `receive_imf()` pipeline. This is similar
|
/// 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.
|
/// to `recv_msg()`, but doesn't assume that the message is shown in the chat.
|
||||||
pub async fn recv_msg_opt(
|
pub async fn recv_msg_opt(&self, msg: &SentMessage<'_>) -> Option<ReceivedMsg> {
|
||||||
&self,
|
|
||||||
msg: &SentMessage<'_>,
|
|
||||||
) -> Option<crate::receive_imf::ReceivedMsg> {
|
|
||||||
receive_imf(self, msg.payload().as_bytes(), false)
|
receive_imf(self, msg.payload().as_bytes(), false)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -1231,6 +1231,68 @@ ORDER BY id"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn encrypt_raw_message(
|
||||||
|
context: &Context,
|
||||||
|
receivers: &[&TestContext],
|
||||||
|
payload: &[u8],
|
||||||
|
) -> Result<String> {
|
||||||
|
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<ReceivedMsg> {
|
||||||
|
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 {
|
impl Deref for TestContext {
|
||||||
type Target = Context;
|
type Target = Context;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use crate::mimeparser::SystemMessage;
|
|||||||
use crate::receive_imf::receive_imf;
|
use crate::receive_imf::receive_imf;
|
||||||
use crate::securejoin::{get_securejoin_qr, join_securejoin};
|
use crate::securejoin::{get_securejoin_qr, join_securejoin};
|
||||||
use crate::stock_str;
|
use crate::stock_str;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{
|
use crate::test_utils::{
|
||||||
E2EE_INFO_MSGS, TestContext, TestContextManager, get_chat_msg, mark_as_verified,
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_degrade_verified_oneonone_chat() -> Result<()> {
|
async fn test_degrade_verified_oneonone_chat() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
let alice = tcm.alice().await;
|
let alice = &tcm.alice().await;
|
||||||
let bob = tcm.bob().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(
|
receive_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: Bob <bob@example.net>\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
To: alice@example.org\n\
|
To: alice@example.org\r\n\
|
||||||
Message-ID: <1234-2@example.org>\n\
|
Message-ID: <1234-2@example.net>\r\n\
|
||||||
\n\
|
\r\n\
|
||||||
hello\n",
|
hello\r\n",
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let msg0 = get_chat_msg(&alice, alice_chat.id, 0, 1).await;
|
let msg0 = get_chat_msg(alice, alice_chat.id, 0, 1).await;
|
||||||
let enabled = stock_str::messages_e2ee_info_msg(&alice);
|
let enabled = stock_str::messages_e2ee_info_msg(alice);
|
||||||
assert_eq!(msg0.text, enabled);
|
assert_eq!(msg0.text, enabled);
|
||||||
assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatE2ee);
|
assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatE2ee);
|
||||||
|
|
||||||
let email_chat = alice.get_email_chat(&bob).await;
|
let email_chat = alice.get_email_chat(bob).await;
|
||||||
assert!(!email_chat.is_encrypted(&alice).await?);
|
assert!(!email_chat.is_encrypted(alice).await?);
|
||||||
let email_msg = get_chat_msg(&alice, email_chat.id, 0, 1).await;
|
let email_msg = get_chat_msg(alice, email_chat.id, 0, 1).await;
|
||||||
assert_eq!(email_msg.text, "hello".to_string());
|
assert_eq!(email_msg.text, "hello".to_string());
|
||||||
assert!(!email_msg.is_system_message());
|
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.
|
/// This test tests that the messages are still in the right order.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_old_message_4() -> Result<()> {
|
async fn test_old_message_4() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
let msg_incoming = receive_imf(
|
let alice = &tcm.alice().await;
|
||||||
&alice,
|
let bob = &tcm.bob().await;
|
||||||
b"From: Bob <bob@example.net>\n\
|
let msg_incoming = test_utils::receive_encrypted_imf(
|
||||||
To: alice@example.org\n\
|
alice,
|
||||||
Message-ID: <1234-2-3@example.org>\n\
|
bob,
|
||||||
Date: Sun, 08 Dec 2019 19:00:27 +0000\n\
|
b"From: Bob <bob@example.net>\r\n\
|
||||||
\n\
|
To: alice@example.org\r\n\
|
||||||
Thanks, Alice!\n",
|
Message-ID: <1234-2-3@example.org>\r\n\
|
||||||
true,
|
Date: Sun, 08 Dec 2019 19:00:27 +0000\r\n\
|
||||||
|
\r\n\
|
||||||
|
Thanks, Alice!\r\n",
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let msg_sent = receive_imf(
|
let msg_sent = test_utils::receive_encrypted_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: alice@example.org\n\
|
alice,
|
||||||
To: Bob <bob@example.net>\n\
|
b"From: alice@example.org\r\n\
|
||||||
Message-ID: <1234-2-4@example.org>\n\
|
To: Bob <bob@example.net>\r\n\
|
||||||
Date: Sat, 07 Dec 2019 19:00:27 +0000\n\
|
Message-ID: <1234-2-4@example.org>\r\n\
|
||||||
\n\
|
Date: Sat, 07 Dec 2019 19:00:27 +0000\r\n\
|
||||||
Happy birthday, Bob!\n",
|
\r\n\
|
||||||
true,
|
Happy birthday, Bob!\r\n",
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// The "Happy birthday" message should be shown first, and then the "Thanks" message
|
// The "Happy birthday" message should be shown first, and then the "Thanks" message
|
||||||
assert!(msg_sent.sort_timestamp < msg_incoming.sort_timestamp);
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_outgoing_mua_msg() -> Result<()> {
|
async fn test_outgoing_mua_msg() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
let alice = tcm.alice().await;
|
let alice = &tcm.alice().await;
|
||||||
let bob = tcm.bob().await;
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
mark_as_verified(&alice, &bob).await;
|
mark_as_verified(alice, bob).await;
|
||||||
mark_as_verified(&bob, &alice).await;
|
mark_as_verified(bob, alice).await;
|
||||||
|
|
||||||
tcm.send_recv_accept(&bob, &alice, "Heyho from DC").await;
|
tcm.send_recv_accept(bob, alice, "Heyho from DC").await;
|
||||||
assert_verified(&alice, &bob).await;
|
assert_verified(alice, bob).await;
|
||||||
|
|
||||||
let sent = receive_imf(
|
let sent = receive_imf(
|
||||||
&alice,
|
alice,
|
||||||
b"From: alice@example.org\n\
|
b"From: alice@example.org\n\
|
||||||
To: bob@example.net\n\
|
To: bob@example.net\n\
|
||||||
\n\
|
\n\
|
||||||
@@ -288,7 +289,7 @@ async fn test_outgoing_mua_msg() -> Result<()> {
|
|||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.unwrap();
|
.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.
|
// Unencrypted message from MUA gets into a separate chat.
|
||||||
// PGP chat gets all encrypted messages.
|
// 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")
|
.golden_test_chat(sent.chat_id, "test_outgoing_mua_msg")
|
||||||
.await;
|
.await;
|
||||||
alice
|
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;
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ impl Params {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::chat::Chat;
|
use crate::chat::Chat;
|
||||||
use crate::receive_imf::receive_imf;
|
use crate::test_utils;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContextManager;
|
||||||
use crate::tools::time;
|
use crate::tools::time;
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
@@ -115,37 +115,39 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_out_of_order_subject() -> Result<()> {
|
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(
|
test_utils::receive_encrypted_imf(
|
||||||
&t,
|
alice,
|
||||||
b"From: Bob Authname <bob@example.org>\n\
|
bob,
|
||||||
To: alice@example.org\n\
|
b"From: Bob Authname <bob@example.net>\r\n\
|
||||||
Subject: updated subject\n\
|
To: alice@example.org\r\n\
|
||||||
Message-ID: <msg2@example.org>\n\
|
Subject: updated subject\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <msg2@example.org>\r\n\
|
||||||
Date: Sun, 22 Mar 2021 23:37:57 +0000\n\
|
Chat-Version: 1.0\r\n\
|
||||||
\n\
|
Date: Sun, 22 Mar 2021 23:37:57 +0000\r\n\
|
||||||
second message\n",
|
\r\n\
|
||||||
false,
|
second message\r\n",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
receive_imf(
|
test_utils::receive_encrypted_imf(
|
||||||
&t,
|
alice,
|
||||||
b"From: Bob Authname <bob@example.org>\n\
|
bob,
|
||||||
To: alice@example.org\n\
|
b"From: Bob Authname <bob@example.net>\r\n\
|
||||||
Subject: original subject\n\
|
To: alice@example.org\r\n\
|
||||||
Message-ID: <msg1@example.org>\n\
|
Subject: original subject\r\n\
|
||||||
Chat-Version: 1.0\n\
|
Message-ID: <msg1@example.org>\r\n\
|
||||||
Date: Sun, 22 Mar 2021 22:37:57 +0000\n\
|
Chat-Version: 1.0\r\n\
|
||||||
\n\
|
Date: Sun, 22 Mar 2021 22:37:57 +0000\r\n\
|
||||||
first message\n",
|
\r\n\
|
||||||
false,
|
first message\r\n",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let msg = t.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
let chat = Chat::load_from_db(&t, msg.chat_id).await?;
|
let chat = Chat::load_from_db(alice, msg.chat_id).await?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
chat.param.get(Param::LastSubject).unwrap(),
|
chat.param.get(Param::LastSubject).unwrap(),
|
||||||
"updated subject"
|
"updated subject"
|
||||||
|
|||||||
@@ -169,49 +169,54 @@ pub(crate) async fn intercept_get_updates(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::chat::{ChatId, create_group};
|
use crate::chat::create_group;
|
||||||
use crate::chatlist::Chatlist;
|
use crate::chatlist::Chatlist;
|
||||||
use crate::contact::Contact;
|
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
use crate::test_utils::TestContext;
|
use crate::test_utils::TestContextManager;
|
||||||
use crate::webxdc::StatusUpdateSerial;
|
use crate::webxdc::StatusUpdateSerial;
|
||||||
use crate::{EventType, location};
|
use crate::{EventType, location};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_maps_integration() -> Result<()> {
|
async fn test_maps_integration() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
let bytes = include_bytes!("../../test-data/webxdc/mapstest-integration-set.xdc");
|
let bytes = include_bytes!("../../test-data/webxdc/mapstest-integration-set.xdc");
|
||||||
let file = t.get_blobdir().join("maps.xdc");
|
let file = alice.get_blobdir().join("maps.xdc");
|
||||||
tokio::fs::write(&file, bytes).await.unwrap();
|
tokio::fs::write(&file, bytes).await.unwrap();
|
||||||
t.set_webxdc_integration(file.to_str().unwrap()).await?;
|
alice.set_webxdc_integration(file.to_str().unwrap()).await?;
|
||||||
|
|
||||||
let chatlist = Chatlist::try_load(&t, 0, None, None).await?;
|
let chatlist = Chatlist::try_load(alice, 0, None, None).await?;
|
||||||
let summary = chatlist.get_summary(&t, 0, None).await?;
|
let summary = chatlist.get_summary(alice, 0, None).await?;
|
||||||
assert_eq!(summary.text, "No messages.");
|
assert_eq!(summary.text, "No messages.");
|
||||||
|
|
||||||
// Integrate Webxdc into a chat with Bob;
|
// Integrate Webxdc into a chat with Bob;
|
||||||
// sending updates is intercepted by integrations and results in setting a POI in core
|
// sending updates is intercepted by integrations and results in setting a POI in core
|
||||||
let bob_id = Contact::create(&t, "", "bob@example.net").await?;
|
let bob_chat_id = alice.create_chat_id(bob).await;
|
||||||
let bob_chat_id = ChatId::create_for_contact(&t, bob_id).await?;
|
let integration_id = alice
|
||||||
let integration_id = t.init_webxdc_integration(Some(bob_chat_id)).await?.unwrap();
|
.init_webxdc_integration(Some(bob_chat_id))
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
assert!(!integration_id.is_special());
|
assert!(!integration_id.is_special());
|
||||||
|
|
||||||
let integration = Message::load_from_db(&t, integration_id).await?;
|
let integration = Message::load_from_db(alice, integration_id).await?;
|
||||||
let info = integration.get_webxdc_info(&t).await?;
|
let info = integration.get_webxdc_info(alice).await?;
|
||||||
assert_eq!(info.name, "Maps Test 2");
|
assert_eq!(info.name, "Maps Test 2");
|
||||||
assert_eq!(info.internet_access, true);
|
assert_eq!(info.internet_access, true);
|
||||||
|
|
||||||
t.send_webxdc_status_update(
|
alice
|
||||||
integration_id,
|
.send_webxdc_status_update(
|
||||||
r#"{"payload": {"action": "pos", "lat": 11.0, "lng": 12.0, "label": "poi #1"}}"#,
|
integration_id,
|
||||||
)
|
r#"{"payload": {"action": "pos", "lat": 11.0, "lng": 12.0, "label": "poi #1"}}"#,
|
||||||
.await?;
|
)
|
||||||
t.evtracker
|
.await?;
|
||||||
|
alice
|
||||||
|
.evtracker
|
||||||
.get_matching(|evt| matches!(evt, EventType::WebxdcStatusUpdate { .. }))
|
.get_matching(|evt| matches!(evt, EventType::WebxdcStatusUpdate { .. }))
|
||||||
.await;
|
.await;
|
||||||
let updates = t
|
let updates = alice
|
||||||
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
||||||
.await?;
|
.await?;
|
||||||
assert!(updates.contains(r#""lat":11"#));
|
assert!(updates.contains(r#""lat":11"#));
|
||||||
@@ -220,28 +225,32 @@ mod tests {
|
|||||||
assert!(updates.contains(r#""contactId":"#)); // checking for sth. that is not in the sent update make sure integration is called
|
assert!(updates.contains(r#""contactId":"#)); // checking for sth. that is not in the sent update make sure integration is called
|
||||||
assert!(updates.contains(r#""name":"Me""#));
|
assert!(updates.contains(r#""name":"Me""#));
|
||||||
assert!(updates.contains(r##""color":"#"##));
|
assert!(updates.contains(r##""color":"#"##));
|
||||||
let locations = location::get_range(&t, Some(bob_chat_id), None, 0, 0).await?;
|
let locations = location::get_range(alice, Some(bob_chat_id), None, 0, 0).await?;
|
||||||
assert_eq!(locations.len(), 1);
|
assert_eq!(locations.len(), 1);
|
||||||
let location = locations.last().unwrap();
|
let location = locations.last().unwrap();
|
||||||
assert_eq!(location.latitude, 11.0);
|
assert_eq!(location.latitude, 11.0);
|
||||||
assert_eq!(location.longitude, 12.0);
|
assert_eq!(location.longitude, 12.0);
|
||||||
assert_eq!(location.independent, 1);
|
assert_eq!(location.independent, 1);
|
||||||
let msg = t.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.text, "poi #1");
|
assert_eq!(msg.text, "poi #1");
|
||||||
assert_eq!(msg.chat_id, bob_chat_id);
|
assert_eq!(msg.chat_id, bob_chat_id);
|
||||||
|
|
||||||
// Integrate Webxdc into another group
|
// Integrate Webxdc into another group
|
||||||
let group_id = create_group(&t, "foo").await?;
|
let group_id = create_group(alice, "foo").await?;
|
||||||
let integration_id = t.init_webxdc_integration(Some(group_id)).await?.unwrap();
|
let integration_id = alice
|
||||||
|
.init_webxdc_integration(Some(group_id))
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let locations = location::get_range(&t, Some(group_id), None, 0, 0).await?;
|
let locations = location::get_range(alice, Some(group_id), None, 0, 0).await?;
|
||||||
assert_eq!(locations.len(), 0);
|
assert_eq!(locations.len(), 0);
|
||||||
t.send_webxdc_status_update(
|
alice
|
||||||
integration_id,
|
.send_webxdc_status_update(
|
||||||
r#"{"payload": {"action": "pos", "lat": 22.0, "lng": 23.0, "label": "poi #2"}}"#,
|
integration_id,
|
||||||
)
|
r#"{"payload": {"action": "pos", "lat": 22.0, "lng": 23.0, "label": "poi #2"}}"#,
|
||||||
.await?;
|
)
|
||||||
let updates = t
|
.await?;
|
||||||
|
let updates = alice
|
||||||
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
||||||
.await?;
|
.await?;
|
||||||
assert!(!updates.contains(r#""lat":11"#));
|
assert!(!updates.contains(r#""lat":11"#));
|
||||||
@@ -249,27 +258,27 @@ mod tests {
|
|||||||
assert!(updates.contains(r#""lat":22"#));
|
assert!(updates.contains(r#""lat":22"#));
|
||||||
assert!(updates.contains(r#""lng":23"#));
|
assert!(updates.contains(r#""lng":23"#));
|
||||||
assert!(updates.contains(r#""label":"poi #2""#));
|
assert!(updates.contains(r#""label":"poi #2""#));
|
||||||
let locations = location::get_range(&t, Some(group_id), None, 0, 0).await?;
|
let locations = location::get_range(alice, Some(group_id), None, 0, 0).await?;
|
||||||
assert_eq!(locations.len(), 1);
|
assert_eq!(locations.len(), 1);
|
||||||
let location = locations.last().unwrap();
|
let location = locations.last().unwrap();
|
||||||
assert_eq!(location.latitude, 22.0);
|
assert_eq!(location.latitude, 22.0);
|
||||||
assert_eq!(location.longitude, 23.0);
|
assert_eq!(location.longitude, 23.0);
|
||||||
assert_eq!(location.independent, 1);
|
assert_eq!(location.independent, 1);
|
||||||
let msg = t.get_last_msg().await;
|
let msg = alice.get_last_msg().await;
|
||||||
assert_eq!(msg.text, "poi #2");
|
assert_eq!(msg.text, "poi #2");
|
||||||
assert_eq!(msg.chat_id, group_id);
|
assert_eq!(msg.chat_id, group_id);
|
||||||
|
|
||||||
// In global map, both POI are visible
|
// In global map, both POI are visible
|
||||||
let integration_id = t.init_webxdc_integration(None).await?.unwrap();
|
let integration_id = alice.init_webxdc_integration(None).await?.unwrap();
|
||||||
|
|
||||||
let updates = t
|
let updates = alice
|
||||||
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
.get_webxdc_status_updates(integration_id, StatusUpdateSerial(0))
|
||||||
.await?;
|
.await?;
|
||||||
assert!(updates.contains(r#""lat":11"#));
|
assert!(updates.contains(r#""lat":11"#));
|
||||||
assert!(updates.contains(r#""label":"poi #1""#));
|
assert!(updates.contains(r#""label":"poi #1""#));
|
||||||
assert!(updates.contains(r#""lat":22"#));
|
assert!(updates.contains(r#""lat":22"#));
|
||||||
assert!(updates.contains(r#""label":"poi #2""#));
|
assert!(updates.contains(r#""label":"poi #2""#));
|
||||||
let locations = location::get_range(&t, None, None, 0, 0).await?;
|
let locations = location::get_range(alice, None, None, 0, 0).await?;
|
||||||
assert_eq!(locations.len(), 2);
|
assert_eq!(locations.len(), 2);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ use crate::chat::{
|
|||||||
use crate::chatlist::Chatlist;
|
use crate::chatlist::Chatlist;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::ephemeral;
|
use crate::ephemeral;
|
||||||
use crate::receive_imf::receive_imf;
|
|
||||||
use crate::securejoin::get_securejoin_qr;
|
use crate::securejoin::get_securejoin_qr;
|
||||||
|
use crate::test_utils;
|
||||||
use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager};
|
use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager};
|
||||||
use crate::tools::{self, SystemTime};
|
use crate::tools::{self, SystemTime};
|
||||||
use crate::{message, sql};
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_receive_webxdc_instance() -> Result<()> {
|
async fn test_receive_webxdc_instance() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
receive_imf(
|
let alice = &tcm.alice().await;
|
||||||
&t,
|
let bob = &tcm.bob().await;
|
||||||
|
test_utils::receive_encrypted_imf(
|
||||||
|
alice,
|
||||||
|
bob,
|
||||||
include_bytes!("../../test-data/message/webxdc_good_extension.eml"),
|
include_bytes!("../../test-data/message/webxdc_good_extension.eml"),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let instance = t.get_last_msg().await;
|
let instance = alice.get_last_msg().await;
|
||||||
assert_eq!(instance.viewtype, Viewtype::Webxdc);
|
assert_eq!(instance.viewtype, Viewtype::Webxdc);
|
||||||
assert_eq!(instance.get_filename().unwrap(), "minimal.xdc");
|
assert_eq!(instance.get_filename().unwrap(), "minimal.xdc");
|
||||||
|
|
||||||
receive_imf(
|
test_utils::receive_encrypted_imf(
|
||||||
&t,
|
alice,
|
||||||
|
bob,
|
||||||
include_bytes!("../../test-data/message/webxdc_bad_extension.eml"),
|
include_bytes!("../../test-data/message/webxdc_bad_extension.eml"),
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.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.viewtype, Viewtype::File); // we require the correct extension, only a mime type is not sufficient
|
||||||
assert_eq!(instance.get_filename().unwrap(), "index.html");
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_send_webxdc_status_update() -> Result<()> {
|
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?;
|
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
|
// Alice sends an webxdc instance and a status update
|
||||||
let alice_chat = alice.create_email_chat(&bob).await;
|
let alice_chat = alice.create_email_chat(bob).await;
|
||||||
let alice_instance = send_webxdc_instance(&alice, alice_chat.id).await?;
|
let alice_instance = send_webxdc_instance(alice, alice_chat.id).await?;
|
||||||
let sent1 = &alice.pop_sent_msg().await;
|
let sent1 = &alice.pop_sent_msg().await;
|
||||||
assert_eq!(alice_instance.viewtype, Viewtype::Webxdc);
|
assert_eq!(alice_instance.viewtype, Viewtype::Webxdc);
|
||||||
assert!(!sent1.payload().contains("report-type=status-update"));
|
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"}}"#)
|
.send_webxdc_status_update(alice_instance.id, r#"{"payload" : {"foo":"bar"}}"#)
|
||||||
.await?;
|
.await?;
|
||||||
alice.flush_status_updates().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 sent2 = &alice.pop_sent_msg().await;
|
||||||
let alice_update = sent2.load_from_db().await;
|
let alice_update = sent2.load_from_db().await;
|
||||||
assert!(alice_update.hidden);
|
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.text, BODY_DESCR.to_string());
|
||||||
assert_eq!(alice_update.chat_id, alice_instance.chat_id);
|
assert_eq!(alice_update.chat_id, alice_instance.chat_id);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
alice_update.parent(&alice).await?.unwrap().id,
|
alice_update.parent(alice).await?.unwrap().id,
|
||||||
alice_instance.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("report-type=status-update"));
|
||||||
assert!(sent2.payload().contains(BODY_DESCR));
|
assert!(sent2.payload().contains(BODY_DESCR));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -735,12 +738,12 @@ async fn test_send_webxdc_status_update() -> Result<()> {
|
|||||||
let bob_chat_id = bob_instance.chat_id;
|
let bob_chat_id = bob_instance.chat_id;
|
||||||
assert_eq!(bob_instance.rfc724_mid, alice_instance.rfc724_mid);
|
assert_eq!(bob_instance.rfc724_mid, alice_instance.rfc724_mid);
|
||||||
assert_eq!(bob_instance.viewtype, Viewtype::Webxdc);
|
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;
|
let bob_received_update = bob.recv_msg_opt(sent2).await;
|
||||||
assert!(bob_received_update.is_none());
|
assert!(bob_received_update.is_none());
|
||||||
expect_status_update_event(&bob, bob_instance.id).await?;
|
expect_status_update_event(bob, bob_instance.id).await?;
|
||||||
assert_eq!(bob_chat_id.get_msg_cnt(&bob).await?, 1);
|
assert_eq!(bob_chat_id.get_msg_cnt(bob).await?, 1);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bob.get_webxdc_status_updates(bob_instance.id, StatusUpdateSerial(0))
|
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
|
// 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(sent1).await;
|
||||||
alice2.recv_msg_trash(sent2).await;
|
alice2.recv_msg_trash(sent2).await;
|
||||||
let alice2_instance = alice2.get_last_msg().await;
|
let alice2_instance = alice2.get_last_msg().await;
|
||||||
let alice2_chat_id = alice2_instance.chat_id;
|
let alice2_chat_id = alice2_instance.chat_id;
|
||||||
assert_eq!(alice2_instance.viewtype, Viewtype::Webxdc);
|
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;
|
// To support the second device, Alice has enabled bcc_self and will receive their own messages;
|
||||||
// these messages, however, should be ignored
|
// these messages, however, should be ignored
|
||||||
alice.recv_msg_opt(sent1).await;
|
alice.recv_msg_opt(sent1).await;
|
||||||
alice.recv_msg_opt(sent2).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!(
|
assert_eq!(
|
||||||
alice
|
alice
|
||||||
.get_webxdc_status_updates(alice_instance.id, StatusUpdateSerial(0))
|
.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<()> {
|
async fn test_draft_and_send_webxdc_status_update() -> Result<()> {
|
||||||
let alice = TestContext::new_alice().await;
|
let alice = TestContext::new_alice().await;
|
||||||
let bob = TestContext::new_bob().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,
|
// prepare webxdc instance,
|
||||||
// status updates are not sent for drafts, therefore send_webxdc_status_update() returns Ok(None)
|
// 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;
|
let bob_instance = bob.recv_msg(&sent1).await;
|
||||||
assert_eq!(bob_instance.viewtype, Viewtype::Webxdc);
|
assert_eq!(bob_instance.viewtype, Viewtype::Webxdc);
|
||||||
assert_eq!(bob_instance.get_filename().unwrap(), "minimal.xdc");
|
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!(
|
assert_eq!(
|
||||||
bob.get_webxdc_status_updates(bob_instance.id, StatusUpdateSerial(0))
|
bob.get_webxdc_status_updates(bob_instance.id, StatusUpdateSerial(0))
|
||||||
.await?,
|
.await?,
|
||||||
@@ -1557,16 +1558,18 @@ async fn test_webxdc_info_msg_no_cleanup_on_interrupted_series() -> Result<()> {
|
|||||||
// even if they use the deprecated option `request_internet_access` in manifest.toml
|
// even if they use the deprecated option `request_internet_access` in manifest.toml
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_webxdc_no_internet_access() -> Result<()> {
|
async fn test_webxdc_no_internet_access() -> Result<()> {
|
||||||
let t = TestContext::new_alice().await;
|
let mut tcm = TestContextManager::new();
|
||||||
|
let t = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
let self_id = t.get_self_chat().await.id;
|
let self_id = t.get_self_chat().await.id;
|
||||||
let single_id = t.create_chat_with_contact("bob", "bob@e.com").await.id;
|
let single_id = t.create_chat_id(bob).await;
|
||||||
let group_id = create_group(&t, "chat").await?;
|
let group_id = create_group(t, "chat").await?;
|
||||||
let broadcast_id = create_broadcast(&t, "Channel".to_string()).await?;
|
let broadcast_id = create_broadcast(t, "Channel".to_string()).await?;
|
||||||
|
|
||||||
for chat_id in [self_id, single_id, group_id, broadcast_id] {
|
for chat_id in [self_id, single_id, group_id, broadcast_id] {
|
||||||
for internet_xdc in [true, false] {
|
for internet_xdc in [true, false] {
|
||||||
let mut instance = create_webxdc_instance(
|
let mut instance = create_webxdc_instance(
|
||||||
&t,
|
t,
|
||||||
"foo.xdc",
|
"foo.xdc",
|
||||||
if internet_xdc {
|
if internet_xdc {
|
||||||
include_bytes!("../../test-data/webxdc/request-internet-access.xdc")
|
include_bytes!("../../test-data/webxdc/request-internet-access.xdc")
|
||||||
@@ -1574,14 +1577,14 @@ async fn test_webxdc_no_internet_access() -> Result<()> {
|
|||||||
include_bytes!("../../test-data/webxdc/minimal.xdc")
|
include_bytes!("../../test-data/webxdc/minimal.xdc")
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
let instance_id = send_msg(&t, chat_id, &mut instance).await?;
|
let instance_id = send_msg(t, chat_id, &mut instance).await?;
|
||||||
t.send_webxdc_status_update(
|
t.send_webxdc_status_update(
|
||||||
instance_id,
|
instance_id,
|
||||||
r#"{"summary":"real summary", "payload": 42}"#,
|
r#"{"summary":"real summary", "payload": 42}"#,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let instance = Message::load_from_db(&t, instance_id).await?;
|
let instance = Message::load_from_db(t, instance_id).await?;
|
||||||
let info = instance.get_webxdc_info(&t).await?;
|
let info = instance.get_webxdc_info(t).await?;
|
||||||
assert_eq!(info.internet_access, false);
|
assert_eq!(info.internet_access, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)
|
From: Test Sender <bob@example.net>
|
||||||
From: Test Sender <sender@testrun.org>
|
|
||||||
Subject: Large image test
|
Subject: Large image test
|
||||||
To: alice@example.org
|
To: alice@example.org
|
||||||
Message-ID: <big-image-test@testrun.org>
|
Message-ID: <big-image-test@testrun.org>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)
|
From: Test Sender <bob@example.net>
|
||||||
From: Test Sender <sender@testrun.org>
|
|
||||||
Subject: Large image test
|
Subject: Large image test
|
||||||
To: alice@example.org
|
To: alice@example.org
|
||||||
Message-ID: <huge-image-test@testrun.org>
|
Message-ID: <huge-image-test@localhost>
|
||||||
Date: Thu, 17 Dec 2020 15:38:45 +0100
|
Date: Thu, 17 Dec 2020 15:38:45 +0100
|
||||||
User-Agent: Test-Agent/1.0
|
User-Agent: Test-Agent/1.0
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
X-Mozilla-Status: 0801
|
|
||||||
X-Mozilla-Status2: 10000000
|
|
||||||
Content-Type: multipart/mixed; boundary="------------L1v4sF5IlAZ0HirXymXElgpK"
|
Content-Type: multipart/mixed; boundary="------------L1v4sF5IlAZ0HirXymXElgpK"
|
||||||
Message-ID: <1e3b3bb0-f34f-71e2-6b86-bce80bef2c6f@example.org>
|
Message-ID: <1e3b3bb0-f34f-71e2-6b86-bce80bef2c6f@example.net>
|
||||||
Date: Thu, 3 Aug 2023 13:31:01 -0300
|
Date: Thu, 3 Aug 2023 13:31:01 -0300
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
|
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Subject: webxdc object attached
|
Subject: webxdc object attached
|
||||||
Message-ID: 67890@example.org
|
Message-ID: 67890@example.net
|
||||||
Date: Fri, 03 Dec 2021 10:00:27 +0000
|
Date: Fri, 03 Dec 2021 10:00:27 +0000
|
||||||
To: alice@example.org
|
To: alice@example.org
|
||||||
From: bob@example.org
|
From: bob@example.net
|
||||||
Chat-Version: 1.0
|
Chat-Version: 1.0
|
||||||
Content-Type: multipart/mixed; boundary="==BREAK=="
|
Content-Type: multipart/mixed; boundary="==BREAK=="
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Subject: webxdc object attached
|
Subject: webxdc object attached
|
||||||
Message-ID: 12345@example.org
|
Message-ID: 12345@example.net
|
||||||
Date: Fri, 03 Dec 2021 10:00:27 +0000
|
Date: Fri, 03 Dec 2021 10:00:27 +0000
|
||||||
To: alice@example.org
|
To: alice@example.org
|
||||||
From: bob@example.org
|
From: bob@example.net
|
||||||
Chat-Version: 1.0
|
Chat-Version: 1.0
|
||||||
Content-Type: multipart/mixed; boundary="==BREAK=="
|
Content-Type: multipart/mixed; boundary="==BREAK=="
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user