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  }