github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/jsonrpc/types/codec_test.go (about) 1 package types 2 3 import ( 4 "context" 5 "encoding/json" 6 "strconv" 7 "testing" 8 9 "github.com/0xPolygon/supernets2-node/jsonrpc/mocks" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestBlockNumberMarshalJSON(t *testing.T) { 15 testCases := []struct { 16 jsonValue string 17 expectedBlockNumber int64 18 expectedError error 19 }{ 20 {"latest", int64(LatestBlockNumber), nil}, 21 {"pending", int64(PendingBlockNumber), nil}, 22 {"earliest", int64(EarliestBlockNumber), nil}, 23 {"safe", int64(SafeBlockNumber), nil}, 24 {"finalized", int64(FinalizedBlockNumber), nil}, 25 {"", int64(LatestBlockNumber), nil}, 26 {"0", int64(0), nil}, 27 {"10", int64(10), nil}, 28 {"0x2", int64(2), nil}, 29 {"0xA", int64(10), nil}, 30 {"abc", int64(0), &strconv.NumError{Err: strconv.ErrSyntax, Func: "ParseUint", Num: "abc"}}, 31 } 32 33 for _, testCase := range testCases { 34 t.Run(testCase.jsonValue, func(t *testing.T) { 35 data, err := json.Marshal(testCase.jsonValue) 36 require.NoError(t, err) 37 bn := BlockNumber(int64(0)) 38 err = json.Unmarshal(data, &bn) 39 assert.Equal(t, testCase.expectedError, err) 40 assert.Equal(t, testCase.expectedBlockNumber, int64(bn)) 41 }) 42 } 43 } 44 45 func TestGetNumericBlockNumber(t *testing.T) { 46 s := mocks.NewStateMock(t) 47 48 type testCase struct { 49 name string 50 bn *BlockNumber 51 expectedBlockNumber uint64 52 expectedError Error 53 setupMocks func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) 54 } 55 56 testCases := []testCase{ 57 { 58 name: "BlockNumber nil", 59 bn: nil, 60 expectedBlockNumber: 40, 61 expectedError: nil, 62 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) { 63 s. 64 On("GetLastL2BlockNumber", context.Background(), d). 65 Return(uint64(40), nil). 66 Once() 67 }, 68 }, 69 { 70 name: "BlockNumber LatestBlockNumber", 71 bn: bnPtr(LatestBlockNumber), 72 expectedBlockNumber: 50, 73 expectedError: nil, 74 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) { 75 s. 76 On("GetLastL2BlockNumber", context.Background(), d). 77 Return(uint64(50), nil). 78 Once() 79 }, 80 }, 81 { 82 name: "BlockNumber PendingBlockNumber", 83 bn: bnPtr(PendingBlockNumber), 84 expectedBlockNumber: 30, 85 expectedError: nil, 86 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) { 87 s. 88 On("GetLastL2BlockNumber", context.Background(), d). 89 Return(uint64(30), nil). 90 Once() 91 }, 92 }, 93 { 94 name: "BlockNumber EarliestBlockNumber", 95 bn: bnPtr(EarliestBlockNumber), 96 expectedBlockNumber: 0, 97 expectedError: nil, 98 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {}, 99 }, 100 { 101 name: "BlockNumber SafeBlockNumber", 102 bn: bnPtr(SafeBlockNumber), 103 expectedBlockNumber: 40, 104 expectedError: nil, 105 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) { 106 s. 107 On("GetLastVirtualizedL2BlockNumber", context.Background(), d). 108 Return(uint64(40), nil). 109 Once() 110 }, 111 }, 112 { 113 name: "BlockNumber FinalizedBlockNumber", 114 bn: bnPtr(FinalizedBlockNumber), 115 expectedBlockNumber: 50, 116 expectedError: nil, 117 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) { 118 s. 119 On("GetLastConsolidatedL2BlockNumber", context.Background(), d). 120 Return(uint64(50), nil). 121 Once() 122 }, 123 }, 124 { 125 name: "BlockNumber Positive Number", 126 bn: bnPtr(BlockNumber(int64(10))), 127 expectedBlockNumber: 10, 128 expectedError: nil, 129 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {}, 130 }, 131 { 132 name: "BlockNumber Negative Number <= -6", 133 bn: bnPtr(BlockNumber(int64(-6))), 134 expectedBlockNumber: 0, 135 expectedError: NewRPCError(InvalidParamsErrorCode, "invalid block number: -6"), 136 setupMocks: func(s *mocks.StateMock, d *mocks.DBTxMock, t *testCase) {}, 137 }, 138 } 139 140 for _, testCase := range testCases { 141 t.Run(testCase.name, func(t *testing.T) { 142 tc := testCase 143 dbTx := mocks.NewDBTxMock(t) 144 testCase.setupMocks(s, dbTx, &tc) 145 result, rpcErr := testCase.bn.GetNumericBlockNumber(context.Background(), s, dbTx) 146 assert.Equal(t, testCase.expectedBlockNumber, result) 147 if rpcErr != nil || testCase.expectedError != nil { 148 assert.Equal(t, testCase.expectedError.ErrorCode(), rpcErr.ErrorCode()) 149 assert.Equal(t, testCase.expectedError.Error(), rpcErr.Error()) 150 } 151 }) 152 } 153 } 154 155 func TestResponseMarshal(t *testing.T) { 156 testCases := []struct { 157 Name string 158 JSONRPC string 159 ID interface{} 160 Result interface{} 161 Error Error 162 163 ExpectedJSON string 164 }{ 165 { 166 Name: "Error is nil", 167 JSONRPC: "2.0", 168 ID: 1, 169 Result: struct { 170 A string `json:"A"` 171 }{"A"}, 172 Error: nil, 173 174 ExpectedJSON: "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"A\":\"A\"}}", 175 }, 176 { 177 Name: "Result is nil and Error is not nil", 178 JSONRPC: "2.0", 179 ID: 1, 180 Result: nil, 181 Error: NewRPCError(123, "m"), 182 183 ExpectedJSON: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":123,\"message\":\"m\"}}", 184 }, 185 { 186 Name: "Result is not nil and Error is not nil", 187 JSONRPC: "2.0", 188 ID: 1, 189 Result: struct { 190 A string `json:"A"` 191 }{"A"}, 192 Error: NewRPCError(123, "m"), 193 194 ExpectedJSON: "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":123,\"message\":\"m\"}}", 195 }, 196 } 197 198 for _, testCase := range testCases { 199 t.Run(testCase.Name, func(t *testing.T) { 200 req := Request{ 201 JSONRPC: testCase.JSONRPC, 202 ID: testCase.ID, 203 } 204 var result []byte 205 if testCase.Result != nil { 206 r, err := json.Marshal(testCase.Result) 207 require.NoError(t, err) 208 result = r 209 } 210 211 res := NewResponse(req, result, testCase.Error) 212 bytes, err := json.Marshal(res) 213 require.NoError(t, err) 214 assert.Equal(t, string(testCase.ExpectedJSON), string(bytes)) 215 }) 216 } 217 } 218 219 func TestIndexUnmarshalJSON(t *testing.T) { 220 testCases := []struct { 221 input []byte 222 expectedIndex int64 223 expectedError error 224 }{ 225 { 226 input: []byte("\"0x86\""), 227 expectedIndex: 134, 228 expectedError: nil, 229 }, 230 { 231 input: []byte("\"abc\""), 232 expectedIndex: 0, 233 expectedError: &strconv.NumError{}, 234 }, 235 } 236 237 for _, testCase := range testCases { 238 var i Index 239 err := json.Unmarshal(testCase.input, &i) 240 assert.Equal(t, int64(testCase.expectedIndex), int64(i)) 241 assert.IsType(t, testCase.expectedError, err) 242 } 243 } 244 245 func TestBlockNumberStringOrHex(t *testing.T) { 246 testCases := []struct { 247 bn *BlockNumber 248 expectedResult string 249 }{ 250 {bn: bnPtr(BlockNumber(-3)), expectedResult: "pending"}, 251 {bn: bnPtr(BlockNumber(-2)), expectedResult: "latest"}, 252 {bn: bnPtr(BlockNumber(-1)), expectedResult: "earliest"}, 253 {bn: bnPtr(BlockNumber(0)), expectedResult: "0x0"}, 254 {bn: bnPtr(BlockNumber(100)), expectedResult: "0x64"}, 255 } 256 257 for _, testCase := range testCases { 258 result := testCase.bn.StringOrHex() 259 assert.Equal(t, testCase.expectedResult, result) 260 } 261 } 262 263 func bnPtr(bn BlockNumber) *BlockNumber { 264 return &bn 265 }