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}