hermez-node/api/parsers_test.go
api/parsers_test.goRaw
1package api
2
3import (
4 "encoding/base64"
5 "math/big"
6 "strconv"
7 "strings"
8 "testing"
9
10 ethCommon "github.com/ethereum/go-ethereum/common"
11 "github.com/hermeznetwork/hermez-node/common"
12 "github.com/iden3/go-iden3-crypto/babyjub"
13 "github.com/stretchr/testify/assert"
14)
15
16type queryParser struct {
17 m map[string]string
18}
19
20func (qp *queryParser) Query(query string) string {
21 if val, ok := qp.m[query]; ok {
22 return val
23 }
24 return ""
25}
26
27func (qp *queryParser) Param(param string) string {
28 if val, ok := qp.m[param]; ok {
29 return val
30 }
31 return ""
32}
33
34func TestParseQueryUint(t *testing.T) {
35 name := "foo"
36 c := &queryParser{}
37 c.m = make(map[string]string)
38 var min uint = 1
39 var max uint = 10
40 var dflt *uint
41 // Not uint
42 c.m[name] = "-1"
43 _, err := parseQueryUint(name, dflt, min, max, c)
44 assert.Error(t, err)
45 c.m[name] = "a"
46 _, err = parseQueryUint(name, dflt, min, max, c)
47 assert.Error(t, err)
48 c.m[name] = "0.1"
49 _, err = parseQueryUint(name, dflt, min, max, c)
50 assert.Error(t, err)
51 c.m[name] = "1.0"
52 _, err = parseQueryUint(name, dflt, min, max, c)
53 assert.Error(t, err)
54 // Out of range
55 c.m[name] = strconv.Itoa(int(min) - 1)
56 _, err = parseQueryUint(name, dflt, min, max, c)
57 assert.Error(t, err)
58 c.m[name] = strconv.Itoa(int(max) + 1)
59 _, err = parseQueryUint(name, dflt, min, max, c)
60 assert.Error(t, err)
61 // Default nil
62 c.m[name] = ""
63 res, err := parseQueryUint(name, dflt, min, max, c)
64 assert.NoError(t, err)
65 assert.Nil(t, res)
66 // Default not nil
67 dflt = new(uint)
68 *dflt = uint(min)
69 res, err = parseQueryUint(name, dflt, min, max, c)
70 assert.NoError(t, err)
71 assert.Equal(t, uint(min), *res)
72 // Correct
73 c.m[name] = strconv.Itoa(int(max))
74 res, err = parseQueryUint(name, res, min, max, c)
75 assert.NoError(t, err)
76 assert.Equal(t, uint(max), *res)
77}
78
79func TestParseQueryBool(t *testing.T) {
80 name := "foo"
81 c := &queryParser{}
82 c.m = make(map[string]string)
83 var dflt *bool
84 // Not bool
85 c.m[name] = "x"
86 _, err := parseQueryBool(name, dflt, c)
87 assert.Error(t, err)
88 c.m[name] = "False"
89 _, err = parseQueryBool(name, dflt, c)
90 assert.Error(t, err)
91 c.m[name] = "0"
92 _, err = parseQueryBool(name, dflt, c)
93 assert.Error(t, err)
94 c.m[name] = "1"
95 _, err = parseQueryBool(name, dflt, c)
96 assert.Error(t, err)
97 // Default nil
98 c.m[name] = ""
99 res, err := parseQueryBool(name, dflt, c)
100 assert.NoError(t, err)
101 assert.Nil(t, res)
102 // Default not nil
103 dflt = new(bool)
104 *dflt = true
105 res, err = parseQueryBool(name, dflt, c)
106 assert.NoError(t, err)
107 assert.True(t, *res)
108 // Correct
109 c.m[name] = "false"
110 res, err = parseQueryBool(name, dflt, c)
111 assert.NoError(t, err)
112 assert.False(t, *res)
113 c.m[name] = "true"
114 res, err = parseQueryBool(name, dflt, c)
115 assert.NoError(t, err)
116 assert.True(t, *res)
117}
118
119func TestParsePagination(t *testing.T) {
120 c := &queryParser{}
121 c.m = make(map[string]string)
122 // fromItem out of range
123 c.m["fromItem"] = "-1"
124 _, _, _, err := parsePagination(c)
125 assert.Error(t, err)
126 c.m["fromItem"] = strconv.Itoa(maxUint32 + 1)
127 _, _, _, err = parsePagination(c)
128 assert.Error(t, err)
129 c.m["fromItem"] = ""
130 // Bad order
131 c.m["order"] = "0"
132 _, _, _, err = parsePagination(c)
133 assert.Error(t, err)
134 c.m["order"] = strconv.Itoa(int(maxLimit) + 1)
135 _, _, _, err = parsePagination(c)
136 assert.Error(t, err)
137 // Default
138 c.m["fromItem"] = ""
139 c.m["order"] = ""
140 c.m["limit"] = ""
141 fromItem, order, limit, err := parsePagination(c)
142 assert.NoError(t, err)
143 assert.Nil(t, fromItem)
144 assert.Equal(t, dfltOrder, order)
145 assert.Equal(t, dfltLimit, *limit)
146 // Correct
147 c.m["fromItem"] = ""
148 c.m["order"] = "ASC"
149 c.m["limit"] = "25"
150 fromItem, order, limit, err = parsePagination(c)
151 assert.NoError(t, err)
152 assert.Nil(t, fromItem)
153 assert.Equal(t, "ASC", order)
154 assert.Equal(t, 25, int(*limit))
155 c.m["fromItem"] = "25"
156 c.m["order"] = "DESC"
157 c.m["limit"] = "50"
158 fromItem, order, limit, err = parsePagination(c)
159 assert.NoError(t, err)
160 assert.Equal(t, 25, int(*fromItem))
161 assert.Equal(t, "DESC", order)
162 assert.Equal(t, 50, int(*limit))
163}
164
165func TestParseQueryHezEthAddr(t *testing.T) {
166 name := "hermezEthereumAddress"
167 c := &queryParser{}
168 c.m = make(map[string]string)
169 ethAddr := ethCommon.BigToAddress(big.NewInt(int64(347683)))
170 // Not HEZ Eth addr
171 c.m[name] = "hez:0xf"
172 _, err := parseQueryHezEthAddr(c)
173 assert.Error(t, err)
174 c.m[name] = ethAddr.String()
175 _, err = parseQueryHezEthAddr(c)
176 assert.Error(t, err)
177 c.m[name] = "hez:0xXX942cfcd25ad4d90a62358b0dd84f33b39826XX"
178 _, err = parseQueryHezEthAddr(c)
179 assert.Error(t, err)
180 // Default
181 c.m[name] = ""
182 res, err := parseQueryHezEthAddr(c)
183 assert.NoError(t, err)
184 assert.Nil(t, res)
185 // Correct
186 c.m[name] = "hez:" + ethAddr.String()
187 res, err = parseQueryHezEthAddr(c)
188 assert.NoError(t, err)
189 assert.Equal(t, ethAddr, *res)
190}
191
192func TestParseQueryBJJ(t *testing.T) {
193 name := "BJJ"
194 c := &queryParser{}
195 c.m = make(map[string]string)
196 privK := babyjub.NewRandPrivKey()
197 pubK := privK.Public()
198 pkComp := [32]byte(pubK.Compress())
199 // Not HEZ Eth addr
200 c.m[name] = "hez:abcd"
201 _, err := parseQueryBJJ(c)
202 assert.Error(t, err)
203 c.m[name] = pubK.String()
204 _, err = parseQueryBJJ(c)
205 assert.Error(t, err)
206 // Wrong checksum
207 bjjSum := append(pkComp[:], byte(1))
208 c.m[name] = "hez:" + base64.RawStdEncoding.EncodeToString(bjjSum)
209 _, err = parseQueryBJJ(c)
210 assert.Error(t, err)
211 // Default
212 c.m[name] = ""
213 res, err := parseQueryBJJ(c)
214 assert.NoError(t, err)
215 assert.Nil(t, res)
216 // Correct
217 c.m[name] = bjjToString(pubK)
218 res, err = parseQueryBJJ(c)
219 assert.NoError(t, err)
220 assert.Equal(t, *pubK, *res)
221}
222
223func TestParseQueryTxType(t *testing.T) {
224 name := "type"
225 c := &queryParser{}
226 c.m = make(map[string]string)
227 // Incorrect values
228 c.m[name] = "deposit"
229 _, err := parseQueryTxType(c)
230 assert.Error(t, err)
231 c.m[name] = "1"
232 _, err = parseQueryTxType(c)
233 assert.Error(t, err)
234 // Default
235 c.m[name] = ""
236 res, err := parseQueryTxType(c)
237 assert.NoError(t, err)
238 assert.Nil(t, res)
239 // Correct values
240 c.m[name] = string(common.TxTypeExit)
241 res, err = parseQueryTxType(c)
242 assert.NoError(t, err)
243 assert.Equal(t, common.TxTypeExit, *res)
244 c.m[name] = string(common.TxTypeTransfer)
245 res, err = parseQueryTxType(c)
246 assert.NoError(t, err)
247 assert.Equal(t, common.TxTypeTransfer, *res)
248 c.m[name] = string(common.TxTypeDeposit)
249 res, err = parseQueryTxType(c)
250 assert.NoError(t, err)
251 assert.Equal(t, common.TxTypeDeposit, *res)
252 c.m[name] = string(common.TxTypeCreateAccountDeposit)
253 res, err = parseQueryTxType(c)
254 assert.NoError(t, err)
255 assert.Equal(t, common.TxTypeCreateAccountDeposit, *res)
256 c.m[name] = string(common.TxTypeCreateAccountDepositTransfer)
257 res, err = parseQueryTxType(c)
258 assert.NoError(t, err)
259 assert.Equal(t, common.TxTypeCreateAccountDepositTransfer, *res)
260 c.m[name] = string(common.TxTypeDepositTransfer)
261 res, err = parseQueryTxType(c)
262 assert.NoError(t, err)
263 assert.Equal(t, common.TxTypeDepositTransfer, *res)
264 c.m[name] = string(common.TxTypeForceTransfer)
265 res, err = parseQueryTxType(c)
266 assert.NoError(t, err)
267 assert.Equal(t, common.TxTypeForceTransfer, *res)
268 c.m[name] = string(common.TxTypeForceExit)
269 res, err = parseQueryTxType(c)
270 assert.NoError(t, err)
271 assert.Equal(t, common.TxTypeForceExit, *res)
272 c.m[name] = string(common.TxTypeTransferToEthAddr)
273 res, err = parseQueryTxType(c)
274 assert.NoError(t, err)
275 assert.Equal(t, common.TxTypeTransferToEthAddr, *res)
276 c.m[name] = string(common.TxTypeTransferToBJJ)
277 res, err = parseQueryTxType(c)
278 assert.NoError(t, err)
279 assert.Equal(t, common.TxTypeTransferToBJJ, *res)
280}
281
282func TestParseTokenFilters(t *testing.T) {
283 ids := "ids"
284 symbols := "symbols"
285 name := "name"
286 nameValue := "1"
287 symbolsValue := "1,2,3"
288 idsValue := "2,3,4"
289 c := &queryParser{}
290 c.m = make(map[string]string)
291 // Incorrect values
292 c.m[name] = nameValue
293 c.m[ids] = idsValue
294 c.m[symbols] = symbolsValue
295
296 idsParse, symbolsParse, nameParse, err := parseTokenFilters(c)
297 assert.NoError(t, err)
298
299 // Correct values
300 var tokenIds []common.TokenID = []common.TokenID{2, 3, 4}
301 assert.Equal(t, tokenIds, idsParse)
302 var symbolsArray []string = []string{"1", "2", "3"}
303 assert.Equal(t, symbolsArray, symbolsParse)
304 assert.Equal(t, nameValue, nameParse)
305}
306func TestParseEthAddr(t *testing.T) {
307 name := "forgerAddr"
308 c := &queryParser{}
309 c.m = make(map[string]string)
310 ethAddr := ethCommon.BigToAddress(big.NewInt(int64(123456)))
311 // Default
312 c.m[name] = ""
313 res, err := parseQueryEthAddr(name, c)
314 assert.NoError(t, err)
315 assert.Nil(t, res)
316 // Incorrect
317 c.m[name] = "0x12345678"
318 _, err = parseQueryEthAddr(name, c)
319 assert.Error(t, err)
320 // Correct
321 c.m[name] = ethAddr.String()
322 res, err = parseQueryEthAddr(name, c)
323 assert.NoError(t, err)
324 assert.Equal(t, ethAddr, *res)
325}
326
327func TestParseBidFilters(t *testing.T) {
328 slotNum := "slotNum"
329 bidderAddr := "bidderAddr"
330 slotNumValue := "2"
331 bidderAddrValue := "0xaa942cfcd25ad4d90a62358b0dd84f33b398262a"
332 c := &queryParser{}
333 c.m = make(map[string]string)
334 // Incorrect values
335 c.m[slotNum] = slotNumValue
336 c.m[bidderAddr] = bidderAddrValue
337
338 slotNumParse, bidderAddrParse, err := parseBidFilters(c)
339 assert.NoError(t, err)
340
341 // Correct values
342 assert.Equal(t, strings.ToLower(bidderAddrParse.Hex()), bidderAddrValue)
343 assert.Equal(t, slotNumValue, strconv.FormatUint(uint64(*slotNumParse), 10))
344}