mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 05:16:28 +03:00
test: MDN on pre-message has effect if received before sending full message (#8004)
Actually, the problem in #8004 is that a pre-message doesn't "want MDN" if it has no text. Anyway, the added test reproduces the bug.
This commit is contained in:
@@ -427,6 +427,10 @@ pub enum Config {
|
|||||||
/// storing the same token multiple times on the server.
|
/// storing the same token multiple times on the server.
|
||||||
EncryptedDeviceToken,
|
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`.
|
/// 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
|
/// This way is better than conditional compilation, i.e. `#[cfg(test)]`, because tests not
|
||||||
/// using this still run unmodified code.
|
/// using this still run unmodified code.
|
||||||
|
|||||||
@@ -1084,6 +1084,13 @@ impl Context {
|
|||||||
.await?
|
.await?
|
||||||
.to_string(),
|
.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(
|
res.insert(
|
||||||
"test_hooks",
|
"test_hooks",
|
||||||
self.sql
|
self.sql
|
||||||
|
|||||||
@@ -1904,9 +1904,10 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
|
|||||||
//
|
//
|
||||||
// We also don't send read receipts for contact requests.
|
// We also don't send read receipts for contact requests.
|
||||||
// Read receipts will not be sent even after accepting the chat.
|
// Read receipts will not be sent even after accepting the chat.
|
||||||
|
let wants_mdn = curr_param.get_bool(Param::WantsMdn).unwrap_or_default();
|
||||||
let to_id = if curr_blocked == Blocked::Not
|
let to_id = if curr_blocked == Blocked::Not
|
||||||
&& !curr_hidden
|
&& !curr_hidden
|
||||||
&& curr_param.get_bool(Param::WantsMdn).unwrap_or_default()
|
&& wants_mdn
|
||||||
&& curr_param.get_cmd() == SystemMessage::Unknown
|
&& curr_param.get_cmd() == SystemMessage::Unknown
|
||||||
&& context.should_send_mdns().await?
|
&& context.should_send_mdns().await?
|
||||||
{
|
{
|
||||||
@@ -1928,6 +1929,11 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
if let Some(to_id) = to_id {
|
if let Some(to_id) = to_id {
|
||||||
|
info!(
|
||||||
|
context,
|
||||||
|
"Queuing MDN to {to_id} for {id} from {curr_from_id}, wants_mdn={wants_mdn}, cmd={}.",
|
||||||
|
curr_param.get_cmd()
|
||||||
|
);
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.execute(
|
.execute(
|
||||||
|
|||||||
@@ -2501,6 +2501,8 @@ async fn handle_mdn(
|
|||||||
let Some((msg_id, chat_id, has_mdns, is_dup)) = context
|
let Some((msg_id, chat_id, has_mdns, is_dup)) = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_optional(
|
.query_row_optional(
|
||||||
|
// MDN on a pre-message references the post-message, see `receive_imf`. So we can't tell
|
||||||
|
// which one was seen, but this is on purpose.
|
||||||
"SELECT
|
"SELECT
|
||||||
m.id AS msg_id,
|
m.id AS msg_id,
|
||||||
c.id AS chat_id,
|
c.id AS chat_id,
|
||||||
|
|||||||
@@ -624,16 +624,25 @@ impl TestContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn pop_sent_msg_opt(&self, timeout: Duration) -> Option<SentMessage<'_>> {
|
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 start = Instant::now();
|
||||||
let (rowid, msg_id, payload, recipients) = loop {
|
let (rowid, msg_id, payload, recipients) = loop {
|
||||||
let row = self
|
let row = self
|
||||||
.ctx
|
.ctx
|
||||||
.sql
|
.sql
|
||||||
.query_row_optional(
|
.query_row_optional(
|
||||||
r#"
|
&format!(
|
||||||
SELECT id, msg_id, mime, recipients
|
"SELECT id, msg_id, mime, recipients
|
||||||
FROM smtp
|
FROM smtp
|
||||||
ORDER BY id DESC"#,
|
ORDER BY id{order_subst}"
|
||||||
|
),
|
||||||
(),
|
(),
|
||||||
|row| {
|
|row| {
|
||||||
let rowid: i64 = row.get(0)?;
|
let rowid: i64 = row.get(0)?;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use pretty_assertions::assert_eq;
|
|||||||
|
|
||||||
use crate::EventType;
|
use crate::EventType;
|
||||||
use crate::chat;
|
use crate::chat;
|
||||||
|
use crate::config::Config;
|
||||||
use crate::contact;
|
use crate::contact;
|
||||||
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PostMsgMetadata};
|
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PostMsgMetadata};
|
||||||
use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs};
|
use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs};
|
||||||
@@ -253,6 +254,64 @@ async fn test_lost_pre_msg() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_pre_msg_mdn_before_sending_full() -> Result<()> {
|
||||||
|
pre_msg_mdn_before_sending_full("").await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_pre_msg_mdn_before_sending_full_with_text() -> Result<()> {
|
||||||
|
pre_msg_mdn_before_sending_full("text").await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pre_msg_mdn_before_sending_full(text: &str) -> 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(text.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, text);
|
||||||
|
assert!(msg.param.get_bool(Param::WantsMdn).unwrap_or_default());
|
||||||
|
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 WHERE from_id=?",
|
||||||
|
(msg.from_id,)
|
||||||
|
)
|
||||||
|
.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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_post_msg_bad_sender() -> Result<()> {
|
async fn test_post_msg_bad_sender() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
@@ -539,7 +598,10 @@ async fn test_markseen_pre_msg() -> Result<()> {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
alice
|
alice
|
||||||
.sql
|
.sql
|
||||||
.count("SELECT COUNT(*) FROM smtp_mdns", ())
|
.count(
|
||||||
|
"SELECT COUNT(*) FROM smtp_mdns WHERE from_id=?",
|
||||||
|
(msg.from_id,)
|
||||||
|
)
|
||||||
.await?,
|
.await?,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user