package rpc import ( "encoding/json" "errors" "testing" "github.com/stretchr/testify/require" ) func TestNewSuccessResponse(t *testing.T) { cases := []struct { name string result json.RawMessage id json.RawMessage expected string }{ {"string", json.RawMessage(`"3434=done"`), nil, `{"jsonrpc":"2.0","id":0,"result":"3434=done"}`}, {"struct_nil_id", json.RawMessage(`{"field": "value"}`), nil, `{"jsonrpc":"2.0","id":0,"result":{"field":"value"}}`}, {"struct_non_nil_id", json.RawMessage(`{"field": "value"}`), json.RawMessage(`42`), `{"jsonrpc":"2.0","id":42,"result":{"field":"value"}}`}, {"null", json.RawMessage(`null`), json.RawMessage(`7`), `{"jsonrpc":"2.0","id":7,"result":null}`}, {"null_nil", nil, json.RawMessage(`7`), `{"jsonrpc":"2.0","id":7,"result":null}`}, } for _, test := range cases { t.Run(test.name, func(t *testing.T) { got := newSuccessResponse(test.result, test.id) require.Equal(t, test.expected, got) }) } } func TestNewErrorResponse(t *testing.T) { got := newErrorResponse(-32601, errors.New("Method not found"), json.RawMessage(`42`)) expected := `{"jsonrpc":"2.0","id":42,"error":{"code":-32601,"message":"Method not found"}}` require.Equal(t, expected, got) } func TestUnmarshalMessage(t *testing.T) { body := json.RawMessage(`{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}}`) got, err := unmarshalMessage(body) require.NoError(t, err) expected := &jsonrpcRequest{ jsonrpcMessage: jsonrpcMessage{Version: "2.0"}, Method: "subtract", Params: json.RawMessage(`{"subtrahend": 23, "minuend": 42}`), } require.Equal(t, expected, got) } func TestMethodAndParamsFromBody(t *testing.T) { cases := []struct { name string body json.RawMessage params []interface{} method string id json.RawMessage chainID uint64 shouldFail bool }{ { "params_array", json.RawMessage(`{"jsonrpc": "2.0", "id": 42, "method": "subtract", "params": [{"subtrahend": 23, "minuend": 42}]}`), []interface{}{ map[string]interface{}{ "subtrahend": float64(23), "minuend": float64(42), }, }, "subtract", json.RawMessage(`42`), 0, false, }, { "params_empty_array", json.RawMessage(`{"jsonrpc": "2.0", "method": "test", "params": []}`), []interface{}{}, "test", nil, 0, false, }, { "params_none", json.RawMessage(`{"jsonrpc": "2.0", "method": "test"}`), []interface{}{}, "test", nil, 0, false, }, { "params_chain_id", json.RawMessage(`{"jsonrpc": "2.0", "chainId": 2, "method": "test"}`), []interface{}{}, "test", nil, 2, false, }, { "getFilterMessage", json.RawMessage(`{"jsonrpc":"2.0","id":44,"method":"shh_getFilterMessages","params":["3de6a8867aeb75be74d68478b853b4b0e063704d30f8231c45d0fcbd97af207e"]}`), []interface{}{string("3de6a8867aeb75be74d68478b853b4b0e063704d30f8231c45d0fcbd97af207e")}, "shh_getFilterMessages", json.RawMessage(`44`), 0, false, }, { "getFilterMessage_array", json.RawMessage(`[{"jsonrpc":"2.0","id":44,"method":"shh_getFilterMessages","params":["3de6a8867aeb75be74d68478b853b4b0e063704d30f8231c45d0fcbd97af207e"]}]`), []interface{}{}, "", nil, 0, true, }, { "empty_array", json.RawMessage(`[]`), []interface{}{}, "", nil, 0, true, }, } for _, test := range cases { t.Run(test.name, func(t *testing.T) { chainID, method, params, id, err := methodAndParamsFromBody(test.body) if test.shouldFail { require.Error(t, err) return } require.NoError(t, err) require.Equal(t, test.chainID, chainID) require.Equal(t, test.method, method) require.Equal(t, test.params, params) require.EqualValues(t, test.id, id) }) } } func TestIsBatch(t *testing.T) { cases := []struct { name string body json.RawMessage expected bool }{ {"single", json.RawMessage(`{"jsonrpc":"2.0","id":44,"method":"shh_getFilterMessages","params":["3de6a8867aeb75be74d68478b853b4b0e063704d30f8231c45d0fcbd97af207e"]}`), false}, {"array", json.RawMessage(`[{"jsonrpc":"2.0","id":44,"method":"shh_getFilterMessages","params":["3de6a8867aeb75be74d68478b853b4b0e063704d30f8231c45d0fcbd97af207e"]}]`), true}, } for _, test := range cases { t.Run(test.name, func(t *testing.T) { got := isBatch(test.body) require.Equal(t, test.expected, got) }) } }