mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 10:56:29 +03:00
fix: Sync chat action even if sync message arrives before first one from contact (#6259)
A sync message for accepting or blocking a 1:1 chat may arrive before the first message from the contact, when it does not exist yet. This frequently happens in non-chatmail accounts that have moving to the DeltaChat folder disabled because Delta Chat unconditionally uploads sync messages to the DeltaChat folder. Let's create a hidden contact in this case and a 1:1 chat for it.
This commit is contained in:
76
src/chat.rs
76
src/chat.rs
@@ -4657,9 +4657,9 @@ impl Context {
|
|||||||
Contact::create_ex(self, Nosync, to, addr).await?;
|
Contact::create_ex(self, Nosync, to, addr).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let contact_id = Contact::lookup_id_by_addr_ex(self, addr, Origin::Unknown, None)
|
let addr = ContactAddress::new(addr).context("Invalid address")?;
|
||||||
.await?
|
let (contact_id, _) =
|
||||||
.with_context(|| format!("No contact for addr '{addr}'"))?;
|
Contact::add_or_lookup(self, "", &addr, Origin::Hidden).await?;
|
||||||
match action {
|
match action {
|
||||||
SyncAction::Block => {
|
SyncAction::Block => {
|
||||||
return contact::set_blocked(self, Nosync, contact_id, true).await
|
return contact::set_blocked(self, Nosync, contact_id, true).await
|
||||||
@@ -4669,9 +4669,10 @@ impl Context {
|
|||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
ChatIdBlocked::lookup_by_contact(self, contact_id)
|
// Use `Request` so that even if the program crashes, the user doesn't have to look
|
||||||
|
// into the blocked contacts.
|
||||||
|
ChatIdBlocked::get_for_contact(self, contact_id, Blocked::Request)
|
||||||
.await?
|
.await?
|
||||||
.with_context(|| format!("No chat for addr '{addr}'"))?
|
|
||||||
.id
|
.id
|
||||||
}
|
}
|
||||||
SyncId::Grpid(grpid) => {
|
SyncId::Grpid(grpid) => {
|
||||||
@@ -7477,6 +7478,71 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_sync_accept_before_first_msg() -> Result<()> {
|
||||||
|
let alice0 = &TestContext::new_alice().await;
|
||||||
|
let alice1 = &TestContext::new_alice().await;
|
||||||
|
for a in [alice0, alice1] {
|
||||||
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
||||||
|
}
|
||||||
|
let bob = TestContext::new_bob().await;
|
||||||
|
|
||||||
|
let ba_chat = bob.create_chat(alice0).await;
|
||||||
|
let sent_msg = bob.send_text(ba_chat.id, "hi").await;
|
||||||
|
let a0b_chat_id = alice0.recv_msg(&sent_msg).await.chat_id;
|
||||||
|
assert_eq!(alice0.get_chat(&bob).await.blocked, Blocked::Request);
|
||||||
|
a0b_chat_id.accept(alice0).await?;
|
||||||
|
let a0b_contact = alice0.add_or_lookup_contact(&bob).await;
|
||||||
|
assert_eq!(a0b_contact.origin, Origin::CreateChat);
|
||||||
|
assert_eq!(alice0.get_chat(&bob).await.blocked, Blocked::Not);
|
||||||
|
|
||||||
|
sync(alice0, alice1).await;
|
||||||
|
let a1b_contact = alice1.add_or_lookup_contact(&bob).await;
|
||||||
|
assert_eq!(a1b_contact.origin, Origin::CreateChat);
|
||||||
|
let a1b_chat = alice1.get_chat(&bob).await;
|
||||||
|
assert_eq!(a1b_chat.blocked, Blocked::Not);
|
||||||
|
let chats = Chatlist::try_load(alice1, 0, None, None).await?;
|
||||||
|
assert_eq!(chats.len(), 1);
|
||||||
|
|
||||||
|
let rcvd_msg = alice1.recv_msg(&sent_msg).await;
|
||||||
|
assert_eq!(rcvd_msg.chat_id, a1b_chat.id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_sync_block_before_first_msg() -> Result<()> {
|
||||||
|
let alice0 = &TestContext::new_alice().await;
|
||||||
|
let alice1 = &TestContext::new_alice().await;
|
||||||
|
for a in [alice0, alice1] {
|
||||||
|
a.set_config_bool(Config::SyncMsgs, true).await?;
|
||||||
|
}
|
||||||
|
let bob = TestContext::new_bob().await;
|
||||||
|
|
||||||
|
let ba_chat = bob.create_chat(alice0).await;
|
||||||
|
let sent_msg = bob.send_text(ba_chat.id, "hi").await;
|
||||||
|
let a0b_chat_id = alice0.recv_msg(&sent_msg).await.chat_id;
|
||||||
|
assert_eq!(alice0.get_chat(&bob).await.blocked, Blocked::Request);
|
||||||
|
a0b_chat_id.block(alice0).await?;
|
||||||
|
let a0b_contact = alice0.add_or_lookup_contact(&bob).await;
|
||||||
|
assert_eq!(a0b_contact.origin, Origin::IncomingUnknownFrom);
|
||||||
|
assert_eq!(alice0.get_chat(&bob).await.blocked, Blocked::Yes);
|
||||||
|
|
||||||
|
sync(alice0, alice1).await;
|
||||||
|
let a1b_contact = alice1.add_or_lookup_contact(&bob).await;
|
||||||
|
assert_eq!(a1b_contact.origin, Origin::Hidden);
|
||||||
|
assert!(ChatIdBlocked::lookup_by_contact(alice1, a1b_contact.id)
|
||||||
|
.await?
|
||||||
|
.is_none());
|
||||||
|
|
||||||
|
let rcvd_msg = alice1.recv_msg(&sent_msg).await;
|
||||||
|
let a1b_contact = alice1.add_or_lookup_contact(&bob).await;
|
||||||
|
assert_eq!(a1b_contact.origin, Origin::IncomingUnknownFrom);
|
||||||
|
let a1b_chat = alice1.get_chat(&bob).await;
|
||||||
|
assert_eq!(a1b_chat.blocked, Blocked::Yes);
|
||||||
|
assert_eq!(rcvd_msg.chat_id, a1b_chat.id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_sync_adhoc_grp() -> Result<()> {
|
async fn test_sync_adhoc_grp() -> Result<()> {
|
||||||
let alice0 = &TestContext::new_alice().await;
|
let alice0 = &TestContext::new_alice().await;
|
||||||
|
|||||||
Reference in New Issue
Block a user