From 58a17ebb8a98ec7bcea3fb31412e2019c1007402 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 16 Sep 2023 22:27:06 +0100 Subject: [PATCH] add test --- src/Simplex/Chat.hs | 18 ++++++------- src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/Store/Groups.hs | 6 +++-- src/Simplex/Chat/Types.hs | 2 +- src/Simplex/Chat/View.hs | 1 + tests/ChatTests/Groups.hs | 43 ++++++++++++++++++++++++-------- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index fadba7b121..a03cd8d25e 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -4269,11 +4269,11 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do forM_ r $ \c1 -> probeMatch c1 (CGMContact c2) probe xInfoProbeMember :: GroupInfo -> GroupMember -> Probe -> m () - xInfoProbeMember GroupInfo {membership} m2 probe = + xInfoProbeMember g m2 probe = -- [incognito] unless connected incognito unless (memberIncognito m2) $ do r <- withStore' $ \db -> matchReceivedMemberProbe db user m2 probe - forM_ r $ \c1 -> probeMatch c1 (CGMGroupMember m2) probe + forM_ r $ \c1 -> probeMatch c1 (CGMGroupMember g m2) probe xInfoProbeCheck :: Contact -> ProbeHash -> m () xInfoProbeCheck c1 probeHash = @@ -4290,10 +4290,10 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do void . sendDirectContactMessage c1 $ XInfoProbeOk probe mergeContacts c1 c2 | otherwise -> messageWarning "probeMatch ignored: profiles don't match or same contact id" - CGMGroupMember m2@GroupMember {groupMemberId = mId2, memberProfile = p2, memberContactId} + CGMGroupMember g m2@GroupMember {memberProfile = p2, memberContactId} | isNothing memberContactId && profilesMatch p1 p2 -> do void . sendDirectContactMessage c1 $ XInfoProbeOk probe - connectContactToMember c1 m2 + connectContactToMember c1 g m2 | otherwise -> messageWarning "probeMatch ignored: profiles don't match or member already has contact" xInfoProbeOk :: Contact -> Probe -> m () @@ -4302,8 +4302,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do Just (CGMContact c2@Contact {contactId = cId2}) | cId1 /= cId2 -> mergeContacts c1 c2 | otherwise -> messageWarning "xInfoProbeOk ignored: same contact id" - Just (CGMGroupMember m2@GroupMember {memberContactId}) - | isNothing memberContactId -> connectContactToMember c1 m2 + Just (CGMGroupMember g m2@GroupMember {memberContactId}) + | isNothing memberContactId -> connectContactToMember c1 g m2 | otherwise -> messageWarning "xInfoProbeOk ignored: member already has contact" _ -> pure () @@ -4417,10 +4417,10 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do withStore' $ \db -> mergeContactRecords db userId c1 c2 toView $ CRContactsMerged user c1 c2 - connectContactToMember :: Contact -> GroupMember -> m () - connectContactToMember c1 m2 = do + connectContactToMember :: Contact -> GroupInfo -> GroupMember -> m () + connectContactToMember c1 g m2 = do withStore' $ \db -> updateMemberContact db user c1 m2 - -- TODO a new event that possibly already exists in member-contact branch + toView $ CRMemberContactConnected user c1 g m2 saveConnInfo :: Connection -> ConnInfo -> m Connection saveConnInfo activeConn connInfo = do diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 7b6212650b..2c829e4a95 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -560,6 +560,7 @@ data ChatResponse | CRNewMemberContact {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} | CRNewMemberContactSentInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} | CRNewMemberContactReceivedInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} + | CRMemberContactConnected {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember} | CRMemberSubError {user :: User, groupInfo :: GroupInfo, member :: GroupMember, chatError :: ChatError} | CRMemberSubSummary {user :: User, memberSubscriptions :: [MemberSubStatus]} | CRGroupSubscribed {user :: User, groupInfo :: GroupInfo} diff --git a/src/Simplex/Chat/Store/Groups.hs b/src/Simplex/Chat/Store/Groups.hs index 0349c835ce..0e5532b774 100644 --- a/src/Simplex/Chat/Store/Groups.hs +++ b/src/Simplex/Chat/Store/Groups.hs @@ -1271,7 +1271,8 @@ matchReceivedProbeHash db user@User {userId} _from@Contact {contactId} (ProbeHas [] -> getMembers >>= \case [] -> pure Nothing - (gId, mId, probe) : _ -> get CGMGroupMember probe $ getGroupMember db user gId mId + (gId, mId, probe) : _ -> + get (uncurry CGMGroupMember) probe $ (,) <$> getGroupInfo db user gId <*> getGroupMember db user gId mId (cId, probe) : _ -> get CGMContact probe $ getContact db user cId currentTs <- getCurrentTime DB.execute @@ -1389,6 +1390,7 @@ updateMemberContact GroupMember {groupId, groupMemberId, localDisplayName = memLDN, memberProfile = LocalProfile {profileId = memProfileId}} = do -- TODO possibly, we should update profiles and local_display_names of all members linked to the same remote user, -- once we decide on how we identify it, either based on shared contact_profile_id or on local_display_name + currentTs <- getCurrentTime DB.execute db [sql| @@ -1396,7 +1398,7 @@ updateMemberContact SET contact_id = ?, local_display_name = ?, contact_profile_id = ?, updated_at = ? WHERE user_id = ? AND group_id = ? AND group_member_id = ? |] - (contactId, localDisplayName, profileId, userId, groupId, groupMemberId) + (contactId, localDisplayName, profileId, currentTs, userId, groupId, groupMemberId) when (memProfileId /= profileId) $ deleteUnusedProfile_ db userId memProfileId when (memLDN /= localDisplayName) $ deleteUnusedDisplayName_ db userId memLDN diff --git a/src/Simplex/Chat/Types.hs b/src/Simplex/Chat/Types.hs index 5e7e0ab7f3..b5faa4faf0 100644 --- a/src/Simplex/Chat/Types.hs +++ b/src/Simplex/Chat/Types.hs @@ -216,7 +216,7 @@ data ContactRef = ContactRef instance ToJSON ContactRef where toEncoding = J.genericToEncoding J.defaultOptions -data ContactOrGroupMember = CGMContact Contact | CGMGroupMember GroupMember +data ContactOrGroupMember = CGMContact Contact | CGMGroupMember GroupInfo GroupMember data UserContact = UserContact { userContactLinkId :: Int64, diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 5cbab08ae2..51dbfee9e9 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -234,6 +234,7 @@ responseToView user_ ChatConfig {logLevel, showReactions, showReceipts, testView CRNewMemberContact u _ g m -> ttyUser u ["contact for member " <> ttyGroup' g <> " " <> ttyMember m <> " is created"] CRNewMemberContactSentInv u _ct g m -> ttyUser u ["sent invitation to connect directly to member " <> ttyGroup' g <> " " <> ttyMember m] CRNewMemberContactReceivedInv u ct g m -> ttyUser u [ttyGroup' g <> " " <> ttyMember m <> " is creating direct contact " <> ttyContact' ct <> " with you"] + CRMemberContactConnected u ct g m -> ttyUser u [ttyGroup' g <> " " <> ttyMember m <> " is connected to contact " <> ttyContact' ct] CRMemberSubError u g m e -> ttyUser u [ttyGroup' g <> " member " <> ttyMember m <> " error: " <> sShow e] CRMemberSubSummary u summary -> ttyUser u $ viewErrorsSummary (filter (isJust . memberError) summary) " group member errors" CRGroupSubscribed u g -> ttyUser u $ viewGroupSubscribed g diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 51e1db5c75..e6f32cc120 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -84,7 +84,7 @@ chatGroupTests = do testNoDirect4 _1 _1 _0 False False False testNoDirect4 _1 _1 _1 False False False it "members have different local display names in different groups" testNoDirectDifferentLDNs - -- it "member should connect to contact when profile match" testConnectMemberToContact + it "member should connect to contact when profile match" testConnectMemberToContact describe "create member contact" $ do it "create contact with group member with invitation message" testMemberContactMessage it "create contact with group member without invitation message" testMemberContactNoMessage @@ -2783,15 +2783,38 @@ testNoDirectDifferentLDNs = bob <# ("#" <> gName <> " " <> cathLDN <> "> hey") ] --- testConnectMemberToContact :: HasCallStack => FilePath -> IO () --- testConnectMemberToContact = --- testChat3 aliceProfile bobProfile cathProfile $ --- \alice bob cath -> do --- connectUsers alice bob --- connectUsers alice cath --- alice ##> "/g team" --- alice <## "group #team is created" --- alice ##> "/a team bob" +testConnectMemberToContact :: HasCallStack => FilePath -> IO () +testConnectMemberToContact = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + connectUsers alice bob + connectUsers alice cath + createGroup2 "team" bob cath + bob ##> "/a #team alice" + bob <## "invitation to join the group #team sent to alice" + alice <## "#team: bob invites you to join the group as member" + alice <## "use /j team to accept" + alice ##> "/j team" + concurrentlyN_ + [ do + alice <## "#team: you joined the group" + alice <## "#team: member cath_1 (Catherine) is connected" + alice <## "#team cath_1 is connected to contact cath", + do + bob <## "#team: alice joined the group", + do + cath <## "#team: bob added alice_1 (Alice) to the group (connecting...)" + cath <## "#team: new member alice_1 is connected" + cath <## "#team alice_1 is connected to contact alice" + ] + alice #> "@cath hi" + cath <# "alice> hi" + alice #> "#team hello" + bob <# "#team alice> hello" + cath <# "#team alice> hello" + cath #> "#team hello too" + bob <# "#team cath> hello too" + alice <# "#team cath> hello too" testMemberContactMessage :: HasCallStack => FilePath -> IO () testMemberContactMessage =