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	pendingItems = t.PendingItems
 33	lastItemID = t.Bids[len(t.Bids)-1].ItemID
 34	return pendingItems, lastItemID
 35}
 36
 37func (t testBidsResponse) Len() int {
 38	return len(t.Bids)
 39}
 40
 41func genTestBids(blocks []common.Block, coordinators []historydb.CoordinatorAPI, bids []common.Bid) []testBid {
 42	tBids := []testBid{}
 43	for _, bid := range bids {
 44		block := getBlockByNum(bid.EthBlockNum, blocks)
 45		coordinator := getCoordinatorByBidder(bid.Bidder, coordinators)
 46		tBid := testBid{
 47			SlotNum:     bid.SlotNum,
 48			BidValue:    bid.BidValue.String(),
 49			EthBlockNum: bid.EthBlockNum,
 50			Bidder:      bid.Bidder,
 51			Forger:      coordinator.Forger,
 52			URL:         coordinator.URL,
 53			Timestamp:   block.Timestamp,
 54		}
 55		tBids = append(tBids, tBid)
 56	}
 57	return tBids
 58}
 59
 60func TestGetBids(t *testing.T) {
 61	endpoint := apiURL + "bids"
 62	fetchedBids := []testBid{}
 63	appendIter := func(intr interface{}) {
 64		for i := 0; i < len(intr.(*testBidsResponse).Bids); i++ {
 65			tmp, err := copystructure.Copy(intr.(*testBidsResponse).Bids[i])
 66			if err != nil {
 67				panic(err)
 68			}
 69			fetchedBids = append(fetchedBids, tmp.(testBid))
 70		}
 71	}
 72
 73	limit := 3
 74	// bidderAddress
 75	fetchedBids = []testBid{}
 76	bidderAddress := tc.bids[3].Bidder
 77	path := fmt.Sprintf("%s?bidderAddr=%s&limit=%d&fromItem=", endpoint, bidderAddress.String(), limit)
 78	err := doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
 79	assert.NoError(t, err)
 80	bidderAddrBids := []testBid{}
 81	for i := 0; i < len(tc.bids); i++ {
 82		if tc.bids[i].Bidder == bidderAddress {
 83			bidderAddrBids = append(bidderAddrBids, tc.bids[i])
 84		}
 85	}
 86	assertBids(t, bidderAddrBids, fetchedBids)
 87
 88	// slotNum
 89	fetchedBids = []testBid{}
 90	slotNum := tc.bids[3].SlotNum
 91	path = fmt.Sprintf("%s?slotNum=%d&limit=%d&fromItem=", endpoint, slotNum, limit)
 92	err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
 93	assert.NoError(t, err)
 94	slotNumBids := []testBid{}
 95	for i := 0; i < len(tc.bids); i++ {
 96		if tc.bids[i].SlotNum == slotNum {
 97			slotNumBids = append(slotNumBids, tc.bids[i])
 98		}
 99	}
100	assertBids(t, slotNumBids, fetchedBids)
101
102	// slotNum, in reverse order
103	fetchedBids = []testBid{}
104	path = fmt.Sprintf("%s?slotNum=%d&limit=%d&fromItem=", endpoint, slotNum, limit)
105	err = doGoodReqPaginated(path, historydb.OrderDesc, &testBidsResponse{}, appendIter)
106	assert.NoError(t, err)
107	flippedBids := []testBid{}
108	for i := len(slotNumBids) - 1; i >= 0; i-- {
109		flippedBids = append(flippedBids, slotNumBids[i])
110	}
111	assertBids(t, flippedBids, fetchedBids)
112
113	// Mixed filters
114	fetchedBids = []testBid{}
115	bidderAddress = tc.bids[1].Bidder
116	slotNum = tc.bids[5].SlotNum
117	path = fmt.Sprintf("%s?bidderAddr=%s&slotNum=%d&limit=%d&fromItem=", endpoint, bidderAddress.String(), slotNum, limit)
118	err = doGoodReqPaginated(path, historydb.OrderAsc, &testBidsResponse{}, appendIter)
119	assert.NoError(t, err)
120	slotNumBidderAddrBids := []testBid{}
121	for i := 0; i < len(tc.bids); i++ {
122		if tc.bids[i].Bidder == bidderAddress && tc.bids[i].SlotNum == slotNum {
123			slotNumBidderAddrBids = append(slotNumBidderAddrBids, tc.bids[i])
124		}
125	}
126	assertBids(t, slotNumBidderAddrBids, fetchedBids)
127
128	// 400
129	// No filters
130	path = fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit)
131	err = doBadReq("GET", path, nil, 400)
132	assert.NoError(t, err)
133	// Invalid slotNum
134	path = fmt.Sprintf("%s?slotNum=%d", endpoint, -2)
135	err = doBadReq("GET", path, nil, 400)
136	assert.NoError(t, err)
137	// Invalid bidderAddress
138	path = fmt.Sprintf("%s?bidderAddr=%s", endpoint, "0xG0000001")
139	err = doBadReq("GET", path, nil, 400)
140	assert.NoError(t, err)
141	// 404
142	path = fmt.Sprintf("%s?slotNum=%d&bidderAddr=%s", endpoint, tc.bids[0].SlotNum, tc.bids[1].Bidder.String())
143	err = doBadReq("GET", path, nil, 404)
144	assert.NoError(t, err)
145}
146
147func assertBids(t *testing.T, expected, actual []testBid) {
148	assert.Equal(t, len(expected), len(actual))
149	for i := 0; i < len(expected); i++ {
150		assertBid(t, expected[i], actual[i])
151	}
152}
153
154func assertBid(t *testing.T, expected, actual testBid) {
155	assert.Equal(t, expected.Timestamp.Unix(), actual.Timestamp.Unix())
156	expected.Timestamp = actual.Timestamp
157	actual.ItemID = expected.ItemID
158	assert.Equal(t, expected, actual)
159}