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 }