mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 04:58:47 +03:00
fix: keep a message read status if a failure arrives later
also simplifies tests to use a shared helper for receiving an mdn
This commit is contained in:
@@ -1972,6 +1972,10 @@ pub(crate) async fn set_msg_failed(
|
||||
msg: &mut Message,
|
||||
error: &str,
|
||||
) -> Result<()> {
|
||||
if msg.state == MessageState::OutMdnRcvd {
|
||||
info!(context, "{} was read, ignoring failure: {}", msg.id, error);
|
||||
return Ok(());
|
||||
}
|
||||
if msg.state.can_fail() {
|
||||
msg.state = MessageState::OutFailed;
|
||||
warn!(context, "{} failed: {}", msg.id, error);
|
||||
|
||||
@@ -454,6 +454,28 @@ async fn test_get_state() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tests that a failure reported after a read receipt leaves the message untouched.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_set_msg_failed_after_mdn() -> 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 sent = alice.send_text(alice_chat.id, "hi").await;
|
||||
let bob_msg = bob.recv_msg(&sent).await;
|
||||
alice.recv_mdn(bob, &bob_msg).await?;
|
||||
let mut msg = sent.load_from_db().await;
|
||||
assert_eq!(msg.state, MessageState::OutMdnRcvd);
|
||||
|
||||
set_msg_failed(alice, &mut msg, "relay bounced").await?;
|
||||
let msg = sent.load_from_db().await;
|
||||
assert_eq!(msg.state, MessageState::OutMdnRcvd);
|
||||
assert_eq!(msg.error(), None);
|
||||
let chats = Chatlist::try_load(alice, 0, None, None).await?;
|
||||
assert_eq!(chats.get_msg_id(0)?, Some(msg.id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_is_bot() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
|
||||
@@ -2723,20 +2723,8 @@ async fn test_read_receipts_dont_create_chats() -> Result<()> {
|
||||
let chats = Chatlist::try_load(&alice, 0, None, None).await?;
|
||||
assert_eq!(chats.len(), 0);
|
||||
|
||||
// Bob sends a read receipt.
|
||||
let mdn_mimefactory = crate::mimefactory::MimeFactory::from_mdn(
|
||||
&bob,
|
||||
received_msg.from_id,
|
||||
received_msg.rfc724_mid,
|
||||
vec![],
|
||||
)
|
||||
.await?;
|
||||
let bob_addr = bob.get_primary_self_addr().await?;
|
||||
let rendered_mdn = mdn_mimefactory.render(&bob, &bob_addr).await?;
|
||||
let mdn_body = rendered_mdn.message;
|
||||
|
||||
// Alice receives the read receipt.
|
||||
receive_imf(&alice, mdn_body.as_bytes(), false).await?;
|
||||
// Alice receives Bob's read receipt.
|
||||
alice.recv_mdn(&bob, &received_msg).await?;
|
||||
|
||||
// Chat should not pop up in the chatlist.
|
||||
let chats = Chatlist::try_load(&alice, 0, None, None).await?;
|
||||
@@ -2759,20 +2747,8 @@ async fn test_read_receipts_dont_unmark_bots() -> Result<()> {
|
||||
.await;
|
||||
let received_msg = bob.get_last_msg().await;
|
||||
|
||||
// Bob sends a read receipt.
|
||||
let mdn_mimefactory = crate::mimefactory::MimeFactory::from_mdn(
|
||||
bob,
|
||||
received_msg.from_id,
|
||||
received_msg.rfc724_mid,
|
||||
vec![],
|
||||
)
|
||||
.await?;
|
||||
let bob_addr = bob.get_primary_self_addr().await?;
|
||||
let rendered_mdn = mdn_mimefactory.render(bob, &bob_addr).await?;
|
||||
let mdn_body = rendered_mdn.message;
|
||||
|
||||
// Alice receives the read receipt.
|
||||
receive_imf(alice, mdn_body.as_bytes(), false).await?;
|
||||
// Alice receives Bob's read receipt.
|
||||
alice.recv_mdn(bob, &received_msg).await?;
|
||||
let msg = alice.get_last_msg_in(alice_chat.id).await;
|
||||
assert_eq!(msg.state, MessageState::OutMdnRcvd);
|
||||
let ab_contact = alice.add_or_lookup_contact(bob).await;
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::context::Context;
|
||||
use crate::events::{Event, EventEmitter, EventType, Events};
|
||||
use crate::key::{self, DcKey, self_fingerprint};
|
||||
use crate::message::{Message, MessageState, MsgId};
|
||||
use crate::mimefactory;
|
||||
use crate::mimefactory::{self, MimeFactory};
|
||||
use crate::mimeparser::{MimeMessage, SystemMessage};
|
||||
use crate::pgp::SeipdVersion;
|
||||
use crate::receive_imf::{ReceivedMsg, receive_imf};
|
||||
@@ -850,6 +850,17 @@ ORDER BY id"
|
||||
assert_eq!(received.chat_id, ChatId::TRASH);
|
||||
}
|
||||
|
||||
/// Receives a read receipt from `reader`, who received `msg`.
|
||||
pub async fn recv_mdn(&self, reader: &TestContext, msg: &Message) -> Result<()> {
|
||||
let mdn = MimeFactory::from_mdn(reader, msg.from_id, msg.rfc724_mid.clone(), vec![])
|
||||
.await?
|
||||
.render(reader, &reader.get_primary_self_addr().await?)
|
||||
.await?
|
||||
.message;
|
||||
receive_imf(self, mdn.as_bytes(), false).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the most recent message ID of a chat.
|
||||
///
|
||||
/// Panics on errors or if the most recent message is a marker.
|
||||
|
||||
Reference in New Issue
Block a user