You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.1 KiB

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