arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/api/bids_test.go
api/bids_test.goRaw
  1package api
  2
  3import (
  4	"fmt"
  5	"testing"
  6	"time"
  7
  8	ethCommon "github.com/ethereum/go-ethereum/common"
  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 testBid struct {
 16	ItemID      uint64            `json:"itemId"`
 17	SlotNum     int64             `json:"slotNum"`
 18	BidValue    string            `json:"bidValue"`
 19	EthBlockNum int64             `json:"ethereumBlockNum"`
 20	Bidder      ethCommon.Address `json:"bidderAddr"`
 21	Forger      ethCommon.Address `json:"forgerAddr"`
 22	URL         string            `json:"URL"`
 23	Timestamp   time.Time         `json:"timestamp"`
 24}
 25
 26type testBidsResponse struct {
 27	Bids         []testBid `json:"bids"`
 28	PendingItems uint64    `json:"pendingItems"`
 29}
 30
 31func (t testBidsResponse) GetPending() (pendingItems, lastItemID uint64) {
 32	if len(t.Bids) == 0 {
 33		return 0, 0
 34	}
 35	pendingItems = t.PendingItems
 36	lastItemID = t.Bids[len(t.Bids)-1].ItemID
 37	return pendingItems, lastItemID
 38}
 39
 40func (t testBidsResponse) Len() int {
 41	return len(t.Bids)
 42}
 43
 44func (t testBidsResponse) New() Pendinger { return &testBidsResponse{} }
 45
 46func genTestBids(blocks []common.Block, coordinators []historydb.CoordinatorAPI, bids []common.Bid) []testBid {
 47	tBids := []testBid{}
 48	for _, bid := range bids {
 49		block := getBlockByNum(bid.EthBlockNum, blocks)
 50		coordinator := getCoordinatorByBidder(bid.Bidder, coordinators)
 51		tBid := testBid{
 52			SlotNum:     bid.SlotNum,
 53			BidValue:    bid.BidValue.String(),
 54			EthBlockNum: bid.EthBlockNum,
 55			Bidder:      bid.Bidder,
 56			Forger:      coordinator.Forger,
 57			URL:         coordinator.URL,
 58			Timestamp:   block.Timestamp,
 59		}
 60		tBids = append(tBids, tBid)
 61	}
 62	return tBids
 63}
 64
 65func TestGetBids(t *testing.T) {
 66	endpoint := apiURL + "bids"
 67	fetchedBids := []testBid{}
 68	appendIter := func(intr interface{}) {
 69		for i := 0; i < len(intr.(*testBidsResponse).Bids); i++ {
 70			tmp, err := copystructure.Copy(intr.(*testBidsResponse).Bids[i])
 71			if err != nil {
 72				panic(err)
 73			}
 74			fetchedBids = append(fetchedBids, tmp.(testBid))
 75		}
 76	}
 77
 78	limit := 3
 79	// bidderAddress
 80	fetchedBids = []testBid{}
 81	bidderAddress := tc.bids[3].Bidder
 82	path := fmt.Sprintf("%s?bidderAddr=%s&limit=%d", endpoint, bidderAddress.String(), limit)
 83	err := doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
 84	assert.NoError(t, err)
 85	bidderAddrBids := []testBid{}
 86	for i := 0; i < len(tc.bids); i++ {
 87		if tc.bids[i].Bidder == bidderAddress {
 88			bidderAddrBids = append(bidderAddrBids, tc.bids[i])
 89		}
 90	}
 91	assertBids(t, bidderAddrBids, fetchedBids)
 92
 93	// slotNum
 94	fetchedBids = []testBid{}
 95	slotNum := tc.bids[3].SlotNum
 96	path = fmt.Sprintf("%s?slotNum=%d&limit=%d", endpoint, slotNum, limit)
 97	err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
 98	assert.NoError(t, err)
 99	slotNumBids := []testBid{}
100	for i := 0; i < len(tc.bids); i++ {
101		if tc.bids[i].SlotNum == slotNum {
102			slotNumBids = append(slotNumBids, tc.bids[i])
103		}
104	}
105	assertBids(t, slotNumBids, fetchedBids)
106
107	// slotNum, in reverse order
108	fetchedBids = []testBid{}
109	path = fmt.Sprintf("%s?slotNum=%d&limit=%d", endpoint, slotNum, limit)
110	err = doGoodReqPaginated(path, historydb.OrderDesc, &testBidsResponse{}, appendIter)
111	assert.NoError(t, err)
112	flippedBids := []testBid{}
113	for i := len(slotNumBids) - 1; i >= 0; i-- {
114		flippedBids = append(flippedBids, slotNumBids[i])
115	}
116	assertBids(t, flippedBids, fetchedBids)
117
118	// Mixed filters
119	fetchedBids = []testBid{}
120	bidderAddress = tc.bids[1].Bidder
121	slotNum = tc.bids[1].SlotNum
122	path = fmt.Sprintf("%s?bidderAddr=%s&slotNum=%d&limit=%d", endpoint, bidderAddress.String(), slotNum, limit)
123	err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
124	assert.NoError(t, err)
125	slotNumBidderAddrBids := []testBid{}
126	for i := 0; i < len(tc.bids); i++ {
127		if tc.bids[i].Bidder == bidderAddress && tc.bids[i].SlotNum == slotNum {
128			slotNumBidderAddrBids = append(slotNumBidderAddrBids, tc.bids[i])
129		}
130	}
131	assertBids(t, slotNumBidderAddrBids, fetchedBids)
132
133	// Empty array
134	fetchedBids = []testBid{}
135	path = fmt.Sprintf("%s?slotNum=%d&bidderAddr=%s", endpoint, 5, tc.bids[1].Bidder.String())
136	err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
137	assert.NoError(t, err)
138	assertBids(t, []testBid{}, fetchedBids)
139
140	// 400
141	// No filters
142	path = fmt.Sprintf("%s?limit=%d", endpoint, limit)
143	err = doBadReq("GET", path, nil, 400)
144	assert.NoError(t, err)
145	// Invalid slotNum
146	path = fmt.Sprintf("%s?slotNum=%d", endpoint, -2)
147	err = doBadReq("GET", path, nil, 400)
148	assert.NoError(t, err)
149	// Invalid bidderAddress
150	path = fmt.Sprintf("%s?bidderAddr=%s", endpoint, "0xG0000001")
151	err = doBadReq("GET", path, nil, 400)
152	assert.NoError(t, err)
153}
154
155func assertBids(t *testing.T, expected, actual []testBid) {
156	assert.Equal(t, len(expected), len(actual))
157	for i := 0; i < len(expected); i++ {
158		assertBid(t, expected[i], actual[i])
159	}
160}
161
162func assertBid(t *testing.T, expected, actual testBid) {
163	assert.Equal(t, expected.Timestamp.Unix(), actual.Timestamp.Unix())
164	expected.Timestamp = actual.Timestamp
165	actual.ItemID = expected.ItemID
166	assert.Equal(t, expected, actual)
167}