Merge pyextra subtree

This commit is contained in:
Vehicle Researcher
2019-03-26 01:03:51 -07:00
69 changed files with 8796 additions and 0 deletions
View File
+7
View File
@@ -0,0 +1,7 @@
# Python3.5+ code.
# This won't even parse in earlier versions, so it's kept in a separate file
# and imported when needed.
def distance(a: float, b: float) -> float:
return (a ** 2 + b ** 2) ** 0.5
@@ -0,0 +1,11 @@
SECRET_KEY = 'secret'
ROOT_URLCONF = 'jsonrpc.tests.test_backend_django.urls'
ALLOWED_HOSTS = ['testserver']
DATABASE_ENGINE = 'django.db.backends.sqlite3'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
}
JSONRPC_MAP_VIEW_ENABLED = True
@@ -0,0 +1,89 @@
""" Test Django Backend."""
from __future__ import absolute_import
import os
try:
from django.core.urlresolvers import RegexURLPattern
from django.test import TestCase
except ImportError:
import unittest
raise unittest.SkipTest('Django not found for testing')
from ...backend.django import JSONRPCAPI, api
import json
class TestDjangoBackend(TestCase):
@classmethod
def setUpClass(cls):
os.environ['DJANGO_SETTINGS_MODULE'] = \
'jsonrpc.tests.test_backend_django.settings'
super(TestDjangoBackend, cls).setUpClass()
def test_urls(self):
self.assertTrue(isinstance(api.urls, list))
for api_url in api.urls:
self.assertTrue(isinstance(api_url, RegexURLPattern))
def test_client(self):
@api.dispatcher.add_method
def dummy(request):
return ""
json_data = {
"id": "0",
"jsonrpc": "2.0",
"method": "dummy",
}
response = self.client.post(
'',
json.dumps(json_data),
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode('utf8'))
self.assertEqual(data['result'], '')
def test_method_not_allowed(self):
response = self.client.get(
'',
content_type='application/json',
)
self.assertEqual(response.status_code, 405, "Should allow only POST")
def test_invalid_request(self):
response = self.client.post(
'',
'{',
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.content.decode('utf8'))
self.assertEqual(data['error']['code'], -32700)
self.assertEqual(data['error']['message'], 'Parse error')
def test_resource_map(self):
response = self.client.get('/map')
self.assertEqual(response.status_code, 200)
data = response.content.decode('utf8')
self.assertIn("JSON-RPC map", data)
def test_method_not_allowed_prefix(self):
response = self.client.get(
'/prefix/',
content_type='application/json',
)
self.assertEqual(response.status_code, 405)
def test_resource_map_prefix(self):
response = self.client.get('/prefix/map')
self.assertEqual(response.status_code, 200)
def test_empty_initial_dispatcher(self):
class SubDispatcher(type(api.dispatcher)):
pass
custom_dispatcher = SubDispatcher()
custom_api = JSONRPCAPI(custom_dispatcher)
self.assertEqual(type(custom_api.dispatcher), SubDispatcher)
self.assertEqual(id(custom_api.dispatcher), id(custom_dispatcher))
@@ -0,0 +1,7 @@
from django.conf.urls import url, include
from jsonrpc.backend.django import api
urlpatterns = [
url(r'', include(api.urls)),
url(r'^prefix/', include(api.urls)),
]
@@ -0,0 +1,182 @@
import json
import sys
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
# Flask is supported only for python2 and python3.3+
if sys.version_info < (3, 0) or sys.version_info >= (3, 3):
try:
from flask import Flask
except ImportError:
raise unittest.SkipTest('Flask not found for testing')
from ...backend.flask import JSONRPCAPI, api
@api.dispatcher.add_method
def dummy():
return ""
@unittest.skipIf((3, 0) <= sys.version_info < (3, 3),
'Flask does not support python 3.0 - 3.2')
class TestFlaskBackend(unittest.TestCase):
REQUEST = json.dumps({
"id": "0",
"jsonrpc": "2.0",
"method": "dummy",
})
def setUp(self):
self.client = self._get_test_client(JSONRPCAPI())
def _get_test_client(self, api):
@api.dispatcher.add_method
def dummy():
return ""
app = Flask(__name__)
app.config["TESTING"] = True
app.register_blueprint(api.as_blueprint())
return app.test_client()
def test_client(self):
response = self.client.post(
'/',
data=self.REQUEST,
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['result'], '')
def test_method_not_allowed(self):
response = self.client.get(
'/',
content_type='application/json',
)
self.assertEqual(response.status_code, 405, "Should allow only POST")
def test_parse_error(self):
response = self.client.post(
'/',
data='{',
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['error']['code'], -32700)
self.assertEqual(data['error']['message'], 'Parse error')
def test_wrong_content_type(self):
response = self.client.post(
'/',
data=self.REQUEST,
content_type='application/x-www-form-urlencoded',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['error']['code'], -32700)
self.assertEqual(data['error']['message'], 'Parse error')
def test_invalid_request(self):
response = self.client.post(
'/',
data='{"method": "dummy", "id": 1}',
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['error']['code'], -32600)
self.assertEqual(data['error']['message'], 'Invalid Request')
def test_method_not_found(self):
data = {
"jsonrpc": "2.0",
"method": "dummy2",
"id": 1
}
response = self.client.post(
'/',
data=json.dumps(data),
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['error']['code'], -32601)
self.assertEqual(data['error']['message'], 'Method not found')
def test_invalid_parameters(self):
data = {
"jsonrpc": "2.0",
"method": "dummy",
"params": [42],
"id": 1
}
response = self.client.post(
'/',
data=json.dumps(data),
content_type='application/json',
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['error']['code'], -32602)
self.assertEqual(data['error']['message'], 'Invalid params')
def test_resource_map(self):
response = self.client.get('/map')
self.assertEqual(response.status_code, 200)
self.assertTrue("JSON-RPC map" in response.data.decode('utf8'))
def test_method_not_allowed_prefix(self):
response = self.client.get(
'/',
content_type='application/json',
)
self.assertEqual(response.status_code, 405)
def test_resource_map_prefix(self):
response = self.client.get('/map')
self.assertEqual(response.status_code, 200)
def test_as_view(self):
api = JSONRPCAPI()
with patch.object(api, 'jsonrpc') as mock_jsonrpc:
self.assertIs(api.as_view(), mock_jsonrpc)
def test_not_check_content_type(self):
client = self._get_test_client(JSONRPCAPI(check_content_type=False))
response = client.post(
'/',
data=self.REQUEST,
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['result'], '')
def test_check_content_type(self):
client = self._get_test_client(JSONRPCAPI(check_content_type=False))
response = client.post(
'/',
data=self.REQUEST,
content_type="application/x-www-form-urlencoded"
)
self.assertEqual(response.status_code, 200)
data = json.loads(response.data.decode('utf8'))
self.assertEqual(data['result'], '')
def test_empty_initial_dispatcher(self):
class SubDispatcher(type(api.dispatcher)):
pass
custom_dispatcher = SubDispatcher()
custom_api = JSONRPCAPI(custom_dispatcher)
self.assertEqual(type(custom_api.dispatcher), SubDispatcher)
self.assertEqual(id(custom_api.dispatcher), id(custom_dispatcher))
+39
View File
@@ -0,0 +1,39 @@
""" Test base JSON-RPC classes."""
import sys
from ..base import JSONRPCBaseRequest, JSONRPCBaseResponse
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPCBaseRequest(unittest.TestCase):
""" Test JSONRPCBaseRequest functionality."""
def test_data(self):
request = JSONRPCBaseRequest()
self.assertEqual(request.data, {})
with self.assertRaises(ValueError):
request.data = []
with self.assertRaises(ValueError):
request.data = None
class TestJSONRPCBaseResponse(unittest.TestCase):
""" Test JSONRPCBaseResponse functionality."""
def test_data(self):
response = JSONRPCBaseResponse(result="")
self.assertEqual(response.data, {})
with self.assertRaises(ValueError):
response.data = []
with self.assertRaises(ValueError):
response.data = None
+34
View File
@@ -0,0 +1,34 @@
""" Exmples of usage with tests.
Tests in this file represent examples taken from JSON-RPC specification.
http://www.jsonrpc.org/specification#examples
"""
import sys
import json
from ..manager import JSONRPCResponseManager
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
def isjsonequal(json1, json2):
return json.loads(json1) == json.loads(json2)
class TestJSONRPCExamples(unittest.TestCase):
def setUp(self):
self.dispatcher = {
"return_none": lambda: None,
}
def test_none_as_result(self):
req = '{"jsonrpc": "2.0", "method": "return_none", "id": 0}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "result": null, "id": 0}'
))
+142
View File
@@ -0,0 +1,142 @@
from ..dispatcher import Dispatcher
import sys
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class Math:
def sum(self, a, b):
return a + b
def diff(self, a, b):
return a - b
class TestDispatcher(unittest.TestCase):
""" Test Dispatcher functionality."""
def test_getter(self):
d = Dispatcher()
with self.assertRaises(KeyError):
d["method"]
d["add"] = lambda *args: sum(args)
self.assertEqual(d["add"](1, 1), 2)
def test_in(self):
d = Dispatcher()
d["method"] = lambda: ""
self.assertIn("method", d)
def test_add_method(self):
d = Dispatcher()
@d.add_method
def add(x, y):
return x + y
self.assertIn("add", d)
self.assertEqual(d["add"](1, 1), 2)
def test_add_method_with_name(self):
d = Dispatcher()
@d.add_method(name="this.add")
def add(x, y):
return x + y
self.assertNotIn("add", d)
self.assertIn("this.add", d)
self.assertEqual(d["this.add"](1, 1), 2)
def test_add_class(self):
d = Dispatcher()
d.add_class(Math)
self.assertIn("math.sum", d)
self.assertIn("math.diff", d)
self.assertEqual(d["math.sum"](3, 8), 11)
self.assertEqual(d["math.diff"](6, 9), -3)
def test_add_object(self):
d = Dispatcher()
d.add_object(Math())
self.assertIn("math.sum", d)
self.assertIn("math.diff", d)
self.assertEqual(d["math.sum"](5, 2), 7)
self.assertEqual(d["math.diff"](15, 9), 6)
def test_add_dict(self):
d = Dispatcher()
d.add_dict({"sum": lambda *args: sum(args)}, "util")
self.assertIn("util.sum", d)
self.assertEqual(d["util.sum"](13, -2), 11)
def test_add_method_keep_function_definitions(self):
d = Dispatcher()
@d.add_method
def one(x):
return x
self.assertIsNotNone(one)
def test_del_method(self):
d = Dispatcher()
d["method"] = lambda: ""
self.assertIn("method", d)
del d["method"]
self.assertNotIn("method", d)
def test_to_dict(self):
d = Dispatcher()
def func():
return ""
d["method"] = func
self.assertEqual(dict(d), {"method": func})
def test_init_from_object_instance(self):
class Dummy():
def one(self):
pass
def two(self):
pass
dummy = Dummy()
d = Dispatcher(dummy)
self.assertIn("one", d)
self.assertIn("two", d)
self.assertNotIn("__class__", d)
def test_init_from_dictionary(self):
dummy = {
'one': lambda x: x,
'two': lambda x: x,
}
d = Dispatcher(dummy)
self.assertIn("one", d)
self.assertIn("two", d)
def test_dispatcher_representation(self):
d = Dispatcher()
self.assertEqual('{}', repr(d))
+206
View File
@@ -0,0 +1,206 @@
""" Exmples of usage with tests.
Tests in this file represent examples taken from JSON-RPC specification.
http://www.jsonrpc.org/specification#examples
"""
import sys
import json
from ..manager import JSONRPCResponseManager
from ..jsonrpc2 import JSONRPC20Request, JSONRPC20BatchRequest
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
def isjsonequal(json1, json2):
return json.loads(json1) == json.loads(json2)
class TestJSONRPCExamples(unittest.TestCase):
def setUp(self):
self.dispatcher = {
"subtract": lambda a, b: a - b,
}
def test_rpc_call_with_positional_parameters(self):
req = '{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}' # noqa
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "result": 19, "id": 1}'
))
req = '{"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}' # noqa
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "result": -19, "id": 2}'
))
def test_rpc_call_with_named_parameters(self):
def subtract(minuend=None, subtrahend=None):
return minuend - subtrahend
dispatcher = {
"subtract": subtract,
"sum": lambda *args: sum(args),
"get_data": lambda: ["hello", 5],
}
req = '{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}' # noqa
response = JSONRPCResponseManager.handle(req, dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "result": 19, "id": 3}'
))
req = '{"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}' # noqa
response = JSONRPCResponseManager.handle(req, dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "result": 19, "id": 4}',
))
def test_notification(self):
req = '{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertEqual(response, None)
req = '{"jsonrpc": "2.0", "method": "foobar"}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertEqual(response, None)
def test_rpc_call_of_non_existent_method(self):
req = '{"jsonrpc": "2.0", "method": "foobar", "id": "1"}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}' # noqa
))
def test_rpc_call_with_invalid_json(self):
req = '{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}' # noqa
))
def test_rpc_call_with_invalid_request_object(self):
req = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}' # noqa
))
def test_rpc_call_batch_invalid_json(self):
req = """[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method"
]"""
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}' # noqa
))
def test_rpc_call_with_an_empty_array(self):
req = '[]'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}' # noqa
))
def test_rpc_call_with_rpc_call_with_an_invalid_batch_but_not_empty(self):
req = '[1]'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isjsonequal(
response.json,
'{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}' # noqa
))
def test_rpc_call_with_invalid_batch(self):
req = '[1,2,3]'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(
response,
json.loads("""[
{"jsonrpc": "2.0", "error": {"code": -32600,
"message": "Invalid Request"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32600,
"message": "Invalid Request"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32600,
"message": "Invalid Request"}, "id": null}
]""")
)
def test_rpc_call_batch(self):
req = """[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract",
"params": [42,23], "id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get",
"params": {"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
]"""
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(
response,
json.loads("""[
{"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"},
{"jsonrpc": "2.0", "error": {"code": -32600,
"message": "Invalid Request"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32601,
"message": "Method not found"}, "id": "5"},
{"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
]""")
)
def test_rpc_call_batch_all_notifications(self):
req = """[
{"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
]"""
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertEqual(response, None)
def test_rpc_call_response_request(self):
req = '{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}' # noqa
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isinstance(
response.request,
JSONRPC20Request
))
self.assertTrue(isjsonequal(
response.request.json,
req
))
def test_rpc_call_response_request_batch(self):
req = """[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract",
"params": [42,23], "id": "2"},
{"jsonrpc": "2.0", "method": "foo.get",
"params": {"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
]"""
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isinstance(
response.request,
JSONRPC20BatchRequest
))
self.assertTrue(isjsonequal(
response.request.json,
req
))
+1
View File
@@ -0,0 +1 @@
""" Tets base JSON-RPC structures."""
+429
View File
@@ -0,0 +1,429 @@
import json
import sys
from ..exceptions import JSONRPCInvalidRequestException
from ..jsonrpc1 import (
JSONRPC10Request,
JSONRPC10Response,
)
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPC10Request(unittest.TestCase):
""" Test JSONRPC10Request functionality."""
def setUp(self):
self.request_params = {
"method": "add",
"params": [1, 2],
"_id": 1,
}
def test_correct_init(self):
""" Test object is created."""
JSONRPC10Request(**self.request_params)
def test_validation_incorrect_no_parameters(self):
with self.assertRaises(ValueError):
JSONRPC10Request()
def test_method_validation_str(self):
self.request_params.update({"method": "add"})
JSONRPC10Request(**self.request_params)
def test_method_validation_not_str(self):
self.request_params.update({"method": []})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
self.request_params.update({"method": {}})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
self.request_params.update({"method": None})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
def test_params_validation_list(self):
self.request_params.update({"params": []})
JSONRPC10Request(**self.request_params)
self.request_params.update({"params": [0]})
JSONRPC10Request(**self.request_params)
def test_params_validation_tuple(self):
self.request_params.update({"params": ()})
JSONRPC10Request(**self.request_params)
self.request_params.update({"params": tuple([0])})
JSONRPC10Request(**self.request_params)
def test_params_validation_dict(self):
self.request_params.update({"params": {}})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
self.request_params.update({"params": {"a": 0}})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
def test_params_validation_none(self):
self.request_params.update({"params": None})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
def test_params_validation_incorrect(self):
self.request_params.update({"params": "str"})
with self.assertRaises(ValueError):
JSONRPC10Request(**self.request_params)
def test_request_args(self):
self.assertEqual(JSONRPC10Request("add", []).args, ())
self.assertEqual(JSONRPC10Request("add", [1, 2]).args, (1, 2))
def test_id_validation_string(self):
self.request_params.update({"_id": "id"})
JSONRPC10Request(**self.request_params)
def test_id_validation_int(self):
self.request_params.update({"_id": 0})
JSONRPC10Request(**self.request_params)
def test_id_validation_null(self):
self.request_params.update({"_id": "null"})
JSONRPC10Request(**self.request_params)
def test_id_validation_none(self):
self.request_params.update({"_id": None})
JSONRPC10Request(**self.request_params)
def test_id_validation_float(self):
self.request_params.update({"_id": 0.1})
JSONRPC10Request(**self.request_params)
def test_id_validation_list_tuple(self):
self.request_params.update({"_id": []})
JSONRPC10Request(**self.request_params)
self.request_params.update({"_id": ()})
JSONRPC10Request(**self.request_params)
def test_id_validation_default_id_none(self):
del self.request_params["_id"]
JSONRPC10Request(**self.request_params)
def test_data_method_1(self):
r = JSONRPC10Request("add", [])
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_method_2(self):
r = JSONRPC10Request(method="add", params=[])
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_params_1(self):
r = JSONRPC10Request("add", params=[], _id=None)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_params_2(self):
r = JSONRPC10Request("add", ())
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_params_3(self):
r = JSONRPC10Request("add", (1, 2))
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [1, 2],
"id": None,
})
def test_data_id_1(self):
r = JSONRPC10Request("add", [], _id="null")
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": "null",
})
def test_data_id_1_notification(self):
r = JSONRPC10Request("add", [], _id="null", is_notification=True)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_id_2(self):
r = JSONRPC10Request("add", [], _id=None)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_id_2_notification(self):
r = JSONRPC10Request("add", [], _id=None, is_notification=True)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_id_3(self):
r = JSONRPC10Request("add", [], _id="id")
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": "id",
})
def test_data_id_3_notification(self):
r = JSONRPC10Request("add", [], _id="id", is_notification=True)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_data_id_4(self):
r = JSONRPC10Request("add", [], _id=0)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": 0,
})
def test_data_id_4_notification(self):
r = JSONRPC10Request("add", [], _id=0, is_notification=True)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"method": "add",
"params": [],
"id": None,
})
def test_is_notification(self):
r = JSONRPC10Request("add", [])
self.assertTrue(r.is_notification)
r = JSONRPC10Request("add", [], _id=None)
self.assertTrue(r.is_notification)
r = JSONRPC10Request("add", [], _id="null")
self.assertFalse(r.is_notification)
r = JSONRPC10Request("add", [], _id=0)
self.assertFalse(r.is_notification)
r = JSONRPC10Request("add", [], is_notification=True)
self.assertTrue(r.is_notification)
r = JSONRPC10Request("add", [], is_notification=True, _id=None)
self.assertTrue(r.is_notification)
r = JSONRPC10Request("add", [], is_notification=True, _id=0)
self.assertTrue(r.is_notification)
def test_set_unset_notification_keep_id(self):
r = JSONRPC10Request("add", [], is_notification=True, _id=0)
self.assertTrue(r.is_notification)
self.assertEqual(r.data["id"], None)
r.is_notification = False
self.assertFalse(r.is_notification)
self.assertEqual(r.data["id"], 0)
def test_error_if_notification_true_but_id_none(self):
r = JSONRPC10Request("add", [], is_notification=True, _id=None)
with self.assertRaises(ValueError):
r.is_notification = False
def test_from_json_invalid_request_method(self):
str_json = json.dumps({
"params": [1, 2],
"id": 0,
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC10Request.from_json(str_json)
def test_from_json_invalid_request_params(self):
str_json = json.dumps({
"method": "add",
"id": 0,
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC10Request.from_json(str_json)
def test_from_json_invalid_request_id(self):
str_json = json.dumps({
"method": "add",
"params": [1, 2],
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC10Request.from_json(str_json)
def test_from_json_invalid_request_extra_data(self):
str_json = json.dumps({
"method": "add",
"params": [1, 2],
"id": 0,
"is_notification": True,
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC10Request.from_json(str_json)
def test_from_json_request(self):
str_json = json.dumps({
"method": "add",
"params": [1, 2],
"id": 0,
})
request = JSONRPC10Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC10Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, [1, 2])
self.assertEqual(request._id, 0)
self.assertFalse(request.is_notification)
def test_from_json_request_notification(self):
str_json = json.dumps({
"method": "add",
"params": [1, 2],
"id": None,
})
request = JSONRPC10Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC10Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, [1, 2])
self.assertEqual(request._id, None)
self.assertTrue(request.is_notification)
def test_from_json_string_not_dict(self):
with self.assertRaises(ValueError):
JSONRPC10Request.from_json("[]")
with self.assertRaises(ValueError):
JSONRPC10Request.from_json("0")
def test_data_setter(self):
request = JSONRPC10Request(**self.request_params)
with self.assertRaises(ValueError):
request.data = []
with self.assertRaises(ValueError):
request.data = ""
with self.assertRaises(ValueError):
request.data = None
class TestJSONRPC10Response(unittest.TestCase):
""" Test JSONRPC10Response functionality."""
def setUp(self):
self.response_success_params = {
"result": "",
"error": None,
"_id": 1,
}
self.response_error_params = {
"result": None,
"error": {
"code": 1,
"message": "error",
},
"_id": 1,
}
def test_correct_init(self):
""" Test object is created."""
JSONRPC10Response(**self.response_success_params)
JSONRPC10Response(**self.response_error_params)
def test_validation_incorrect_no_parameters(self):
with self.assertRaises(ValueError):
JSONRPC10Response()
def test_validation_success_incorrect(self):
wrong_params = self.response_success_params
del wrong_params["_id"]
with self.assertRaises(ValueError):
JSONRPC10Response(**wrong_params)
def test_validation_error_incorrect(self):
wrong_params = self.response_error_params
del wrong_params["_id"]
with self.assertRaises(ValueError):
JSONRPC10Response(**wrong_params)
def _test_validation_incorrect_result_and_error(self):
# @todo: remove
# It is OK because result is an mepty string, it is still result
with self.assertRaises(ValueError):
JSONRPC10Response(result="", error="", _id=0)
response = JSONRPC10Response(error="", _id=0)
with self.assertRaises(ValueError):
response.result = ""
def test_data(self):
r = JSONRPC10Response(result="", _id=0)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"result": "",
"id": 0,
})
def test_data_setter(self):
response = JSONRPC10Response(**self.response_success_params)
with self.assertRaises(ValueError):
response.data = []
with self.assertRaises(ValueError):
response.data = ""
with self.assertRaises(ValueError):
response.data = None
def test_validation_id(self):
response = JSONRPC10Response(**self.response_success_params)
self.assertEqual(response._id, self.response_success_params["_id"])
+728
View File
@@ -0,0 +1,728 @@
import json
import sys
from ..exceptions import JSONRPCInvalidRequestException
from ..jsonrpc2 import (
JSONRPC20Request,
JSONRPC20BatchRequest,
JSONRPC20Response,
JSONRPC20BatchResponse,
)
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPC20Request(unittest.TestCase):
""" Test JSONRPC20Request functionality."""
def setUp(self):
self.request_params = {
"method": "add",
"params": [1, 2],
"_id": 1,
}
def test_correct_init(self):
""" Test object is created."""
JSONRPC20Request(**self.request_params)
def test_validation_incorrect_no_parameters(self):
with self.assertRaises(ValueError):
JSONRPC20Request()
def test_method_validation_str(self):
self.request_params.update({"method": "add"})
JSONRPC20Request(**self.request_params)
def test_method_validation_not_str(self):
self.request_params.update({"method": []})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
self.request_params.update({"method": {}})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
def test_method_validation_str_rpc_prefix(self):
""" Test method SHOULD NOT starts with rpc. """
self.request_params.update({"method": "rpc."})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
self.request_params.update({"method": "rpc.test"})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
self.request_params.update({"method": "rpccorrect"})
JSONRPC20Request(**self.request_params)
self.request_params.update({"method": "rpc"})
JSONRPC20Request(**self.request_params)
def test_params_validation_list(self):
self.request_params.update({"params": []})
JSONRPC20Request(**self.request_params)
self.request_params.update({"params": [0]})
JSONRPC20Request(**self.request_params)
def test_params_validation_tuple(self):
self.request_params.update({"params": ()})
JSONRPC20Request(**self.request_params)
self.request_params.update({"params": tuple([0])})
JSONRPC20Request(**self.request_params)
def test_params_validation_dict(self):
self.request_params.update({"params": {}})
JSONRPC20Request(**self.request_params)
self.request_params.update({"params": {"a": 0}})
JSONRPC20Request(**self.request_params)
def test_params_validation_none(self):
self.request_params.update({"params": None})
JSONRPC20Request(**self.request_params)
def test_params_validation_incorrect(self):
self.request_params.update({"params": "str"})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
def test_request_args(self):
self.assertEqual(JSONRPC20Request("add").args, ())
self.assertEqual(JSONRPC20Request("add", []).args, ())
self.assertEqual(JSONRPC20Request("add", {"a": 1}).args, ())
self.assertEqual(JSONRPC20Request("add", [1, 2]).args, (1, 2))
def test_request_kwargs(self):
self.assertEqual(JSONRPC20Request("add").kwargs, {})
self.assertEqual(JSONRPC20Request("add", [1, 2]).kwargs, {})
self.assertEqual(JSONRPC20Request("add", {}).kwargs, {})
self.assertEqual(JSONRPC20Request("add", {"a": 1}).kwargs, {"a": 1})
def test_id_validation_string(self):
self.request_params.update({"_id": "id"})
JSONRPC20Request(**self.request_params)
def test_id_validation_int(self):
self.request_params.update({"_id": 0})
JSONRPC20Request(**self.request_params)
def test_id_validation_null(self):
self.request_params.update({"_id": "null"})
JSONRPC20Request(**self.request_params)
def test_id_validation_none(self):
self.request_params.update({"_id": None})
JSONRPC20Request(**self.request_params)
def test_id_validation_float(self):
self.request_params.update({"_id": 0.1})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
def test_id_validation_incorrect(self):
self.request_params.update({"_id": []})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
self.request_params.update({"_id": ()})
with self.assertRaises(ValueError):
JSONRPC20Request(**self.request_params)
def test_data_method_1(self):
r = JSONRPC20Request("add")
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": None,
})
def test_data_method_2(self):
r = JSONRPC20Request(method="add")
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": None,
})
def test_data_method_3(self):
r = JSONRPC20Request("add", None)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": None,
})
def test_data_params_1(self):
r = JSONRPC20Request("add", params=None, _id=None)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": None,
})
def test_data_params_2(self):
r = JSONRPC20Request("add", [])
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"params": [],
"id": None,
})
def test_data_params_3(self):
r = JSONRPC20Request("add", ())
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"params": [],
"id": None,
})
def test_data_params_4(self):
r = JSONRPC20Request("add", (1, 2))
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"params": [1, 2],
"id": None,
})
def test_data_params_5(self):
r = JSONRPC20Request("add", {"a": 0})
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"params": {"a": 0},
"id": None,
})
def test_data_id_1(self):
r = JSONRPC20Request("add", _id="null")
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": "null",
})
def test_data_id_1_notification(self):
r = JSONRPC20Request("add", _id="null", is_notification=True)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
})
def test_data_id_2(self):
r = JSONRPC20Request("add", _id=None)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": None,
})
def test_data_id_2_notification(self):
r = JSONRPC20Request("add", _id=None, is_notification=True)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
})
def test_data_id_3(self):
r = JSONRPC20Request("add", _id="id")
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": "id",
})
def test_data_id_3_notification(self):
r = JSONRPC20Request("add", _id="id", is_notification=True)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
})
def test_data_id_4(self):
r = JSONRPC20Request("add", _id=0)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
"id": 0,
})
def test_data_id_4_notification(self):
r = JSONRPC20Request("add", _id=0, is_notification=True)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"method": "add",
})
def test_is_notification(self):
r = JSONRPC20Request("add")
self.assertFalse(r.is_notification)
r = JSONRPC20Request("add", _id=None)
self.assertFalse(r.is_notification)
r = JSONRPC20Request("add", _id="null")
self.assertFalse(r.is_notification)
r = JSONRPC20Request("add", _id=0)
self.assertFalse(r.is_notification)
r = JSONRPC20Request("add", is_notification=True)
self.assertTrue(r.is_notification)
r = JSONRPC20Request("add", is_notification=True, _id=None)
self.assertTrue(r.is_notification)
self.assertNotIn("id", r.data)
r = JSONRPC20Request("add", is_notification=True, _id=0)
self.assertTrue(r.is_notification)
self.assertNotIn("id", r.data)
def test_set_unset_notification_keep_id(self):
r = JSONRPC20Request("add", is_notification=True, _id=0)
self.assertTrue(r.is_notification)
self.assertFalse("id" in r.data)
r.is_notification = False
self.assertFalse(r.is_notification)
self.assertTrue("id" in r.data)
self.assertEqual(r.data["id"], 0)
def test_serialize_method_1(self):
r = JSONRPC20Request("add")
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": None,
}, json.loads(r.json))
def test_serialize_method_2(self):
r = JSONRPC20Request(method="add")
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": None,
}, json.loads(r.json))
def test_serialize_method_3(self):
r = JSONRPC20Request("add", None)
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": None,
}, json.loads(r.json))
def test_serialize_params_1(self):
r = JSONRPC20Request("add", params=None, _id=None)
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": None,
}, json.loads(r.json))
def test_serialize_params_2(self):
r = JSONRPC20Request("add", [])
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"params": [],
"id": None,
}, json.loads(r.json))
def test_serialize_params_3(self):
r = JSONRPC20Request("add", ())
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"params": [],
"id": None,
}, json.loads(r.json))
def test_serialize_params_4(self):
r = JSONRPC20Request("add", (1, 2))
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"params": [1, 2],
"id": None,
}, json.loads(r.json))
def test_serialize_params_5(self):
r = JSONRPC20Request("add", {"a": 0})
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"params": {"a": 0},
"id": None,
}, json.loads(r.json))
def test_serialize_id_1(self):
r = JSONRPC20Request("add", _id="null")
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": "null",
}, json.loads(r.json))
def test_serialize_id_2(self):
r = JSONRPC20Request("add", _id=None)
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": None,
}, json.loads(r.json))
def test_serialize_id_3(self):
r = JSONRPC20Request("add", _id="id")
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": "id",
}, json.loads(r.json))
def test_serialize_id_4(self):
r = JSONRPC20Request("add", _id=0)
self.assertTrue({
"jsonrpc": "2.0",
"method": "add",
"id": 0,
}, json.loads(r.json))
def test_from_json_request_no_id(self):
str_json = json.dumps({
"method": "add",
"params": [1, 2],
"jsonrpc": "2.0",
})
request = JSONRPC20Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC20Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, [1, 2])
self.assertEqual(request._id, None)
self.assertTrue(request.is_notification)
def test_from_json_request_no_params(self):
str_json = json.dumps({
"method": "add",
"jsonrpc": "2.0",
})
request = JSONRPC20Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC20Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, None)
self.assertEqual(request._id, None)
self.assertTrue(request.is_notification)
def test_from_json_request_null_id(self):
str_json = json.dumps({
"method": "add",
"jsonrpc": "2.0",
"id": None,
})
request = JSONRPC20Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC20Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, None)
self.assertEqual(request._id, None)
self.assertFalse(request.is_notification)
def test_from_json_request(self):
str_json = json.dumps({
"method": "add",
"params": [0, 1],
"jsonrpc": "2.0",
"id": "id",
})
request = JSONRPC20Request.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPC20Request))
self.assertEqual(request.method, "add")
self.assertEqual(request.params, [0, 1])
self.assertEqual(request._id, "id")
self.assertFalse(request.is_notification)
def test_from_json_invalid_request_jsonrpc(self):
str_json = json.dumps({
"method": "add",
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC20Request.from_json(str_json)
def test_from_json_invalid_request_method(self):
str_json = json.dumps({
"jsonrpc": "2.0",
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC20Request.from_json(str_json)
def test_from_json_invalid_request_extra_data(self):
str_json = json.dumps({
"jsonrpc": "2.0",
"method": "add",
"is_notification": True,
})
with self.assertRaises(JSONRPCInvalidRequestException):
JSONRPC20Request.from_json(str_json)
def test_data_setter(self):
request = JSONRPC20Request(**self.request_params)
with self.assertRaises(ValueError):
request.data = []
with self.assertRaises(ValueError):
request.data = ""
with self.assertRaises(ValueError):
request.data = None
class TestJSONRPC20BatchRequest(unittest.TestCase):
""" Test JSONRPC20BatchRequest functionality."""
def test_batch_request(self):
request = JSONRPC20BatchRequest(
JSONRPC20Request("devide", {"num": 1, "denom": 2}, _id=1),
JSONRPC20Request("devide", {"num": 3, "denom": 2}, _id=2),
)
self.assertEqual(json.loads(request.json), [
{"method": "devide", "params": {"num": 1, "denom": 2}, "id": 1,
"jsonrpc": "2.0"},
{"method": "devide", "params": {"num": 3, "denom": 2}, "id": 2,
"jsonrpc": "2.0"},
])
def test_from_json_batch(self):
str_json = json.dumps([
{"method": "add", "params": [1, 2], "jsonrpc": "2.0"},
{"method": "mul", "params": [1, 2], "jsonrpc": "2.0"},
])
requests = JSONRPC20BatchRequest.from_json(str_json)
self.assertTrue(isinstance(requests, JSONRPC20BatchRequest))
for r in requests:
self.assertTrue(isinstance(r, JSONRPC20Request))
self.assertTrue(r.method in ["add", "mul"])
self.assertEqual(r.params, [1, 2])
self.assertEqual(r._id, None)
self.assertTrue(r.is_notification)
def test_from_json_batch_one(self):
str_json = json.dumps([
{"method": "add", "params": [1, 2], "jsonrpc": "2.0", "id": None},
])
requests = JSONRPC20Request.from_json(str_json)
self.assertTrue(isinstance(requests, JSONRPC20BatchRequest))
requests = list(requests)
self.assertEqual(len(requests), 1)
r = requests[0]
self.assertTrue(isinstance(r, JSONRPC20Request))
self.assertEqual(r.method, "add")
self.assertEqual(r.params, [1, 2])
self.assertEqual(r._id, None)
self.assertFalse(r.is_notification)
def test_response_iterator(self):
requests = JSONRPC20BatchRequest(
JSONRPC20Request("devide", {"num": 1, "denom": 2}, _id=1),
JSONRPC20Request("devide", {"num": 3, "denom": 2}, _id=2),
)
for request in requests:
self.assertTrue(isinstance(request, JSONRPC20Request))
self.assertEqual(request.method, "devide")
class TestJSONRPC20Response(unittest.TestCase):
""" Test JSONRPC20Response functionality."""
def setUp(self):
self.response_success_params = {
"result": "",
"_id": 1,
}
self.response_error_params = {
"error": {
"code": 1,
"message": "error",
},
"_id": 1,
}
def test_correct_init(self):
""" Test object is created."""
JSONRPC20Response(**self.response_success_params)
def test_validation_incorrect_no_parameters(self):
with self.assertRaises(ValueError):
JSONRPC20Response()
def test_validation_incorrect_result_and_error(self):
response = JSONRPC20Response(error={"code": 1, "message": ""})
with self.assertRaises(ValueError):
response.result = ""
def test_validation_error_correct(self):
JSONRPC20Response(**self.response_error_params)
def test_validation_error_incorrect(self):
self.response_error_params["error"].update({"code": "str"})
with self.assertRaises(ValueError):
JSONRPC20Response(**self.response_error_params)
def test_validation_error_incorrect_no_code(self):
del self.response_error_params["error"]["code"]
with self.assertRaises(ValueError):
JSONRPC20Response(**self.response_error_params)
def test_validation_error_incorrect_no_message(self):
del self.response_error_params["error"]["message"]
with self.assertRaises(ValueError):
JSONRPC20Response(**self.response_error_params)
def test_validation_error_incorrect_message_not_str(self):
self.response_error_params["error"].update({"message": 0})
with self.assertRaises(ValueError):
JSONRPC20Response(**self.response_error_params)
def test_validation_id(self):
response = JSONRPC20Response(**self.response_success_params)
self.assertEqual(response._id, self.response_success_params["_id"])
def test_validation_id_incorrect_type(self):
response = JSONRPC20Response(**self.response_success_params)
with self.assertRaises(ValueError):
response._id = []
with self.assertRaises(ValueError):
response._id = {}
with self.assertRaises(ValueError):
response._id = 0.1
def test_data_result(self):
r = JSONRPC20Response(result="")
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"result": "",
"id": None,
})
def test_data_result_id_none(self):
r = JSONRPC20Response(result="", _id=None)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"result": "",
"id": None,
})
def test_data_result_id(self):
r = JSONRPC20Response(result="", _id=0)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"result": "",
"id": 0,
})
def test_data_error(self):
r = JSONRPC20Response(error={"code": 0, "message": ""})
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"error": {
"code": 0,
"message": "",
},
"id": None,
})
def test_data_error_id_none(self):
r = JSONRPC20Response(error={"code": 0, "message": ""}, _id=None)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"error": {
"code": 0,
"message": "",
},
"id": None,
})
def test_data_error_id(self):
r = JSONRPC20Response(error={"code": 0, "message": ""}, _id=0)
self.assertEqual(json.loads(r.json), r.data)
self.assertEqual(r.data, {
"jsonrpc": "2.0",
"error": {
"code": 0,
"message": "",
},
"id": 0,
})
def test_data_setter(self):
response = JSONRPC20Response(**self.response_success_params)
with self.assertRaises(ValueError):
response.data = []
with self.assertRaises(ValueError):
response.data = ""
with self.assertRaises(ValueError):
response.data = None
class TestJSONRPC20BatchResponse(unittest.TestCase):
""" Test JSONRPC20BatchResponse functionality."""
def test_batch_response(self):
response = JSONRPC20BatchResponse(
JSONRPC20Response(result="result", _id=1),
JSONRPC20Response(error={"code": 0, "message": ""}, _id=2),
)
self.assertEqual(json.loads(response.json), [
{"result": "result", "id": 1, "jsonrpc": "2.0"},
{"error": {"code": 0, "message": ""}, "id": 2, "jsonrpc": "2.0"},
])
def test_response_iterator(self):
responses = JSONRPC20BatchResponse(
JSONRPC20Response(result="result", _id=1),
JSONRPC20Response(result="result", _id=2),
)
for response in responses:
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.result, "result")
def test_batch_response_data(self):
response = JSONRPC20BatchResponse(
JSONRPC20Response(result="result", _id=1),
JSONRPC20Response(result="result", _id=2),
JSONRPC20Response(result="result"),
)
self.assertEqual(response.data, [
{"id": 1, "jsonrpc": "2.0", "result": "result"},
{"id": 2, "jsonrpc": "2.0", "result": "result"},
{"id": None, "jsonrpc": "2.0", "result": "result"},
])
@@ -0,0 +1,150 @@
import json
import sys
from ..exceptions import (
JSONRPCError,
JSONRPCInternalError,
JSONRPCInvalidParams,
JSONRPCInvalidRequest,
JSONRPCMethodNotFound,
JSONRPCParseError,
JSONRPCServerError,
JSONRPCDispatchException,
)
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPCError(unittest.TestCase):
def setUp(self):
self.error_params = {
"code": 0,
"message": "",
}
def test_correct_init(self):
""" Test object is created."""
JSONRPCError(**self.error_params)
def test_validation_incorrect_no_parameters(self):
with self.assertRaises(ValueError):
JSONRPCError()
def test_code_validation_int(self):
self.error_params.update({"code": 32000})
JSONRPCError(**self.error_params)
def test_code_validation_no_code(self):
del self.error_params["code"]
with self.assertRaises(ValueError):
JSONRPCError(**self.error_params)
def test_code_validation_str(self):
self.error_params.update({"code": "0"})
with self.assertRaises(ValueError):
JSONRPCError(**self.error_params)
def test_message_validation_str(self):
self.error_params.update({"message": ""})
JSONRPCError(**self.error_params)
def test_message_validation_none(self):
del self.error_params["message"]
with self.assertRaises(ValueError):
JSONRPCError(**self.error_params)
def test_message_validation_int(self):
self.error_params.update({"message": 0})
with self.assertRaises(ValueError):
JSONRPCError(**self.error_params)
def test_data_validation_none(self):
self.error_params.update({"data": None})
JSONRPCError(**self.error_params)
def test_data_validation(self):
self.error_params.update({"data": {}})
JSONRPCError(**self.error_params)
self.error_params.update({"data": ""})
JSONRPCError(**self.error_params)
def test_json(self):
error = JSONRPCError(**self.error_params)
self.assertEqual(
json.loads(error.json),
self.error_params,
)
def test_from_json(self):
str_json = json.dumps({
"code": 0,
"message": "",
"data": {},
})
request = JSONRPCError.from_json(str_json)
self.assertTrue(isinstance(request, JSONRPCError))
self.assertEqual(request.code, 0)
self.assertEqual(request.message, "")
self.assertEqual(request.data, {})
class TestJSONRPCParseError(unittest.TestCase):
def test_code_message(self):
error = JSONRPCParseError()
self.assertEqual(error.code, -32700)
self.assertEqual(error.message, "Parse error")
self.assertEqual(error.data, None)
class TestJSONRPCServerError(unittest.TestCase):
def test_code_message(self):
error = JSONRPCServerError()
self.assertEqual(error.code, -32000)
self.assertEqual(error.message, "Server error")
self.assertEqual(error.data, None)
class TestJSONRPCInternalError(unittest.TestCase):
def test_code_message(self):
error = JSONRPCInternalError()
self.assertEqual(error.code, -32603)
self.assertEqual(error.message, "Internal error")
self.assertEqual(error.data, None)
class TestJSONRPCInvalidParams(unittest.TestCase):
def test_code_message(self):
error = JSONRPCInvalidParams()
self.assertEqual(error.code, -32602)
self.assertEqual(error.message, "Invalid params")
self.assertEqual(error.data, None)
class TestJSONRPCInvalidRequest(unittest.TestCase):
def test_code_message(self):
error = JSONRPCInvalidRequest()
self.assertEqual(error.code, -32600)
self.assertEqual(error.message, "Invalid Request")
self.assertEqual(error.data, None)
class TestJSONRPCMethodNotFound(unittest.TestCase):
def test_code_message(self):
error = JSONRPCMethodNotFound()
self.assertEqual(error.code, -32601)
self.assertEqual(error.message, "Method not found")
self.assertEqual(error.data, None)
class TestJSONRPCDispatchException(unittest.TestCase):
def test_code_message(self):
error = JSONRPCDispatchException(message="message",
code=400, data={"param": 1})
self.assertEqual(error.error.code, 400)
self.assertEqual(error.error.message, "message")
self.assertEqual(error.error.data, {"param": 1})
+175
View File
@@ -0,0 +1,175 @@
import sys
from ..manager import JSONRPCResponseManager
from ..jsonrpc2 import (
JSONRPC20BatchRequest,
JSONRPC20BatchResponse,
JSONRPC20Request,
JSONRPC20Response,
)
from ..jsonrpc1 import JSONRPC10Request, JSONRPC10Response
from ..exceptions import JSONRPCDispatchException
if sys.version_info < (3, 3):
from mock import MagicMock
else:
from unittest.mock import MagicMock
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPCResponseManager(unittest.TestCase):
def setUp(self):
def raise_(e):
raise e
self.long_time_method = MagicMock()
self.dispatcher = {
"add": sum,
"multiply": lambda a, b: a * b,
"list_len": len,
"101_base": lambda **kwargs: int("101", **kwargs),
"error": lambda: raise_(KeyError("error_explanation")),
"type_error": lambda: raise_(TypeError("TypeError inside method")),
"long_time_method": self.long_time_method,
"dispatch_error": lambda x: raise_(
JSONRPCDispatchException(code=4000, message="error",
data={"param": 1})),
}
def test_dispatch_error(self):
request = JSONRPC20Request("dispatch_error", ["test"], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "error")
self.assertEqual(response.error["code"], 4000)
self.assertEqual(response.error["data"], {"param": 1})
def test_returned_type_response(self):
request = JSONRPC20Request("add", [[]], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
def test_returned_type_butch_response(self):
request = JSONRPC20BatchRequest(
JSONRPC20Request("add", [[]], _id=0))
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20BatchResponse))
def test_returned_type_response_rpc10(self):
request = JSONRPC10Request("add", [[]], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC10Response))
def test_parse_error(self):
req = '{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Parse error")
self.assertEqual(response.error["code"], -32700)
def test_invalid_request(self):
req = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
response = JSONRPCResponseManager.handle(req, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid Request")
self.assertEqual(response.error["code"], -32600)
def test_method_not_found(self):
request = JSONRPC20Request("does_not_exist", [[]], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Method not found")
self.assertEqual(response.error["code"], -32601)
def test_invalid_params(self):
request = JSONRPC20Request("add", {"a": 0}, _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
self.assertIn(response.error["data"]["message"], [
'sum() takes no keyword arguments',
"sum() got an unexpected keyword argument 'a'",
])
def test_invalid_params_custom_function(self):
request = JSONRPC20Request("multiply", [0], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
request = JSONRPC20Request("multiply", [0, 1, 2], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
request = JSONRPC20Request("multiply", {"a": 1}, _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
request = JSONRPC20Request("multiply", {"a": 1, "b": 2, "c": 3}, _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
def test_server_error(self):
request = JSONRPC20Request("error", _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Server error")
self.assertEqual(response.error["code"], -32000)
self.assertEqual(response.error["data"]['type'], "KeyError")
self.assertEqual(
response.error["data"]['args'], ('error_explanation',))
self.assertEqual(
response.error["data"]['message'], "'error_explanation'")
def test_notification_calls_method(self):
request = JSONRPC20Request("long_time_method", is_notification=True)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertEqual(response, None)
self.long_time_method.assert_called_once_with()
def test_notification_does_not_return_error_does_not_exist(self):
request = JSONRPC20Request("does_not_exist", is_notification=True)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertEqual(response, None)
def test_notification_does_not_return_error_invalid_params(self):
request = JSONRPC20Request("add", {"a": 0}, is_notification=True)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertEqual(response, None)
def test_notification_does_not_return_error(self):
request = JSONRPC20Request("error", is_notification=True)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertEqual(response, None)
def test_type_error_inside_method(self):
request = JSONRPC20Request("type_error", _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Server error")
self.assertEqual(response.error["code"], -32000)
self.assertEqual(response.error["data"]['type'], "TypeError")
self.assertEqual(
response.error["data"]['args'], ('TypeError inside method',))
self.assertEqual(
response.error["data"]['message'], 'TypeError inside method')
def test_invalid_params_before_dispatcher_error(self):
request = JSONRPC20Request(
"dispatch_error", ["invalid", "params"], _id=0)
response = JSONRPCResponseManager.handle(request.json, self.dispatcher)
self.assertTrue(isinstance(response, JSONRPC20Response))
self.assertEqual(response.error["message"], "Invalid params")
self.assertEqual(response.error["code"], -32602)
+28
View File
@@ -0,0 +1,28 @@
from ..manager import JSONRPCResponseManager
import sys
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONRPCResponseManager(unittest.TestCase):
@unittest.skipIf(sys.version_info < (3, 5), "Test Py3.5+ functionality")
def test_typeerror_with_annotations(self):
"""If a function has Python3 annotations and is called with improper
arguments, make sure the framework doesn't fail with inspect.getargspec
"""
from .py35_utils import distance
dispatcher = {
"distance": distance,
}
req = '{"jsonrpc": "2.0", "method": "distance", "params": [], "id": 1}'
result = JSONRPCResponseManager.handle(req, dispatcher)
# Make sure this returns JSONRPCInvalidParams rather than raising
# UnboundLocalError
self.assertEqual(result.error['code'], -32602)
+130
View File
@@ -0,0 +1,130 @@
""" Test utility functionality."""
from ..utils import JSONSerializable, DatetimeDecimalEncoder, is_invalid_params
import datetime
import decimal
import json
import sys
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
class TestJSONSerializable(unittest.TestCase):
""" Test JSONSerializable functionality."""
def setUp(self):
class A(JSONSerializable):
@property
def json(self):
pass
self._class = A
def test_abstract_class(self):
with self.assertRaises(TypeError):
JSONSerializable()
self._class()
def test_definse_serialize_deserialize(self):
""" Test classmethods of inherited class."""
self.assertEqual(self._class.serialize({}), "{}")
self.assertEqual(self._class.deserialize("{}"), {})
def test_from_json(self):
self.assertTrue(isinstance(self._class.from_json('{}'), self._class))
def test_from_json_incorrect(self):
with self.assertRaises(ValueError):
self._class.from_json('[]')
class TestDatetimeDecimalEncoder(unittest.TestCase):
""" Test DatetimeDecimalEncoder functionality."""
def test_date_encoder(self):
obj = datetime.date.today()
with self.assertRaises(TypeError):
json.dumps(obj)
self.assertEqual(
json.dumps(obj, cls=DatetimeDecimalEncoder),
'"{0}"'.format(obj.isoformat()),
)
def test_datetime_encoder(self):
obj = datetime.datetime.now()
with self.assertRaises(TypeError):
json.dumps(obj)
self.assertEqual(
json.dumps(obj, cls=DatetimeDecimalEncoder),
'"{0}"'.format(obj.isoformat()),
)
def test_decimal_encoder(self):
obj = decimal.Decimal('0.1')
with self.assertRaises(TypeError):
json.dumps(obj)
result = json.dumps(obj, cls=DatetimeDecimalEncoder)
self.assertTrue(isinstance(result, str))
self.assertEqual(float(result), float(0.1))
def test_default(self):
encoder = DatetimeDecimalEncoder()
with patch.object(json.JSONEncoder, 'default') as json_default:
encoder.default("")
self.assertEqual(json_default.call_count, 1)
class TestUtils(unittest.TestCase):
""" Test utils functions."""
def test_is_invalid_params_builtin(self):
self.assertTrue(is_invalid_params(sum, 0, 0))
# NOTE: builtin functions could not be recognized by inspect.isfunction
# It would raise TypeError if parameters are incorrect already.
# self.assertFalse(is_invalid_params(sum, [0, 0])) # <- fails
def test_is_invalid_params_args(self):
self.assertTrue(is_invalid_params(lambda a, b: None, 0))
self.assertTrue(is_invalid_params(lambda a, b: None, 0, 1, 2))
def test_is_invalid_params_kwargs(self):
self.assertTrue(is_invalid_params(lambda a: None, **{}))
self.assertTrue(is_invalid_params(lambda a: None, **{"a": 0, "b": 1}))
def test_invalid_params_correct(self):
self.assertFalse(is_invalid_params(lambda: None))
self.assertFalse(is_invalid_params(lambda a: None, 0))
self.assertFalse(is_invalid_params(lambda a, b=0: None, 0))
self.assertFalse(is_invalid_params(lambda a, b=0: None, 0, 0))
def test_is_invalid_params_mixed(self):
self.assertFalse(is_invalid_params(lambda a, b: None, 0, **{"b": 1}))
self.assertFalse(is_invalid_params(
lambda a, b, c=0: None, 0, **{"b": 1}))
def test_is_invalid_params_py2(self):
with patch('jsonrpc.utils.sys') as mock_sys:
mock_sys.version_info = (2, 7)
with patch('jsonrpc.utils.is_invalid_params_py2') as mock_func:
is_invalid_params(lambda a: None, 0)
assert mock_func.call_count == 1