mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 12:56:30 +03:00
fix: forward message with file (#7755)
resolves #7724: When forwarding a message with file to another profile, the file was not copied to the target $blobdir and so the forwarded message missed it --------- Co-authored-by: Hocuri <hocuri@gmx.de>
This commit is contained in:
@@ -4380,7 +4380,14 @@ pub async fn forward_msgs_2ctx(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let param = &mut param;
|
let param = &mut param;
|
||||||
msg.param.steal(param, Param::File);
|
|
||||||
|
// When forwarding between different accounts, blob files must be physically copied
|
||||||
|
// because each account has its own blob directory.
|
||||||
|
if let Some(src_path) = param.get_file_path(ctx_src)? {
|
||||||
|
let new_blob = BlobObject::create_and_deduplicate(ctx_dst, &src_path, &src_path)
|
||||||
|
.context("Failed to copy blob file to destination account")?;
|
||||||
|
msg.param.set(Param::File, new_blob.as_name());
|
||||||
|
}
|
||||||
msg.param.steal(param, Param::Filename);
|
msg.param.steal(param, Param::Filename);
|
||||||
msg.param.steal(param, Param::Width);
|
msg.param.steal(param, Param::Width);
|
||||||
msg.param.steal(param, Param::Height);
|
msg.param.steal(param, Param::Height);
|
||||||
|
|||||||
@@ -5491,6 +5491,97 @@ async fn test_forward_msgs_2ctx() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_forward_msgs_2ctx_with_file() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
|
// First, establish a chat between Alice and Bob to have the chat IDs
|
||||||
|
let alice_chat = alice.create_chat(bob).await;
|
||||||
|
let alice_initial = alice.send_text(alice_chat.id, "hi").await;
|
||||||
|
let bob_alice_msg = bob.recv_msg(&alice_initial).await;
|
||||||
|
let bob_chat_id = bob_alice_msg.chat_id;
|
||||||
|
bob_chat_id.accept(bob).await?;
|
||||||
|
|
||||||
|
// Alice sends a message with an attached file to her self-chat
|
||||||
|
let alice_self_chat = alice.get_self_chat().await;
|
||||||
|
let file_bytes = b"test file content";
|
||||||
|
let file = alice.get_blobdir().join("test.txt");
|
||||||
|
tokio::fs::write(&file, file_bytes).await?;
|
||||||
|
|
||||||
|
let mut msg = Message::new(Viewtype::File);
|
||||||
|
msg.set_file_and_deduplicate(alice, &file, Some("test.txt"), Some("text/plain"))?;
|
||||||
|
msg.set_text("Here's a file".to_string());
|
||||||
|
|
||||||
|
alice.send_msg(alice_self_chat.id, &mut msg).await;
|
||||||
|
let alice_self_msg = alice.get_last_msg().await;
|
||||||
|
|
||||||
|
// Verify the file exists in Alice's blobdir
|
||||||
|
assert_eq!(alice_self_msg.viewtype, Viewtype::File);
|
||||||
|
let alice_original_file_path = alice_self_msg.get_file(alice).unwrap();
|
||||||
|
let alice_original_content = tokio::fs::read(&alice_original_file_path).await?;
|
||||||
|
assert_eq!(alice_original_content, file_bytes);
|
||||||
|
|
||||||
|
// Alice forwards the message to Bob using forward_msgs_2ctx
|
||||||
|
forward_msgs_2ctx(alice, &[alice_self_msg.id], bob, bob_chat_id).await?;
|
||||||
|
|
||||||
|
// Bob should have the forwarded message with the file in his database
|
||||||
|
let bob_msg = bob.get_last_msg().await;
|
||||||
|
assert_eq!(bob_msg.viewtype, Viewtype::File);
|
||||||
|
assert!(bob_msg.is_forwarded());
|
||||||
|
assert_eq!(bob_msg.text, "Here's a file");
|
||||||
|
assert_eq!(bob_msg.from_id, ContactId::SELF);
|
||||||
|
|
||||||
|
// Verify Bob has the file in his blobdir with correct content
|
||||||
|
let bob_file_path = bob_msg.get_file(bob).unwrap();
|
||||||
|
let bob_file_content = tokio::fs::read(&bob_file_path).await?;
|
||||||
|
assert_eq!(bob_file_content, file_bytes);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_forward_msgs_2ctx_missing_blob() -> Result<()> {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &tcm.alice().await;
|
||||||
|
let bob = &tcm.bob().await;
|
||||||
|
|
||||||
|
let alice_chat = alice.create_chat(bob).await;
|
||||||
|
let alice_initial = alice.send_text(alice_chat.id, "hi").await;
|
||||||
|
let bob_alice_msg = bob.recv_msg(&alice_initial).await;
|
||||||
|
let bob_chat_id = bob_alice_msg.chat_id;
|
||||||
|
bob_chat_id.accept(bob).await?;
|
||||||
|
// Alice sends a file to her self-chat
|
||||||
|
let alice_self_chat = alice.get_self_chat().await;
|
||||||
|
let file_bytes = b"test content";
|
||||||
|
let file = alice.get_blobdir().join("test.txt");
|
||||||
|
tokio::fs::write(&file, file_bytes).await?;
|
||||||
|
|
||||||
|
let mut msg = Message::new(Viewtype::File);
|
||||||
|
msg.set_file_and_deduplicate(alice, &file, Some("test.txt"), Some("text/plain"))?;
|
||||||
|
msg.set_text("File message".to_string());
|
||||||
|
|
||||||
|
alice.send_msg(alice_self_chat.id, &mut msg).await;
|
||||||
|
let alice_self_msg = alice.get_last_msg().await;
|
||||||
|
|
||||||
|
// Delete the blob file from Alice's blobdir to simulate a missing file
|
||||||
|
let alice_file_path = alice_self_msg.get_file(alice).unwrap();
|
||||||
|
tokio::fs::remove_file(&alice_file_path).await?;
|
||||||
|
|
||||||
|
// Alice tries to forward the message - this should fail with an error
|
||||||
|
let result = forward_msgs_2ctx(alice, &[alice_self_msg.id], bob, bob_chat_id).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert!(
|
||||||
|
result
|
||||||
|
.unwrap_err()
|
||||||
|
.to_string()
|
||||||
|
.contains("Failed to copy blob file")
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Tests that in multi-device setup
|
/// Tests that in multi-device setup
|
||||||
/// second device learns the key of a contact
|
/// second device learns the key of a contact
|
||||||
/// via Autocrypt-Gossip in 1:1 chats.
|
/// via Autocrypt-Gossip in 1:1 chats.
|
||||||
|
|||||||
Reference in New Issue
Block a user