mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-08-19 15:13:42 +08:00
Merge pyextra subtree
This commit is contained in:
@@ -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))
|
||||
@@ -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
|
||||
@@ -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}'
|
||||
))
|
||||
@@ -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))
|
||||
@@ -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
|
||||
))
|
||||
@@ -0,0 +1 @@
|
||||
""" Tets base JSON-RPC structures."""
|
||||
@@ -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"])
|
||||
@@ -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})
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user