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