status-im/status-go

View on GitHub
protocol/messenger_sync_settings_test.go

Summary

Maintainability
A
0 mins
Test Coverage
package protocol

import (
    "encoding/json"
    "errors"
    "testing"

    "github.com/stretchr/testify/suite"
    "go.uber.org/zap"

    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/multiaccounts/settings"
    "github.com/status-im/status-go/params"
    "github.com/status-im/status-go/protocol/encryption/multidevice"
    "github.com/status-im/status-go/protocol/tt"
    "github.com/status-im/status-go/services/stickers"
    "github.com/status-im/status-go/waku"
)

var (
    pf         = "A Preferred Name"
    pf2        = "AnotherPreferredName.eth"
    rawSticker = []byte(`{
  "1":{
    "author":"cryptoworld1373",
    "id":1,
    "name":"Status Cat",
    "preview":"e3010170122050efc0a3e661339f31e1e44b3d15a1bf4e501c965a0523f57b701667fa90ccca",
    "price":0,
    "stickers":[
      {"hash":"e30101701220eab9a8ef4eac6c3e5836a3768d8e04935c10c67d9a700436a0e53199e9b64d29"},
      {"hash":"e30101701220c8f28aebe4dbbcee896d1cdff89ceeaceaf9f837df55c79125388f954ee5f1fe"},
      {"hash":"e301017012204861f93e29dd8e7cf6699135c7b13af1bce8ceeaa1d9959ab8592aa20f05d15f"},
      {"hash":"e301017012203ffa57a51cceaf2ce040852de3b300d395d5ba4d70e08ba993f93a25a387e3a9"},
      {"hash":"e301017012204f2674db0bc7f7cfc0382d1d7f79b4ff73c41f5c487ef4c3bb3f3a4cf3f87d70"},
      {"hash":"e30101701220e8d4d8b9fb5f805add2f63c1cb5c891e60f9929fc404e3bb725aa81628b97b5f"},
      {"hash":"e301017012206fdad56fe7a2facb02dabe8294f3ac051443fcc52d67c2fbd8615eb72f9d74bd"},
      {"hash":"e30101701220a691193cf0559905c10a3c5affb9855d730eae05509d503d71327e6c820aaf98"},
      {"hash":"e30101701220d8004af925f8e85b4e24813eaa5ef943fa6a0c76035491b64fbd2e632a5cc2fd"},
      {"hash":"e3010170122049f7bc650615568f14ee1cfa9ceaf89bfbc4745035479a7d8edee9b4465e64de"},
      {"hash":"e301017012201915dc0faad8e6783aca084a854c03553450efdabf977d57b4f22f73d5c53b50"},
      {"hash":"e301017012200b9fb71a129048c2a569433efc8e4d9155c54d598538be7f65ea26f665be1e84"},
      {"hash":"e30101701220d37944e3fb05213d45416fa634cf9e10ec1f43d3bf72c4eb3062ae6cc4ed9b08"},
      {"hash":"e3010170122059390dca66ba8713a9c323925bf768612f7dd16298c13a07a6b47cb5af4236e6"},
      {"hash":"e30101701220daaf88ace8a3356559be5d6912d5d442916e3cc92664954526c9815d693dc32b"},
      {"hash":"e301017012203ae30594fdf56d7bfd686cef1a45c201024e9c10a792722ef07ba968c83c064d"},
      {"hash":"e3010170122016e5eba0bbd32fc1ff17d80d1247fc67432705cd85731458b52febb84fdd6408"},
      {"hash":"e3010170122014fe2c2186cbf9d15ff61e04054fd6b0a5dbd7f365a1807f6f3d3d3e93e50875"},
      {"hash":"e30101701220f23a7dad3ea7ad3f3553a98fb305148d285e4ebf66b427d85a2340f66d51da94"},
      {"hash":"e3010170122047a637c6af02904a8ae702ec74b3df5fd8914df6fb11c99446a36d890beeb7ee"},
      {"hash":"e30101701220776f1ff89f6196ae68414545f6c6a5314c35eee7406cb8591d607a2b0533cc86"}
    ],
    "thumbnail":"e30101701220e9876531554a7cb4f20d7ebbf9daef2253e6734ad9c96ba288586a9b88bef491"
  }
}`)
)

func TestMessengerSyncSettings(t *testing.T) {
    suite.Run(t, new(MessengerSyncSettingsSuite))
}

type MessengerSyncSettingsSuite struct {
    suite.Suite
    alice  *Messenger
    alice2 *Messenger
    // If one wants to send messages between different instances of Messenger,
    // a single Waku service should be shared.
    shh    types.Waku
    logger *zap.Logger

    ignoreTests bool
}

