Skip to content

Commit 01fbcb9

Browse files
committed
More tests added
1 parent b00beaf commit 01fbcb9

File tree

2 files changed

+106
-59
lines changed

2 files changed

+106
-59
lines changed

pyjsonrpclite/jsonrpc.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def defaultJsonEncode(o):
2323
class JsonRpcMessage(object):
2424

2525
@classmethod
26-
def Request(cls, id, method, params):
26+
def Request(cls, id, method, params = None):
2727
return JsonRpcRequest(id, method, params)
2828

2929
@classmethod
@@ -122,19 +122,26 @@ def SubIsMethodCorrect(jsondict):
122122

123123
def SubValidateHeader(jsondict):
124124
'''Parses header and validate values.
125-
Returns True or raises JsonRpcException in case of error'''
125+
Raises JsonRpcException in case of error'''
126126
if not 'jsonrpc' in jsondict:
127127
raise JsonRpcException('Message have no "jsonrpc" field')
128128
if jsondict['jsonrpc'] <> '2.0':
129-
raise JsonRpcException('"jsonrpc" field value should be 2.0')
130-
return True
129+
raise JsonRpcException('"jsonrpc" field value should be 2.0')
131130

132-
def SubValidateMethod(jsondict):
131+
def SubValidateMethod(jsondict):
132+
'''Checks if method field exists and has correct value'''
133133
if not SubHasMethod(jsondict):
134134
raise JsonRpcException('No "method" field')
135135
if not SubIsMethodCorrect(jsondict):
136-
raise JsonRpcException('Invalid "method" field value')
137-
return True
136+
raise JsonRpcException('Invalid "method" field value')
137+
138+
def SubValidateErrorObj(errdict):
139+
'''Checks if Error object has JSON-RPC 2.0 required fields. '''
140+
hasCode = 'code' in errdict
141+
hasMessage = 'message' in errdict
142+
if not (hasCode and hasMessage):
143+
raise JsonRpcException('Invalid JSON-RPC 2.0 Error object structure')
144+
return True
138145

139146
def SubParseJsonRpcObject(jsondict):
140147
'''Check if jsondict is valid JSON-RPC 2.0 object.
@@ -149,15 +156,15 @@ def SubParseJsonRpcObject(jsondict):
149156
try:
150157
SubValidateMethod(jsondict)
151158
data = JsonRpcMessage.Notification(jsondict['method'], \
152-
jsondict['params'])
159+
jsondict.get('params', None))
153160
return JsonRpcParsed(JsonRpcParsedType.NOTIFICATION, data)
154161
except JsonRpcException as e:
155162
raise JsonRpcParseError(JsonRpcError.InvalidRequest(str(e)))
156163
#else it has Id so it may be: request, success, error message
157164
isRequest = SubIsMethodCorrect(jsondict)
158165
if isRequest:
159166
data = JsonRpcMessage.Request(jsondict['id'], \
160-
jsondict['method'], jsondict['params'])
167+
jsondict['method'], jsondict.get('params', None))
161168
return JsonRpcParsed(JsonRpcParsedType.REQUEST, data)
162169
# no METHOD field so it may be: success, error message
163170

@@ -168,11 +175,15 @@ def SubParseJsonRpcObject(jsondict):
168175

169176
isErrorMsg = 'error' in jsondict
170177
if isErrorMsg:
171-
err = jsondict['error']
172-
errorobj = JsonRpcError(err['code'], err['message'], \
173-
err['data'])
174-
data = JsonRpcMessage.Error(jsondict['id'], errorobj)
175-
return JsonRpcParsed(JsonRpcParsedType.ERROR, data)
178+
err = jsondict['error']
179+
try:
180+
SubValidateErrorObj(err)
181+
errorobj = JsonRpcError(err['code'], err['message'], \
182+
err.get('data', None))
183+
data = JsonRpcMessage.Error(jsondict['id'], errorobj)
184+
return JsonRpcParsed(JsonRpcParsedType.ERROR, data)
185+
except JsonRpcException as e:
186+
raise JsonRpcParseError(JsonRpcError.InvalidParams(str(e)))
176187
# no result, no error - id only
177188
raise JsonRpcParseError(
178189
JsonRpcError.InvalidRequest('No reqired fields'))

tests/test_jsonrpc.py

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,47 +23,57 @@ def setUp(self):
2323
def tearDown(self):
2424
pass
2525

