You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
6.1 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package api
  2. import (
  3. "fmt"
  4. "strconv"
  5. "testing"
  6. "github.com/hermeznetwork/hermez-node/apitypes"
  7. "github.com/hermeznetwork/hermez-node/common"
  8. "github.com/hermeznetwork/hermez-node/db/historydb"
  9. "github.com/mitchellh/copystructure"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. type testAccount struct {
  13. ItemID uint64 `json:"itemId"`
  14. Idx apitypes.HezIdx `json:"accountIndex"`
  15. BatchNum common.BatchNum `json:"batchNum"`
  16. PublicKey apitypes.HezBJJ `json:"bjj"`
  17. EthAddr apitypes.HezEthAddr `json:"hezEthereumAddress"`
  18. Nonce common.Nonce `json:"nonce"`
  19. Balance *apitypes.BigIntStr `json:"balance"`
  20. Token historydb.TokenWithUSD `json:"token"`
  21. }
  22. type testAccountsResponse struct {
  23. Accounts []testAccount `json:"accounts"`
  24. PendingItems uint64 `json:"pendingItems"`
  25. }
  26. func (t testAccountsResponse) GetPending() (pendingItems, lastItemID uint64) {
  27. pendingItems = t.PendingItems
  28. lastItemID = t.Accounts[len(t.Accounts)-1].ItemID
  29. return pendingItems, lastItemID
  30. }
  31. func (t *testAccountsResponse) Len() int { return len(t.Accounts) }
  32. func genTestAccounts(accounts []common.Account, tokens []historydb.TokenWithUSD) []testAccount {
  33. tAccounts := []testAccount{}
  34. for x, account := range accounts {
  35. token := getTokenByID(account.TokenID, tokens)
  36. tAccount := testAccount{
  37. ItemID: uint64(x + 1),
  38. Idx: apitypes.HezIdx(idxToHez(account.Idx, token.Symbol)),
  39. PublicKey: apitypes.NewHezBJJ(account.PublicKey),
  40. EthAddr: apitypes.NewHezEthAddr(account.EthAddr),
  41. Nonce: account.Nonce,
  42. Balance: apitypes.NewBigIntStr(account.Balance),
  43. Token: token,
  44. }
  45. tAccounts = append(tAccounts, tAccount)
  46. }
  47. return tAccounts
  48. }
  49. func TestGetAccounts(t *testing.T) {
  50. endpoint := apiURL + "accounts"
  51. fetchedAccounts := []testAccount{}
  52. appendIter := func(intr interface{}) {
  53. for i := 0; i < len(intr.(*testAccountsResponse).Accounts); i++ {
  54. tmp, err := copystructure.Copy(intr.(*testAccountsResponse).Accounts[i])
  55. if err != nil {
  56. panic(err)
  57. }
  58. fetchedAccounts = append(fetchedAccounts, tmp.(testAccount))
  59. }
  60. }
  61. limit := 5
  62. stringIds := strconv.Itoa(int(tc.tokens[2].TokenID)) + "," + strconv.Itoa(int(tc.tokens[5].TokenID)) + "," + strconv.Itoa(int(tc.tokens[6].TokenID))
  63. // Filter by BJJ
  64. path := fmt.Sprintf("%s?BJJ=%s&limit=%d&fromItem=", endpoint, tc.accounts[0].PublicKey, limit)
  65. err := doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter)
  66. assert.NoError(t, err)
  67. assert.Greater(t, len(fetchedAccounts), 0)
  68. assert.LessOrEqual(t, len(fetchedAccounts), len(tc.accounts))
  69. fetchedAccounts = []testAccount{}
  70. // Filter by ethAddr
  71. path = fmt.Sprintf("%s?hermezEthereumAddress=%s&limit=%d&fromItem=", endpoint, tc.accounts[0].EthAddr, limit)
  72. err = doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter)
  73. assert.NoError(t, err)
  74. assert.Greater(t, len(fetchedAccounts), 0)
  75. assert.LessOrEqual(t, len(fetchedAccounts), len(tc.accounts))
  76. fetchedAccounts = []testAccount{}
  77. // both filters (incompatible)
  78. path = fmt.Sprintf("%s?hermezEthereumAddress=%s&BJJ=%s&limit=%d&fromItem=", endpoint, tc.accounts[0].EthAddr, tc.accounts[0].PublicKey, limit)
  79. err = doBadReq("GET", path, nil, 400)
  80. assert.NoError(t, err)
  81. fetchedAccounts = []testAccount{}
  82. // Filter by token IDs
  83. path = fmt.Sprintf("%s?tokenIds=%s&limit=%d&fromItem=", endpoint, stringIds, limit)
  84. err = doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter)
  85. assert.NoError(t, err)
  86. assert.Greater(t, len(fetchedAccounts), 0)
  87. assert.LessOrEqual(t, len(fetchedAccounts), len(tc.accounts))
  88. fetchedAccounts = []testAccount{}
  89. // Token Ids + bjj
  90. path = fmt.Sprintf("%s?tokenIds=%s&BJJ=%s&limit=%d&fromItem=", endpoint, stringIds, tc.accounts[0].PublicKey, limit)
  91. err = doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter)
  92. assert.NoError(t, err)
  93. assert.Greater(t, len(fetchedAccounts), 0)
  94. assert.LessOrEqual(t, len(fetchedAccounts), len(tc.accounts))
  95. fetchedAccounts = []testAccount{}
  96. // No filters (checks response content)
  97. path = fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
  98. err = doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter)
  99. assert.NoError(t, err)
  100. assert.Equal(t, len(tc.accounts), len(fetchedAccounts))
  101. for i := 0; i < len(fetchedAccounts); i++ {
  102. fetchedAccounts[i].Token.ItemID = 0
  103. if tc.accounts[i].Token.USDUpdate != nil {
  104. assert.Less(t, fetchedAccounts[i].Token.USDUpdate.Unix()-3, tc.accounts[i].Token.USDUpdate.Unix())
  105. fetchedAccounts[i].Token.USDUpdate = tc.accounts[i].Token.USDUpdate
  106. }
  107. assert.Equal(t, tc.accounts[i], fetchedAccounts[i])
  108. }
  109. // No filters Reverse Order (checks response content)
  110. reversedAccounts := []testAccount{}
  111. appendIter = func(intr interface{}) {
  112. for i := 0; i < len(intr.(*testAccountsResponse).Accounts); i++ {
  113. tmp, err := copystructure.Copy(intr.(*testAccountsResponse).Accounts[i])
  114. if err != nil {
  115. panic(err)
  116. }
  117. reversedAccounts = append(reversedAccounts, tmp.(testAccount))
  118. }
  119. }
  120. err = doGoodReqPaginated(path, historydb.OrderDesc, &testAccountsResponse{}, appendIter)
  121. assert.NoError(t, err)
  122. assert.Equal(t, len(reversedAccounts), len(fetchedAccounts))
  123. for i := 0; i < len(fetchedAccounts); i++ {
  124. reversedAccounts[i].Token.ItemID = 0
  125. fetchedAccounts[len(fetchedAccounts)-1-i].Token.ItemID = 0
  126. if reversedAccounts[i].Token.USDUpdate != nil {
  127. assert.Less(t, fetchedAccounts[len(fetchedAccounts)-1-i].Token.USDUpdate.Unix()-3, reversedAccounts[i].Token.USDUpdate.Unix())
  128. fetchedAccounts[len(fetchedAccounts)-1-i].Token.USDUpdate = reversedAccounts[i].Token.USDUpdate
  129. }
  130. assert.Equal(t, reversedAccounts[i], fetchedAccounts[len(fetchedAccounts)-1-i])
  131. }
  132. // Test GetAccount
  133. path = fmt.Sprintf("%s/%s", endpoint, fetchedAccounts[2].Idx)
  134. account := testAccount{}
  135. assert.NoError(t, doGoodReq("GET", path, nil, &account))
  136. account.Token.ItemID = 0
  137. assert.Equal(t, fetchedAccounts[2], account)
  138. // 400
  139. path = fmt.Sprintf("%s/hez:12345", endpoint)
  140. err = doBadReq("GET", path, nil, 400)
  141. assert.NoError(t, err)
  142. // 404
  143. path = fmt.Sprintf("%s/hez:10:12345", endpoint)
  144. err = doBadReq("GET", path, nil, 404)
  145. assert.NoError(t, err)
  146. }