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