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.

162 lines
6.2 KiB

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