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.

166 lines
6.4 KiB

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