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

     1  package protocol
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  	"go.uber.org/zap"
    10  
    11  	gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
    12  	"github.com/status-im/status-go/eth-node/types"
    13  	"github.com/status-im/status-go/multiaccounts/settings"
    14  	"github.com/status-im/status-go/params"
    15  	"github.com/status-im/status-go/protocol/encryption/multidevice"
    16  	"github.com/status-im/status-go/protocol/tt"
    17  	"github.com/status-im/status-go/services/stickers"
    18  	"github.com/status-im/status-go/waku"
    19  )
    20  
    21  var (
    22  	pf         = "A Preferred Name"
    23  	pf2        = "AnotherPreferredName.eth"
    24  	rawSticker = []byte(`{
    25    "1":{
    26      "author":"cryptoworld1373",
    27      "id":1,
    28      "name":"Status Cat",
    29      "preview":"e3010170122050efc0a3e661339f31e1e44b3d15a1bf4e501c965a0523f57b701667fa90ccca",
    30      "price":0,
    31      "stickers":[
    32        {"hash":"e30101701220eab9a8ef4eac6c3e5836a3768d8e04935c10c67d9a700436a0e53199e9b64d29"},
    33        {"hash":"e30101701220c8f28aebe4dbbcee896d1cdff89ceeaceaf9f837df55c79125388f954ee5f1fe"},
    34        {"hash":"e301017012204861f93e29dd8e7cf6699135c7b13af1bce8ceeaa1d9959ab8592aa20f05d15f"},
    35        {"hash":"e301017012203ffa57a51cceaf2ce040852de3b300d395d5ba4d70e08ba993f93a25a387e3a9"},
    36        {"hash":"e301017012204f2674db0bc7f7cfc0382d1d7f79b4ff73c41f5c487ef4c3bb3f3a4cf3f87d70"},
    37        {"hash":"e30101701220e8d4d8b9fb5f805add2f63c1cb5c891e60f9929fc404e3bb725aa81628b97b5f"},
    38        {"hash":"e301017012206fdad56fe7a2facb02dabe8294f3ac051443fcc52d67c2fbd8615eb72f9d74bd"},
    39        {"hash":"e30101701220a691193cf0559905c10a3c5affb9855d730eae05509d503d71327e6c820aaf98"},
    40        {"hash":"e30101701220d8004af925f8e85b4e24813eaa5ef943fa6a0c76035491b64fbd2e632a5cc2fd"},
    41        {"hash":"e3010170122049f7bc650615568f14ee1cfa9ceaf89bfbc4745035479a7d8edee9b4465e64de"},
    42        {"hash":"e301017012201915dc0faad8e6783aca084a854c03553450efdabf977d57b4f22f73d5c53b50"},
    43        {"hash":"e301017012200b9fb71a129048c2a569433efc8e4d9155c54d598538be7f65ea26f665be1e84"},
    44        {"hash":"e30101701220d37944e3fb05213d45416fa634cf9e10ec1f43d3bf72c4eb3062ae6cc4ed9b08"},
    45        {"hash":"e3010170122059390dca66ba8713a9c323925bf768612f7dd16298c13a07a6b47cb5af4236e6"},
    46        {"hash":"e30101701220daaf88ace8a3356559be5d6912d5d442916e3cc92664954526c9815d693dc32b"},
    47        {"hash":"e301017012203ae30594fdf56d7bfd686cef1a45c201024e9c10a792722ef07ba968c83c064d"},
    48        {"hash":"e3010170122016e5eba0bbd32fc1ff17d80d1247fc67432705cd85731458b52febb84fdd6408"},
    49        {"hash":"e3010170122014fe2c2186cbf9d15ff61e04054fd6b0a5dbd7f365a1807f6f3d3d3e93e50875"},
    50        {"hash":"e30101701220f23a7dad3ea7ad3f3553a98fb305148d285e4ebf66b427d85a2340f66d51da94"},
    51        {"hash":"e3010170122047a637c6af02904a8ae702ec74b3df5fd8914df6fb11c99446a36d890beeb7ee"},
    52        {"hash":"e30101701220776f1ff89f6196ae68414545f6c6a5314c35eee7406cb8591d607a2b0533cc86"}
    53      ],
    54      "thumbnail":"e30101701220e9876531554a7cb4f20d7ebbf9daef2253e6734ad9c96ba288586a9b88bef491"
    55    }
    56  }`)
    57  )
    58  
    59  func TestMessengerSyncSettings(t *testing.T) {
    60  	suite.Run(t, new(MessengerSyncSettingsSuite))
    61  }
    62  
    63  type MessengerSyncSettingsSuite struct {
    64  	suite.Suite
    65  	alice  *Messenger
    66  	alice2 *Messenger
    67  	// If one wants to send messages between different instances of Messenger,
    68  	// a single Waku service should be shared.
    69  	shh    types.Waku
    70  	logger *zap.Logger
    71  
    72  	ignoreTests bool
    73  }
    74  
    75  func (s *MessengerSyncSettingsSuite) SetupSuite() {
    76  	s.ignoreTests = true
    77  }
    78  
    79  func (s *MessengerSyncSettingsSuite) SetupTest() {
    80  	s.logger = tt.MustCreateTestLogger()
    81  
    82  	config := waku.DefaultConfig
    83  	config.MinimumAcceptedPoW = 0
    84  	shh := waku.New(&config, s.logger)
    85  	s.shh = gethbridge.NewGethWakuWrapper(shh)
    86  	s.Require().NoError(shh.Start())
    87  
    88  	s.alice = s.newMessenger()
    89  	_, err := s.alice.Start()
    90  	s.Require().NoError(err)
    91  
    92  	s.alice2, err = newMessengerWithKey(s.shh, s.alice.identity, s.logger, nil)
    93  	s.Require().NoError(err)
    94  
    95  	prepAliceMessengersForPairing(&s.Suite, s.alice, s.alice2)
    96  }
    97  
    98  func (s *MessengerSyncSettingsSuite) TearDownTest() {
    99  	TearDownMessenger(&s.Suite, s.alice)
   100  	_ = s.logger.Sync()
   101  }
   102  
   103  func (s *MessengerSyncSettingsSuite) newMessenger() *Messenger {
   104  	config := params.NodeConfig{
   105  		NetworkID: 10,
   106  		DataDir:   "test",
   107  	}
   108  
   109  	networks := json.RawMessage("{}")
   110  	setting := settings.Settings{
   111  		Address:                   types.HexToAddress("0x1122334455667788990011223344556677889900"),
   112  		AnonMetricsShouldSend:     false,
   113  		CurrentNetwork:            "mainnet_rpc",
   114  		DappsAddress:              types.HexToAddress("0x1122334455667788990011223344556677889900"),
   115  		InstallationID:            "d3efcff6-cffa-560e-a547-21d3858cbc51",
   116  		KeyUID:                    "0x1122334455667788990011223344556677889900",
   117  		LatestDerivedPath:         0,
   118  		Name:                      "Test",
   119  		Networks:                  &networks,
   120  		PhotoPath:                 "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==",
   121  		PreviewPrivacy:            false,
   122  		PublicKey:                 "0x04112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900",
   123  		SigningPhrase:             "yurt joey vibe",
   124  		SendPushNotifications:     true,
   125  		ProfilePicturesShowTo:     1,
   126  		ProfilePicturesVisibility: 1,
   127  		DefaultSyncPeriod:         86400,
   128  		UseMailservers:            true,
   129  		LinkPreviewRequestEnabled: true,
   130  		SendStatusUpdates:         true,
   131  		WalletRootAddress:         types.HexToAddress("0x1122334455667788990011223344556677889900"),
   132  		URLUnfurlingMode:          settings.URLUnfurlingAlwaysAsk,
   133  		PreferredName:             &pf,
   134  		Currency:                  "eth",
   135  	}
   136  
   137  	m, err := newTestMessenger(s.shh, testMessengerConfig{
   138  		extraOptions: []Option{WithAppSettings(setting, config)},
   139  	})
   140  	s.Require().NoError(err)
   141  	return m
   142  }
   143  
   144  func prepAliceMessengersForPairing(s *suite.Suite, alice1, alice2 *Messenger) {
   145  	// Set Alice's installation metadata
   146  	aim := &multidevice.InstallationMetadata{
   147  		Name:       "alice's-device",
   148  		DeviceType: "alice's-device-type",
   149  	}
   150  	err := alice1.SetInstallationMetadata(alice1.installationID, aim)
   151  	s.Require().NoError(err)
   152  
   153  	// Set Alice 2's installation metadata
   154  	a2im := &multidevice.InstallationMetadata{
   155  		Name:       "alice's-other-device",
   156  		DeviceType: "alice's-other-device-type",
   157  	}
   158  	err = alice2.SetInstallationMetadata(alice2.installationID, a2im)
   159  	s.Require().NoError(err)
   160  }
   161  
   162  func (s *MessengerSyncSettingsSuite) syncSettingAndCheck(m1 *Messenger, m2 *Messenger, settingField settings.SettingField, settingValue interface{}) settings.Settings {
   163  	err := m1.settings.SaveSettingField(settingField, settingValue)
   164  	s.Require().NoError(err)
   165  
   166  	// Wait for the message to reach its destination
   167  	err = tt.RetryWithBackOff(func() error {
   168  		mr, err := m2.RetrieveAll()
   169  		if err != nil {
   170  			return err
   171  		}
   172  		if len(mr.Settings) == 0 {
   173  			return errors.New("sync settings not in MessengerResponse")
   174  		}
   175  		return nil
   176  	})
   177  	s.Require().NoError(err)
   178  
   179  	// Check settings values
   180  	m2s, err := m2.settings.GetSettings()
   181  	s.Require().NoError(err)
   182  	return m2s
   183  }
   184  
   185  func (s *MessengerSyncSettingsSuite) TestSyncSettings() {
   186  	// Pair alice's two devices
   187  	PairDevices(&s.Suite, s.alice2, s.alice)
   188  	PairDevices(&s.Suite, s.alice, s.alice2)
   189  
   190  	// Check alice 1 settings values
   191  	as, err := s.alice.settings.GetSettings()
   192  	s.Require().NoError(err)
   193  	s.Require().Exactly(settings.ProfilePicturesShowToContactsOnly, as.ProfilePicturesShowTo)
   194  	s.Require().Exactly(settings.ProfilePicturesVisibilityContactsOnly, as.ProfilePicturesVisibility)
   195  	s.Require().Exactly(settings.URLUnfurlingAlwaysAsk, as.URLUnfurlingMode)
   196  
   197  	// Check alice 2 settings values
   198  	aos, err := s.alice2.settings.GetSettings()
   199  	s.Require().NoError(err)
   200  	s.Require().Exactly(settings.ProfilePicturesShowToContactsOnly, aos.ProfilePicturesShowTo)
   201  	s.Require().Exactly(settings.ProfilePicturesVisibilityContactsOnly, aos.ProfilePicturesVisibility)
   202  	s.Require().Exactly(settings.URLUnfurlingAlwaysAsk, as.URLUnfurlingMode)
   203  
   204  	aos = s.syncSettingAndCheck(s.alice, s.alice2, settings.ProfilePicturesVisibility, settings.ProfilePicturesVisibilityEveryone)
   205  	s.Require().Equal(settings.ProfilePicturesVisibilityEveryone, aos.ProfilePicturesVisibility)
   206  
   207  	as = s.syncSettingAndCheck(s.alice2, s.alice, settings.ProfilePicturesShowTo, settings.ProfilePicturesShowToEveryone)
   208  	s.Require().Exactly(settings.ProfilePicturesShowToEveryone, as.ProfilePicturesShowTo)
   209  
   210  	aos = s.syncSettingAndCheck(s.alice, s.alice2, settings.URLUnfurlingMode, settings.URLUnfurlingDisableAll)
   211  	s.Require().Exactly(settings.URLUnfurlingDisableAll, aos.URLUnfurlingMode)
   212  }
   213  
   214  func (s *MessengerSyncSettingsSuite) TestSyncSettings_StickerPacks() {
   215  	if s.ignoreTests {
   216  		s.T().Skip("Currently sticker pack syncing has been deactivated, testing to resume after sticker packs works correctly")
   217  		return
   218  	}
   219  
   220  	// Check alice 1 settings values
   221  	as, err := s.alice.settings.GetSettings()
   222  	s.Require().NoError(err)
   223  	s.Require().Nil(as.StickerPacksInstalled)
   224  	s.Require().Nil(as.StickerPacksPending)
   225  	s.Require().Nil(as.StickersRecentStickers)
   226  
   227  	// Check alice 2 settings values
   228  	aos, err := s.alice2.settings.GetSettings()
   229  	s.Require().NoError(err)
   230  	s.Require().Nil(aos.StickerPacksInstalled)
   231  	s.Require().Nil(aos.StickerPacksPending)
   232  	s.Require().Nil(aos.StickersRecentStickers)
   233  
   234  	// Pair devices. Allows alice to send to alicesOtherDevice
   235  	PairDevices(&s.Suite, s.alice2, s.alice)
   236  
   237  	// Add sticker pack to alice device
   238  	stickerPacks := make(stickers.StickerPackCollection)
   239  	err = json.Unmarshal(rawSticker, &stickerPacks)
   240  	s.Require().NoError(err)
   241  
   242  	err = s.alice.settings.SaveSettingField(settings.StickersPacksInstalled, stickerPacks)
   243  	s.Require().NoError(err)
   244  
   245  	as, err = s.alice.settings.GetSettings()
   246  	s.Require().NoError(err)
   247  	spi, err := as.StickerPacksInstalled.MarshalJSON()
   248  	s.Require().NoError(err)
   249  	s.Require().Equal(2169, len(spi))
   250  
   251  	// Wait for the message to reach its destination
   252  	err = tt.RetryWithBackOff(func() error {
   253  		mr, err := s.alice2.RetrieveAll()
   254  		if err != nil {
   255  			return err
   256  		}
   257  
   258  		if len(mr.Settings) == 0 {
   259  			return errors.New("sync settings not in MessengerResponse")
   260  		}
   261  
   262  		return nil
   263  	})
   264  	s.Require().NoError(err)
   265  
   266  	aos, err = s.alice2.settings.GetSettings()
   267  	s.Require().NoError(err)
   268  	ospi, err := aos.StickerPacksInstalled.MarshalJSON()
   269  	s.Require().NoError(err)
   270  	s.Require().Exactly(spi, ospi)
   271  }
   272  
   273  func (s *MessengerSyncSettingsSuite) TestSyncSettings_PreferredName() {
   274  	// Check alice 1 settings values
   275  	as, err := s.alice.settings.GetSettings()
   276  	s.Require().NoError(err)
   277  	s.Require().Equal(pf, *as.PreferredName)
   278  
   279  	// Check alice 2 settings values
   280  	aos, err := s.alice2.settings.GetSettings()
   281  	s.Require().NoError(err)
   282  	s.Require().Nil(aos.PreferredName)
   283  
   284  	// Pair devices. Allows alice to send to alicesOtherDevice
   285  	PairDevices(&s.Suite, s.alice2, s.alice)
   286  
   287  	// Update Alice's PreferredName
   288  	err = s.alice.settings.SaveSettingField(settings.PreferredName, pf2)
   289  	s.Require().NoError(err)
   290  
   291  	apn, err := s.alice.settings.GetPreferredUsername()
   292  	s.Require().NoError(err)
   293  	s.Require().Equal(pf2, apn)
   294  
   295  	// Wait for the sync message to reach its destination
   296  	err = tt.RetryWithBackOff(func() error {
   297  		mr, err := s.alice2.RetrieveAll()
   298  		if err != nil {
   299  			return err
   300  		}
   301  
   302  		if len(mr.Settings) == 0 {
   303  			return errors.New("sync settings not in MessengerResponse")
   304  		}
   305  
   306  		return nil
   307  	})
   308  	s.Require().NoError(err)
   309  
   310  	opn, err := s.alice2.settings.GetPreferredUsername()
   311  	s.Require().NoError(err)
   312  	s.Require().Equal(pf2, opn)
   313  }