package walletsettings import ( "encoding/json" "testing" "github.com/stretchr/testify/require" "github.com/status-im/status-go/appdatabase" "github.com/status-im/status-go/multiaccounts/settings" "github.com/status-im/status-go/params" "github.com/status-im/status-go/t/helpers" ) var ( config = params.NodeConfig{ NetworkID: 10, DataDir: "test", } networks = json.RawMessage("{}") settingsObj = settings.Settings{ Networks: &networks, } ) func setupTestDB(t *testing.T) (*WalletSettings, func()) { db, stop, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "settings-wallet-tests-") require.NoError(t, err) settDb, err := settings.MakeNewDB(db) require.NoError(t, err) err = settDb.CreateSettings(settingsObj, config) require.NoError(t, err) walletSettings := NewWalletSettings(db) return walletSettings, func() { require.NoError(t, stop()) } } func TestSetClockOfLastTokenPreferencesChange(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() clock, err := walletSettings.GetClockOfLastTokenPreferencesChange() require.NoError(t, err) require.Equal(t, uint64(0), clock) err = walletSettings.setClockOfLastTokenPreferencesChange(nil, 123) require.Error(t, err) tx, err := walletSettings.db.Begin() require.NoError(t, err) err = walletSettings.setClockOfLastTokenPreferencesChange(tx, 123) require.NoError(t, err) err = tx.Commit() require.NoError(t, err) clock, err = walletSettings.GetClockOfLastTokenPreferencesChange() require.NoError(t, err) require.Equal(t, uint64(123), clock) } func TestGetTokenPreferencesEmpty(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() preferences, err := walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 0, len(preferences)) preferences, err = walletSettings.GetTokenPreferences(false) require.NoError(t, err) require.Equal(t, 0, len(preferences)) } func TestUpdateTokenPreferencesEmpty(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() err := walletSettings.UpdateTokenPreferences([]TokenPreferences{}, false, false, 0) require.Error(t, err) err = walletSettings.UpdateTokenPreferences([]TokenPreferences{}, false, true, 0) require.Error(t, err) } func TestUpdateTokenPreferencesTestnet(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() err := walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, false, ""}, }, false, true, 0) require.NoError(t, err) // Mainnet is not affected by testnet preferences preferences, err := walletSettings.GetTokenPreferences(false) require.NoError(t, err) require.Equal(t, 0, len(preferences)) preferences, err = walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 1, len(preferences)) require.Equal(t, "SNT", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, false, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) // Inserting into testnet doesn't affect mainnet err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"ABC0", 0, -1, true, ""}, {"ABC1", 1, -1, true, ""}, }, false, false, 0) require.NoError(t, err) err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"ABC0", 1, -1, true, ""}, {"ABC1", 0, -1, true, ""}, }, false, true, 0) require.NoError(t, err) // Having same symbols on mainnet and testnet is allowed preferences, err = walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 2, len(preferences)) require.Equal(t, "ABC0", preferences[0].Key) require.Equal(t, 1, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, true, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) require.Equal(t, "ABC1", preferences[1].Key) require.Equal(t, 0, preferences[1].Position) require.Equal(t, -1, preferences[1].GroupPosition) require.Equal(t, true, preferences[1].Visible) require.Equal(t, "", preferences[1].CommunityID) preferences, err = walletSettings.GetTokenPreferences(false) require.NoError(t, err) require.Equal(t, 2, len(preferences)) require.Equal(t, "ABC0", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, true, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) require.Equal(t, "ABC1", preferences[1].Key) require.Equal(t, 1, preferences[1].Position) require.Equal(t, -1, preferences[1].GroupPosition) require.Equal(t, true, preferences[1].Visible) require.Equal(t, "", preferences[1].CommunityID) } func TestUpdateTokenPreferencesRollback(t *testing.T) { db, stop := setupTestDB(t) defer stop() err := db.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, false, ""}, }, false, true, 0) require.NoError(t, err) // Duplicate is not allowed err = db.UpdateTokenPreferences([]TokenPreferences{ {"ABC", 0, -1, false, ""}, {"ABC", 0, -1, true, ""}, }, false, true, 0) require.Error(t, err) // Rolled back to previous state preferences, err := db.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 1, len(preferences)) require.Equal(t, "SNT", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, false, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) } func TestTokenPrefrencesGroupByCommunity(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() communityID01 := "0x000001" communityID02 := "0x000002" err := walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, -1, true, communityID01}, {"T02", 1, -1, true, communityID01}, }, false, true, 0) require.NoError(t, err) preferences, err := walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 4, len(preferences)) require.Equal(t, "SNT", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, true, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) require.Equal(t, "ETH", preferences[1].Key) require.Equal(t, 1, preferences[1].Position) require.Equal(t, -1, preferences[1].GroupPosition) require.Equal(t, true, preferences[1].Visible) require.Equal(t, "", preferences[1].CommunityID) require.Equal(t, "T01", preferences[2].Key) require.Equal(t, 0, preferences[2].Position) require.Equal(t, -1, preferences[2].GroupPosition) require.Equal(t, true, preferences[2].Visible) require.Equal(t, communityID01, preferences[2].CommunityID) require.Equal(t, "T02", preferences[3].Key) require.Equal(t, 1, preferences[3].Position) require.Equal(t, -1, preferences[3].GroupPosition) require.Equal(t, true, preferences[3].Visible) require.Equal(t, communityID01, preferences[3].CommunityID) err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, 1, true, communityID01}, {"T02", 1, 0, true, communityID01}, {"T03", 0, 0, true, communityID02}, }, false, true, 0) require.NoError(t, err) preferences, err = walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, 5, len(preferences)) require.Equal(t, "SNT", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, -1, preferences[0].GroupPosition) require.Equal(t, true, preferences[0].Visible) require.Equal(t, "", preferences[0].CommunityID) require.Equal(t, "ETH", preferences[1].Key) require.Equal(t, 1, preferences[1].Position) require.Equal(t, -1, preferences[1].GroupPosition) require.Equal(t, true, preferences[1].Visible) require.Equal(t, "", preferences[1].CommunityID) require.Equal(t, "T01", preferences[2].Key) require.Equal(t, 0, preferences[2].Position) require.Equal(t, 1, preferences[2].GroupPosition) require.Equal(t, true, preferences[2].Visible) require.Equal(t, communityID01, preferences[2].CommunityID) require.Equal(t, "T02", preferences[3].Key) require.Equal(t, 1, preferences[3].Position) require.Equal(t, 0, preferences[3].GroupPosition) require.Equal(t, true, preferences[3].Visible) require.Equal(t, communityID01, preferences[3].CommunityID) require.Equal(t, "T03", preferences[4].Key) require.Equal(t, 0, preferences[4].Position) require.Equal(t, 0, preferences[4].GroupPosition) require.Equal(t, true, preferences[4].Visible) require.Equal(t, communityID02, preferences[4].CommunityID) // Insert not full group positioning (one group has -1 group position) err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, 1, true, communityID01}, {"T02", 1, 0, true, communityID01}, {"T03", 0, -1, true, communityID02}, }, true, true, 0) require.Error(t, err) // Group by community is disabled so there's no check for proper grouping err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, 1, true, communityID01}, {"T02", 1, 0, true, communityID01}, {"T03", 0, -1, true, communityID02}, }, false, true, 0) require.NoError(t, err) // Insert not full group positioning with invsibile item set err = walletSettings.UpdateTokenPreferences([]TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, 1, true, communityID01}, {"T02", 1, 0, true, communityID01}, {"T03", 0, -1, false, communityID02}, }, true, true, 0) require.NoError(t, err) } func TestUpdateTokenPreferencesSettings(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() preferences := []TokenPreferences{ {"SNT", 0, -1, true, ""}, {"ETH", 1, -1, true, ""}, {"T01", 0, 1, true, "0x000001"}, {"T02", 1, 0, true, "0x000001"}, } err := walletSettings.UpdateTokenPreferences(preferences, true, true, 123) require.NoError(t, err) // Verify that the preferences are updated correctly prefs, err := walletSettings.GetTokenPreferences(true) require.NoError(t, err) require.Equal(t, len(preferences), len(prefs)) for i := range preferences { require.Equal(t, preferences[i], prefs[i]) } // Verify that the clock is updated clock, err := walletSettings.GetClockOfLastTokenPreferencesChange() require.NoError(t, err) require.True(t, clock > 0) } func TestSetClockOfLastCollectiblePreferencesChange(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() clock, err := walletSettings.GetClockOfLastCollectiblePreferencesChange() require.NoError(t, err) require.Equal(t, uint64(0), clock) err = walletSettings.setClockOfLastCollectiblePreferencesChange(nil, 123) require.Error(t, err) tx, err := walletSettings.db.Begin() require.NoError(t, err) err = walletSettings.setClockOfLastCollectiblePreferencesChange(tx, 123) require.NoError(t, err) err = tx.Commit() require.NoError(t, err) clock, err = walletSettings.GetClockOfLastCollectiblePreferencesChange() require.NoError(t, err) require.Equal(t, uint64(123), clock) } func TestGetCollectiblePreferencesEmpty(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() preferences, err := walletSettings.GetCollectiblePreferences(true) require.NoError(t, err) require.Equal(t, 0, len(preferences)) preferences, err = walletSettings.GetCollectiblePreferences(false) require.NoError(t, err) require.Equal(t, 0, len(preferences)) } func TestUpdateCollectiblePreferencesEmpty(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() err := walletSettings.UpdateCollectiblePreferences([]CollectiblePreferences{}, false, false, false, 0) require.Error(t, err) err = walletSettings.UpdateCollectiblePreferences([]CollectiblePreferences{}, false, false, true, 0) require.Error(t, err) } func TestUpdateCollectiblePreferencesTestnet(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() err := walletSettings.UpdateCollectiblePreferences([]CollectiblePreferences{ {CollectiblePreferencesTypeNonCommunityCollectible, "First", 0, false}, }, false, false, true, 0) require.NoError(t, err) // Mainnet is not affected by testnet preferences preferences, err := walletSettings.GetCollectiblePreferences(false) require.NoError(t, err) require.Equal(t, 0, len(preferences)) preferences, err = walletSettings.GetCollectiblePreferences(true) require.NoError(t, err) require.Equal(t, 1, len(preferences)) require.Equal(t, CollectiblePreferencesTypeNonCommunityCollectible, preferences[0].Type) require.Equal(t, "First", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, false, preferences[0].Visible) // Inserting into testnet doesn't affect mainnet err = walletSettings.UpdateCollectiblePreferences([]CollectiblePreferences{ {CollectiblePreferencesTypeNonCommunityCollectible, "First", 0, true}, {CollectiblePreferencesTypeNonCommunityCollectible, "Second", 1, true}, }, false, false, false, 0) require.NoError(t, err) err = walletSettings.UpdateCollectiblePreferences([]CollectiblePreferences{ {CollectiblePreferencesTypeCommunityCollectible, "First", 1, true}, {CollectiblePreferencesTypeCommunityCollectible, "Second", 2, true}, }, false, false, true, 0) require.NoError(t, err) // Having same symbols on mainnet and testnet is allowed preferences, err = walletSettings.GetCollectiblePreferences(true) require.NoError(t, err) require.Equal(t, 2, len(preferences)) require.Equal(t, CollectiblePreferencesTypeCommunityCollectible, preferences[0].Type) require.Equal(t, "First", preferences[0].Key) require.Equal(t, 1, preferences[0].Position) require.Equal(t, true, preferences[0].Visible) require.Equal(t, CollectiblePreferencesTypeCommunityCollectible, preferences[1].Type) require.Equal(t, "Second", preferences[1].Key) require.Equal(t, 2, preferences[1].Position) require.Equal(t, true, preferences[1].Visible) preferences, err = walletSettings.GetCollectiblePreferences(false) require.NoError(t, err) require.Equal(t, 2, len(preferences)) require.Equal(t, CollectiblePreferencesTypeNonCommunityCollectible, preferences[0].Type) require.Equal(t, "First", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, true, preferences[0].Visible) require.Equal(t, CollectiblePreferencesTypeNonCommunityCollectible, preferences[1].Type) require.Equal(t, "Second", preferences[1].Key) require.Equal(t, 1, preferences[1].Position) require.Equal(t, true, preferences[1].Visible) } func TestUpdateCollectiblePreferencesRollback(t *testing.T) { db, stop := setupTestDB(t) defer stop() err := db.UpdateCollectiblePreferences([]CollectiblePreferences{ {CollectiblePreferencesTypeNonCommunityCollectible, "First", 0, false}, }, false, false, true, 0) require.NoError(t, err) // Duplicate is not allowed err = db.UpdateCollectiblePreferences([]CollectiblePreferences{ {CollectiblePreferencesTypeNonCommunityCollectible, "Second", -1, false}, {CollectiblePreferencesTypeNonCommunityCollectible, "Third", -1, false}, }, false, false, true, 0) require.Error(t, err) // Rolled back to previous state preferences, err := db.GetCollectiblePreferences(true) require.NoError(t, err) require.Equal(t, 1, len(preferences)) require.Equal(t, CollectiblePreferencesTypeNonCommunityCollectible, preferences[0].Type) require.Equal(t, "First", preferences[0].Key) require.Equal(t, 0, preferences[0].Position) require.Equal(t, false, preferences[0].Visible) } func TestUpdateCollectiblePreferencesSettings(t *testing.T) { walletSettings, stop := setupTestDB(t) defer stop() preferences := []CollectiblePreferences{ {CollectiblePreferencesTypeNonCommunityCollectible, "First", 0, false}, {CollectiblePreferencesTypeCommunityCollectible, "Second", 1, true}, {CollectiblePreferencesTypeCollection, "Third", 2, false}, {CollectiblePreferencesTypeCommunity, "Fourth", 3, true}, } err := walletSettings.UpdateCollectiblePreferences(preferences, true, true, true, 123) require.NoError(t, err) // Verify that the preferences are updated correctly prefs, err := walletSettings.GetCollectiblePreferences(true) require.NoError(t, err) require.Equal(t, len(preferences), len(prefs)) for i := range preferences { require.Equal(t, preferences[i], prefs[i]) } // Verify that the clock is updated clock, err := walletSettings.GetClockOfLastCollectiblePreferencesChange() require.NoError(t, err) require.True(t, clock > 0) }