status-go/services/wallet/history/balance_test.go
Ivan Belyakov d07f9b5b16 fix(wallet)_: no balance chart for tokens, due to wrong symbol (ETH) used
instead.

Fixed padding points being removed from final result, regression.
Edge points not added per address as it does not make sense.
Fixed padding points number with respect to edge points number.
Padding points now duplicate previous entry.
Fixed timestamp boundaries to ignore addresses, as we want the whole
range for all passed addresses.
Fixed missing indices in balance_history table and clean up of
duplicate rows.
Removed ERC1155 from balance history sql query
2024-07-18 13:11:02 +02:00

532 lines
11 KiB
Go

package history
import (
"math/big"
"reflect"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/walletdatabase"
)
func newTestDB(t *testing.T) *BalanceDB {
db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
require.NoError(t, err)
return NewBalanceDB(db)
}
func dbWithEntries(t *testing.T, entries []*entry) *BalanceDB {
db := newTestDB(t)
for _, entry := range entries {
err := db.add(entry)
require.NoError(t, err)
}
return db
}
func TestBalance_addPaddingPoints(t *testing.T) {
type args struct {
currency string
addresses []common.Address
fromTimestamp uint64
currentTimestamp uint64
data []*entry
limit int
}
tests := []struct {
name string
args args
want []*entry
wantErr bool
}{
{
name: "addOnePaddingPointAtMiddle",
args: args{
currency: "ETH",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 0,
currentTimestamp: 2,
data: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(2),
timestamp: 2,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
limit: 3,
},
want: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(2),
timestamp: 2,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "noPaddingEqualsLimit",
args: args{
currency: "ETH",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 0,
currentTimestamp: 2,
data: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
block: big.NewInt(1),
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(1),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "ETH",
address: common.Address{1},
},
},
limit: 2,
},
want: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
block: big.NewInt(1),
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(1),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "ETH",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "limitLessThanDataSize",
args: args{
currency: "ETH",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 0,
currentTimestamp: 2,
data: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
block: big.NewInt(1),
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(1),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "ETH",
address: common.Address{1},
},
},
limit: 1,
},
want: []*entry{
{
balance: big.NewInt(0),
timestamp: 0,
block: big.NewInt(1),
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(1),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "ETH",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "addMultiplePaddingPoints",
args: args{
currency: "ETH",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 1,
currentTimestamp: 5,
data: []*entry{
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(4),
timestamp: 4,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(5),
timestamp: 5,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
limit: 5,
},
want: []*entry{
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 2,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 3,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(4),
timestamp: 4,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(5),
timestamp: 5,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "addMultiplePaddingPointsDuplicateTimestamps",
args: args{
currency: "ETH",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 1,
currentTimestamp: 5,
data: []*entry{
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(4),
timestamp: 4,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(5),
timestamp: 5,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
limit: 5,
},
want: []*entry{
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(0),
timestamp: 2,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(4),
timestamp: 4,
tokenSymbol: "ETH",
address: common.Address{1},
},
{
balance: big.NewInt(5),
timestamp: 5,
tokenSymbol: "ETH",
address: common.Address{1},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRes, err := addPaddingPoints(tt.args.currency, tt.args.addresses, tt.args.currentTimestamp, tt.args.data, tt.args.limit)
if (err != nil) != tt.wantErr {
t.Errorf("Balance.addPaddingPoints() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.want) {
t.Errorf("Balance.addPaddingPoints() = %v, want %v", gotRes, tt.want)
}
})
}
}
func TestBalance_addEdgePoints(t *testing.T) {
walletDB := newTestDB(t)
type fields struct {
db *BalanceDB
}
type args struct {
chainID uint64
currency string
addresses []common.Address
fromTimestamp uint64
toTimestamp uint64
data []*entry
}
tests := []struct {
name string
fields fields
args args
wantRes []*entry
wantErr bool
}{
{
name: "addToEmptyData",
fields: fields{
db: walletDB,
},
args: args{
chainID: 111,
currency: "SNT",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 1,
toTimestamp: 2,
data: []*entry{},
},
wantRes: []*entry{
{
chainID: 111,
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(0),
timestamp: 2,
tokenSymbol: "SNT",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "addToEmptyDataSinceGenesis",
fields: fields{
db: walletDB,
},
args: args{
chainID: 111,
currency: "SNT",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 0, // will set to genesisTimestamp
toTimestamp: genesisTimestamp + 1,
data: []*entry{},
},
wantRes: []*entry{
{
chainID: 111,
balance: big.NewInt(0),
timestamp: genesisTimestamp,
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(0),
timestamp: genesisTimestamp + 1,
tokenSymbol: "SNT",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "addToNonEmptyDataFromPreviousEntry",
fields: fields{
db: dbWithEntries(t, []*entry{
{
chainID: 111,
balance: big.NewInt(1),
timestamp: 1,
block: big.NewInt(1),
tokenSymbol: "SNT",
address: common.Address{1},
},
}),
},
args: args{
chainID: 111,
currency: "SNT",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 2,
toTimestamp: 4,
data: []*entry{
{
chainID: 111,
balance: big.NewInt(3),
timestamp: 3,
block: big.NewInt(3),
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(2),
timestamp: 4,
block: big.NewInt(4),
tokenSymbol: "SNT",
address: common.Address{1},
},
},
},
wantRes: []*entry{
{
chainID: 111,
balance: big.NewInt(1),
timestamp: 2,
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(3),
timestamp: 3,
block: big.NewInt(3),
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(2),
timestamp: 4,
block: big.NewInt(4),
tokenSymbol: "SNT",
address: common.Address{1},
},
},
wantErr: false,
},
{
name: "addToNonEmptyData",
fields: fields{
db: walletDB,
},
args: args{
chainID: 111,
currency: "SNT",
addresses: []common.Address{common.Address{1}},
fromTimestamp: 1,
toTimestamp: 2,
data: []*entry{
{
chainID: 111,
balance: big.NewInt(2),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "SNT",
address: common.Address{1},
},
},
},
wantRes: []*entry{
{
chainID: 111,
balance: big.NewInt(0),
timestamp: 1,
tokenSymbol: "SNT",
address: common.Address{1},
},
{
chainID: 111,
balance: big.NewInt(2),
timestamp: 2,
block: big.NewInt(2),
tokenSymbol: "SNT",
address: common.Address{1},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &Balance{
db: tt.fields.db,
}
gotRes, err := b.addEdgePoints(tt.args.chainID, tt.args.currency, tt.args.addresses, tt.args.fromTimestamp, tt.args.toTimestamp, tt.args.data)
if (err != nil) != tt.wantErr {
t.Errorf("Balance.addEdgePoints() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("Balance.addEdgePoints() = \n%v,\nwant \n%v", gotRes, tt.wantRes)
}
})
}
}