fix: do not emit events in set_profile_image() if contact avatar is unchanged

Previously `changed` variable was always set to `true`.
This commit is contained in:
link2xt
2026-08-29 17:32:45 +00:00
committed by l
parent 3ff8011676
commit 0b0398561d
2 changed files with 78 additions and 9 deletions

View File

@@ -1479,3 +1479,74 @@ async fn test_name_changes() -> Result<()> {
Ok(())
}
/// Tests that ChatlistItemChanged event is not emitted if the same contact avatar is received.
///
/// We don't test ContactsChanged event because it is emitted in any case due to "last seen" update.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_same_avatar_no_changed_event() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let bob2 = &tcm.bob().await;
// Create chat with Bob.
// No messages will be sent to it,
// but it should be updated when Bob's avatar changes.
let alice_bob_chat = alice.create_chat(bob).await;
async fn wait_for_chatlist_event(context: &TestContext, expected_chat_id: ChatId) {
context
.evtracker
.get_matching(|evt| {
matches!(evt, EventType::ChatlistItemChanged { chat_id } if *chat_id == Some(expected_chat_id))
})
.await;
}
// One event is for adding E2EE notice ("Messages are end-to-end encrypted")
// and another event is for creating the chat itself.
wait_for_chatlist_event(alice, alice_bob_chat.id).await;
wait_for_chatlist_event(alice, alice_bob_chat.id).await;
// Create a group chat and single chat with Bob.
// Bob will send messages to group chat,
// but single chat should get ChatlistItemChanged event
// when avatar changes.
let alice_group_id = alice.create_group_with_members("test group", &[bob]).await;
let alice_sent_msg = alice.send_text(alice_group_id, "testing").await;
let bob_group_id = bob.recv_msg(&alice_sent_msg).await.chat_id;
bob_group_id.accept(bob).await?;
let bob2_group_id = bob2.recv_msg(&alice_sent_msg).await.chat_id;
bob2_group_id.accept(bob2).await?;
// Bob sets the same avatar on two devices at the same time.
// Receiving the same avatar should only emit the event about contact change once.
for profile in &[bob, bob2] {
let avatar_src = profile.get_blobdir().join("avatar.png");
tokio::fs::write(&avatar_src, test_utils::AVATAR_900x900_BYTES).await?;
profile
.set_config(Config::Selfavatar, Some(avatar_src.to_str().unwrap()))
.await?;
}
// Avatar is changed by a group message,
// so chatlist item for single chat should be refreshed.
let sent = bob.send_text(bob_group_id, "Avatar change").await;
alice.recv_msg(&sent).await;
wait_for_chatlist_event(alice, alice_bob_chat.id).await;
// Avatar is the same, so single chat is not updated.
let sent2 = bob2.send_text(bob2_group_id, "No avatar change").await;
alice.recv_msg(&sent2).await;
let event_opt = alice
.evtracker
.get_matching_opt(alice, |evt| {
matches!(evt, EventType::ChatlistItemChanged { chat_id } if *chat_id == Some(alice_bob_chat.id))
})
.await;
assert_eq!(event_opt, None);
Ok(())
}