func (s *MessengerSyncSettingsSuite) SetupSuite() {
    s.ignoreTests = true
}

func (s *MessengerSyncSettingsSuite) SetupTest() {
    s.logger = tt.MustCreateTestLogger()

    config := waku.DefaultConfig
    config.MinimumAcceptedPoW = 0
    shh := waku.New(&config, s.logger)
    s.shh = gethbridge.NewGethWakuWrapper(shh)
    s.Require().NoError(shh.Start())

    s.alice = s.newMessenger()
    _, err := s.alice.Start()
    s.Require().NoError(err)

    s.alice2, err = newMessengerWithKey(s.shh, s.alice.identity, s.logger, nil)
    s.Require().NoError(err)

    prepAliceMessengersForPairing(&s.Suite, s.alice, s.alice2)
}

func (s *MessengerSyncSettingsSuite) TearDownTest() {
    TearDownMessenger(&s.Suite, s.alice)
    _ = s.logger.Sync()
}

func (s *MessengerSyncSettingsSuite) newMessenger() *Messenger {
    config := params.NodeConfig{
        NetworkID: 10,
        DataDir:   "test",
    }

    networks := json.RawMessage("{}")
    setting := settings.Settings{
        Address:                   types.HexToAddress("0x1122334455667788990011223344556677889900"),
        AnonMetricsShouldSend:     false,
        CurrentNetwork:            "mainnet_rpc",
        DappsAddress:              types.HexToAddress("0x1122334455667788990011223344556677889900"),
        InstallationID:            "d3efcff6-cffa-560e-a547-21d3858cbc51",
        KeyUID:                    "0x1122334455667788990011223344556677889900",
        LatestDerivedPath:         0,
        Name:                      "Test",
        Networks:                  &networks,
        PhotoPath:                 "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==",
        PreviewPrivacy:            false,
        PublicKey:                 "0x04112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900",
        SigningPhrase:             "yurt joey vibe",
        SendPushNotifications:     true,
        ProfilePicturesShowTo:     1,
        ProfilePicturesVisibility: 1,
        DefaultSyncPeriod:         86400,
        UseMailservers:            true,
        LinkPreviewRequestEnabled: true,
        SendStatusUpdates:         true,
        WalletRootAddress:         types.HexToAddress("0x1122334455667788990011223344556677889900"),
        URLUnfurlingMode:          settings.URLUnfurlingAlwaysAsk,
        PreferredName:             &pf,
        Currency:                  "eth",
    }

    m, err := newTestMessenger(s.shh, testMessengerConfig{
        extraOptions: []Option{WithAppSettings(setting, config)},
    })
    s.Require().NoError(err)
    return m
}

func prepAliceMessengersForPairing(s *suite.Suite, alice1, alice2 *Messenger) {
    // Set Alice's installation metadata
    aim := &multidevice.InstallationMetadata{
        Name:       "alice's-device",
        DeviceType: "alice's-device-type",
    }
    err := alice1.SetInstallationMetadata(alice1.installationID, aim)
    s.Require().NoError(err)

    // Set Alice 2's installation metadata
    a2im := &multidevice.InstallationMetadata{
        Name:       "alice's-other-device",
        DeviceType: "alice's-other-device-type",
    }
    err = alice2.SetInstallationMetadata(alice2.installationID, a2im)
    s.Require().NoError(err)
}

func (s *MessengerSyncSettingsSuite) syncSettingAndCheck(m1 *Messenger, m2 *Messenger, settingField settings.SettingField, settingValue interface{}) settings.Settings {
    err := m1.settings.SaveSettingField(settingField, settingValue)
    s.Require().NoError(err)

    // Wait for the message to reach its destination
    err = tt.RetryWithBackOff(func() error {
        mr, err := m2.RetrieveAll()
        if err != nil {
            return err
        }
        if len(mr.Settings) == 0 {
            return errors.New("sync settings not in MessengerResponse")
        }
        return nil
    })
    s.Require().NoError(err)

    // Check settings values
    m2s, err := m2.settings.GetSettings()
    s.Require().NoError(err)
    return m2s
}

