fix: do not fail to fully download previously trashed messages

This commit is contained in:
link2xt
2025-10-11 02:50:04 +00:00
committed by l
parent 4d76a5b599
commit 2d7dc7a1be
2 changed files with 47 additions and 3 deletions

View File

@@ -283,8 +283,9 @@ mod tests {
use super::*;
use crate::chat::{get_chat_msgs, send_msg};
use crate::ephemeral::Timer;
use crate::message::delete_msgs;
use crate::receive_imf::receive_imf_from_inbox;
use crate::test_utils::{E2EE_INFO_MSGS, TestContext};
use crate::test_utils::{E2EE_INFO_MSGS, TestContext, TestContextManager};
#[test]
fn test_downloadstate_values() {
@@ -543,4 +544,43 @@ mod tests {
Ok(())
}
/// Tests that fully downloading the message
/// works even if the Message-ID already exists
/// in the database assigned to the trash chat.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_partial_download_trashed() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let imf_raw = b"From: Bob <bob@example.org>\n\
To: Alice <alice@example.org>\n\
Chat-Version: 1.0\n\
Subject: subject\n\
Message-ID: <first@example.org>\n\
Date: Sun, 14 Nov 2021 00:10:00 +0000\
Content-Type: text/plain";
// Download message from Bob partially.
let partial_received_msg =
receive_imf_from_inbox(alice, "first@example.org", imf_raw, false, Some(100000))
.await?
.unwrap();
assert_eq!(partial_received_msg.msg_ids.len(), 1);
// Delete the received message.
// Not it is still in the database,
// but in the trash chat.
delete_msgs(alice, &[partial_received_msg.msg_ids[0]]).await?;
// Fully download message after deletion.
let full_received_msg =
receive_imf_from_inbox(alice, "first@example.org", imf_raw, false, None).await?;
// The message does not reappear.
// However, `receive_imf` should not fail.
assert!(full_received_msg.is_none());
Ok(())
}
}

View File

@@ -557,13 +557,17 @@ pub(crate) async fn receive_imf_inner(
// make sure, this check is done eg. before securejoin-processing.
let (replace_msg_id, replace_chat_id);
if let Some((old_msg_id, _)) = message::rfc724_mid_exists(context, rfc724_mid).await? {
let msg = Message::load_from_db(context, old_msg_id).await?;
replace_msg_id = Some(old_msg_id);
replace_chat_id = if msg.download_state() != DownloadState::Done {
replace_chat_id = if let Some(msg) = Message::load_from_db_optional(context, old_msg_id)
.await?
.filter(|msg| msg.download_state() != DownloadState::Done)
{
// the message was partially downloaded before and is fully downloaded now.
info!(context, "Message already partly in DB, replacing.");
Some(msg.chat_id)
} else {
// The message was already fully downloaded
// or cannot be loaded because it is deleted.
None
};
} else {