From e0bbb7e2ec8f3bfd6138a8483bfa269afd1dfb21 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Thu, 7 Dec 2023 21:32:37 +0530 Subject: [PATCH] fix: send chats along with response after joining (#4416) When an open community was created by Device A and shared with Device B and when Device B would request to join such a community, the general channel would be forever in loading state. This happened because as part of messenger response the chatId of general channel was not sent and mobile client would not fetch that chat data. This commit fixes that issue by sending chatId as part of messenger response right after the request to join community succeeds. --- protocol/communities_messenger_test.go | 90 ++++++++++++++++++++++++++ protocol/messenger.go | 1 + protocol/messenger_handler.go | 9 ++- protocol/messenger_response.go | 7 ++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/protocol/communities_messenger_test.go b/protocol/communities_messenger_test.go index c4339be84..40120b0d9 100644 --- a/protocol/communities_messenger_test.go +++ b/protocol/communities_messenger_test.go @@ -182,6 +182,96 @@ func (s *MessengerCommunitiesSuite) TestRetrieveCommunity() { s.Require().Equal(community.IDString(), response.Messages()[0].CommunityID) } +func (s *MessengerCommunitiesSuite) TestJoiningOpenCommunityReturnsChatsResponse() { + ctx := context.Background() + + openCommunityDescription := &requests.CreateCommunity{ + Name: "open community", + Description: "open community to join with no requests", + Color: "#26a69a", + HistoryArchiveSupportEnabled: true, + Membership: protobuf.CommunityPermissions_AUTO_ACCEPT, + PinMessageAllMembersEnabled: false, + } + + response, err := s.bob.CreateCommunity(openCommunityDescription, true) + generalChannelChatID := response.Chats()[0].ID + s.Require().NoError(err) + s.Require().NotNil(response) + s.Require().Len(response.Communities(), 1) + s.Require().Len(response.CommunitiesSettings(), 1) + s.Require().Len(response.Chats(), 1) + + community := response.Communities()[0] + + chat := CreateOneToOneChat(common.PubkeyToHex(&s.alice.identity.PublicKey), &s.alice.identity.PublicKey, s.alice.transport) + + s.Require().NoError(s.bob.SaveChat(chat)) + + message := buildTestMessage(*chat) + message.CommunityID = community.IDString() + + // Bob sends the community link to Alice + response, err = s.bob.SendChatMessage(ctx, message) + s.Require().NoError(err) + s.Require().NotNil(response) + + // Retrieve community link & community for Alice + response, err = WaitOnMessengerResponse( + s.alice, + func(r *MessengerResponse) bool { + return len(r.Communities()) > 0 + }, + "message not received", + ) + s.Require().NoError(err) + s.Require().NotNil(response) + s.Require().Len(response.Chats(), 1) + + // Alice request to join community + request := &requests.RequestToJoinCommunity{CommunityID: community.ID()} + + response, err = s.alice.RequestToJoinCommunity(request) + s.Require().NoError(err) + s.Require().NotNil(response) + s.Require().Len(response.RequestsToJoinCommunity, 1) + + requestToJoin := response.RequestsToJoinCommunity[0] + s.Require().NotNil(requestToJoin) + s.Require().Equal(community.ID(), requestToJoin.CommunityID) + s.Require().NotEmpty(requestToJoin.ID) + s.Require().NotEmpty(requestToJoin.Clock) + s.Require().Equal(requestToJoin.PublicKey, common.PubkeyToHex(&s.alice.identity.PublicKey)) + s.Require().Len(response.Communities(), 1) + s.Require().Equal(communities.RequestToJoinStatePending, requestToJoin.State) + + // Bobs receives the request to join and it's automatically accepted + response, err = WaitOnMessengerResponse( + s.bob, + func(r *MessengerResponse) bool { + return len(r.Communities()) > 0 && len(r.RequestsToJoinCommunity) > 0 + }, + "message not received", + ) + s.Require().NoError(err) + s.Require().NotNil(response) + + // Alice receives the updated community description with channel information + response, err = WaitOnMessengerResponse( + s.alice, + func(r *MessengerResponse) bool { + return len(r.Communities()) > 0 && len(r.chats) > 0 + }, + "message not received", + ) + s.Require().NoError(err) + s.Require().NotNil(response) + + // Check whether community's general chat is available for Alice + _, exists := response.chats[generalChannelChatID] + s.Require().True(exists) +} + func (s *MessengerCommunitiesSuite) TestJoinCommunity() { ctx := context.Background() diff --git a/protocol/messenger.go b/protocol/messenger.go index d866cc0bd..f3cfcddf8 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -4033,6 +4033,7 @@ func (m *Messenger) MessageByChatID(chatID, cursor string, limit int) ([]*common } } + if m.httpServer != nil { for idx := range msgs { m.prepareMessage(msgs[idx], m.httpServer) diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index d8bfefa53..7653682e1 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -1620,11 +1620,16 @@ func (m *Messenger) HandleCommunityRequestToJoinResponse(state *ReceivedMessageS if err != nil { return err } + + // we merge to include chats in response signal to joining a community + err = state.Response.Merge(response) + if err != nil { + return err + } + if len(response.Communities()) > 0 { communitySettings := response.CommunitiesSettings()[0] community := response.Communities()[0] - state.Response.AddCommunity(community) - state.Response.AddCommunitySettings(communitySettings) magnetlink := requestToJoinResponseProto.MagnetUri if m.torrentClientReady() && communitySettings != nil && communitySettings.HistoryArchiveSupportEnabled && magnetlink != "" { diff --git a/protocol/messenger_response.go b/protocol/messenger_response.go index f2eca5181..d8817d6a6 100644 --- a/protocol/messenger_response.go +++ b/protocol/messenger_response.go @@ -316,6 +316,7 @@ func (r *MessengerResponse) Merge(response *MessengerResponse) error { r.AddMessages(response.Messages()) r.AddContacts(response.Contacts) r.AddCommunities(response.Communities()) + r.UpdateCommunitySettings(response.CommunitiesSettings()) r.AddPinMessages(response.PinMessages()) r.AddVerificationRequests(response.VerificationRequests()) r.AddTrustStatuses(response.trustStatus) @@ -362,6 +363,12 @@ func (r *MessengerResponse) AddCommunitySettings(c *communities.CommunitySetting r.communitiesSettings[c.CommunityID] = c } +func (r *MessengerResponse) UpdateCommunitySettings(communitySettings []*communities.CommunitySettings) { + for _, communitySetting := range communitySettings { + r.AddCommunitySettings(communitySetting) + } +} + func (r *MessengerResponse) AddRequestsToJoinCommunity(requestsToJoin []*communities.RequestToJoin) { r.RequestsToJoinCommunity = append(r.RequestsToJoinCommunity, requestsToJoin...) }