func (s *MessengerSyncSettingsSuite) TestSyncSettings() {
    // Pair alice's two devices
    PairDevices(&s.Suite, s.alice2, s.alice)
    PairDevices(&s.Suite, s.alice, s.alice2)

    // Check alice 1 settings values
    as, err := s.alice.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Exactly(settings.ProfilePicturesShowToContactsOnly, as.ProfilePicturesShowTo)
    s.Require().Exactly(settings.ProfilePicturesVisibilityContactsOnly, as.ProfilePicturesVisibility)
    s.Require().Exactly(settings.URLUnfurlingAlwaysAsk, as.URLUnfurlingMode)

    // Check alice 2 settings values
    aos, err := s.alice2.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Exactly(settings.ProfilePicturesShowToContactsOnly, aos.ProfilePicturesShowTo)
    s.Require().Exactly(settings.ProfilePicturesVisibilityContactsOnly, aos.ProfilePicturesVisibility)
    s.Require().Exactly(settings.URLUnfurlingAlwaysAsk, as.URLUnfurlingMode)

    aos = s.syncSettingAndCheck(s.alice, s.alice2, settings.ProfilePicturesVisibility, settings.ProfilePicturesVisibilityEveryone)
    s.Require().Equal(settings.ProfilePicturesVisibilityEveryone, aos.ProfilePicturesVisibility)

    as = s.syncSettingAndCheck(s.alice2, s.alice, settings.ProfilePicturesShowTo, settings.ProfilePicturesShowToEveryone)
    s.Require().Exactly(settings.ProfilePicturesShowToEveryone, as.ProfilePicturesShowTo)

    aos = s.syncSettingAndCheck(s.alice, s.alice2, settings.URLUnfurlingMode, settings.URLUnfurlingDisableAll)
    s.Require().Exactly(settings.URLUnfurlingDisableAll, aos.URLUnfurlingMode)
}

func (s *MessengerSyncSettingsSuite) TestSyncSettings_StickerPacks() {
    if s.ignoreTests {
        s.T().Skip("Currently sticker pack syncing has been deactivated, testing to resume after sticker packs works correctly")
        return
    }

    // Check alice 1 settings values
    as, err := s.alice.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Nil(as.StickerPacksInstalled)
    s.Require().Nil(as.StickerPacksPending)
    s.Require().Nil(as.StickersRecentStickers)

    // Check alice 2 settings values
    aos, err := s.alice2.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Nil(aos.StickerPacksInstalled)
    s.Require().Nil(aos.StickerPacksPending)
    s.Require().Nil(aos.StickersRecentStickers)

    // Pair devices. Allows alice to send to alicesOtherDevice
    PairDevices(&s.Suite, s.alice2, s.alice)

    // Add sticker pack to alice device
    stickerPacks := make(stickers.StickerPackCollection)
    err = json.Unmarshal(rawSticker, &stickerPacks)
    s.Require().NoError(err)

    err = s.alice.settings.SaveSettingField(settings.StickersPacksInstalled, stickerPacks)
    s.Require().NoError(err)

    as, err = s.alice.settings.GetSettings()
    s.Require().NoError(err)
    spi, err := as.StickerPacksInstalled.MarshalJSON()
    s.Require().NoError(err)
    s.Require().Equal(2169, len(spi))

    // Wait for the message to reach its destination
    err = tt.RetryWithBackOff(func() error {
        mr, err := s.alice2.RetrieveAll()
        if err != nil {
            return err
        }

        if len(mr.Settings) == 0 {
            return errors.New("sync settings not in MessengerResponse")
        }

        return nil
    })
    s.Require().NoError(err)

    aos, err = s.alice2.settings.GetSettings()
    s.Require().NoError(err)
    ospi, err := aos.StickerPacksInstalled.MarshalJSON()
    s.Require().NoError(err)
    s.Require().Exactly(spi, ospi)
}

func (s *MessengerSyncSettingsSuite) TestSyncSettings_PreferredName() {
    // Check alice 1 settings values
    as, err := s.alice.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Equal(pf, *as.PreferredName)

    // Check alice 2 settings values
    aos, err := s.alice2.settings.GetSettings()
    s.Require().NoError(err)
    s.Require().Nil(aos.PreferredName)

    // Pair devices. Allows alice to send to alicesOtherDevice
    PairDevices(&s.Suite, s.alice2, s.alice)

    // Update Alice's PreferredName
    err = s.alice.settings.SaveSettingField(settings.PreferredName, pf2)
    s.Require().NoError(err)

    apn, err := s.alice.settings.GetPreferredUsername()
    s.Require().NoError(err)
    s.Require().Equal(pf2, apn)

    // Wait for the sync message to reach its destination
    err = tt.RetryWithBackOff(func() error {
        mr, err := s.alice2.RetrieveAll()
        if err != nil {
            return err
        }

        if len(mr.Settings) == 0 {
            return errors.New("sync settings not in MessengerResponse")
        }

        return nil
    })
    s.Require().NoError(err)

    opn, err := s.alice2.settings.GetPreferredUsername()
    s.Require().NoError(err)
    s.Require().Equal(pf2, opn)
}