test: MDN on pre-message has effect if received before sending full message (#8004)

This commit is contained in:
iequidoo
2026-03-18 10:46:46 -03:00
parent e0803bfeb1
commit d3370d5d54
4 changed files with 68 additions and 4 deletions

View File

@@ -427,6 +427,10 @@ pub enum Config {
/// storing the same token multiple times on the server.
EncryptedDeviceToken,
/// Make `TestContext::pop_sent_msg_opt()` and related functions pop messages from the `smtp`
/// head, i.e. make it a queue. For historical reasons the default is a stack.
PopSentMsgFromHead,
/// Enables running test hooks, e.g. see `InnerContext::pre_encrypt_mime_hook`.
/// This way is better than conditional compilation, i.e. `#[cfg(test)]`, because tests not
/// using this still run unmodified code.

View File

@@ -1084,6 +1084,13 @@ impl Context {
.await?
.to_string(),
);
res.insert(
"pop_sent_msg_from_head",
self.sql
.get_raw_config("pop_sent_msg_from_head")
.await?
.unwrap_or_default(),
);
res.insert(
"test_hooks",
self.sql

View File

@@ -624,16 +624,25 @@ impl TestContext {
}
pub async fn pop_sent_msg_opt(&self, timeout: Duration) -> Option<SentMessage<'_>> {
let from_head = self
.get_config_bool(Config::PopSentMsgFromHead)
.await
.unwrap();
let order_subst = match from_head {
true => "",
false => " DESC",
};
let start = Instant::now();
let (rowid, msg_id, payload, recipients) = loop {
let row = self
.ctx
.sql
.query_row_optional(
r#"
SELECT id, msg_id, mime, recipients
FROM smtp
ORDER BY id DESC"#,
&format!(
"SELECT id, msg_id, mime, recipients
FROM smtp
ORDER BY id{order_subst}"
),
(),
|row| {
let rowid: i64 = row.get(0)?;

View File

@@ -4,6 +4,7 @@ use pretty_assertions::assert_eq;
use crate::EventType;
use crate::chat;
use crate::config::Config;
use crate::contact;
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PostMsgMetadata};
use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs};
@@ -253,6 +254,49 @@ async fn test_lost_pre_msg() -> Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pre_msg_mdn() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
alice
.set_config_bool(Config::PopSentMsgFromHead, true)
.await?;
let bob = &tcm.bob().await;
let alice_chat_id = alice.create_group_with_members("", &[bob]).await;
let file_bytes = include_bytes!("../../../test-data/image/screenshot.gif");
let mut msg = Message::new(Viewtype::Image);
msg.set_file_from_bytes(alice, "a.jpg", file_bytes, None)?;
msg.set_text("populate".to_string());
let pre_msg = alice.send_msg(alice_chat_id, &mut msg).await;
let alice_msg_id = msg.id;
let msg = bob.recv_msg(&pre_msg).await;
assert_eq!(msg.download_state, DownloadState::Available);
assert_eq!(msg.id.get_state(bob).await?, MessageState::InFresh);
assert_eq!(msg.text, "populate");
msg.chat_id.accept(bob).await?;
markseen_msgs(bob, vec![msg.id]).await?;
assert_eq!(msg.id.get_state(bob).await?, MessageState::InSeen);
assert_eq!(
bob.sql.count("SELECT COUNT(*) FROM smtp_mdns", ()).await?,
1
);
smtp::queue_mdn(bob).await?;
alice.recv_msg_trash(&bob.pop_sent_msg().await).await;
assert_eq!(
alice_msg_id.get_state(alice).await?,
MessageState::OutPending
);
let _full_msg = alice.pop_sent_msg().await;
assert_eq!(
alice_msg_id.get_state(alice).await?,
MessageState::OutMdnRcvd
);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_post_msg_bad_sender() -> Result<()> {
let mut tcm = TestContextManager::new();