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

     1  package protocol
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/suite"
     8  
     9  	"github.com/status-im/status-go/protocol/protobuf"
    10  )
    11  
    12  type MessageValidatorSuite struct {
    13  	suite.Suite
    14  }
    15  
    16  func TestMessageValidatorSuite(t *testing.T) {
    17  	suite.Run(t, new(MessageValidatorSuite))
    18  }
    19  
    20  func (s *MessageValidatorSuite) TestValidateRequestAddressForTransaction() {
    21  	testCases := []struct {
    22  		Name             string
    23  		WhisperTimestamp uint64
    24  		Valid            bool
    25  		Message          *protobuf.RequestAddressForTransaction
    26  	}{
    27  		{
    28  			Name:             "valid message",
    29  			WhisperTimestamp: 30,
    30  			Valid:            true,
    31  			Message: &protobuf.RequestAddressForTransaction{
    32  				Clock:    30,
    33  				Value:    "0.34",
    34  				Contract: "some contract",
    35  			},
    36  		},
    37  		{
    38  			Name:             "missing clock value",
    39  			WhisperTimestamp: 30,
    40  			Valid:            false,
    41  			Message: &protobuf.RequestAddressForTransaction{
    42  				Value:    "0.34",
    43  				Contract: "some contract",
    44  			},
    45  		},
    46  		{
    47  			Name:             "missing value",
    48  			WhisperTimestamp: 30,
    49  			Valid:            false,
    50  			Message: &protobuf.RequestAddressForTransaction{
    51  				Clock:    30,
    52  				Contract: "some contract",
    53  			},
    54  		},
    55  		{
    56  			Name:             "non number value",
    57  			WhisperTimestamp: 30,
    58  			Valid:            false,
    59  			Message: &protobuf.RequestAddressForTransaction{
    60  				Clock:    30,
    61  				Value:    "most definitely not a number",
    62  				Contract: "some contract",
    63  			},
    64  		},
    65  		{
    66  			Name:             "Clock value too high",
    67  			WhisperTimestamp: 30,
    68  			Valid:            false,
    69  			Message: &protobuf.RequestAddressForTransaction{
    70  				Clock:    151000,
    71  				Value:    "0.34",
    72  				Contract: "some contract",
    73  			},
    74  		},
    75  	}
    76  	for _, tc := range testCases {
    77  		s.Run(tc.Name, func() {
    78  			err := ValidateReceivedRequestAddressForTransaction(tc.Message, tc.WhisperTimestamp)
    79  			if tc.Valid {
    80  				s.Nil(err)
    81  			} else {
    82  				s.NotNil(err)
    83  			}
    84  		})
    85  	}
    86  
    87  }
    88  
    89  func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
    90  	testCases := []struct {
    91  		Name             string
    92  		WhisperTimestamp uint64
    93  		Valid            bool
    94  		Message          *protobuf.ChatMessage
    95  	}{
    96  		{
    97  			Name:             "A valid message",
    98  			WhisperTimestamp: 2,
    99  			Valid:            true,
   100  			Message: &protobuf.ChatMessage{
   101  				ChatId:      "a",
   102  				Clock:       1,
   103  				Timestamp:   2,
   104  				Text:        strings.Repeat("É", maxChatMessageTextLength),
   105  				ResponseTo:  "",
   106  				EnsName:     "",
   107  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   108  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   109  			},
   110  		},
   111  		{
   112  			Name:             "Missing chatId",
   113  			WhisperTimestamp: 2,
   114  			Valid:            false,
   115  			Message: &protobuf.ChatMessage{
   116  				Clock:       1,
   117  				Timestamp:   2,
   118  				Text:        "some-text",
   119  				ResponseTo:  "",
   120  				EnsName:     "",
   121  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   122  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   123  			},
   124  		},
   125  		{
   126  			Name:             "Missing clock",
   127  			WhisperTimestamp: 2,
   128  			Valid:            false,
   129  			Message: &protobuf.ChatMessage{
   130  				ChatId:      "a",
   131  				Timestamp:   2,
   132  				Text:        "some-text",
   133  				ResponseTo:  "",
   134  				EnsName:     "",
   135  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   136  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   137  			},
   138  		},
   139  		{
   140  			Name:             "Clock value too high",
   141  			WhisperTimestamp: 2,
   142  			Valid:            false,
   143  			Message: &protobuf.ChatMessage{
   144  				ChatId:      "a",
   145  				Clock:       133000,
   146  				Timestamp:   1,
   147  				Text:        "some-text",
   148  				ResponseTo:  "",
   149  				EnsName:     "",
   150  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   151  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   152  			},
   153  		},
   154  		{
   155  			Name:             "Missing timestamp",
   156  			WhisperTimestamp: 2,
   157  			Valid:            false,
   158  			Message: &protobuf.ChatMessage{
   159  				ChatId:      "a",
   160  				Clock:       2,
   161  				Text:        "some-text",
   162  				ResponseTo:  "",
   163  				EnsName:     "",
   164  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   165  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   166  			},
   167  		},
   168  		{
   169  			Name:             "Missing text",
   170  			WhisperTimestamp: 2,
   171  			Valid:            false,
   172  			Message: &protobuf.ChatMessage{
   173  				ChatId:      "a",
   174  				Clock:       2,
   175  				Timestamp:   3,
   176  				ResponseTo:  "",
   177  				EnsName:     "",
   178  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   179  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   180  			},
   181  		},
   182  		{
   183  			Name:             "Blank text",
   184  			WhisperTimestamp: 2,
   185  			Valid:            false,
   186  			Message: &protobuf.ChatMessage{
   187  				ChatId:      "a",
   188  				Text:        "  \n \t \n  ",
   189  				Clock:       2,
   190  				Timestamp:   3,
   191  				ResponseTo:  "",
   192  				EnsName:     "",
   193  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   194  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   195  			},
   196  		},
   197  		{
   198  			Name:             "Too long text",
   199  			WhisperTimestamp: 2,
   200  			Valid:            false,
   201  			Message: &protobuf.ChatMessage{
   202  				ChatId:      "a",
   203  				Clock:       1,
   204  				Timestamp:   2,
   205  				Text:        strings.Repeat("É", maxChatMessageTextLength+1),
   206  				ResponseTo:  "",
   207  				EnsName:     "",
   208  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   209  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   210  			},
   211  		},
   212  		{
   213  			Name:             "Unknown MessageType",
   214  			WhisperTimestamp: 2,
   215  			Valid:            false,
   216  			Message: &protobuf.ChatMessage{
   217  				ChatId:      "a",
   218  				Text:        "valid",
   219  				Clock:       2,
   220  				Timestamp:   3,
   221  				ResponseTo:  "",
   222  				EnsName:     "",
   223  				MessageType: protobuf.MessageType_UNKNOWN_MESSAGE_TYPE,
   224  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   225  			},
   226  		},
   227  		{
   228  			Name:             "Unknown ContentType",
   229  			WhisperTimestamp: 2,
   230  			Valid:            false,
   231  			Message: &protobuf.ChatMessage{
   232  				ChatId:      "a",
   233  				Text:        "valid",
   234  				Clock:       2,
   235  				Timestamp:   3,
   236  				ResponseTo:  "",
   237  				EnsName:     "",
   238  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   239  				ContentType: protobuf.ChatMessage_UNKNOWN_CONTENT_TYPE,
   240  			},
   241  		},
   242  		{
   243  			Name:             "System message MessageType",
   244  			WhisperTimestamp: 2,
   245  			Valid:            false,
   246  			Message: &protobuf.ChatMessage{
   247  				ChatId:      "a",
   248  				Text:        "valid",
   249  				Clock:       2,
   250  				Timestamp:   3,
   251  				ResponseTo:  "",
   252  				EnsName:     "",
   253  				MessageType: protobuf.MessageType_SYSTEM_MESSAGE_PRIVATE_GROUP,
   254  				ContentType: protobuf.ChatMessage_TEXT_PLAIN,
   255  			},
   256  		},
   257  		{
   258  			Name:             "Request address for transaction message type",
   259  			WhisperTimestamp: 2,
   260  			Valid:            false,
   261  			Message: &protobuf.ChatMessage{
   262  				ChatId:      "a",
   263  				Text:        "valid",
   264  				Clock:       2,
   265  				Timestamp:   3,
   266  				ResponseTo:  "",
   267  				EnsName:     "",
   268  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   269  				ContentType: protobuf.ChatMessage_TRANSACTION_COMMAND,
   270  			},
   271  		},
   272  		{
   273  			Name:             "Valid  emoji only emssage",
   274  			WhisperTimestamp: 2,
   275  			Valid:            true,
   276  			Message: &protobuf.ChatMessage{
   277  				ChatId:      "a",
   278  				Text:        ":+1:",
   279  				Clock:       2,
   280  				Timestamp:   3,
   281  				ResponseTo:  "",
   282  				EnsName:     "",
   283  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   284  				ContentType: protobuf.ChatMessage_EMOJI,
   285  			},
   286  		},
   287  		// TODO: FIX ME
   288  		/*		{
   289  					Name:  "Invalid  emoji only emssage",
   290  					Valid: false,
   291  					Message: protobuf.ChatMessage{
   292  						ChatID:      "a",
   293  						Text:        ":+1: not valid",
   294  						Clock:       2,
   295  						Timestamp:   3,
   296  						ResponseTo:  "",
   297  						EnsName:     "",
   298  						MessageType: protobuf.MessageType_ONE_TO_ONE,
   299  						ContentType: protobuf.ChatMessage_EMOJI,
   300  					},
   301  				}
   302  				,*/
   303  		{
   304  			Name:             "Valid sticker message",
   305  			WhisperTimestamp: 2,
   306  			Valid:            true,
   307  			Message: &protobuf.ChatMessage{
   308  				ChatId:     "a",
   309  				Text:       "valid",
   310  				Clock:      2,
   311  				Timestamp:  3,
   312  				ResponseTo: "",
   313  				EnsName:    "",
   314  				Payload: &protobuf.ChatMessage_Sticker{
   315  					Sticker: &protobuf.StickerMessage{
   316  						Pack: 1,
   317  						Hash: "some-hash",
   318  					},
   319  				},
   320  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   321  				ContentType: protobuf.ChatMessage_STICKER,
   322  			},
   323  		},
   324  		{
   325  			Name:             "Invalid sticker message without Hash",
   326  			WhisperTimestamp: 2,
   327  			Valid:            false,
   328  			Message: &protobuf.ChatMessage{
   329  				ChatId:     "a",
   330  				Text:       "valid",
   331  				Clock:      2,
   332  				Timestamp:  3,
   333  				ResponseTo: "",
   334  				EnsName:    "",
   335  				Payload: &protobuf.ChatMessage_Sticker{
   336  					Sticker: &protobuf.StickerMessage{
   337  						Pack: 1,
   338  					},
   339  				},
   340  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   341  				ContentType: protobuf.ChatMessage_STICKER,
   342  			},
   343  		},
   344  		{
   345  			Name:             "Invalid sticker message without any content",
   346  			WhisperTimestamp: 2,
   347  			Valid:            false,
   348  			Message: &protobuf.ChatMessage{
   349  				ChatId:      "a",
   350  				Text:        "valid",
   351  				Clock:       2,
   352  				Timestamp:   3,
   353  				ResponseTo:  "",
   354  				EnsName:     "",
   355  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   356  				ContentType: protobuf.ChatMessage_STICKER,
   357  			},
   358  		},
   359  		{
   360  			Name:             "Valid image message",
   361  			WhisperTimestamp: 2,
   362  			Valid:            true,
   363  			Message: &protobuf.ChatMessage{
   364  				ChatId:     "a",
   365  				Text:       "valid",
   366  				Clock:      2,
   367  				Timestamp:  3,
   368  				ResponseTo: "",
   369  				EnsName:    "",
   370  				Payload: &protobuf.ChatMessage_Image{
   371  					Image: &protobuf.ImageMessage{
   372  						Format:  1,
   373  						Payload: []byte("some-payload"),
   374  					},
   375  				},
   376  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   377  				ContentType: protobuf.ChatMessage_IMAGE,
   378  			},
   379  		},
   380  		{
   381  			Name:             "Invalid image message, type unknown",
   382  			WhisperTimestamp: 2,
   383  			Valid:            false,
   384  			Message: &protobuf.ChatMessage{
   385  				ChatId:     "a",
   386  				Text:       "valid",
   387  				Clock:      2,
   388  				Timestamp:  3,
   389  				ResponseTo: "",
   390  				EnsName:    "",
   391  				Payload: &protobuf.ChatMessage_Image{
   392  					Image: &protobuf.ImageMessage{
   393  						Format:  protobuf.ImageFormat_UNKNOWN_IMAGE_FORMAT,
   394  						Payload: []byte("some-payload"),
   395  					},
   396  				},
   397  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   398  				ContentType: protobuf.ChatMessage_STICKER,
   399  			},
   400  		},
   401  		{
   402  			Name:             "Invalid image message, missing payload",
   403  			WhisperTimestamp: 2,
   404  			Valid:            false,
   405  			Message: &protobuf.ChatMessage{
   406  				ChatId:     "a",
   407  				Text:       "valid",
   408  				Clock:      2,
   409  				Timestamp:  3,
   410  				ResponseTo: "",
   411  				EnsName:    "",
   412  				Payload: &protobuf.ChatMessage_Image{
   413  					Image: &protobuf.ImageMessage{
   414  						Format: 1,
   415  					},
   416  				},
   417  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   418  				ContentType: protobuf.ChatMessage_IMAGE,
   419  			},
   420  		},
   421  		{
   422  			Name:             "Valid audio message",
   423  			WhisperTimestamp: 2,
   424  			Valid:            true,
   425  			Message: &protobuf.ChatMessage{
   426  				ChatId:     "a",
   427  				Text:       "valid",
   428  				Clock:      2,
   429  				Timestamp:  3,
   430  				ResponseTo: "",
   431  				EnsName:    "",
   432  				Payload: &protobuf.ChatMessage_Audio{
   433  					Audio: &protobuf.AudioMessage{
   434  						Type:    1,
   435  						Payload: []byte("some-payload"),
   436  					},
   437  				},
   438  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   439  				ContentType: protobuf.ChatMessage_AUDIO,
   440  			},
   441  		},
   442  		{
   443  			Name:             "Invalid audio message, type unknown",
   444  			WhisperTimestamp: 2,
   445  			Valid:            false,
   446  			Message: &protobuf.ChatMessage{
   447  				ChatId:     "a",
   448  				Text:       "valid",
   449  				Clock:      2,
   450  				Timestamp:  3,
   451  				ResponseTo: "",
   452  				EnsName:    "",
   453  				Payload: &protobuf.ChatMessage_Audio{
   454  					Audio: &protobuf.AudioMessage{
   455  						Type:    protobuf.AudioMessage_UNKNOWN_AUDIO_TYPE,
   456  						Payload: []byte("some-payload"),
   457  					},
   458  				},
   459  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   460  				ContentType: protobuf.ChatMessage_STICKER,
   461  			},
   462  		},
   463  		{
   464  			Name:             "Invalid audio message, missing payload",
   465  			WhisperTimestamp: 2,
   466  			Valid:            false,
   467  			Message: &protobuf.ChatMessage{
   468  				ChatId:     "a",
   469  				Text:       "valid",
   470  				Clock:      2,
   471  				Timestamp:  3,
   472  				ResponseTo: "",
   473  				EnsName:    "",
   474  				Payload: &protobuf.ChatMessage_Audio{
   475  					Audio: &protobuf.AudioMessage{
   476  						Type: 1,
   477  					},
   478  				},
   479  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   480  				ContentType: protobuf.ChatMessage_AUDIO,
   481  			},
   482  		},
   483  		{
   484  			Name:             "Valid bridge message",
   485  			WhisperTimestamp: 2,
   486  			Valid:            true,
   487  			Message: &protobuf.ChatMessage{
   488  				ChatId:     "a",
   489  				Text:       "",
   490  				Clock:      2,
   491  				Timestamp:  3,
   492  				ResponseTo: "",
   493  				EnsName:    "",
   494  				Payload: &protobuf.ChatMessage_BridgeMessage{
   495  					BridgeMessage: &protobuf.BridgeMessage{
   496  						BridgeName: "discord",
   497  						UserName:   "mike",
   498  						Content:    "some text",
   499  					},
   500  				},
   501  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   502  				ContentType: protobuf.ChatMessage_BRIDGE_MESSAGE,
   503  			},
   504  		},
   505  		{
   506  			Name:             "Invalid bridge message",
   507  			WhisperTimestamp: 2,
   508  			Valid:            false,
   509  			Message: &protobuf.ChatMessage{
   510  				ChatId:     "a",
   511  				Text:       "",
   512  				Clock:      2,
   513  				Timestamp:  3,
   514  				ResponseTo: "",
   515  				EnsName:    "",
   516  				Payload: &protobuf.ChatMessage_BridgeMessage{
   517  					BridgeMessage: &protobuf.BridgeMessage{
   518  						BridgeName: "",
   519  						UserName:   "",
   520  						Content:    "",
   521  					},
   522  				},
   523  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   524  				ContentType: protobuf.ChatMessage_BRIDGE_MESSAGE,
   525  			},
   526  		},
   527  	}
   528  
   529  	for _, tc := range testCases {
   530  		s.Run(tc.Name, func() {
   531  			err := ValidateReceivedChatMessage(tc.Message, tc.WhisperTimestamp)
   532  			if tc.Valid {
   533  				s.Nil(err)
   534  			} else {
   535  				s.NotNil(err)
   536  			}
   537  		})
   538  	}
   539  }
   540  
   541  func (s *MessageValidatorSuite) TestValidateEmojiReaction() {
   542  	testCases := []struct {
   543  		Name             string
   544  		Valid            bool
   545  		WhisperTimestamp uint64
   546  		Message          *protobuf.EmojiReaction
   547  	}{
   548  		{
   549  			Name:             "valid emoji reaction",
   550  			Valid:            true,
   551  			WhisperTimestamp: 30,
   552  			Message: &protobuf.EmojiReaction{
   553  				Clock:       30,
   554  				ChatId:      "chat-id",
   555  				MessageId:   "message-id",
   556  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   557  				Type:        protobuf.EmojiReaction_LOVE,
   558  			},
   559  		},
   560  		{
   561  			Name:             "valid emoji retraction",
   562  			Valid:            true,
   563  			WhisperTimestamp: 30,
   564  			Message: &protobuf.EmojiReaction{
   565  				Clock:       30,
   566  				ChatId:      "0.34",
   567  				MessageId:   "message-id",
   568  				Type:        protobuf.EmojiReaction_LOVE,
   569  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   570  				Retracted:   true,
   571  			},
   572  		},
   573  		{
   574  			Name:             "missing chatID",
   575  			Valid:            false,
   576  			WhisperTimestamp: 30,
   577  			Message: &protobuf.EmojiReaction{
   578  				Clock:       30,
   579  				MessageId:   "message-id",
   580  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   581  				Type:        protobuf.EmojiReaction_LOVE,
   582  			},
   583  		},
   584  		{
   585  			Name:             "missing messageID",
   586  			Valid:            false,
   587  			WhisperTimestamp: 30,
   588  			Message: &protobuf.EmojiReaction{
   589  				Clock:       30,
   590  				ChatId:      "chat-id",
   591  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   592  				Type:        protobuf.EmojiReaction_LOVE,
   593  			},
   594  		},
   595  		{
   596  			Name:             "missing type",
   597  			Valid:            false,
   598  			WhisperTimestamp: 30,
   599  			Message: &protobuf.EmojiReaction{
   600  				Clock:       30,
   601  				ChatId:      "chat-id",
   602  				MessageId:   "message-id",
   603  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   604  			},
   605  		},
   606  		{
   607  			Name:             "missing message type",
   608  			Valid:            false,
   609  			WhisperTimestamp: 30,
   610  			Message: &protobuf.EmojiReaction{
   611  				Clock:     30,
   612  				ChatId:    "chat-id",
   613  				MessageId: "message-id",
   614  				Type:      protobuf.EmojiReaction_LOVE,
   615  			},
   616  		},
   617  		{
   618  			Name:             "clock value too high",
   619  			Valid:            false,
   620  			WhisperTimestamp: 30,
   621  			Message: &protobuf.EmojiReaction{
   622  				Clock:       900000,
   623  				ChatId:      "chat-id",
   624  				MessageId:   "message-id",
   625  				MessageType: protobuf.MessageType_ONE_TO_ONE,
   626  				Type:        protobuf.EmojiReaction_LOVE,
   627  			},
   628  		},
   629  	}
   630  	for _, tc := range testCases {
   631  		s.Run(tc.Name, func() {
   632  			err := ValidateReceivedEmojiReaction(tc.Message, tc.WhisperTimestamp)
   633  			if tc.Valid {
   634  				s.Nil(err)
   635  			} else {
   636  				s.NotNil(err)
   637  			}
   638  		})
   639  	}
   640  
   641  }