Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4305,6 +4305,14 @@ pub async fn forward_msgs(context: &Context, msg_ids: &[MsgId], chat_id: ChatId)
msg.viewtype = Viewtype::Text;
}

if msg.download_state != DownloadState::Done {
// we don't use Message.get_text() here,
// because it may change in future,
// when UI shows this info itself,
// then the additional_text will not be added in get_text anymore.
msg.text += &msg.additional_text;
}

msg.param.remove(Param::GuaranteeE2ee);
msg.param.remove(Param::ForcePlaintext);
msg.param.remove(Param::Cmd);
Expand All @@ -4316,6 +4324,8 @@ pub async fn forward_msgs(context: &Context, msg_ids: &[MsgId], chat_id: ChatId)
msg.param.remove(Param::IsEdited);
msg.param.remove(Param::WebrtcRoom);
msg.param.remove(Param::WebrtcAccepted);
msg.param.remove(Param::PostMessageFileBytes);
msg.param.remove(Param::PostMessageViewtype);
msg.in_reply_to = None;

// do not leak data as group names; a default subject is generated by mimefactory
Expand Down Expand Up @@ -4382,31 +4392,42 @@ pub(crate) async fn save_copy_in_self_talk(
msg.param.remove(Param::WebxdcDocumentTimestamp);
msg.param.remove(Param::WebxdcSummary);
msg.param.remove(Param::WebxdcSummaryTimestamp);
msg.param.remove(Param::PostMessageFileBytes);
msg.param.remove(Param::PostMessageViewtype);

if msg.download_state != DownloadState::Done {
// we don't use Message.get_text() here,
// because it may change in future,
// when UI shows this info itself,
// then the additional_text will not be added in get_text anymore.
msg.text += &msg.additional_text;
}

if !msg.original_msg_id.is_unset() {
bail!("message already saved.");
}

let copy_fields = "from_id, to_id, timestamp_rcvd, type, txt,
let copy_fields = "from_id, to_id, timestamp_rcvd, type,
mime_modified, mime_headers, mime_compressed, mime_in_reply_to, subject, msgrmsg";
let row_id = context
.sql
.insert(
&format!(
"INSERT INTO msgs ({copy_fields},
timestamp_sent,
chat_id, rfc724_mid, state, timestamp, param, starred)
txt, chat_id, rfc724_mid, state, timestamp, param, starred)
SELECT {copy_fields},
-- Outgoing messages on originating device
-- have timestamp_sent == 0.
-- We copy sort timestamp instead
-- so UIs display the same timestamp
-- for saved and original message.
IIF(timestamp_sent == 0, timestamp, timestamp_sent),
?, ?, ?, ?, ?, ?
?, ?, ?, ?, ?, ?, ?
FROM msgs WHERE id=?;"
),
(
msg.text,
dest_chat_id,
dest_rfc724_mid,
if msg.from_id == ContactId::SELF {
Expand Down
6 changes: 5 additions & 1 deletion src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,11 @@ pub(crate) async fn download_msgs(context: &Context, session: &mut Session) -> R
);
remove_from_download_table(context, rfc724_mid).await?;
} else if available_post_msgs_contains_rfc724_mid(context, rfc724_mid).await? {
// set the message to DownloadState::Failure - probably it was deleted on the server in the meantime
warn!(
context,
"{rfc724_mid} is in available_post_msgs table but we failed to fetch it,
so set the message to DownloadState::Failure - probably it was deleted on the server in the meantime"
);
set_msg_state_to_failed(context, rfc724_mid).await?;
remove_from_download_table(context, rfc724_mid).await?;
remove_from_available_post_msgs_table(context, rfc724_mid).await?;
Expand Down
8 changes: 8 additions & 0 deletions src/imap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,7 @@ impl Imap {
.get_header_value(HeaderDef::ChatIsPostMessage)
.is_some()
{
info!(context, "{} is a post message", message_id.clone());
// This is a Post-Message
available_post_msgs.push(message_id.clone());

Expand All @@ -731,6 +732,7 @@ impl Imap {
false
}
} else {
info!(context, "{} is not a post message", message_id.clone());
// This is not a Post-Message
if is_background_fetch {
if size < MAX_FETCH_MSG_SIZE {
Expand Down Expand Up @@ -824,6 +826,12 @@ impl Imap {

// TODO: is there correct place for this?
if fetch_res.is_ok() {
info!(
context,
"available_post_msgs: {}, download_when_normal_starts: {}",
available_post_msgs.len(),
download_when_normal_starts.len()
);
for rfc724_mid in available_post_msgs {
context
.sql
Expand Down
1 change: 1 addition & 0 deletions src/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ async fn fetch_idle(
Ok(session)
}

/// The simplified IMAP IDLE loop to watch non primary folders (non-inbox folders)
async fn simple_imap_loop(
ctx: Context,
started: oneshot::Sender<()>,
Expand Down
122 changes: 122 additions & 0 deletions src/tests/pre_messages/forward_and_save.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//! Tests about forwarding and saving Pre-Messages
use anyhow::Result;
use pretty_assertions::assert_eq;

use crate::chat::{self};
use crate::chat::{forward_msgs, save_msgs};
use crate::chatlist::get_last_message_for_chat;
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD};
use crate::message::{Message, Viewtype};
use crate::test_utils::TestContextManager;

/// Test that forwarding Pre-Message should forward additional text to not be empty
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_forwarding_pre_message_empty_text() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_group_id = alice.create_group_with_members("test group", &[bob]).await;

let pre_message = {
let mut msg = Message::new(Viewtype::File);
msg.set_file_from_bytes(alice, "test.bin", &vec![0u8; 1_000_000], None)?;
assert!(msg.get_filebytes(alice).await?.unwrap() > PRE_MSG_ATTACHMENT_SIZE_THRESHOLD);
let msg_id = chat::send_msg(alice, alice_group_id, &mut msg).await?;
let smtp_rows = alice.get_smtp_rows_for_msg(msg_id).await;
assert_eq!(smtp_rows.len(), 2);
smtp_rows.first().expect("Pre-Message exists").to_owned()
};

let bob_msg = bob.recv_msg(&pre_message).await;
assert_eq!(bob_msg.download_state, DownloadState::Available);
bob_msg.chat_id.accept(bob).await?;
tcm.section("forward pre message and check it on bobs side");
forward_msgs(bob, &[bob_msg.id], bob_msg.chat_id).await?;
let forwarded_msg_id = get_last_message_for_chat(bob, bob_msg.chat_id)
.await?
.unwrap();
let forwarded_msg = Message::load_from_db(bob, forwarded_msg_id).await?;
assert_eq!(forwarded_msg.is_forwarded(), true);
assert_eq!(forwarded_msg.download_state(), DownloadState::Done);
assert_eq!(
forwarded_msg
.param
.exists(crate::param::Param::PostMessageFileBytes),
false,
"PostMessageFileBytes not set"
);
assert_eq!(
forwarded_msg
.param
.exists(crate::param::Param::PostMessageViewtype),
false,
"PostMessageViewtype not set"
);
assert_eq!(
forwarded_msg.get_text(),
" [test.bin - 976.56 KiB]".to_owned()
);
assert_eq!(forwarded_msg.get_viewtype(), Viewtype::Text);
assert!(forwarded_msg.additional_text.is_empty());
tcm.section("check it on alices side");
let sent_forward_msg = bob.pop_sent_msg().await;
let alice_forwarded_msg = alice.recv_msg(&sent_forward_msg).await;
assert!(alice_forwarded_msg.additional_text.is_empty());
assert_eq!(alice_forwarded_msg.is_forwarded(), true);
assert_eq!(alice_forwarded_msg.download_state(), DownloadState::Done);
assert_eq!(
alice_forwarded_msg
.param
.exists(crate::param::Param::PostMessageFileBytes),
false,
"PostMessageFileBytes not set"
);
assert_eq!(
alice_forwarded_msg
.param
.exists(crate::param::Param::PostMessageViewtype),
false,
"PostMessageViewtype not set"
);
assert_eq!(
alice_forwarded_msg.get_text(),
" [test.bin - 976.56 KiB]".to_owned()
);

Ok(())
}

/// Test that forwarding Pre-Message should forward additional text to not be empty
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_saving_pre_message_empty_text() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_group_id = alice.create_group_with_members("test group", &[bob]).await;

let pre_message = {
let mut msg = Message::new(Viewtype::File);
msg.set_file_from_bytes(alice, "test.bin", &vec![0u8; 1_000_000], None)?;
assert!(msg.get_filebytes(alice).await?.unwrap() > PRE_MSG_ATTACHMENT_SIZE_THRESHOLD);
let msg_id = chat::send_msg(alice, alice_group_id, &mut msg).await?;
let smtp_rows = alice.get_smtp_rows_for_msg(msg_id).await;
assert_eq!(smtp_rows.len(), 2);
smtp_rows.first().expect("Pre-Message exists").to_owned()
};

let bob_msg = bob.recv_msg(&pre_message).await;
assert_eq!(bob_msg.download_state, DownloadState::Available);
bob_msg.chat_id.accept(bob).await?;
tcm.section("save pre message and check it");
save_msgs(bob, &[bob_msg.id]).await?;
let saved_msg_id = get_last_message_for_chat(bob, bob.get_self_chat().await.id)
.await?
.unwrap();
let saved_msg = Message::load_from_db(bob, saved_msg_id).await?;
assert!(saved_msg.additional_text.is_empty());
assert!(saved_msg.get_original_msg_id(bob).await?.is_some());
assert_eq!(saved_msg.download_state(), DownloadState::Done);
assert_eq!(saved_msg.get_text(), " [test.bin - 976.56 KiB]".to_owned());

Ok(())
}
1 change: 1 addition & 0 deletions src/tests/pre_messages/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod additional_text;
mod forward_and_save;
mod legacy;
mod receiving;
mod sending;
Expand Down
Loading