mirror of
https://github.com/chatmail/core.git
synced 2026-10-02 11:10:25 +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,
|
msg: &mut Message,
|
||||||
error: &str,
|
error: &str,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if msg.state == MessageState::OutMdnRcvd {
|
||||||
|
info!(context, "{} was read, ignoring failure: {}", msg.id, error);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
if msg.state.can_fail() {
|
if msg.state.can_fail() {
|
||||||
msg.state = MessageState::OutFailed;
|
msg.state = MessageState::OutFailed;
|
||||||
warn!(context, "{} failed: {}", msg.id, error);
|
warn!(context, "{} failed: {}", msg.id, error);
|
||||||
|
|||||||
@@ -454,6 +454,28 @@ async fn test_get_state() -> Result<()> {
|
|||||||
Ok(())
|
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)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_is_bot() -> Result<()> {
|
async fn test_is_bot() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
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?;
|
let chats = Chatlist::try_load(&alice, 0, None, None).await?;
|
||||||
assert_eq!(chats.len(), 0);
|
assert_eq!(chats.len(), 0);
|
||||||
|
|
||||||
// Bob sends a read receipt.
|
// Alice receives Bob's read receipt.
|
||||||
let mdn_mimefactory = crate::mimefactory::MimeFactory::from_mdn(
|
alice.recv_mdn(&bob, &received_msg).await?;
|
||||||
&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?;
|
|
||||||
|
|
||||||
// Chat should not pop up in the chatlist.
|
// Chat should not pop up in the chatlist.
|
||||||
let chats = Chatlist::try_load(&alice, 0, None, None).await?;
|
let chats = Chatlist::try_load(&alice, 0, None, None).await?;
|
||||||
@@ -2759,20 +2747,8 @@ async fn test_read_receipts_dont_unmark_bots() -> Result<()> {
|
|||||||
.await;
|
.await;
|
||||||
let received_msg = bob.get_last_msg().await;
|
let received_msg = bob.get_last_msg().await;
|
||||||
|
|
||||||
// Bob sends a read receipt.
|
// Alice receives Bob's read receipt.
|
||||||
let mdn_mimefactory = crate::mimefactory::MimeFactory::from_mdn(
|
alice.recv_mdn(bob, &received_msg).await?;
|
||||||
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?;
|
|
||||||
let msg = alice.get_last_msg_in(alice_chat.id).await;
|
let msg = alice.get_last_msg_in(alice_chat.id).await;
|
||||||
assert_eq!(msg.state, MessageState::OutMdnRcvd);
|
assert_eq!(msg.state, MessageState::OutMdnRcvd);
|
||||||
let ab_contact = alice.add_or_lookup_contact(bob).await;
|
let ab_contact = alice.add_or_lookup_contact(bob).await;
|
||||||
|
|||||||
+12
-1
@@ -35,7 +35,7 @@ use crate::context::Context;
|
|||||||
use crate::events::{Event, EventEmitter, EventType, Events};
|
use crate::events::{Event, EventEmitter, EventType, Events};
|
||||||
use crate::key::{self, DcKey, self_fingerprint};
|
use crate::key::{self, DcKey, self_fingerprint};
|
||||||
use crate::message::{Message, MessageState, MsgId};
|
use crate::message::{Message, MessageState, MsgId};
|
||||||
use crate::mimefactory;
|
use crate::mimefactory::{self, MimeFactory};
|
||||||
use crate::mimeparser::{MimeMessage, SystemMessage};
|
use crate::mimeparser::{MimeMessage, SystemMessage};
|
||||||
use crate::pgp::SeipdVersion;
|
use crate::pgp::SeipdVersion;
|
||||||
use crate::receive_imf::{ReceivedMsg, receive_imf};
|
use crate::receive_imf::{ReceivedMsg, receive_imf};
|
||||||
@@ -850,6 +850,17 @@ ORDER BY id"
|
|||||||
assert_eq!(received.chat_id, ChatId::TRASH);
|
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.
|
/// Gets the most recent message ID of a chat.
|
||||||
///
|
///
|
||||||
/// Panics on errors or if the most recent message is a marker.
|
/// Panics on errors or if the most recent message is a marker.
|
||||||
|
|||||||
Reference in New Issue
Block a user