From e76dc33cf07569cf01a866cc9c39320f5f8ad43c Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:47:54 +0400 Subject: [PATCH] core: associate new contact with all corresponding members on member contact re-creation (e.g. after it was merged to many members and then deleted) (#5028) --- src/Simplex/Chat/Store/Groups.hs | 10 ++--- tests/ChatTests/Groups.hs | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 55847114ca..142c702f77 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -1933,8 +1933,8 @@ createMemberContact contactId <- insertedRowId db DB.execute db - "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?" - (contactId, currentTs, groupMemberId) + "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE contact_profile_id = ?" + (contactId, currentTs, memberContactProfileId) DB.execute db [sql| @@ -2003,7 +2003,7 @@ createMemberContactInvited user@User {userId, profile = LocalProfile {preferences}} connIds gInfo - m@GroupMember {groupMemberId, localDisplayName = memberLDN, memberProfile, memberContactProfileId} + m@GroupMember {localDisplayName = memberLDN, memberProfile, memberContactProfileId} mConn subMode = do currentTs <- liftIO getCurrentTime @@ -2031,8 +2031,8 @@ createMemberContactInvited contactId <- insertedRowId db DB.execute db - "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE group_member_id = ?" - (contactId, currentTs, groupMemberId) + "UPDATE group_members SET contact_id = ?, updated_at = ? WHERE contact_profile_id = ?" + (contactId, currentTs, memberContactProfileId) pure contactId updateMemberContactInvited :: DB.Connection -> User -> (CommandId, ConnId) -> GroupInfo -> Connection -> Contact -> SubscriptionMode -> ExceptT StoreError IO Contact diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 1d12625cdc..f1a36c8722 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -130,6 +130,7 @@ chatGroupTests = do it "invited member replaces member contact reference if it already exists" testMemberContactInvitedConnectionReplaced it "share incognito profile" testMemberContactIncognito it "sends and updates profile when creating contact" testMemberContactProfileUpdate + it "re-create member contact after deletion, many groups" testRecreateMemberContactManyGroups describe "group message forwarding" $ do it "forward messages between invitee and introduced (x.msg.new)" testGroupMsgForward it "deduplicate forwarded messages" testGroupMsgForwardDeduplicate @@ -4537,6 +4538,73 @@ testMemberContactProfileUpdate = alice <# "#team kate> hello there" bob <# "#team kate> hello there" -- updated profile +testRecreateMemberContactManyGroups :: HasCallStack => FilePath -> IO () +testRecreateMemberContactManyGroups = + testChat2 aliceProfile bobProfile $ + \alice bob -> do + connectUsers alice bob + createGroup2' "team" alice bob False + createGroup2' "club" alice bob False + + -- alice can message bob via team and via club + alice ##> "@#team bob 1" + alice <# "@bob 1" + bob <# "alice> 1" + + bob ##> "@#team alice 2" + bob <# "@alice 2" + alice <# "bob> 2" + + alice ##> "@#club bob 3" + alice <# "@bob 3" + bob <# "alice> 3" + + bob ##> "@#club alice 4" + bob <# "@alice 4" + alice <# "bob> 4" + + -- alice deletes contact with bob + alice ##> "/d bob" + alice <## "bob: contact is deleted" + bob <## "alice (Alice) deleted contact with you" + + bob ##> "/d alice" + bob <## "alice: contact is deleted" + + -- alice creates member contact with bob + alice ##> "@#team bob hi" + alice + <### [ "member #team bob does not have direct connection, creating", + "contact for member #team bob is created", + "sent invitation to connect directly to member #team bob", + WithTime "@bob hi" + ] + bob + <### [ "#team alice is creating direct contact alice with you", + WithTime "alice> hi" + ] + bob <## "alice (Alice): you can send messages to contact" + concurrently_ + (alice <## "bob (Bob): contact is connected") + (bob <## "alice (Alice): contact is connected") + + -- alice can message bob via team and via club + alice ##> "@#team bob 1" + alice <# "@bob 1" + bob <# "alice> 1" + + bob ##> "@#team alice 2" + bob <# "@alice 2" + alice <# "bob> 2" + + alice ##> "@#club bob 3" + alice <# "@bob 3" + bob <# "alice> 3" + + bob ##> "@#club alice 4" + bob <# "@alice 4" + alice <# "bob> 4" + testGroupMsgForward :: HasCallStack => FilePath -> IO () testGroupMsgForward = testChat3 aliceProfile bobProfile cathProfile $