mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
feat: get contact-id for info messages (#6714)
instead of showing addresses in info message, provide an API to get the contact-id. UI can then make the info message tappable and open the contact profile in scope the corresponding iOS PR - incl. **screencast** - is at https://github.com/deltachat/deltachat-ios/pull/2652 ; jsonrpc can come in a subsequent PR when things are settled on android/ios the number of parameters in `add_info_msg_with_cmd` gets bigger and bigger, however, i did not want to refactor this in this PR. it is also not really adding complexity closes #6702 --------- Co-authored-by: link2xt <link2xt@testrun.org> Co-authored-by: Hocuri <hocuri@gmx.de>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use super::*;
|
||||
use crate::chatlist::get_archived_cnt;
|
||||
use crate::constants::{DC_GCL_ARCHIVED_ONLY, DC_GCL_NO_SPECIALS};
|
||||
use crate::ephemeral::Timer;
|
||||
use crate::headerdef::HeaderDef;
|
||||
use crate::imex::{has_backup, imex, ImexMode};
|
||||
use crate::message::{delete_msgs, MessengerMessage};
|
||||
@@ -331,11 +332,12 @@ async fn test_member_add_remove() -> Result<()> {
|
||||
// Alice adds Bob to the chat.
|
||||
add_contact_to_chat(&alice, alice_chat_id, alice_bob_contact_id).await?;
|
||||
let sent = alice.pop_sent_msg().await;
|
||||
|
||||
// Locally set name "robert" should not leak.
|
||||
assert!(!sent.payload.contains("robert"));
|
||||
assert_eq!(
|
||||
sent.load_from_db().await.get_text(),
|
||||
"You added member robert (bob@example.net)."
|
||||
"You added member robert."
|
||||
);
|
||||
|
||||
// Alice removes Bob from the chat.
|
||||
@@ -344,7 +346,7 @@ async fn test_member_add_remove() -> Result<()> {
|
||||
assert!(!sent.payload.contains("robert"));
|
||||
assert_eq!(
|
||||
sent.load_from_db().await.get_text(),
|
||||
"You removed member robert (bob@example.net)."
|
||||
"You removed member robert."
|
||||
);
|
||||
|
||||
// Alice leaves the chat.
|
||||
@@ -412,7 +414,7 @@ async fn test_parallel_member_remove() -> Result<()> {
|
||||
// Test that remove message is rewritten.
|
||||
assert_eq!(
|
||||
bob_received_remove_msg.get_text(),
|
||||
"Member Me (bob@example.net) removed by alice@example.org."
|
||||
"Member Me removed by alice@example.org."
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@@ -521,6 +523,14 @@ async fn test_modify_chat_multi_device() -> Result<()> {
|
||||
assert!(a2_msg.is_system_message());
|
||||
assert_eq!(a1_msg.get_info_type(), SystemMessage::GroupNameChanged);
|
||||
assert_eq!(a2_msg.get_info_type(), SystemMessage::GroupNameChanged);
|
||||
assert_eq!(
|
||||
a1_msg.get_info_contact_id(&a1).await?,
|
||||
Some(ContactId::SELF)
|
||||
);
|
||||
assert_eq!(
|
||||
a2_msg.get_info_contact_id(&a2).await?,
|
||||
Some(ContactId::SELF)
|
||||
);
|
||||
assert_eq!(Chat::load_from_db(&a1, a1_chat_id).await?.name, "bar");
|
||||
assert_eq!(Chat::load_from_db(&a2, a2_chat_id).await?.name, "bar");
|
||||
|
||||
@@ -1574,6 +1584,7 @@ async fn test_add_info_msg_with_cmd() -> Result<()> {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -3332,6 +3343,128 @@ async fn test_do_not_overwrite_draft() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_info_contact_id() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let alice2 = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
async fn pop_recv_and_check(
|
||||
alice: &TestContext,
|
||||
alice2: &TestContext,
|
||||
bob: &TestContext,
|
||||
expected_type: SystemMessage,
|
||||
expected_alice_id: ContactId,
|
||||
expected_bob_id: ContactId,
|
||||
) -> Result<()> {
|
||||
let sent_msg = alice.pop_sent_msg().await;
|
||||
let msg = Message::load_from_db(alice, sent_msg.sender_msg_id).await?;
|
||||
assert_eq!(msg.get_info_type(), expected_type);
|
||||
assert_eq!(
|
||||
msg.get_info_contact_id(alice).await?,
|
||||
Some(expected_alice_id)
|
||||
);
|
||||
|
||||
let msg = alice2.recv_msg(&sent_msg).await;
|
||||
assert_eq!(msg.get_info_type(), expected_type);
|
||||
assert_eq!(
|
||||
msg.get_info_contact_id(alice2).await?,
|
||||
Some(expected_alice_id)
|
||||
);
|
||||
|
||||
let msg = bob.recv_msg(&sent_msg).await;
|
||||
assert_eq!(msg.get_info_type(), expected_type);
|
||||
assert_eq!(msg.get_info_contact_id(bob).await?, Some(expected_bob_id));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Alice creates group, Bob receives group
|
||||
let alice_chat_id = alice
|
||||
.create_group_with_members(ProtectionStatus::Unprotected, "play", &[bob])
|
||||
.await;
|
||||
let sent_msg1 = alice.send_text(alice_chat_id, "moin").await;
|
||||
|
||||
let msg = bob.recv_msg(&sent_msg1).await;
|
||||
let bob_alice_id = msg.from_id;
|
||||
assert!(!bob_alice_id.is_special());
|
||||
|
||||
// Alice does group changes, Bob receives them
|
||||
set_chat_name(alice, alice_chat_id, "games").await?;
|
||||
pop_recv_and_check(
|
||||
alice,
|
||||
alice2,
|
||||
bob,
|
||||
SystemMessage::GroupNameChanged,
|
||||
ContactId::SELF,
|
||||
bob_alice_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let file = alice.get_blobdir().join("avatar.png");
|
||||
let bytes = include_bytes!("../../test-data/image/avatar64x64.png");
|
||||
tokio::fs::write(&file, bytes).await?;
|
||||
set_chat_profile_image(alice, alice_chat_id, file.to_str().unwrap()).await?;
|
||||
pop_recv_and_check(
|
||||
alice,
|
||||
alice2,
|
||||
bob,
|
||||
SystemMessage::GroupImageChanged,
|
||||
ContactId::SELF,
|
||||
bob_alice_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
alice_chat_id
|
||||
.set_ephemeral_timer(alice, Timer::Enabled { duration: 60 })
|
||||
.await?;
|
||||
pop_recv_and_check(
|
||||
alice,
|
||||
alice2,
|
||||
bob,
|
||||
SystemMessage::EphemeralTimerChanged,
|
||||
ContactId::SELF,
|
||||
bob_alice_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let fiona_id = alice.add_or_lookup_contact_id(&tcm.fiona().await).await; // contexts are in sync, fiona_id is same everywhere
|
||||
add_contact_to_chat(alice, alice_chat_id, fiona_id).await?;
|
||||
pop_recv_and_check(
|
||||
alice,
|
||||
alice2,
|
||||
bob,
|
||||
SystemMessage::MemberAddedToGroup,
|
||||
fiona_id,
|
||||
fiona_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
remove_contact_from_chat(alice, alice_chat_id, fiona_id).await?;
|
||||
pop_recv_and_check(
|
||||
alice,
|
||||
alice2,
|
||||
bob,
|
||||
SystemMessage::MemberRemovedFromGroup,
|
||||
fiona_id,
|
||||
fiona_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// When fiona_id is deleted, get_info_contact_id() returns None.
|
||||
// We raw delete in db as Contact::delete() leaves a tombstone (which is great as the tap works longer then)
|
||||
alice
|
||||
.sql
|
||||
.execute("DELETE FROM contacts WHERE id=?", (fiona_id,))
|
||||
.await?;
|
||||
let msg = alice.get_last_msg().await;
|
||||
assert_eq!(msg.get_info_type(), SystemMessage::MemberRemovedFromGroup);
|
||||
assert!(msg.get_info_contact_id(alice).await?.is_none());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test group consistency.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_add_member_bug() -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user