diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 5d491b6bc2..0d17e23d46 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -3026,6 +3026,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = xGrpDel :: GroupInfo -> GroupMember -> RcvMessage -> UTCTime -> CM () xGrpDel gInfo@GroupInfo {membership} m@GroupMember {memberRole} msg@RcvMessage {msgSigned} brokerTs = do when (memberRole /= GROwner) $ throwChatError $ CEGroupUserRole gInfo GROwner + deleteGroupLinkIfExists user gInfo withStore' $ \db -> updateGroupMemberStatus db userId membership GSMemGroupDeleted -- TODO [relays] possible improvement is to immediately delete rcv queues if isUserGrpFwdRelay unless (isUserGrpFwdRelay gInfo) $ deleteGroupConnections user gInfo False @@ -3304,14 +3305,14 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = _ -> pure Nothing deleteGroupConnections :: User -> GroupInfo -> Bool -> CM () -deleteGroupConnections user gInfo waitDelivery = do +deleteGroupConnections user gInfo@GroupInfo {membership} waitDelivery = do vr <- chatVersionRange -- member records are not deleted to keep history members <- getMembers vr deleteMembersConnections' user members waitDelivery where getMembers vr - | useRelays' gInfo = withStore' $ \db -> getGroupRelayMembers db vr user gInfo + | useRelays' gInfo, not (isRelay membership) = withStore' $ \db -> getGroupRelayMembers db vr user gInfo | otherwise = withStore' $ \db -> getGroupMembers db vr user gInfo startDeliveryTaskWorkers :: CM () diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index f1a9e1f374..b760cb2efc 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -249,6 +249,8 @@ chatGroupTests = do describe "multiple relays" $ do it "2 relays: should deliver messages to members" testChannels2RelaysDeliver it "should share same incognito profile with all relays" testChannels2RelaysIncognito + describe "channel operations" $ do + it "should delete channel and clean up relay connections" testChannelDeleteGroup describe "channel message operations" $ do it "should update channel message" testChannelMessageUpdate it "should delete channel message" testChannelMessageDelete @@ -8813,6 +8815,37 @@ testChannels2RelaysIncognito ps = [bob, cath] *<# ("#team " <> danIncognito <> "> hey") [alice, eve, frank] *<# ("#team " <> danIncognito <> "> hey [>>]") +testChannelDeleteGroup :: HasCallStack => TestParams -> IO () +testChannelDeleteGroup ps = + withNewTestChat ps "alice" aliceProfile $ \alice -> do + withNewTestChatOpts ps relayTestOpts "bob" bobProfile $ \bob -> do + withNewTestChat ps "cath" cathProfile $ \cath -> do + (shortLink, fullLink) <- prepareChannel1Relay "team" alice bob + memberJoinChannel "team" [bob] shortLink fullLink cath + + -- verify message delivery works + alice #> "#team hi" + bob <# "#team> hi" + cath <# "#team> hi [>>]" + + -- owner deletes channel + alice ##> "/d #team" + concurrentlyN_ + [ alice <## "#team: you deleted the group", + do + bob <## "#team: alice deleted the group" + bob <## "use /d #team to delete the local copy of the group", + do + cath <## "#team: alice deleted the group" + cath <## "use /d #team to delete the local copy of the group" + ] + + -- restart relay, verify no extra subscriptions and no errors + withTestChatOpts ps relayTestOpts "bob" $ \bob -> do + bob <## "subscribed 1 connections on server localhost" + bob ##> "/groups" + bob <## "#team (group deleted, delete local copy: /d #team)" + testChannelMessageUpdate :: HasCallStack => TestParams -> IO () testChannelMessageUpdate ps = withNewTestChat ps "alice" aliceProfile $ \alice ->