From 187274d7b77d05a5e91232afb2da74876c410a6c Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 12 Jan 2025 00:18:18 +0000 Subject: [PATCH] fix: create new tombstone in chats_contacts if the row does not exist Otherwise new members do not see past members even if they receive info about them in every message. --- src/chat.rs | 32 ++++++++++++++++++++++++++++++++ src/receive_imf.rs | 12 +++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 7dde6aafc..0b4d8351d 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -7808,4 +7808,36 @@ mod tests { Ok(()) } + + /// Test that tombstones for past members are added to chats_contacts table + /// even if the row did not exist before. + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_past_members() -> Result<()> { + let mut tcm = TestContextManager::new(); + + let alice = &tcm.alice().await; + let alice_fiona_contact_id = Contact::create(alice, "Fiona", "fiona@example.net").await?; + + let alice_chat_id = + create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?; + add_contact_to_chat(alice, alice_chat_id, alice_fiona_contact_id).await?; + alice + .send_text(alice_chat_id, "Hi! I created a group.") + .await; + remove_contact_from_chat(alice, alice_chat_id, alice_fiona_contact_id).await?; + assert_eq!(get_past_chat_contacts(alice, alice_chat_id).await?.len(), 1); + + let bob = &tcm.bob().await; + let bob_addr = bob.get_config(Config::Addr).await?.unwrap(); + let alice_bob_contact_id = Contact::create(alice, "Bob", &bob_addr).await?; + add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?; + + let add_message = alice.pop_sent_msg().await; + let bob_add_message = bob.recv_msg(&add_message).await; + let bob_chat_id = bob_add_message.chat_id; + assert_eq!(get_chat_contacts(bob, bob_chat_id).await?.len(), 2); + assert_eq!(get_past_chat_contacts(bob, bob_chat_id).await?.len(), 1); + + Ok(()) + } } diff --git a/src/receive_imf.rs b/src/receive_imf.rs index e2000957b..16f5dfbea 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -2161,10 +2161,12 @@ async fn update_chats_contacts_timestamps( } let mut remove_statement = transaction.prepare( - "UPDATE chats_contacts - SET remove_timestamp=?1 - WHERE chat_id=?2 AND contact_id=?3 - AND ?1>remove_timestamp AND ?1>add_timestamp", + "INSERT INTO chats_contacts (chat_id, contact_id, remove_timestamp) + VALUES (?1, ?2, ?3) + ON CONFLICT (chat_id, contact_id) + DO + UPDATE SET remove_timestamp=?3 + WHERE ?3>remove_timestamp AND ?3>add_timestamp", )?; for (contact_id, ts) in iter::zip( @@ -2174,7 +2176,7 @@ async fn update_chats_contacts_timestamps( // It could be that member was already removed, // but updated removal timestamp // is also a modification worth notifying about. - modified |= remove_statement.execute((ts, chat_id, contact_id))? > 0; + modified |= remove_statement.execute((chat_id, contact_id, ts))? > 0; } Ok(())