github.com/status-im/status-go@v1.1.0/protocol/messenger_community_metrics_test.go (about)

     1  package protocol
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/status-im/status-go/eth-node/crypto"
     8  	"github.com/status-im/status-go/eth-node/types"
     9  	"github.com/status-im/status-go/protocol/common"
    10  	"github.com/status-im/status-go/protocol/communities"
    11  	"github.com/status-im/status-go/protocol/protobuf"
    12  	"github.com/status-im/status-go/protocol/requests"
    13  
    14  	"github.com/stretchr/testify/suite"
    15  )
    16  
    17  func TestMessengerCommunityMetricsSuite(t *testing.T) {
    18  	suite.Run(t, new(MessengerCommunityMetricsSuite))
    19  }
    20  
    21  type MessengerCommunityMetricsSuite struct {
    22  	MessengerBaseTestSuite
    23  }
    24  
    25  func (s *MessengerCommunityMetricsSuite) prepareCommunityAndChatIDs() (*communities.Community, []string) {
    26  	description := &requests.CreateCommunity{
    27  		Membership:  protobuf.CommunityPermissions_AUTO_ACCEPT,
    28  		Name:        "status",
    29  		Color:       "#ffffff",
    30  		Description: "status community description",
    31  	}
    32  	response, err := s.m.CreateCommunity(description, true)
    33  	s.Require().NoError(err)
    34  	s.Require().NotNil(response)
    35  
    36  	s.Require().Len(response.Communities(), 1)
    37  	community := response.Communities()[0]
    38  
    39  	s.Require().Len(community.ChatIDs(), 1)
    40  	chatIDs := community.ChatIDs()
    41  
    42  	// Create another chat
    43  	chat := &protobuf.CommunityChat{
    44  		Permissions: &protobuf.CommunityPermissions{
    45  			Access: protobuf.CommunityPermissions_AUTO_ACCEPT,
    46  		},
    47  		Identity: &protobuf.ChatIdentity{
    48  			DisplayName: "status",
    49  			Emoji:       "👍",
    50  			Description: "status community chat",
    51  		},
    52  	}
    53  	response, err = s.m.CreateCommunityChat(community.ID(), chat)
    54  	s.Require().NoError(err)
    55  	s.Require().NotNil(response)
    56  	s.Require().Len(response.Communities(), 1)
    57  	s.Require().Len(response.Chats(), 1)
    58  
    59  	chatIDs = append(chatIDs, response.Chats()[0].ID)
    60  
    61  	return community, chatIDs
    62  }
    63  
    64  func (s *MessengerCommunityMetricsSuite) prepareCommunityChatMessages(communityID string, chatIDs []string) {
    65  	s.generateMessages(chatIDs[0], communityID, []uint64{
    66  		// out ouf range messages in the beginning
    67  		1690162000,
    68  		// 1st column, 1 message
    69  		1690372200,
    70  		// 2nd column, 1 message
    71  		1690372800,
    72  		// 3rd column, 1 message
    73  		1690373000,
    74  		// out ouf range messages in the end
    75  		1690373100,
    76  	})
    77  
    78  	s.generateMessages(chatIDs[1], communityID, []uint64{
    79  		// out ouf range messages in the beginning
    80  		1690151000,
    81  		// 1st column, 2 messages
    82  		1690372000,
    83  		1690372100,
    84  		// 2nd column, 1 message
    85  		1690372700,
    86  		// 3rd column empty
    87  		// out ouf range messages in the end
    88  		1690373100,
    89  	})
    90  }
    91  
    92  func (s *MessengerCommunityMetricsSuite) generateMessages(chatID string, communityID string, timestamps []uint64) {
    93  	var messages []*common.Message
    94  	for i, timestamp := range timestamps {
    95  		message := &common.Message{
    96  			ChatMessage: &protobuf.ChatMessage{
    97  				ChatId:      chatID,
    98  				Text:        fmt.Sprintf("Test message %d", i),
    99  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   100  				// NOTE: should we filter content types for messages metrics
   101  				Clock:     timestamp,
   102  				Timestamp: timestamp,
   103  			},
   104  			WhisperTimestamp: timestamp,
   105  			From:             common.PubkeyToHex(&s.m.identity.PublicKey),
   106  			LocalChatID:      chatID,
   107  			CommunityID:      communityID,
   108  			ID:               types.EncodeHex(crypto.Keccak256([]byte(fmt.Sprintf("%s%s%d", chatID, communityID, timestamp)))),
   109  		}
   110  
   111  		err := message.PrepareContent(common.PubkeyToHex(&s.m.identity.PublicKey))
   112  		s.Require().NoError(err)
   113  
   114  		messages = append(messages, message)
   115  	}
   116  	err := s.m.persistence.SaveMessages(messages)
   117  	s.Require().NoError(err)
   118  }
   119  
   120  func (s *MessengerCommunityMetricsSuite) TestCollectCommunityMetricsInvalidRequest() {
   121  	community, _ := s.prepareCommunityAndChatIDs()
   122  
   123  	request := &requests.CommunityMetricsRequest{
   124  		CommunityID: community.ID(),
   125  		Type:        requests.CommunityMetricsRequestMessagesTimestamps,
   126  		Intervals: []requests.MetricsIntervalRequest{
   127  			requests.MetricsIntervalRequest{
   128  				StartTimestamp: 1690372400,
   129  				EndTimestamp:   1690371800,
   130  			},
   131  			requests.MetricsIntervalRequest{
   132  				StartTimestamp: 1690371900,
   133  				EndTimestamp:   1690373000,
   134  			},
   135  		},
   136  	}
   137  
   138  	// Expect error
   139  	_, err := s.m.CollectCommunityMetrics(request)
   140  	s.Require().Error(err)
   141  	s.Require().Equal(err, requests.ErrInvalidTimestampIntervals)
   142  }
   143  
   144  func (s *MessengerCommunityMetricsSuite) TestCollectCommunityMetricsEmptyInterval() {
   145  	community, _ := s.prepareCommunityAndChatIDs()
   146  
   147  	request := &requests.CommunityMetricsRequest{
   148  		CommunityID: community.ID(),
   149  		Type:        requests.CommunityMetricsRequestMessagesTimestamps,
   150  	}
   151  
   152  	// Expect empty metrics
   153  	resp, err := s.m.CollectCommunityMetrics(request)
   154  	s.Require().NoError(err)
   155  	s.Require().NotNil(resp)
   156  
   157  	// Entries count should be empty
   158  	s.Require().Len(resp.Intervals, 0)
   159  }
   160  
   161  func (s *MessengerCommunityMetricsSuite) TestCollectCommunityMessagesTimestamps() {
   162  	community, chatIDs := s.prepareCommunityAndChatIDs()
   163  
   164  	s.prepareCommunityChatMessages(string(community.ID()), chatIDs)
   165  
   166  	// Request metrics
   167  	request := &requests.CommunityMetricsRequest{
   168  		CommunityID: community.ID(),
   169  		Type:        requests.CommunityMetricsRequestMessagesTimestamps,
   170  		Intervals: []requests.MetricsIntervalRequest{
   171  			requests.MetricsIntervalRequest{
   172  				StartTimestamp: 1690372000,
   173  				EndTimestamp:   1690372300,
   174  			},
   175  			requests.MetricsIntervalRequest{
   176  				StartTimestamp: 1690372400,
   177  				EndTimestamp:   1690372800,
   178  			},
   179  			requests.MetricsIntervalRequest{
   180  				StartTimestamp: 1690372900,
   181  				EndTimestamp:   1690373000,
   182  			},
   183  		},
   184  	}
   185  
   186  	resp, err := s.m.CollectCommunityMetrics(request)
   187  	s.Require().NoError(err)
   188  	s.Require().NotNil(resp)
   189  
   190  	s.Require().Len(resp.Intervals, 3)
   191  
   192  	s.Require().Equal(resp.Intervals[0].Count, 3)
   193  	s.Require().Equal(resp.Intervals[1].Count, 2)
   194  	s.Require().Equal(resp.Intervals[2].Count, 1)
   195  
   196  	s.Require().Equal(resp.Intervals[0].Timestamps, []uint64{1690372000, 1690372100, 1690372200})
   197  	s.Require().Equal(resp.Intervals[1].Timestamps, []uint64{1690372700, 1690372800})
   198  	s.Require().Equal(resp.Intervals[2].Timestamps, []uint64{1690373000})
   199  }
   200  
   201  func (s *MessengerCommunityMetricsSuite) TestCollectCommunityMessagesCount() {
   202  	community, chatIDs := s.prepareCommunityAndChatIDs()
   203  
   204  	s.prepareCommunityChatMessages(string(community.ID()), chatIDs)
   205  
   206  	// Request metrics
   207  	request := &requests.CommunityMetricsRequest{
   208  		CommunityID: community.ID(),
   209  		Type:        requests.CommunityMetricsRequestMessagesCount,
   210  		Intervals: []requests.MetricsIntervalRequest{
   211  			requests.MetricsIntervalRequest{
   212  				StartTimestamp: 1690372000,
   213  				EndTimestamp:   1690372300,
   214  			},
   215  			requests.MetricsIntervalRequest{
   216  				StartTimestamp: 1690372400,
   217  				EndTimestamp:   1690372800,
   218  			},
   219  			requests.MetricsIntervalRequest{
   220  				StartTimestamp: 1690372900,
   221  				EndTimestamp:   1690373000,
   222  			},
   223  		},
   224  	}
   225  
   226  	resp, err := s.m.CollectCommunityMetrics(request)
   227  	s.Require().NoError(err)
   228  	s.Require().NotNil(resp)
   229  
   230  	s.Require().Len(resp.Intervals, 3)
   231  
   232  	s.Require().Equal(resp.Intervals[0].Count, 3)
   233  	s.Require().Equal(resp.Intervals[1].Count, 2)
   234  	s.Require().Equal(resp.Intervals[2].Count, 1)
   235  }