26-
def testJsonRpcMessageRequestCorrect(self):
26+
def testJsonRpcMessageRequestCorrect(self):
2727
expected = JsonRpcRequest(1, 'login', ['user', 'password'])
2828
actual = JsonRpcMessage.Request(1, 'login', ['user', 'password'])
29-
testutils.assertEqualObjects(expected, actual)
29+
testutils.assertEqualObjects(expected, actual)
30+
31+
def testJsonRpcMessageRequestNoParamsCorrect(self):
32+
expected = JsonRpcRequest(1, 'login')
33+
actual = JsonRpcMessage.Request(1, 'login')
34+
testutils.assertEqualObjects(expected, actual)
3035

31-
def testJsonRpcMessageNotificationCorrect(self):
36+
def testJsonRpcMessageNotificationCorrect(self):
3237
expected = JsonRpcNotification('alarm', ['a','b'])
3338
actual = JsonRpcMessage.Notification('alarm', ['a','b'])
34-
testutils.assertEqualObjects(expected, actual)
39+
testutils.assertEqualObjects(expected, actual)
40+
41+
def testJsonRpcMessageNotificationNoParamsCorrect(self):
42+
expected = JsonRpcNotification('alarm')
43+
actual = JsonRpcMessage.Notification('alarm')
44+
testutils.assertEqualObjects(expected, actual)
3545

36-
def testJsonRpcMessageSuccessCorrect(self):
46+
def testJsonRpcMessageSuccessCorrect(self):
3747
expected = JsonRpcSuccessResponse(1, 1107)
3848
actual = JsonRpcMessage.Success(1, 1107)
39-
testutils.assertEqualObjects(expected, actual)
49+
testutils.assertEqualObjects(expected, actual)
4050

41-
def testJsonRpcMessageErrorCorrect(self):
51+
def testJsonRpcMessageErrorCorrect(self):
4252
expected = JsonRpcErrorResponse(1, JsonRpcError(-32001, 'Err MSG', [105, 106]))
4353
actual = JsonRpcMessage.Error(1, JsonRpcError(-32001, 'Err MSG', [105, 106]))
4454
testutils.assertEqualObjects(expected, actual)
4555

46-
def testJsonRpcMessageAsJsonCorrect(self):
56+
def testJsonRpcMessageAsJsonCorrect(self):
4757
expected = '{\n"id": 1,\n"method": "login",\n"params": [\n"user",\n"password"\n]\n}'
4858

4959
msg = JsonRpcMessage.Request(1, 'login', ['user', 'password'])
50-
actual = JsonRpcMessage.AsJson(msg, indent=False, escape=True)
51-
self.assertEqual(expected, actual)
60+
actual = JsonRpcMessage.AsJson(msg, indent=False, escape=True)
61+
self.assertEqual(expected, actual)
5262

5363
def testJsonRpcRequestCorrect(self):
5464
'''Checks object inheritance, structure, init'''
55-
msg = JsonRpcRequest(1, 'methodName', 'params')
65+
msg = JsonRpcRequest(1, 'methodName', 'params')
5666
self.assertTrue(isinstance(msg, JsonRpcMessage))
5767
self.assertTrue(hasattr(msg, 'id'))
5868
self.assertTrue(hasattr(msg, 'method'))
5969
self.assertTrue(hasattr(msg, 'params'))
6070
self.assertEqual(1, msg.id)
6171
self.assertEqual('methodName', msg.method)
62-
self.assertEqual('params', msg.params)
72+
self.assertEqual('params', msg.params)
6373

6474
def testJsonRpcNotificationCorrect(self):
6575
'''Checks object inheritance, structure, init'''
66-
msg = JsonRpcNotification('ntfName', 'params')
76+
msg = JsonRpcNotification('ntfName', 'params')
6777
self.assertTrue(isinstance(msg, JsonRpcRequest))
6878
self.assertTrue(hasattr(msg, 'id'))
6979
self.assertTrue(hasattr(msg, 'method'))
@@ -72,28 +82,28 @@ def testJsonRpcNotificationCorrect(self):
7282
self.assertEqual('ntfName', msg.method)
7383
self.assertEqual('params', msg.params)
7484

