diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 197721085d..dee7ded8af 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -3956,28 +3956,6 @@ int dc_chat_is_protected (const dc_chat_t* chat); int dc_chat_is_encrypted (const dc_chat_t *chat); -/** - * Checks if the chat was protected, and then an incoming message broke this protection. - * - * This function is only useful if the UI enabled the `verified_one_on_one_chats` feature flag, - * otherwise it will return false for all chats. - * - * 1:1 chats are automatically set as protected when a contact is verified. - * When a message comes in that is not encrypted / signed correctly, - * the chat is automatically set as unprotected again. - * dc_chat_is_protection_broken() will return true until dc_accept_chat() is called. - * - * The UI should let the user confirm that this is OK with a message like - * `Bob sent a message from another device. Tap to learn more` and then call dc_accept_chat(). - * - * @deprecated 2025-07 chats protection cannot break any longer - * @memberof dc_chat_t - * @param chat The chat object. - * @return 1=chat protection broken, 0=otherwise. - */ -int dc_chat_is_protection_broken (const dc_chat_t* chat); - - /** * Check if locations are sent to the chat * at the time the object was created using dc_get_chat(). @@ -7214,6 +7192,8 @@ void dc_event_unref(dc_event_t* event); /// "Unknown sender for this chat. See 'info' for more details." /// /// Use as message text if assigning the message to a chat is not totally correct. +/// +/// @deprecated 2025-08-18 #define DC_STR_UNKNOWN_SENDER_FOR_CHAT 72 /// "Message from %1$s" diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index ff323b63c3..ddae6de524 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -3247,16 +3247,6 @@ pub unsafe extern "C" fn dc_chat_is_encrypted(chat: *mut dc_chat_t) -> libc::c_i .unwrap_or_log_default(&ffi_chat.context, "Failed dc_chat_is_encrypted") as libc::c_int } -#[no_mangle] -pub unsafe extern "C" fn dc_chat_is_protection_broken(chat: *mut dc_chat_t) -> libc::c_int { - if chat.is_null() { - eprintln!("ignoring careless call to dc_chat_is_protection_broken()"); - return 0; - } - let ffi_chat = &*chat; - ffi_chat.chat.is_protection_broken() as libc::c_int -} - #[no_mangle] pub unsafe extern "C" fn dc_chat_is_sending_locations(chat: *mut dc_chat_t) -> libc::c_int { if chat.is_null() { diff --git a/deltachat-jsonrpc/src/api/types/chat.rs b/deltachat-jsonrpc/src/api/types/chat.rs index 96388c27be..86f78abee0 100644 --- a/deltachat-jsonrpc/src/api/types/chat.rs +++ b/deltachat-jsonrpc/src/api/types/chat.rs @@ -71,8 +71,6 @@ pub struct FullChat { fresh_message_counter: usize, // is_group - please check over chat.type in frontend instead is_contact_request: bool, - /// Deprecated 2025-07. Chats protection cannot break any longer. - is_protection_broken: bool, is_device_chat: bool, self_in_group: bool, @@ -147,7 +145,6 @@ impl FullChat { color, fresh_message_counter, is_contact_request: chat.is_contact_request(), - is_protection_broken: chat.is_protection_broken(), is_device_chat: chat.is_device_talk(), self_in_group: contact_ids.contains(&ContactId::SELF), is_muted: chat.is_muted(), @@ -218,8 +215,6 @@ pub struct BasicChat { is_self_talk: bool, color: String, is_contact_request: bool, - /// Deprecated 2025-07. Chats protection cannot break any longer. - is_protection_broken: bool, is_device_chat: bool, is_muted: bool, @@ -249,7 +244,6 @@ impl BasicChat { is_self_talk: chat.is_self_talk(), color, is_contact_request: chat.is_contact_request(), - is_protection_broken: chat.is_protection_broken(), is_device_chat: chat.is_device_talk(), is_muted: chat.is_muted(), }) diff --git a/deltachat-jsonrpc/src/api/types/contact.rs b/deltachat-jsonrpc/src/api/types/contact.rs index c4fb5663e7..9a98a75f98 100644 --- a/deltachat-jsonrpc/src/api/types/contact.rs +++ b/deltachat-jsonrpc/src/api/types/contact.rs @@ -38,12 +38,6 @@ pub struct ContactObject { /// See [`Self::verifier_id`]/`Contact.verifierId` for a guidance how to display these information. is_verified: bool, - /// True if the contact profile title should have a green checkmark. - /// - /// This indicates whether 1:1 chat has a green checkmark - /// or will have a green checkmark if created. - is_profile_verified: bool, - /// The contact ID that verified a contact. /// /// As verifier may be unknown, @@ -87,7 +81,6 @@ impl ContactObject { None => None, }; let is_verified = contact.is_verified(context).await?; - let is_profile_verified = contact.is_profile_verified(context).await?; let verifier_id = contact .get_verifier_id(context) @@ -109,7 +102,6 @@ impl ContactObject { is_key_contact: contact.is_key_contact(), e2ee_avail: contact.e2ee_avail(context).await?, is_verified, - is_profile_verified, verifier_id, last_seen: contact.last_seen(), was_seen_recently: contact.was_seen_recently(), diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index 927f1dd372..c8526e68d6 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -406,7 +406,7 @@ def test_forward_messages(acfactory, lp): lp.sec("ac2: check new chat has a forwarded message") assert chat3.is_promoted() messages = chat3.get_messages() - assert len(messages) == 2 + assert len(messages) == 3 msg = messages[-1] assert msg.is_forwarded() ac2.delete_messages(messages) diff --git a/python/tests/test_3_offline.py b/python/tests/test_3_offline.py index 850baba71f..104041b000 100644 --- a/python/tests/test_3_offline.py +++ b/python/tests/test_3_offline.py @@ -663,4 +663,4 @@ def test_audit_log_view_without_daymarker(self, acfactory, lp): lp.sec("check message count of only system messages (without daymarkers)") sysmessages = [x for x in chat.get_messages() if x.is_system_message()] - assert len(sysmessages) == 3 + assert len(sysmessages) == 4 diff --git a/src/chat.rs b/src/chat.rs index e9d63e6090..035818f99e 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1920,11 +1920,6 @@ impl Chat { Ok(is_encrypted) } - /// Deprecated 2025-07. Returns false. - pub fn is_protection_broken(&self) -> bool { - false - } - /// Returns true if location streaming is enabled in the chat. pub fn is_sending_locations(&self) -> bool { self.is_sending_locations @@ -3731,11 +3726,19 @@ pub async fn create_group_ex( chatlist_events::emit_chatlist_changed(context); chatlist_events::emit_chatlist_item_changed(context, chat_id); - if encryption == Some(ProtectionStatus::Protected) { - let protect = ProtectionStatus::Protected; - chat_id - .set_protection_for_timestamp_sort(context, protect, timestamp, None) - .await?; + match encryption { + Some(ProtectionStatus::Protected) => { + let protect = ProtectionStatus::Protected; + chat_id + .set_protection_for_timestamp_sort(context, protect, timestamp, None) + .await?; + } + Some(ProtectionStatus::Unprotected) => { + // Add "Messages are end-to-end encrypted." message + // even to unprotected chats. + chat_id.maybe_add_encrypted_msg(context, timestamp).await?; + } + None => {} } if !context.get_config_bool(Config::Bot).await? diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index 64651f5834..b2124f941b 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -11,7 +11,9 @@ use crate::test_utils::{ AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, E2EE_INFO_MSGS, TestContext, TestContextManager, TimeShiftFalsePositiveNote, sync, }; +use crate::tools::SystemTime; use pretty_assertions::assert_eq; +use std::time::Duration; use strum::IntoEnumIterator; use tokio::fs; @@ -1644,7 +1646,7 @@ async fn test_set_mute_duration() { async fn test_add_info_msg() -> Result<()> { let t = TestContext::new().await; let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?; - add_info_msg(&t, chat_id, "foo info", 200000).await?; + add_info_msg(&t, chat_id, "foo info", time()).await?; let msg = t.get_last_msg_in(chat_id).await; assert_eq!(msg.get_chat_id(), chat_id); @@ -1666,7 +1668,7 @@ async fn test_add_info_msg_with_cmd() -> Result<()> { chat_id, "foo bar info", SystemMessage::EphemeralTimerChanged, - 10000, + time(), None, None, None, diff --git a/src/chatlist.rs b/src/chatlist.rs index 423a30ea96..4e3090c5c2 100644 --- a/src/chatlist.rs +++ b/src/chatlist.rs @@ -488,6 +488,8 @@ mod tests { use crate::stock_str::StockMessage; use crate::test_utils::TestContext; use crate::test_utils::TestContextManager; + use crate::tools::SystemTime; + use std::time::Duration; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_try_load() { @@ -510,6 +512,8 @@ mod tests { assert_eq!(chats.get_chat_id(1).unwrap(), chat_id2); assert_eq!(chats.get_chat_id(2).unwrap(), chat_id1); + SystemTime::shift(Duration::from_secs(5)); + // New drafts are sorted to the top // We have to set a draft on the other two messages, too, as // chat timestamps are only exact to the second and sorting by timestamp diff --git a/src/config.rs b/src/config.rs index 7bfebd868e..b16382cd72 100644 --- a/src/config.rs +++ b/src/config.rs @@ -422,7 +422,7 @@ pub enum Config { /// Regardless of this setting, `chat.is_protected()` returns true while the key is verified, /// and when the key changes, an info message is posted into the chat. /// 0=Nothing else happens when the key changes. - /// 1=After the key changed, `can_send()` returns false and `is_protection_broken()` returns true + /// 1=After the key changed, `can_send()` returns false /// until `chat_id.accept()` is called. #[strum(props(default = "0"))] VerifiedOneOnOneChats, diff --git a/src/contact.rs b/src/contact.rs index a9925a04f1..84750a00d3 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -21,7 +21,7 @@ use tokio::task; use tokio::time::{Duration, timeout}; use crate::blob::BlobObject; -use crate::chat::{ChatId, ChatIdBlocked, ProtectionStatus}; +use crate::chat::ChatId; use crate::color::str_to_color; use crate::config::Config; use crate::constants::{self, Blocked, Chattype}; @@ -1650,29 +1650,6 @@ impl Contact { } } - /// Returns if the contact profile title should display a green checkmark. - /// - /// This generally should be consistent with the 1:1 chat with the contact - /// so 1:1 chat with the contact and the contact profile - /// either both display the green checkmark or both don't display a green checkmark. - /// - /// UI often knows beforehand if a chat exists and can also call - /// `chat.is_protected()` (if there is a chat) - /// or `contact.is_verified()` (if there is no chat) directly. - /// This is often easier and also skips some database calls. - pub async fn is_profile_verified(&self, context: &Context) -> Result { - let contact_id = self.id; - - if let Some(ChatIdBlocked { id: chat_id, .. }) = - ChatIdBlocked::lookup_by_contact(context, contact_id).await? - { - Ok(chat_id.is_protected(context).await? == ProtectionStatus::Protected) - } else { - // 1:1 chat does not exist. - Ok(self.is_verified(context).await?) - } - } - /// Returns the number of real (i.e. non-special) contacts in the database. pub async fn get_real_cnt(context: &Context) -> Result { if !context.sql.is_open().await { diff --git a/src/contact/contact_tests.rs b/src/contact/contact_tests.rs index 48f2f2af4b..646956539c 100644 --- a/src/contact/contact_tests.rs +++ b/src/contact/contact_tests.rs @@ -1,7 +1,7 @@ use deltachat_contact_tools::{addr_cmp, may_be_valid_addr}; use super::*; -use crate::chat::{Chat, get_chat_contacts, send_text_msg}; +use crate::chat::{Chat, ProtectionStatus, get_chat_contacts, send_text_msg}; use crate::chatlist::Chatlist; use crate::receive_imf::receive_imf; use crate::test_utils::{self, TestContext, TestContextManager, TimeShiftFalsePositiveNote}; @@ -1302,7 +1302,6 @@ async fn test_self_is_verified() -> Result<()> { let contact = Contact::get_by_id(&alice, ContactId::SELF).await?; assert_eq!(contact.is_verified(&alice).await?, true); - assert!(contact.is_profile_verified(&alice).await?); assert!(contact.get_verifier_id(&alice).await?.is_none()); assert!(contact.is_key_contact()); diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 51e5304ab7..e426476804 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -1582,15 +1582,6 @@ impl MimeMessage { } } - pub fn replace_msg_by_error(&mut self, error_msg: &str) { - self.is_system_message = SystemMessage::Unknown; - if let Some(part) = self.parts.first_mut() { - part.typ = Viewtype::Text; - part.msg = format!("[{error_msg}]"); - self.parts.truncate(1); - } - } - pub(crate) fn get_rfc724_mid(&self) -> Option { self.get_header(HeaderDef::MessageId) .and_then(|msgid| parse_message_id(msgid).ok()) diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 760a14379d..c228a1b185 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1693,12 +1693,6 @@ async fn add_parts( let name: &str = from.display_name.as_ref().unwrap_or(&from.addr); for part in &mut mime_parser.parts { part.param.set(Param::OverrideSenderDisplayname, name); - - if chat.is_protected() { - // In protected chat, also mark the message with an error. - let s = stock_str::unknown_sender_for_chat(context).await; - part.error = Some(s); - } } } } @@ -1870,25 +1864,6 @@ async fn add_parts( None }; - let mut verification_failed = false; - if !chat_id.is_special() && is_partial_download.is_none() { - // For outgoing emails in the 1:1 chat we have an exception that - // they are allowed to be unencrypted: - // 1. They can't be an attack (they are outgoing, not incoming) - // 2. Probably the unencryptedness is just a temporary state, after all - // the user obviously still uses DC - // -> Showing info messages every time would be a lot of noise - // 3. The info messages that are shown to the user ("Your chat partner - // likely reinstalled DC" or similar) would be wrong. - if chat.is_protected() && (mime_parser.incoming || chat.typ != Chattype::Single) { - if let VerifiedEncryption::NotVerified(err) = verified_encryption { - verification_failed = true; - warn!(context, "Verification problem: {err:#}."); - let s = format!("{err}. Re-download the message or see 'Info' for more details"); - mime_parser.replace_msg_by_error(&s); - } - } - } drop(chat); // Avoid using stale `chat` object. let sort_timestamp = tweak_sort_timestamp( @@ -2162,10 +2137,6 @@ RETURNING id DownloadState::Available } else if mime_parser.decrypting_failed { DownloadState::Undecipherable - } else if verification_failed { - // Verification can fail because of message reordering. Re-downloading the - // message should help if so. - DownloadState::Available } else { DownloadState::Done }, diff --git a/src/receive_imf/receive_imf_tests.rs b/src/receive_imf/receive_imf_tests.rs index 861bb984f3..618a807e73 100644 --- a/src/receive_imf/receive_imf_tests.rs +++ b/src/receive_imf/receive_imf_tests.rs @@ -5133,21 +5133,9 @@ async fn test_unverified_member_msg() -> Result<()> { let fiona_chat_id = fiona.get_last_msg().await.chat_id; let fiona_sent_msg = fiona.send_text(fiona_chat_id, "Hi").await; - // The message can't be verified, but the user can re-download it. - let bob_msg = bob.recv_msg(&fiona_sent_msg).await; - assert_eq!(bob_msg.download_state, DownloadState::Available); - assert!( - bob_msg - .text - .contains("Re-download the message or see 'Info' for more details") - ); - - let alice_sent_msg = alice - .send_text(alice_chat_id, "Hi all, it's Alice introducing Fiona") - .await; - bob.recv_msg(&alice_sent_msg).await; - - // Now Bob has Fiona's key and can verify the message. + // The message is by non-verified member, + // but the checks have been removed + // and the message should be downloaded as usual. let bob_msg = bob.recv_msg(&fiona_sent_msg).await; assert_eq!(bob_msg.download_state, DownloadState::Done); assert_eq!(bob_msg.text, "Hi"); diff --git a/src/securejoin/securejoin_tests.rs b/src/securejoin/securejoin_tests.rs index b5f3fcd84a..e245e7d8e5 100644 --- a/src/securejoin/securejoin_tests.rs +++ b/src/securejoin/securejoin_tests.rs @@ -634,7 +634,7 @@ async fn test_unknown_sender() -> Result<()> { // The message from Bob is delivered late, Bob is already removed. let msg = alice.recv_msg(&sent).await; assert_eq!(msg.text, "Hi hi!"); - assert_eq!(msg.error.unwrap(), "Unknown sender for this chat."); + assert_eq!(msg.get_override_sender_name().unwrap(), "bob@example.net"); Ok(()) } diff --git a/src/stock_str.rs b/src/stock_str.rs index acc3099e0f..3a95caeaf8 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -123,9 +123,6 @@ pub enum StockMessage { however, of course, if they like, you may point them to 👉 https://get.delta.chat"))] WelcomeMessage = 71, - #[strum(props(fallback = "Unknown sender for this chat."))] - UnknownSenderForChat = 72, - #[strum(props(fallback = "Message from %1$s"))] SubjectForNewContact = 73, @@ -909,11 +906,6 @@ pub(crate) async fn welcome_message(context: &Context) -> String { translated(context, StockMessage::WelcomeMessage).await } -/// Stock string: `Unknown sender for this chat.`. -pub(crate) async fn unknown_sender_for_chat(context: &Context) -> String { - translated(context, StockMessage::UnknownSenderForChat).await -} - /// Stock string: `Message from %1$s`. // TODO: This can compute `self_name` itself instead of asking the caller to do this. pub(crate) async fn subject_for_new_contact(context: &Context, self_name: &str) -> String { diff --git a/src/test_utils.rs b/src/test_utils.rs index 664ce993cd..0534a66fce 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -186,8 +186,8 @@ impl TestContextManager { msg, to.name() )); - let chat = from.create_chat(to).await; - let sent = from.send_text(chat.id, msg).await; + let chat_id = from.create_chat_id(to).await; + let sent = from.send_text(chat_id, msg).await; to.recv_msg(&sent).await } @@ -852,14 +852,23 @@ impl TestContext { Chat::load_from_db(&self.ctx, chat_id).await.unwrap() } + /// Creates or returns an existing 1:1 [`ChatId`] with another account. + /// + /// This first creates a contact by exporting a vCard from the `other` + /// and importing it into `self`, + /// then creates a 1:1 chat with this contact. + pub async fn create_chat_id(&self, other: &TestContext) -> ChatId { + let contact_id = self.add_or_lookup_contact_id(other).await; + ChatId::create_for_contact(self, contact_id).await.unwrap() + } + /// Creates or returns an existing 1:1 [`Chat`] with another account. /// /// This first creates a contact by exporting a vCard from the `other` /// and importing it into `self`, /// then creates a 1:1 chat with this contact. pub async fn create_chat(&self, other: &TestContext) -> Chat { - let contact_id = self.add_or_lookup_contact_id(other).await; - let chat_id = ChatId::create_for_contact(self, contact_id).await.unwrap(); + let chat_id = self.create_chat_id(other).await; Chat::load_from_db(self, chat_id).await.unwrap() } diff --git a/src/tests/verified_chats.rs b/src/tests/verified_chats.rs index fbee49fc21..2a85dbc026 100644 --- a/src/tests/verified_chats.rs +++ b/src/tests/verified_chats.rs @@ -881,7 +881,6 @@ async fn assert_verified(this: &TestContext, other: &TestContext, protected: Pro chat.is_protected(), protected == ProtectionStatus::Protected ); - assert_eq!(chat.is_protection_broken(), false); } async fn enable_verified_oneonone_chats(test_contexts: &[&TestContext]) { diff --git a/src/webxdc/webxdc_tests.rs b/src/webxdc/webxdc_tests.rs index 35039459ed..d08ad2b301 100644 --- a/src/webxdc/webxdc_tests.rs +++ b/src/webxdc/webxdc_tests.rs @@ -177,7 +177,7 @@ async fn test_forward_webxdc_instance() -> Result<()> { .await?, r#"[{"payload":42,"info":"foo","document":"doc","summary":"bar","serial":1,"max_serial":1}]"# ); - assert_eq!(chat_id.get_msg_cnt(&t).await?, 2); // instance and info + assert_eq!(chat_id.get_msg_cnt(&t).await?, 3); // "Messages are end-to-end encrypted", instance and info let info = Message::load_from_db(&t, instance.id) .await? .get_webxdc_info(&t) @@ -194,7 +194,7 @@ async fn test_forward_webxdc_instance() -> Result<()> { .await?, "[]" ); - assert_eq!(chat_id.get_msg_cnt(&t).await?, 3); // two instances, only one info + assert_eq!(chat_id.get_msg_cnt(&t).await?, 4); // "Messages are end-to-end encrypted", two instances, only one info let info = Message::load_from_db(&t, instance2.id) .await? .get_webxdc_info(&t) @@ -215,14 +215,14 @@ async fn test_resend_webxdc_instance_and_info() -> Result<()> { alice.set_config_bool(Config::BccSelf, false).await?; let alice_grp = create_group_chat(&alice, ProtectionStatus::Unprotected, "grp").await?; let alice_instance = send_webxdc_instance(&alice, alice_grp).await?; - assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 1); + assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 2); alice .send_webxdc_status_update( alice_instance.id, r#"{"payload":7,"info": "i","summary":"s"}"#, ) .await?; - assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 2); + assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 3); assert!(alice.get_last_msg_in(alice_grp).await.is_info()); // Alice adds Bob and resends already used webxdc @@ -232,7 +232,7 @@ async fn test_resend_webxdc_instance_and_info() -> Result<()> { alice.add_or_lookup_contact_id(&bob).await, ) .await?; - assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 3); + assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 4); resend_msgs(&alice, &[alice_instance.id]).await?; let sent1 = alice.pop_sent_msg().await; alice.flush_status_updates().await?; @@ -1606,12 +1606,12 @@ async fn test_webxdc_info_msg_no_cleanup_on_interrupted_series() -> Result<()> { t.send_webxdc_status_update(instance.id, r#"{"info":"i1", "payload":1}"#) .await?; - assert_eq!(chat_id.get_msg_cnt(&t).await?, 2); + assert_eq!(chat_id.get_msg_cnt(&t).await?, E2EE_INFO_MSGS + 2); send_text_msg(&t, chat_id, "msg between info".to_string()).await?; - assert_eq!(chat_id.get_msg_cnt(&t).await?, 3); + assert_eq!(chat_id.get_msg_cnt(&t).await?, E2EE_INFO_MSGS + 3); t.send_webxdc_status_update(instance.id, r#"{"info":"i2", "payload":2}"#) .await?; - assert_eq!(chat_id.get_msg_cnt(&t).await?, 4); + assert_eq!(chat_id.get_msg_cnt(&t).await?, E2EE_INFO_MSGS + 4); Ok(()) } @@ -2195,6 +2195,5 @@ async fn test_self_addr_consistency() -> Result<()> { let sent = alice.send_msg(alice_chat, &mut instance).await; let db_msg = Message::load_from_db(alice, sent.sender_msg_id).await?; assert_eq!(db_msg.get_webxdc_self_addr(alice).await?, self_addr); - assert_eq!(alice_chat.get_msg_cnt(alice).await?, 1); Ok(()) } diff --git a/test-data/golden/receive_imf_delayed_removal_is_ignored b/test-data/golden/receive_imf_delayed_removal_is_ignored index 43c918f7f2..edcf03c1ec 100644 --- a/test-data/golden/receive_imf_delayed_removal_is_ignored +++ b/test-data/golden/receive_imf_delayed_removal_is_ignored @@ -1,9 +1,10 @@ Group#Chat#10: Group [5 member(s)] -------------------------------------------------------------------------------- -Msg#10🔒: Me (Contact#Contact#Self): populate √ -Msg#11: info (Contact#Contact#Info): Member dom@example.net added. [NOTICED][INFO] -Msg#12: info (Contact#Contact#Info): Member fiona@example.net removed. [NOTICED][INFO] -Msg#13🔒: (Contact#Contact#10): Member elena@example.net added by bob@example.net. [FRESH][INFO] -Msg#14🔒: Me (Contact#Contact#Self): You added member fiona@example.net. [INFO] o -Msg#15🔒: (Contact#Contact#10): Member fiona@example.net removed by bob@example.net. [FRESH][INFO] +Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO] +Msg#11🔒: Me (Contact#Contact#Self): populate √ +Msg#12: info (Contact#Contact#Info): Member dom@example.net added. [NOTICED][INFO] +Msg#13: info (Contact#Contact#Info): Member fiona@example.net removed. [NOTICED][INFO] +Msg#14🔒: (Contact#Contact#10): Member elena@example.net added by bob@example.net. [FRESH][INFO] +Msg#15🔒: Me (Contact#Contact#Self): You added member fiona@example.net. [INFO] o +Msg#16🔒: (Contact#Contact#10): Member fiona@example.net removed by bob@example.net. [FRESH][INFO] --------------------------------------------------------------------------------