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