75-
def testJsonRpcSuccessResponseCorrect(self):
85+
def testJsonRpcSuccessResponseCorrect(self):
7686
'''Checks object inheritance, structure, init'''
77-
msg = JsonRpcSuccessResponse(1, 'result-value')
87+
msg = JsonRpcSuccessResponse(1, 'result-value')
7888
self.assertTrue(isinstance(msg, JsonRpcMessage))
7989
self.assertTrue(hasattr(msg, 'id'))
8090
self.assertTrue(hasattr(msg, 'result'))
8191
self.assertEqual(1, msg.id)
8292
self.assertEqual('result-value', msg.result)
8393

84-
def testJsonRpcErrorResponseCorrect(self):
94+
def testJsonRpcErrorResponseCorrect(self):
8595
'''Checks object inheritance, structure, init'''
86-
msg = JsonRpcErrorResponse(1, JsonRpcError(-32000, 'TestError', 'Error-data'))
96+
msg = JsonRpcErrorResponse(1, JsonRpcError(-32000, 'TestError', 'Error-data'))
8797
self.assertTrue(isinstance(msg, JsonRpcMessage))
8898
self.assertTrue(hasattr(msg, 'id'))
89-
self.assertTrue(hasattr(msg, 'error'))
99+
self.assertTrue(hasattr(msg, 'error'))
90100
self.assertTrue(isinstance(msg.error, JsonRpcError))
91101
self.assertEqual(1, msg.id)
92102
self.assertEqual(msg.error.code, -32000)
93103
self.assertEqual(msg.error.message, 'TestError')
94104
self.assertEqual(msg.error.data, 'Error-data')
95105

96-
def testParseRequest(self):
106+
def testParseRequest(self):
97107
'''Checks if JSON-RPC 2.0 Request object parsed correct'''
98108
testReqJson = '''
99109
{
@@ -104,11 +114,11 @@ def testParseRequest(self):
104114
}'''
105115
expected = JsonRpcParsed(JsonRpcParsedType.REQUEST, \
106116
JsonRpcRequest(521, 'sum', { "param1": 1, "param2": 2 })
107-
)
117+
)
108118
actual = JsonRpcParsed.Parse(testReqJson)
109119
testutils.assertEqualObjects(expected, actual)
110120

111-
def testParseNotificationReq(self):
121+
def testParseNotificationReq(self):
112122
'''Checks if JSON-RPC 2.0 Notification object parsed correct'''
113123
testReqJson = '''
114124
{
@@ -118,11 +128,11 @@ def testParseNotificationReq(self):
118128
}'''
119129
expected = JsonRpcParsed(JsonRpcParsedType.NOTIFICATION, \
120130
JsonRpcNotification('alarmAdd', { "param1": 1, "param2": 2 })
121-
)
131+
)
122132
actual = JsonRpcParsed.Parse(testReqJson)
123133
testutils.assertEqualObjects(expected, actual)
124134

125-
def testParseSuccessRes(self):
135+
def testParseSuccessRes(self):
126136
'''Checks if JSON-RPC 2.0 Success object parsed correct'''
127137
testReqJson = '''
128138
{
@@ -132,11 +142,11 @@ def testParseSuccessRes(self):
132142
}'''
133143
expected = JsonRpcParsed(JsonRpcParsedType.SUCCESS, \
134144
JsonRpcSuccessResponse(521, 3)
135-
)
145+
)
136146
actual = JsonRpcParsed.Parse(testReqJson)
137147
testutils.assertEqualObjects(expected, actual)
138148

