json-rpc icon indicating copy to clipboard operation
json-rpc copied to clipboard

Add JSON RPC response parsing

Open kacper-ka opened this issue 7 years ago • 1 comments

Requirements

  • Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
  • All new code requires tests to ensure against regressions.
  • If pull request breaks tests it would not be merged.

Description of the Change

This PR adds methods needed for parsing JSON RPC responses from a received JSON string. In order to accomplish that the following changes have been made:

  • new exception class: JSONRPCInvalidResponseException (just like JSONRPCInvalidRequestException);
  • new class: JSONRPCResponse - JSON RPC version agnostic parser, based on JSONRPCRequest. It exposes two class methods: from_json and from_data - the former just deserializes JSON string and the latter relays parsing to version-specific class. The mechanism is the exact copy of the one used in JSONRPCRequest;
  • updated JSONRPC10Response and JSONRPC20Response classes:
    • updated error setters - verify whether result field is None prior to assigning the error object (raise ValueError if it is not), delete result key in case of JSONRPC20Response (result and error fields are mutually exclusive), attempt to construct error object before assigning the value;
    • added result and error deleters to JSONRPC20Response;
    • added from_json and from_data class methods - the mechanism reflects the one found in JSONRPC10Request and JSONRPC20Request.

To ensure proper implementation new tests have been added:

  • test_jsonrpc1.py:
    • test_from_json_invalid_response_result - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing result field;
    • test_from_json_invalid_response_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing error field;
    • test_from_json_invalid_response_id - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing id field;
    • test_from_json_invalid_response_both_result_and_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with both result and error fields other than None;
    • test_from_json_invalid_response_extra_data - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with extra fields;
    • test_from_json_response_result - tests whether parsing is correct for a specified result field;
    • test_from_json_response_error - tests whether parsing is correct for a specified error field
    • test_from_json_string_not_dict - tests whether the parser raises a ValueError if supplied JSON string does not represent a dictionary.
  • test_jsonrpc2.py:
    • test_from_json_invalid_response_jsonrpc - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing jsonrpc field;
    • test_from_json_invalid_response_id - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing id field;
    • test_from_json_invalid_response_no_result_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with neither result nor error fields specified;
    • test_from_json_invalid_response_result_and_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with both result and error fields specified;
    • test_from_json_invalid_response_extra_data - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with extra fields;
    • test_from_json_response_result_null - tests whether the parsing is correct for a None as a result;
    • test_from_json_response_result - tests whether the parsing is correct for a list as a result;
    • test_from_json_response_error - tests whether the parsing is correct for an error response.

Benefits

This change provides a symmetrical interface for both JSONRPCRequest and JSONRPCResponse. This provides an easy and consistent way to implement symmetrical interfaces, in which either side of an connection acts as a server-client hybrid, e.g. server that sends notifications to connected clients.

Possible Drawbacks

Should be none. All tests are passing (except for the Python 3.3 environment, but that is an upstream issue), however it may be reasonable to closely inspect whether error.setter update (in JSONRPC10Response and JSONRPC20Response) did not break anything.

kacper-ka avatar Aug 29 '18 08:08 kacper-ka