github.com/status-im/status-go@v1.1.0/services/wallet/activity/filter_test.go (about)

     1  package activity
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  	"testing"
     8  
     9  	eth "github.com/ethereum/go-ethereum/common"
    10  
    11  	"github.com/status-im/status-go/services/wallet/bigint"
    12  	"github.com/status-im/status-go/services/wallet/common"
    13  	"github.com/status-im/status-go/services/wallet/testutils"
    14  	"github.com/status-im/status-go/services/wallet/thirdparty"
    15  	"github.com/status-im/status-go/services/wallet/transfer"
    16  	"github.com/status-im/status-go/t/helpers"
    17  	"github.com/status-im/status-go/walletdatabase"
    18  
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func setupTestFilterDB(t *testing.T) (db *sql.DB, close func()) {
    23  	db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
    24  	require.NoError(t, err)
    25  
    26  	return db, func() {
    27  		require.NoError(t, db.Close())
    28  	}
    29  }
    30  
    31  // insertTestData inserts 6 extractable activity entries: 2 transfers, 2 pending transactions and 2 multi transactions
    32  func insertTestData(t *testing.T, db *sql.DB, nullifyToForIndexes []int) (trs []transfer.TestTransfer, toTrs []eth.Address, multiTxs []transfer.MultiTransaction) {
    33  	// Add 6 extractable transactions
    34  	trs, _, toTrs = transfer.GenerateTestTransfers(t, db, 0, 10)
    35  	multiTxs = []transfer.MultiTransaction{
    36  		transfer.GenerateTestBridgeMultiTransaction(trs[0], trs[1]),
    37  		transfer.GenerateTestSwapMultiTransaction(trs[2], testutils.SntSymbol, 100),
    38  	}
    39  	for j := range nullifyToForIndexes {
    40  		if nullifyToForIndexes[j] == 1 {
    41  			multiTxs[0].ToAddress = eth.Address{}
    42  		}
    43  		if nullifyToForIndexes[j] == 2 {
    44  			multiTxs[1].ToAddress = eth.Address{}
    45  		}
    46  	}
    47  
    48  	trs[0].MultiTransactionID = transfer.InsertTestMultiTransaction(t, db, &multiTxs[0])
    49  	trs[1].MultiTransactionID = trs[0].MultiTransactionID
    50  	trs[2].MultiTransactionID = transfer.InsertTestMultiTransaction(t, db, &multiTxs[1])
    51  
    52  	for i := range trs {
    53  		if i < 5 {
    54  			var nullifyAddresses []eth.Address
    55  			for j := range nullifyToForIndexes {
    56  				if i == nullifyToForIndexes[j] {
    57  					nullifyAddresses = append(nullifyAddresses, trs[i].To)
    58  				}
    59  			}
    60  			transfer.InsertTestTransferWithOptions(t, db, trs[i].To, &trs[i], &transfer.TestTransferOptions{
    61  				NullifyAddresses: nullifyAddresses,
    62  			})
    63  		} else if i >= 7 && i < 10 {
    64  			ci := i - 7
    65  			trs[i].ChainID = transfer.TestCollectibles[ci].ChainID
    66  			transfer.InsertTestTransferWithOptions(t, db, trs[i].To, &trs[i], &transfer.TestTransferOptions{
    67  				TokenID:      transfer.TestCollectibles[ci].TokenID,
    68  				TokenAddress: transfer.TestCollectibles[ci].TokenAddress,
    69  			})
    70  		} else {
    71  			for j := range nullifyToForIndexes {
    72  				if i == nullifyToForIndexes[j] {
    73  					trs[i].To = eth.Address{}
    74  				}
    75  			}
    76  			transfer.InsertTestPendingTransaction(t, db, &trs[i])
    77  		}
    78  	}
    79  	return
    80  }
    81  
    82  func TestGetRecipients(t *testing.T) {
    83  	db, close := setupTestFilterDB(t)
    84  	defer close()
    85  
    86  	trs, toTrs, _ := insertTestData(t, db, nil)
    87  
    88  	// Generate and insert transactions with the same to address
    89  	dupTrs, _, _ := transfer.GenerateTestTransfers(t, db, 8, 4)
    90  	dupTrs[0].To = trs[1].To
    91  	dupTrs[2].To = trs[2].To
    92  	dupMultiTxs := []transfer.MultiTransaction{
    93  		transfer.GenerateTestSendMultiTransaction(dupTrs[0]),
    94  		transfer.GenerateTestSwapMultiTransaction(dupTrs[2], testutils.SntSymbol, 100),
    95  	}
    96  	dupTrs[0].MultiTransactionID = transfer.InsertTestMultiTransaction(t, db, &dupMultiTxs[0])
    97  	transfer.InsertTestTransfer(t, db, dupTrs[0].To, &dupTrs[0])
    98  	dupTrs[2].MultiTransactionID = transfer.InsertTestMultiTransaction(t, db, &dupMultiTxs[1])
    99  	transfer.InsertTestPendingTransaction(t, db, &dupTrs[2])
   100  
   101  	dupTrs[1].To = trs[3].To
   102  	transfer.InsertTestTransfer(t, db, dupTrs[1].To, &dupTrs[1])
   103  	dupTrs[3].To = trs[5].To
   104  	transfer.InsertTestPendingTransaction(t, db, &dupTrs[3])
   105  
   106  	entries, hasMore, err := GetRecipients(context.Background(), db, []common.ChainID{}, []eth.Address{}, 0, 15)
   107  	require.NoError(t, err)
   108  	require.False(t, hasMore)
   109  	require.Equal(t, 9, len(entries))
   110  	for i := range entries {
   111  		found := false
   112  		for j := range toTrs {
   113  			if entries[i] == toTrs[j] {
   114  				found = true
   115  				break
   116  			}
   117  		}
   118  		require.True(t, found, fmt.Sprintf("recipient %s not found in toTrs", entries[i].Hex()))
   119  	}
   120  
   121  	entries, hasMore, err = GetRecipients(context.Background(), db, []common.ChainID{}, []eth.Address{}, 0, 2)
   122  	require.NoError(t, err)
   123  	require.Equal(t, 2, len(entries))
   124  	require.True(t, hasMore)
   125  
   126  	// Get Recipients from specific chains
   127  	entries, hasMore, err = GetRecipients(context.Background(), db, []common.ChainID{10}, []eth.Address{}, 0, 15)
   128  
   129  	require.NoError(t, err)
   130  	require.Equal(t, 2, len(entries))
   131  	require.False(t, hasMore)
   132  	require.Equal(t, trs[5].To, entries[0])
   133  	require.Equal(t, trs[2].To, entries[1])
   134  
   135  	// Get Recipients from specific addresses
   136  	entries, hasMore, err = GetRecipients(context.Background(), db, []common.ChainID{}, []eth.Address{trs[0].From}, 0, 15)
   137  
   138  	require.NoError(t, err)
   139  	require.Equal(t, 1, len(entries))
   140  	require.False(t, hasMore)
   141  	require.Equal(t, trs[1].To, entries[0])
   142  }
   143  
   144  func TestGetRecipients_NullAddresses(t *testing.T) {
   145  	db, close := setupTestFilterDB(t)
   146  	defer close()
   147  
   148  	insertTestData(t, db, []int{1, 2, 3, 5})
   149  
   150  	entries, hasMore, err := GetRecipients(context.Background(), db, []common.ChainID{}, []eth.Address{}, 0, 15)
   151  	require.NoError(t, err)
   152  	require.False(t, hasMore)
   153  	require.Equal(t, 6, len(entries))
   154  }
   155  
   156  func TestGetOldestTimestampEmptyDB(t *testing.T) {
   157  	db, close := setupTestFilterDB(t)
   158  	defer close()
   159  
   160  	timestamp, err := GetOldestTimestamp(context.Background(), db, []eth.Address{eth.HexToAddress("0x1")})
   161  	require.NoError(t, err)
   162  	require.Equal(t, uint64(0), timestamp)
   163  }
   164  
   165  func TestGetOldestTimestamp(t *testing.T) {
   166  	db, close := setupTestFilterDB(t)
   167  	defer close()
   168  
   169  	trs, _, multiTxs := insertTestData(t, db, nil)
   170  
   171  	// Extract oldest timestamp, no filter
   172  	timestamp, err := GetOldestTimestamp(context.Background(), db, []eth.Address{})
   173  	require.NoError(t, err)
   174  	require.Equal(t, multiTxs[0].Timestamp, timestamp)
   175  
   176  	// Test to filter
   177  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   178  		trs[3].To,
   179  	})
   180  	require.NoError(t, err)
   181  	require.Equal(t, uint64(trs[3].Timestamp), timestamp)
   182  
   183  	// Test from filter
   184  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   185  		trs[4].From,
   186  	})
   187  	require.NoError(t, err)
   188  	require.Equal(t, uint64(trs[4].Timestamp), timestamp)
   189  
   190  	// Test MT
   191  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   192  		multiTxs[1].FromAddress, trs[4].To,
   193  	})
   194  	require.NoError(t, err)
   195  	require.Equal(t, multiTxs[1].Timestamp, timestamp)
   196  
   197  	// Test Pending
   198  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   199  		trs[6].To,
   200  	})
   201  	require.NoError(t, err)
   202  	require.Equal(t, uint64(trs[6].Timestamp), timestamp)
   203  }
   204  
   205  func TestGetOldestTimestamp_NullAddresses(t *testing.T) {
   206  	db, close := setupTestFilterDB(t)
   207  	defer close()
   208  
   209  	trs, _, _ := transfer.GenerateTestTransfers(t, db, 0, 3)
   210  	nullifyAddresses := []eth.Address{
   211  		trs[0].To, trs[2].To, trs[1].From,
   212  	}
   213  	for i := range trs {
   214  		transfer.InsertTestTransferWithOptions(t, db, trs[i].To, &trs[i], &transfer.TestTransferOptions{
   215  			NullifyAddresses: nullifyAddresses,
   216  		})
   217  	}
   218  
   219  	// Extract oldest timestamp, no filter
   220  	timestamp, err := GetOldestTimestamp(context.Background(), db, []eth.Address{})
   221  	require.NoError(t, err)
   222  	require.Equal(t, uint64(trs[0].Timestamp), timestamp)
   223  
   224  	// Test to filter
   225  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   226  		trs[1].To, trs[2].To,
   227  	})
   228  	require.NoError(t, err)
   229  	require.Equal(t, uint64(trs[1].Timestamp), timestamp)
   230  
   231  	// Test from filter
   232  	timestamp, err = GetOldestTimestamp(context.Background(), db, []eth.Address{
   233  		trs[1].From,
   234  	})
   235  	require.NoError(t, err)
   236  	require.Equal(t, uint64(0), timestamp)
   237  }
   238  
   239  func TestGetActivityCollectiblesEmptyDB(t *testing.T) {
   240  	db, close := setupTestFilterDB(t)
   241  	defer close()
   242  
   243  	collectibles, err := GetActivityCollectibles(context.Background(), db, []common.ChainID{}, []eth.Address{}, 0, 10)
   244  	require.NoError(t, err)
   245  	require.Equal(t, 0, len(collectibles))
   246  }
   247  
   248  func TestGetActivityCollectibles(t *testing.T) {
   249  	db, close := setupTestFilterDB(t)
   250  	defer close()
   251  
   252  	trs, _, _ := insertTestData(t, db, nil)
   253  
   254  	// Extract all collectibles
   255  	collectibles, err := GetActivityCollectibles(context.Background(), db, []common.ChainID{}, []eth.Address{}, 0, 10)
   256  	require.NoError(t, err)
   257  	require.Equal(t, 3, len(collectibles))
   258  
   259  	// Extract collectibles for a specific chain
   260  	collectibles, err = GetActivityCollectibles(context.Background(), db, []common.ChainID{1}, []eth.Address{}, 0, 10)
   261  	require.NoError(t, err)
   262  	require.Equal(t, 2, len(collectibles))
   263  	require.Equal(t, thirdparty.CollectibleUniqueID{
   264  		TokenID: &bigint.BigInt{Int: transfer.TestCollectibles[0].TokenID},
   265  		ContractID: thirdparty.ContractID{
   266  			ChainID: transfer.TestCollectibles[1].ChainID,
   267  			Address: transfer.TestCollectibles[1].TokenAddress,
   268  		},
   269  	}, collectibles[0])
   270  	require.Equal(t, thirdparty.CollectibleUniqueID{
   271  		TokenID: &bigint.BigInt{Int: transfer.TestCollectibles[1].TokenID},
   272  		ContractID: thirdparty.ContractID{
   273  			ChainID: transfer.TestCollectibles[0].ChainID,
   274  			Address: transfer.TestCollectibles[0].TokenAddress,
   275  		},
   276  	}, collectibles[1])
   277  
   278  	// Extract collectibles for a specific sender addresses
   279  	collectibles, err = GetActivityCollectibles(context.Background(), db, []common.ChainID{}, []eth.Address{trs[8].From}, 0, 10)
   280  	require.NoError(t, err)
   281  	require.Equal(t, 1, len(collectibles))
   282  	require.Equal(t, thirdparty.CollectibleUniqueID{
   283  		TokenID: &bigint.BigInt{Int: transfer.TestCollectibles[1].TokenID},
   284  		ContractID: thirdparty.ContractID{
   285  			ChainID: transfer.TestCollectibles[1].ChainID,
   286  			Address: transfer.TestCollectibles[1].TokenAddress,
   287  		},
   288  	}, collectibles[0])
   289  
   290  	// Extract collectibles for a specific recipient addresses
   291  	collectibles, err = GetActivityCollectibles(context.Background(), db, []common.ChainID{}, []eth.Address{trs[7].To}, 0, 10)
   292  	require.NoError(t, err)
   293  	require.Equal(t, 1, len(collectibles))
   294  	require.Equal(t, thirdparty.CollectibleUniqueID{
   295  		TokenID: &bigint.BigInt{Int: transfer.TestCollectibles[0].TokenID},
   296  		ContractID: thirdparty.ContractID{
   297  			ChainID: transfer.TestCollectibles[0].ChainID,
   298  			Address: transfer.TestCollectibles[0].TokenAddress,
   299  		},
   300  	}, collectibles[0])
   301  }