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