github.com/status-im/status-go@v1.1.0/services/wallet/history/balance_test.go (about) 1 package history 2 3 import ( 4 "math/big" 5 "reflect" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/ethereum/go-ethereum/common" 11 "github.com/status-im/status-go/t/helpers" 12 "github.com/status-im/status-go/walletdatabase" 13 ) 14 15 func newTestDB(t *testing.T) *BalanceDB { 16 db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{}) 17 require.NoError(t, err) 18 return NewBalanceDB(db) 19 } 20 21 func dbWithEntries(t *testing.T, entries []*entry) *BalanceDB { 22 db := newTestDB(t) 23 for _, entry := range entries { 24 err := db.add(entry) 25 require.NoError(t, err) 26 } 27 return db 28 } 29 30 func TestBalance_addPaddingPoints(t *testing.T) { 31 type args struct { 32 currency string 33 addresses []common.Address 34 fromTimestamp uint64 35 currentTimestamp uint64 36 data []*entry 37 limit int 38 } 39 tests := []struct { 40 name string 41 args args 42 want []*entry 43 wantErr bool 44 }{ 45 { 46 name: "addOnePaddingPointAtMiddle", 47 args: args{ 48 currency: "ETH", 49 addresses: []common.Address{common.Address{1}}, 50 fromTimestamp: 0, 51 currentTimestamp: 2, 52 data: []*entry{ 53 { 54 balance: big.NewInt(0), 55 timestamp: 0, 56 tokenSymbol: "ETH", 57 address: common.Address{1}, 58 }, 59 { 60 balance: big.NewInt(2), 61 timestamp: 2, 62 tokenSymbol: "ETH", 63 address: common.Address{1}, 64 }, 65 }, 66 limit: 3, 67 }, 68 want: []*entry{ 69 { 70 balance: big.NewInt(0), 71 timestamp: 0, 72 tokenSymbol: "ETH", 73 address: common.Address{1}, 74 }, 75 { 76 balance: big.NewInt(0), 77 timestamp: 1, 78 tokenSymbol: "ETH", 79 address: common.Address{1}, 80 }, 81 { 82 balance: big.NewInt(2), 83 timestamp: 2, 84 tokenSymbol: "ETH", 85 address: common.Address{1}, 86 }, 87 }, 88 wantErr: false, 89 }, 90 { 91 name: "noPaddingEqualsLimit", 92 args: args{ 93 currency: "ETH", 94 addresses: []common.Address{common.Address{1}}, 95 fromTimestamp: 0, 96 currentTimestamp: 2, 97 data: []*entry{ 98 { 99 balance: big.NewInt(0), 100 timestamp: 0, 101 block: big.NewInt(1), 102 tokenSymbol: "ETH", 103 address: common.Address{1}, 104 }, 105 { 106 balance: big.NewInt(1), 107 timestamp: 2, 108 block: big.NewInt(2), 109 tokenSymbol: "ETH", 110 address: common.Address{1}, 111 }, 112 }, 113 limit: 2, 114 }, 115 want: []*entry{ 116 { 117 balance: big.NewInt(0), 118 timestamp: 0, 119 block: big.NewInt(1), 120 tokenSymbol: "ETH", 121 address: common.Address{1}, 122 }, 123 { 124 balance: big.NewInt(1), 125 timestamp: 2, 126 block: big.NewInt(2), 127 tokenSymbol: "ETH", 128 address: common.Address{1}, 129 }, 130 }, 131 wantErr: false, 132 }, 133 { 134 name: "limitLessThanDataSize", 135 args: args{ 136 currency: "ETH", 137 addresses: []common.Address{common.Address{1}}, 138 fromTimestamp: 0, 139 currentTimestamp: 2, 140 data: []*entry{ 141 { 142 balance: big.NewInt(0), 143 timestamp: 0, 144 block: big.NewInt(1), 145 tokenSymbol: "ETH", 146 address: common.Address{1}, 147 }, 148 { 149 balance: big.NewInt(1), 150 timestamp: 2, 151 block: big.NewInt(2), 152 tokenSymbol: "ETH", 153 address: common.Address{1}, 154 }, 155 }, 156 limit: 1, 157 }, 158 want: []*entry{ 159 { 160 balance: big.NewInt(0), 161 timestamp: 0, 162 block: big.NewInt(1), 163 tokenSymbol: "ETH", 164 address: common.Address{1}, 165 }, 166 { 167 balance: big.NewInt(1), 168 timestamp: 2, 169 block: big.NewInt(2), 170 tokenSymbol: "ETH", 171 address: common.Address{1}, 172 }, 173 }, 174 wantErr: false, 175 }, 176 { 177 name: "addMultiplePaddingPoints", 178 args: args{ 179 currency: "ETH", 180 addresses: []common.Address{common.Address{1}}, 181 fromTimestamp: 1, 182 currentTimestamp: 5, 183 data: []*entry{ 184 { 185 balance: big.NewInt(0), 186 timestamp: 1, 187 tokenSymbol: "ETH", 188 address: common.Address{1}, 189 }, 190 { 191 balance: big.NewInt(4), 192 timestamp: 4, 193 tokenSymbol: "ETH", 194 address: common.Address{1}, 195 }, 196 { 197 balance: big.NewInt(5), 198 timestamp: 5, 199 tokenSymbol: "ETH", 200 address: common.Address{1}, 201 }, 202 }, 203 limit: 5, 204 }, 205 want: []*entry{ 206 { 207 balance: big.NewInt(0), 208 timestamp: 1, 209 tokenSymbol: "ETH", 210 address: common.Address{1}, 211 }, 212 { 213 balance: big.NewInt(0), 214 timestamp: 2, 215 tokenSymbol: "ETH", 216 address: common.Address{1}, 217 }, 218 { 219 balance: big.NewInt(0), 220 timestamp: 3, 221 tokenSymbol: "ETH", 222 address: common.Address{1}, 223 }, 224 { 225 balance: big.NewInt(4), 226 timestamp: 4, 227 tokenSymbol: "ETH", 228 address: common.Address{1}, 229 }, 230 { 231 balance: big.NewInt(5), 232 timestamp: 5, 233 tokenSymbol: "ETH", 234 address: common.Address{1}, 235 }, 236 }, 237 wantErr: false, 238 }, 239 { 240 name: "addMultiplePaddingPointsDuplicateTimestamps", 241 args: args{ 242 currency: "ETH", 243 addresses: []common.Address{common.Address{1}}, 244 fromTimestamp: 1, 245 currentTimestamp: 5, 246 data: []*entry{ 247 { 248 balance: big.NewInt(0), 249 timestamp: 1, 250 tokenSymbol: "ETH", 251 address: common.Address{1}, 252 }, 253 { 254 balance: big.NewInt(0), 255 timestamp: 1, 256 tokenSymbol: "ETH", 257 address: common.Address{1}, 258 }, 259 { 260 balance: big.NewInt(4), 261 timestamp: 4, 262 tokenSymbol: "ETH", 263 address: common.Address{1}, 264 }, 265 { 266 balance: big.NewInt(5), 267 timestamp: 5, 268 tokenSymbol: "ETH", 269 address: common.Address{1}, 270 }, 271 }, 272 limit: 5, 273 }, 274 want: []*entry{ 275 { 276 balance: big.NewInt(0), 277 timestamp: 1, 278 tokenSymbol: "ETH", 279 address: common.Address{1}, 280 }, 281 { 282 balance: big.NewInt(0), 283 timestamp: 1, 284 tokenSymbol: "ETH", 285 address: common.Address{1}, 286 }, 287 { 288 balance: big.NewInt(0), 289 timestamp: 2, 290 tokenSymbol: "ETH", 291 address: common.Address{1}, 292 }, 293 { 294 balance: big.NewInt(4), 295 timestamp: 4, 296 tokenSymbol: "ETH", 297 address: common.Address{1}, 298 }, 299 { 300 balance: big.NewInt(5), 301 timestamp: 5, 302 tokenSymbol: "ETH", 303 address: common.Address{1}, 304 }, 305 }, 306 wantErr: false, 307 }, 308 } 309 310 for _, tt := range tests { 311 t.Run(tt.name, func(t *testing.T) { 312 gotRes, err := addPaddingPoints(tt.args.currency, tt.args.addresses, tt.args.currentTimestamp, tt.args.data, tt.args.limit) 313 if (err != nil) != tt.wantErr { 314 t.Errorf("Balance.addPaddingPoints() error = %v, wantErr %v", err, tt.wantErr) 315 return 316 } 317 if !reflect.DeepEqual(gotRes, tt.want) { 318 t.Errorf("Balance.addPaddingPoints() = %v, want %v", gotRes, tt.want) 319 } 320 }) 321 } 322 } 323 324 func TestBalance_addEdgePoints(t *testing.T) { 325 326 walletDB := newTestDB(t) 327 328 type fields struct { 329 db *BalanceDB 330 } 331 type args struct { 332 chainID uint64 333 currency string 334 addresses []common.Address 335 fromTimestamp uint64 336 toTimestamp uint64 337 data []*entry 338 } 339 tests := []struct { 340 name string 341 fields fields 342 args args 343 wantRes []*entry 344 wantErr bool 345 }{ 346 { 347 name: "addToEmptyData", 348 fields: fields{ 349 db: walletDB, 350 }, 351 args: args{ 352 chainID: 111, 353 currency: "SNT", 354 addresses: []common.Address{common.Address{1}}, 355 fromTimestamp: 1, 356 toTimestamp: 2, 357 data: []*entry{}, 358 }, 359 wantRes: []*entry{ 360 { 361 chainID: 111, 362 balance: big.NewInt(0), 363 timestamp: 1, 364 tokenSymbol: "SNT", 365 address: common.Address{1}, 366 }, 367 { 368 chainID: 111, 369 balance: big.NewInt(0), 370 timestamp: 2, 371 tokenSymbol: "SNT", 372 address: common.Address{1}, 373 }, 374 }, 375 wantErr: false, 376 }, 377 { 378 name: "addToEmptyDataSinceGenesis", 379 fields: fields{ 380 db: walletDB, 381 }, 382 args: args{ 383 chainID: 111, 384 currency: "SNT", 385 addresses: []common.Address{common.Address{1}}, 386 fromTimestamp: 0, // will set to genesisTimestamp 387 toTimestamp: genesisTimestamp + 1, 388 data: []*entry{}, 389 }, 390 wantRes: []*entry{ 391 { 392 chainID: 111, 393 balance: big.NewInt(0), 394 timestamp: genesisTimestamp, 395 tokenSymbol: "SNT", 396 address: common.Address{1}, 397 }, 398 { 399 chainID: 111, 400 balance: big.NewInt(0), 401 timestamp: genesisTimestamp + 1, 402 tokenSymbol: "SNT", 403 address: common.Address{1}, 404 }, 405 }, 406 wantErr: false, 407 }, 408 { 409 name: "addToNonEmptyDataFromPreviousEntry", 410 fields: fields{ 411 db: dbWithEntries(t, []*entry{ 412 { 413 chainID: 111, 414 balance: big.NewInt(1), 415 timestamp: 1, 416 block: big.NewInt(1), 417 tokenSymbol: "SNT", 418 address: common.Address{1}, 419 }, 420 }), 421 }, 422 args: args{ 423 chainID: 111, 424 currency: "SNT", 425 addresses: []common.Address{common.Address{1}}, 426 fromTimestamp: 2, 427 toTimestamp: 4, 428 data: []*entry{ 429 { 430 chainID: 111, 431 balance: big.NewInt(3), 432 timestamp: 3, 433 block: big.NewInt(3), 434 tokenSymbol: "SNT", 435 address: common.Address{1}, 436 }, 437 { 438 chainID: 111, 439 balance: big.NewInt(2), 440 timestamp: 4, 441 block: big.NewInt(4), 442 tokenSymbol: "SNT", 443 address: common.Address{1}, 444 }, 445 }, 446 }, 447 wantRes: []*entry{ 448 { 449 chainID: 111, 450 balance: big.NewInt(1), 451 timestamp: 2, 452 tokenSymbol: "SNT", 453 address: common.Address{1}, 454 }, 455 { 456 chainID: 111, 457 balance: big.NewInt(3), 458 timestamp: 3, 459 block: big.NewInt(3), 460 tokenSymbol: "SNT", 461 address: common.Address{1}, 462 }, 463 { 464 chainID: 111, 465 balance: big.NewInt(2), 466 timestamp: 4, 467 block: big.NewInt(4), 468 tokenSymbol: "SNT", 469 address: common.Address{1}, 470 }, 471 }, 472 wantErr: false, 473 }, 474 { 475 name: "addToNonEmptyData", 476 fields: fields{ 477 db: walletDB, 478 }, 479 args: args{ 480 chainID: 111, 481 currency: "SNT", 482 addresses: []common.Address{common.Address{1}}, 483 fromTimestamp: 1, 484 toTimestamp: 2, 485 data: []*entry{ 486 { 487 chainID: 111, 488 balance: big.NewInt(2), 489 timestamp: 2, 490 block: big.NewInt(2), 491 tokenSymbol: "SNT", 492 address: common.Address{1}, 493 }, 494 }, 495 }, 496 wantRes: []*entry{ 497 { 498 chainID: 111, 499 balance: big.NewInt(0), 500 timestamp: 1, 501 tokenSymbol: "SNT", 502 address: common.Address{1}, 503 }, 504 { 505 chainID: 111, 506 balance: big.NewInt(2), 507 timestamp: 2, 508 block: big.NewInt(2), 509 tokenSymbol: "SNT", 510 address: common.Address{1}, 511 }, 512 }, 513 wantErr: false, 514 }, 515 } 516 for _, tt := range tests { 517 t.Run(tt.name, func(t *testing.T) { 518 b := &Balance{ 519 db: tt.fields.db, 520 } 521 gotRes, err := b.addEdgePoints(tt.args.chainID, tt.args.currency, tt.args.addresses, tt.args.fromTimestamp, tt.args.toTimestamp, tt.args.data) 522 if (err != nil) != tt.wantErr { 523 t.Errorf("Balance.addEdgePoints() error = %v, wantErr %v", err, tt.wantErr) 524 return 525 } 526 if !reflect.DeepEqual(gotRes, tt.wantRes) { 527 t.Errorf("Balance.addEdgePoints() = \n%v,\nwant \n%v", gotRes, tt.wantRes) 528 } 529 }) 530 } 531 }