diff --git a/protocol/communities/manager.go b/protocol/communities/manager.go index 1cb37eb59..556b9e3e3 100644 --- a/protocol/communities/manager.go +++ b/protocol/communities/manager.go @@ -3106,8 +3106,8 @@ func (m *Manager) LeaveCommunity(id types.HexBytes) (*Community, error) { return community, nil } -// Same as LeaveCommunity, but we want to stay spectating -func (m *Manager) KickedOutOfCommunity(id types.HexBytes) (*Community, error) { +// Same as LeaveCommunity, but we have an option to stay spectating +func (m *Manager) KickedOutOfCommunity(id types.HexBytes, spectateMode bool) (*Community, error) { community, err := m.GetByID(id) if err != nil { return nil, err @@ -3115,7 +3115,9 @@ func (m *Manager) KickedOutOfCommunity(id types.HexBytes) (*Community, error) { community.RemoveOurselvesFromOrg(&m.identity.PublicKey) community.Leave() - community.Spectate() + if spectateMode { + community.Spectate() + } if err = m.persistence.SaveCommunity(community); err != nil { return nil, err diff --git a/protocol/communities_messenger_signers_test.go b/protocol/communities_messenger_signers_test.go index bbea5e74c..7f0d05521 100644 --- a/protocol/communities_messenger_signers_test.go +++ b/protocol/communities_messenger_signers_test.go @@ -1,20 +1,16 @@ package protocol import ( - //"bytes" "context" "testing" "time" - //"github.com/golang/protobuf/proto" - "github.com/stretchr/testify/suite" "go.uber.org/zap" gethcommon "github.com/ethereum/go-ethereum/common" hexutil "github.com/ethereum/go-ethereum/common/hexutil" - //utils "github.com/status-im/status-go/common" gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/common" @@ -225,7 +221,9 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() { _, err = WaitOnSignaledMessengerResponse( s.bob, func(r *MessengerResponse) bool { - return len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.bob.identity.PublicKey) + return len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.bob.identity.PublicKey) && + !r.Communities()[0].Joined() && r.Communities()[0].Spectated() && + len(r.ActivityCenterNotifications()) == 0 }, "Bob was not kicked from the community", ) @@ -236,7 +234,8 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() { _, err = WaitOnSignaledMessengerResponse( s.john, func(r *MessengerResponse) bool { - wasKicked := len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey) + inSpectateMode := len(r.Communities()) > 0 && !r.Communities()[0].HasMember(&s.john.identity.PublicKey) && + !r.Communities()[0].Joined() && r.Communities()[0].Spectated() sharedNotificationExist := false for _, acNotification := range r.ActivityCenterNotifications() { if acNotification.Type == ActivityCenterNotificationTypeShareAccounts { @@ -244,7 +243,7 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() { break } } - return wasKicked && sharedNotificationExist + return inSpectateMode && sharedNotificationExist }, "John was not kicked from the community", ) @@ -278,7 +277,8 @@ func (s *MessengerCommunitiesSignersSuite) TestControlNodeUpdateSigner() { _, err = WaitOnMessengerResponse( s.bob, func(r *MessengerResponse) bool { - return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&s.bob.identity.PublicKey) + return len(r.Communities()) > 0 && r.Communities()[0].HasMember(&s.bob.identity.PublicKey) && + r.Communities()[0].Joined() && !r.Communities()[0].Spectated() }, "Bob was auto-accepted", ) diff --git a/protocol/communities_messenger_test.go b/protocol/communities_messenger_test.go index 622df836c..9e2c56050 100644 --- a/protocol/communities_messenger_test.go +++ b/protocol/communities_messenger_test.go @@ -2351,7 +2351,11 @@ func (s *MessengerCommunitiesSuite) TestBanUser() { return len(r.Communities()) == 1 && len(r.Communities()[0].PendingAndBannedMembers()) == 1 && r.Communities()[0].IsBanned(&s.alice.identity.PublicKey) && - len(r.ActivityCenterNotifications()) == 1 && !r.ActivityCenterState().HasSeen + len(r.ActivityCenterNotifications()) == 1 && + !r.ActivityCenterState().HasSeen && + !r.Communities()[0].Spectated() && + !r.Communities()[0].Joined() + }, "no message about alice ban", ) @@ -4094,5 +4098,5 @@ func (s *MessengerCommunitiesSuite) TestBanUserAndDeleteAllUserMessages() { s.Require().True(community.IsBanned(&s.alice.identity.PublicKey)) s.Require().Len(community.PendingAndBannedMembers(), 1) s.Require().False(community.Joined()) - s.Require().True(community.Spectated()) + s.Require().False(community.Spectated()) } diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index 4d2c9cb03..c457eed67 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -1793,17 +1793,19 @@ func (m *Messenger) leaveCommunity(communityID types.HexBytes) (*MessengerRespon return response, nil } -func (m *Messenger) kickedOutOfCommunity(communityID types.HexBytes) (*MessengerResponse, error) { +func (m *Messenger) kickedOutOfCommunity(communityID types.HexBytes, spectateMode bool) (*MessengerResponse, error) { response := &MessengerResponse{} - community, err := m.communitiesManager.KickedOutOfCommunity(communityID) + community, err := m.communitiesManager.KickedOutOfCommunity(communityID, spectateMode) if err != nil { return nil, err } - err = m.DeleteProfileShowcaseCommunity(community) - if err != nil { - return nil, err + if !spectateMode { + err = m.DeleteProfileShowcaseCommunity(community) + if err != nil { + return nil, err + } } response.AddCommunity(community) @@ -2959,7 +2961,7 @@ func (m *Messenger) HandleCommunityUserKicked(state *ReceivedMessageState, messa return nil } - response, err := m.kickedOutOfCommunity(community.ID()) + response, err := m.kickedOutOfCommunity(community.ID(), false) if err != nil { m.logger.Error("cannot leave community", zap.Error(err)) return err @@ -4205,7 +4207,7 @@ func (m *Messenger) processCommunityChanges(messageState *ReceivedMessageState) if changes.IsMemberBanned(pkString) { notificationType = ActivityCenterNotificationTypeCommunityBanned } - m.leaveCommunityDueToKickOrBan(changes.Community, notificationType, messageState.Response) + m.leaveCommunityDueToKickOrBan(changes, notificationType, messageState.Response) } else if changes.IsMemberUnbanned(pkString) { m.AddActivityCenterNotificationToResponse(changes.Community.IDString(), ActivityCenterNotificationTypeCommunityUnbanned, messageState.Response) } @@ -4319,27 +4321,31 @@ func (m *Messenger) AddActivityCenterNotificationToResponse(communityID string, } } -func (m *Messenger) leaveCommunityDueToKickOrBan(community *communities.Community, acType ActivityCenterType, stateResponse *MessengerResponse) { - response, err := m.kickedOutOfCommunity(community.ID()) +func (m *Messenger) leaveCommunityDueToKickOrBan(changes *communities.CommunityChanges, acType ActivityCenterType, stateResponse *MessengerResponse) { + // during the ownership change kicked user must stay in the spectate mode + ownerhipChange := changes.ControlNodeChanged != nil + response, err := m.kickedOutOfCommunity(changes.Community.ID(), ownerhipChange) if err != nil { m.logger.Error("cannot leave community", zap.Error(err)) return } - // Activity Center notification - notification := &ActivityCenterNotification{ - ID: types.FromHex(uuid.New().String()), - Type: acType, - Timestamp: m.getTimesource().GetCurrentTime(), - CommunityID: community.IDString(), - Read: false, - UpdatedAt: m.GetCurrentTimeInMillis(), - } + if !ownerhipChange { + // Activity Center notification + notification := &ActivityCenterNotification{ + ID: types.FromHex(uuid.New().String()), + Type: acType, + Timestamp: m.getTimesource().GetCurrentTime(), + CommunityID: changes.Community.IDString(), + Read: false, + UpdatedAt: m.GetCurrentTimeInMillis(), + } - err = m.addActivityCenterNotification(response, notification, nil) - if err != nil { - m.logger.Error("failed to save notification", zap.Error(err)) - return + err = m.addActivityCenterNotification(response, notification, nil) + if err != nil { + m.logger.Error("failed to save notification", zap.Error(err)) + return + } } if err := stateResponse.Merge(response); err != nil {