From 8c006caeb2ef3e500abed274889fe4570dc4db65 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Tue, 17 Mar 2026 13:51:42 -0300 Subject: [PATCH] test: test_markseen_pre_msg: Check that MDN on pre-message changes message state to OutMdnRcvd (#8004) --- src/smtp.rs | 103 ++++++++++++++++++---------- src/test_utils.rs | 21 +++++- src/tests/pre_messages/receiving.rs | 7 +- 3 files changed, 93 insertions(+), 38 deletions(-) diff --git a/src/smtp.rs b/src/smtp.rs index aca1f46ea..22c112735 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -13,7 +13,7 @@ use crate::config::Config; use crate::contact::{Contact, ContactId}; use crate::context::Context; use crate::events::EventType; -use crate::log::{LogExt, warn}; +use crate::log::warn; use crate::message::Message; use crate::message::{self, MsgId}; use crate::mimefactory::MimeFactory; @@ -584,44 +584,77 @@ async fn send_mdn_rfc724_mid( if context.get_config_bool(Config::BccSelf).await? { add_self_recipients(context, &mut recipients, encrypted).await?; } - let recipients: Vec<_> = recipients - .into_iter() - .filter_map(|addr| { - async_smtp::EmailAddress::new(addr.clone()) - .with_context(|| format!("Invalid recipient: {addr}")) - .log_err(context) - .ok() - }) - .collect(); + #[cfg(not(test))] + { + use crate::log::LogExt; - match smtp_send(context, &recipients, &body, smtp, None).await { - SendResult::Success => { - if !recipients.is_empty() { - info!(context, "Successfully sent MDN for {rfc724_mid}."); + let recipients: Vec<_> = recipients + .into_iter() + .filter_map(|addr| { + async_smtp::EmailAddress::new(addr.clone()) + .with_context(|| format!("Invalid recipient: {addr}")) + .log_err(context) + .ok() + }) + .collect(); + + match smtp_send(context, &recipients, &body, smtp, None).await { + SendResult::Success => { + if !recipients.is_empty() { + info!(context, "Successfully sent MDN for {rfc724_mid}."); + } + context + .sql + .transaction(|transaction| { + let mut stmt = + transaction.prepare("DELETE FROM smtp_mdns WHERE rfc724_mid = ?")?; + stmt.execute((rfc724_mid,))?; + for additional_rfc724_mid in additional_rfc724_mids { + stmt.execute((additional_rfc724_mid,))?; + } + Ok(()) + }) + .await?; + Ok(true) } - context - .sql - .transaction(|transaction| { - let mut stmt = - transaction.prepare("DELETE FROM smtp_mdns WHERE rfc724_mid = ?")?; - stmt.execute((rfc724_mid,))?; - for additional_rfc724_mid in additional_rfc724_mids { - stmt.execute((additional_rfc724_mid,))?; - } - Ok(()) - }) - .await?; - Ok(true) + SendResult::Retry => { + info!( + context, + "Temporary SMTP failure while sending an MDN for {rfc724_mid}." + ); + Ok(false) + } + SendResult::Failure(err) => Err(err), } - SendResult::Retry => { - info!( - context, - "Temporary SMTP failure while sending an MDN for {rfc724_mid}." - ); - Ok(false) - } - SendResult::Failure(err) => Err(err), } + #[cfg(test)] + { + let _ = smtp; + context + .sql + .transaction(|t| { + t.execute( + "INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id) + VALUES (?, ?, ?, ?)", + (rfc724_mid, recipients.join(" "), body, u32::MAX), + )?; + let mut stmt = t.prepare("DELETE FROM smtp_mdns WHERE rfc724_mid = ?")?; + stmt.execute((rfc724_mid,))?; + for additional_rfc724_mid in additional_rfc724_mids { + stmt.execute((additional_rfc724_mid,))?; + } + Ok(()) + }) + .await?; + Ok(true) + } +} + +#[cfg(test)] +pub(crate) async fn queue_mdn(context: &Context) -> Result<()> { + let queued = send_mdn(context, &mut Smtp::new()).await?; + assert!(queued); + Ok(()) } /// Tries to send a single MDN. Returns true if more MDNs should be sent. diff --git a/src/test_utils.rs b/src/test_utils.rs index 95bcc5a0c..0435f330e 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -716,7 +716,8 @@ impl TestContext { } pub async fn get_smtp_rows_for_msg<'a>(&'a self, msg_id: MsgId) -> Vec> { - self.ctx + let sent_msgs = self + .ctx .sql .query_map_vec( "SELECT id, msg_id, mime, recipients FROM smtp WHERE msg_id=?", @@ -738,7 +739,23 @@ impl TestContext { sender_context: &self.ctx, recipients, }) - .collect() + .collect(); + self.ctx + .sql + .execute("DELETE FROM smtp WHERE msg_id=?", (msg_id,)) + .await + .expect("Delete smtp jobs"); + update_msg_state(&self.ctx, msg_id, MessageState::OutDelivered) + .await + .expect("Update message state"); + self.sql + .execute( + "UPDATE msgs SET timestamp_sent=? WHERE id=?", + (time(), msg_id), + ) + .await + .expect("Update timestamp_sent"); + sent_msgs } /// Parses a message. diff --git a/src/tests/pre_messages/receiving.rs b/src/tests/pre_messages/receiving.rs index 1926bbd07..ec0aa9d64 100644 --- a/src/tests/pre_messages/receiving.rs +++ b/src/tests/pre_messages/receiving.rs @@ -10,6 +10,7 @@ use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs use crate::mimeparser::MimeMessage; use crate::param::Param; use crate::reaction::{get_msg_reactions, send_reaction}; +use crate::smtp; use crate::summary::assert_summary_texts; use crate::test_utils::TestContextManager; use crate::tests::pre_messages::util::{ @@ -523,7 +524,7 @@ async fn test_markseen_pre_msg() -> Result<()> { alice.create_chat(bob).await; // Make sure the chat is accepted. tcm.section("Bob sends a large message to Alice"); - let (pre_message, post_message, _bob_msg_id) = + let (pre_message, post_message, bob_msg_id) = send_large_file_message(bob, bob_chat_id, Viewtype::File, &vec![0u8; 1_000_000]).await?; tcm.section("Alice receives a pre-message message from Bob"); @@ -542,6 +543,10 @@ async fn test_markseen_pre_msg() -> Result<()> { .await?, 1 ); + smtp::queue_mdn(alice).await?; + bob.recv_msg_trash(&alice.pop_sent_msg().await).await; + let bob_msg = Message::load_from_db(bob, bob_msg_id).await?; + assert_eq!(bob_msg.get_state(), MessageState::OutMdnRcvd); tcm.section("Alice downloads message"); alice.recv_msg_trash(&post_message).await;