139-
def testParseErrorObj(self):
149+
def testParseErrorObj(self):
140150
'''Checks if JSON-RPC 2.0 Error object parsed correct'''
141151
testReqJson = '''
142152
{
@@ -151,19 +161,19 @@ def testParseErrorObj(self):
151161
rpcerror = JsonRpcError.MethodNotFound('No method called [sum]')
152162
expected = JsonRpcParsed(JsonRpcParsedType.ERROR, \
153163
JsonRpcErrorResponse(521, rpcerror)
154-
)
164+
)
155165
actual = JsonRpcParsed.Parse(testReqJson)
156166
testutils.assertEqualObjects(expected, actual)
157167

158-
def testParseReturnsParseError(self):
168+
def testParseReturnsParseError(self):
159169
'''Parse found invalid json'''
160170
'''testReqJson = """{INVALID_JSON}"""
161171
rpcerror = JsonRpcErrorResponse(None,JsonRpcError.ParseError('{INVALID_JSON}'))
162-
expected = JsonRpcParsed(JsonRpcParsedType.INVALID, rpcerror)
172+
expected = JsonRpcParsed(JsonRpcParsedType.INVALID, rpcerror)
163173
actual = JsonRpcParsed.Parse(testReqJson)
164174
testutils.assertEqualObjects(expected, actual)'''
165175

166-
def testParseInvalidHeader1(self):
176+
def testParseInvalidHeader1(self):
167177
'''Parse found JSON-PRC message without jsonrpc field'''
168178

169179
testReqJson = '''{
@@ -175,12 +185,12 @@ def testParseInvalidHeader1(self):
175185
},
176186
"id": 521
177187
}'''
178-
with self.assertRaises(JsonRpcParseError) as context:
179-
JsonRpcParsed.Parse(testReqJson)
180-
expectedErr = JsonRpcError.InvalidRequest('Message have no "jsonrpc" field')
181-
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
188+
with self.assertRaises(JsonRpcParseError)as context:
189+
JsonRpcParsed.Parse(testReqJson)
190+
expectedErr = JsonRpcError.InvalidRequest('Message have no "jsonrpc" field')
191+
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
182192

183-
def testParseInvalidHeader2(self):
193+
def testParseInvalidHeader2(self):
184194
'''Parse found JSON-PRC message jsonrpc wrong version'''
185195

186196
testReqJson = '''{
@@ -192,32 +202,58 @@ def testParseInvalidHeader2(self):
192202
},
193203
"id": 521
194204
}'''
195-
with self.assertRaises(JsonRpcParseError) as context:
196-
JsonRpcParsed.Parse(testReqJson)
197-
expectedErr = JsonRpcError.InvalidRequest('"jsonrpc" field value should be 2.0')
205+
with self.assertRaises(JsonRpcParseError)as context:
206+
JsonRpcParsed.Parse(testReqJson)
207+
expectedErr = JsonRpcError.InvalidRequest('"jsonrpc" field value should be 2.0')
198208
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
199209

200-
def testParseInvalidNotifyReq1(self):
210+
def testParseInvalidNotifyReq1(self):
201211
'''Parse found JSON-PRC 2.0 Notify Request without method field'''
202212

203213
testReqJson = '''{
204214
"jsonrpc": "2.0"
205215
}'''
206-
with self.assertRaises(JsonRpcParseError) as context:
207-
JsonRpcParsed.Parse(testReqJson)
208-
expectedErr = JsonRpcError.InvalidRequest('No "method" field')
216+
with self.assertRaises(JsonRpcParseError)as context:
217+
JsonRpcParsed.Parse(testReqJson)
218+
expectedErr = JsonRpcError.InvalidRequest('No "method" field')
209219
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
210220

211-
def testParseInvalidNotifyReq2(self):
221+
def testParseInvalidNotifyReq2(self):
212222
'''Parse found JSON-PRC 2.0 Notify Request where method is null'''
213223

214224
testReqJson = '''{
215225
"jsonrpc": "2.0",
216226
"method": null
217227
}'''
218-
with self.assertRaises(JsonRpcParseError) as context:
219-
JsonRpcParsed.Parse(testReqJson)
220-
expectedErr = JsonRpcError.InvalidRequest('Invalid "method" field value')
228+
with self.assertRaises(JsonRpcParseError)as context:
229+
JsonRpcParsed.Parse(testReqJson)
230+
expectedErr = JsonRpcError.InvalidRequest('Invalid "method" field value')
231+
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
232+
233+
def testParseInvalidNotifyReq3(self):
234+
'''Parse found JSON-PRC 2.0 Notify Request where method is empty'''
235+
236+
testReqJson = '''{
237+
"jsonrpc": "2.0",
238+
"method": ""
239+
}'''
240+
with self.assertRaises(JsonRpcParseError)as context:
241+
JsonRpcParsed.Parse(testReqJson)
242+
expectedErr = JsonRpcError.InvalidRequest('Invalid "method" field value')
243+
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
244+
245+
def testParseInvalidErrorRes1(self):
246+
'''Parse found JSON-PRC 2.0 Response Error where error object has invalid structure.
247+
'''
248+
249+
testReqJson = '''{
250+
"jsonrpc": "2.0",
251+
"error": "",
252+
"id": 536
253+
}'''
254+
with self.assertRaises(JsonRpcParseError)as context:
255+
JsonRpcParsed.Parse(testReqJson)
256+
expectedErr = JsonRpcError.InvalidParams('Invalid JSON-RPC 2.0 Error object structure')
221257
testutils.assertEqualObjects(expectedErr, context.exception.rpcError)
222258

223259

0 commit comments

Comments
 (0)