def test_handle_wsgi_request(self): request1 = JSONRPC20Serializer.assemble_request('adder', (2, 3)) request2 = JSONRPC20Serializer.assemble_request('adder', (4, 3)) requests_string = JSONRPC20Serializer.json_dumps([request1, request2]) environ = MockWSGIEnviron(requests_string, [('CONTENT_TYPE', 'application/json'), ('CONTENT_LENGTH', len(requests_string))]) start_response = MockWSGIStartResponse() response_iterable = self.app(environ, start_response) assert response_iterable response_string = ''.join(response_iterable) responses_data = JSONRPC20Serializer.json_loads(response_string) assert len(responses_data) == 2 response_json = responses_data[0] assert 'error' not in response_json assert response_json['id'] == request1['id'] assert response_json['result'] == 5 response_json = responses_data[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7
def test_handle_request_string(self): request1 = JSONRPC20Serializer.assemble_request( 'adder', (2, 3) ) request2 = JSONRPC20Serializer.assemble_request( 'adder', (4, 3) ) requests_string = JSONRPC20Serializer.json_dumps([request1, request2]) response_string = self.app.handle_request_string(requests_string) responses_data = JSONRPC20Serializer.json_loads(response_string) assert len(responses_data) == 2 response_json = responses_data[0] assert 'error' not in response_json assert response_json['id'] == request1['id'] assert response_json['result'] == 5 response_json = responses_data[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7
def test_process_requests(self): request1 = JSONRPC20Serializer.assemble_request( 'adder', (2, 3) ) request2 = JSONRPC20Serializer.assemble_request( 'adder', (4, 3) ) requests, is_batch_mode = JSONRPC20Serializer.parse_request( json.dumps([request1, request2]) ) responses = self.app.process_requests(requests) assert len(responses) == 2 response_json = responses[0] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 5 response_json = responses[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7
def test_process_requests_with_errors(self): request1 = JSONRPC20Serializer.assemble_request( 'blow_up', (2, 3) ) request2 = JSONRPC20Serializer.assemble_request( 'adder', (4, 3) ) requests, is_batch_mode = JSONRPC20Serializer.parse_request( JSONRPC20Serializer.json_dumps([request1, request2]) ) responses = self.app.process_requests(requests) assert len(responses) == 2 response_json = responses[0] assert 'error' in response_json assert set(response_json['error'].keys()) == {'code', 'message', 'data'} assert response_json['error']['message'] == 'Blowing up on command' # actual .message from the raised error assert response_json['id'] == request1['id'] response_json = responses[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7
def test_process_requests(self): request1 = JSONRPC20Serializer.assemble_request('adder', (2, 3)) request2 = JSONRPC20Serializer.assemble_request('adder', (4, 3)) request3 = JSONRPC20Serializer.assemble_request( 'adder' # note: no args. 'adder' can take it. JSONRpc app must too ) assert len({request1['id'], request2['id'], request3['id']}) == 3 requests, is_batch_mode = JSONRPC20Serializer.parse_request( JSONRPC20Serializer.json_dumps([request1, request2, request3])) responses = self.app.process_requests(requests) assert len(responses) == 3 response_json = responses[0] assert 'error' not in response_json assert response_json['id'] == request1['id'] assert response_json['result'] == 5 response_json = responses[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7 response_json = responses[2] assert 'error' not in response_json assert response_json['id'] == request3['id'] assert response_json['result'] == 0
def test_handle_request_string(self): request1 = JSONRPC20Serializer.assemble_request( 'pass_through', (2, 3) ) request_id = request1['id'] requests_string = JSONRPC20Serializer.json_dumps(request1) response_string = self.app.handle_request_string( requests_string, some_context_data='value', more_context_data=['value'] ) response_json = JSONRPC20Serializer.json_loads(response_string) assert 'error' not in response_json assert response_json['id'] == request1['id'] args, kwargs = response_json['result'] assert args == [2, 3] self.assertEqual( dict( request_id=request_id, some_context_data='value', more_context_data=['value'] ), kwargs )
def test_request_parser_attaches_right_error_to_each_parsed_request(self): request_string = json.dumps({}) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id is None assert isinstance(error, errors.RPCInvalidRequest) request_string = json.dumps([{}]) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id is None assert isinstance(error, errors.RPCInvalidRequest) request_data = self.get_base_request_object(notification=False) request_data.pop('jsonrpc') request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidRequest) request_data = self.get_base_request_object(notification=False) request_data.pop('method') request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidRequest)
def test_detect_batch_mode(self): responses, is_batch_mode = JSONRPC20Serializer.parse_response( json.dumps(self.get_base_response_object())) assert not is_batch_mode responses, is_batch_mode = JSONRPC20Serializer.parse_response( json.dumps([self.get_base_response_object()])) assert is_batch_mode
def test_detect_batch_mode(self): responses, is_batch_mode = JSONRPC20Serializer.parse_response(json.dumps( self.get_base_response_object() )) assert not is_batch_mode responses, is_batch_mode = JSONRPC20Serializer.parse_response(json.dumps( [self.get_base_response_object()] )) assert is_batch_mode
def test_response_parser_complains_about_deformed_json(self): response_string = json.dumps("blah") + '}' with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response(response_string) response_string = json.dumps("blah") with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response(response_string) response_string = json.dumps([]) with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response(response_string)
def test_request_parser_detect_batch(self): """JSON-RPC v3 requests may come in "batch" mode - multiple request objects wrapped into an array. To respond to these correctly we need to retain the knowledge of the request coming in as "batch" """ request_string = json.dumps([self.get_base_request_object()]) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert is_batch_mode request_string = json.dumps(self.get_base_request_object()) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert not is_batch_mode
def test_assemble_error_response(self): error = errors.RPCMethodNotFound(request_id=12345) response = JSONRPC20Serializer.assemble_error_response(error) self.assertEqual( {'jsonrpc', 'error', 'id'}, set(response.keys()) ) self.assertEqual( response['jsonrpc'], '2.0' ) self.assertEqual( response['id'], 12345 ) error_object = response['error'] self.assertEqual( {'code', 'message'}, #, 'data'}, set(error_object.keys()) ) self.assertEqual( error_object['code'], errors.METHOD_NOT_FOUND )
def test_response_parser_complains_about_deformed_json(self): response_string = json.dumps("blah") + '}' with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response( response_string) response_string = json.dumps("blah") with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response( response_string) response_string = json.dumps([]) with self.assertRaises(errors.RPCParseError): responses, is_batch_mode = JSONRPC20Serializer.parse_response( response_string)
def test_serialized_request_contains_required_parts(self): request = JSONRPC20Serializer.assemble_request('method_name', (1, 'a')) self.assertEqual( {'jsonrpc', 'method', 'params', 'id'}, set(request.keys()) ) self.assertEqual( request['jsonrpc'], '2.0' ) self.assertEqual( request['method'], 'method_name' ) self.assertEqual( request['params'], (1, 'a') ) assert request['id'] # Truethy
def test_serialized_notification_request_contains_required_parts(self): """Notification requests are different in one respect - no "id (or "id" is null) """ request = JSONRPC20Serializer.assemble_request( 'method_name', (1, 'a'), notification=True ) self.assertEqual( {'jsonrpc', 'method', 'params'}, set(request.keys()) ) self.assertEqual( request['jsonrpc'], '2.0' ) self.assertEqual( request['method'], 'method_name' ) self.assertEqual( request['params'], (1, 'a') )
def test_request_parser_complains_about_poor_params(self): request_data = self.get_base_request_object(params="asdf", notification=False) request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request(request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidMethodParams)
def test_request_parser_detect_batch(self): """JSON-RPC v3 requests may come in "batch" mode - multiple request objects wrapped into an array. To respond to these correctly we need to retain the knowledge of the request coming in as "batch" """ request_string = json.dumps([self.get_base_request_object()]) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert is_batch_mode request_string = json.dumps(self.get_base_request_object()) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert not is_batch_mode
def test_request_parser_complains_about_poor_params(self): request_data = self.get_base_request_object(params="asdf", notification=False) request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidMethodParams)
def test_assemble_success_response(self): response = JSONRPC20Serializer.assemble_response('value', 12345) self.assertEqual({'jsonrpc', 'result', 'id'}, set(response.keys())) self.assertEqual(response['jsonrpc'], '2.0') self.assertEqual(response['result'], 'value') self.assertEqual(response['id'], 12345)
def test_response_parser_success_non_batch(self): response_data1 = self.get_base_response_object() responses, is_batch_mode = JSONRPC20Serializer.parse_response( json.dumps(response_data1)) assert len(responses) assert not is_batch_mode result, request_id, error = responses[0] assert not error assert request_id and request_id == response_data1['id'] assert result and result == response_data1['result']
def test_serialized_request_contains_path_through_id(self): request = JSONRPC20Serializer.assemble_request('method_name', { "arg1": 1, "arg2": 'a' }) self.assertEqual(request['params'], {"arg1": 1, "arg2": 'a'}) self.assertIn('id', request) assert request['id']
def test_request_parser_success_non_batch(self): request_data1 = self.get_base_request_object(notification=False) requests, is_batch_mode = JSONRPC20Serializer.parse_request(json.dumps(request_data1)) assert len(requests) assert not is_batch_mode method, params, request_id, error = requests[0] assert not error assert request_id and request_id == request_data1['id'] assert params and params == request_data1['params'] assert method and method == request_data1['method']
def test_request_parser_success_non_batch(self): request_data1 = self.get_base_request_object(notification=False) requests, is_batch_mode = JSONRPC20Serializer.parse_request( json.dumps(request_data1)) assert len(requests) assert not is_batch_mode method, params, request_id, error = requests[0] assert not error assert request_id and request_id == request_data1['id'] assert params and params == request_data1['params'] assert method and method == request_data1['method']
def test_handle_wsgi_request(self): request1 = JSONRPC20Serializer.assemble_request( 'adder', (2, 3) ) request2 = JSONRPC20Serializer.assemble_request( 'adder', (4, 3) ) requests_string = JSONRPC20Serializer.json_dumps([request1, request2]) environ = MockWSGIEnviron( requests_string, [ ('CONTENT_TYPE', 'application/json'), ('CONTENT_LENGTH', len(requests_string)) ] ) start_response = MockWSGIStartResponse() response_iterable = self.app(environ, start_response) assert response_iterable response_string = ''.join(response_iterable) responses_data = JSONRPC20Serializer.json_loads(response_string) assert len(responses_data) == 2 response_json = responses_data[0] assert 'error' not in response_json assert response_json['id'] == request1['id'] assert response_json['result'] == 5 response_json = responses_data[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7
def test_response_parser_success_non_batch(self): response_data1 = self.get_base_response_object() responses, is_batch_mode = JSONRPC20Serializer.parse_response(json.dumps( response_data1 )) assert len(responses) assert not is_batch_mode result, request_id, error = responses[0] assert not error assert request_id and request_id == response_data1['id'] assert result and result == response_data1['result']
def test_process_requests(self): request1 = JSONRPC20Serializer.assemble_request( 'adder', (2, 3) ) request2 = JSONRPC20Serializer.assemble_request( 'adder', (4, 3) ) request3 = JSONRPC20Serializer.assemble_request( 'adder' # note: no args. 'adder' can take it. JSONRpc app must too ) assert len({request1['id'], request2['id'], request3['id']}) == 3 requests, is_batch_mode = JSONRPC20Serializer.parse_request( JSONRPC20Serializer.json_dumps([request1, request2, request3]) ) responses = self.app.process_requests(requests) assert len(responses) == 3 response_json = responses[0] assert 'error' not in response_json assert response_json['id'] == request1['id'] assert response_json['result'] == 5 response_json = responses[1] assert 'error' not in response_json assert response_json['id'] == request2['id'] assert response_json['result'] == 7 response_json = responses[2] assert 'error' not in response_json assert response_json['id'] == request3['id'] assert response_json['result'] == 0
def test_serialized_request_contains_required_parts(self): request = JSONRPC20Serializer.assemble_request('method_name', (1, 'a')) self.assertEqual({'jsonrpc', 'method', 'params', 'id'}, set(request.keys())) self.assertEqual(request['jsonrpc'], '2.0') self.assertEqual(request['method'], 'method_name') self.assertEqual(request['params'], (1, 'a')) assert request['id'] # Truethy
def test_serialized_notification_request_contains_required_parts(self): """Notification requests are different in one respect - no "id (or "id" is null) """ request = JSONRPC20Serializer.assemble_request('method_name', (1, 'a'), notification=True) self.assertEqual({'jsonrpc', 'method', 'params'}, set(request.keys())) self.assertEqual(request['jsonrpc'], '2.0') self.assertEqual(request['method'], 'method_name') self.assertEqual(request['params'], (1, 'a'))
def test_request_parser_attaches_right_error_to_each_parsed_request(self): request_string = json.dumps({}) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id is None assert isinstance(error, errors.RPCInvalidRequest) request_string = json.dumps([{}]) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id is None assert isinstance(error, errors.RPCInvalidRequest) request_data = self.get_base_request_object(notification=False) request_data.pop('jsonrpc') request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidRequest) request_data = self.get_base_request_object(notification=False) request_data.pop('method') request_string = json.dumps(request_data) requests, is_batch_mode = JSONRPC20Serializer.parse_request( request_string) assert len(requests) method, params, request_id, error = requests[0] assert request_id == request_data['id'] assert isinstance(error, errors.RPCInvalidRequest)
def test_serialized_request_contains_path_through_id(self): request = JSONRPC20Serializer.assemble_request( 'method_name', {"arg1":1, "arg2":'a'} ) self.assertEqual( request['params'], {"arg1":1, "arg2":'a'} ) self.assertIn( 'id', request ) assert request['id']
def test_assemble_error_response(self): error = errors.RPCMethodNotFound(request_id=12345) response = JSONRPC20Serializer.assemble_error_response(error) self.assertEqual({'jsonrpc', 'error', 'id'}, set(response.keys())) self.assertEqual(response['jsonrpc'], '2.0') self.assertEqual(response['id'], 12345) error_object = response['error'] self.assertEqual( {'code', 'message'}, #, 'data'}, set(error_object.keys())) self.assertEqual(error_object['code'], errors.METHOD_NOT_FOUND)
def test_response_parser_success_batch(self): response_data1 = self.get_base_response_object() response_data2 = self.get_base_response_object( result=None, error=errors.RPCMethodNotFound()) responses, is_batch_mode = JSONRPC20Serializer.parse_response( json.dumps([response_data1, response_data2])) assert len(responses) assert is_batch_mode result, request_id, error = responses[0] assert not error assert request_id and request_id == response_data1['id'] assert result and result == response_data1['result'] result, request_id, error = responses[1] assert error assert request_id and request_id == response_data2['id'] assert not result
def test_response_parser_success_batch(self): response_data1 = self.get_base_response_object() response_data2 = self.get_base_response_object(result=None, error=errors.RPCMethodNotFound()) responses, is_batch_mode = JSONRPC20Serializer.parse_response(json.dumps([ response_data1, response_data2 ])) assert len(responses) assert is_batch_mode result, request_id, error = responses[0] assert not error assert request_id and request_id == response_data1['id'] assert result and result == response_data1['result'] result, request_id, error = responses[1] assert error assert request_id and request_id == response_data2['id'] assert not result
def test_assemble_success_response(self): response = JSONRPC20Serializer.assemble_response('value', 12345) self.assertEqual( {'jsonrpc', 'result', 'id'}, set(response.keys()) ) self.assertEqual( response['jsonrpc'], '2.0' ) self.assertEqual( response['result'], 'value' ) self.assertEqual( response['id'], 12345 )