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}