Skip to content

Commit a0952a5

Browse files
committed
unit tests for JSON RPC
1 parent c63b53d commit a0952a5

File tree

4 files changed

+182
-8
lines changed

4 files changed

+182
-8
lines changed

src/odoolib/connector/json_rpc.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
##############################################################################
3232

3333
import json
34-
import logging
3534
import random
3635

3736
import requests
@@ -60,8 +59,7 @@ def __init__(self, hostname: str, port=8069, version="2.0"):
6059
:param hostname: The hostname of the computer holding the instance of Odoo.
6160
:param port: The port used by the Odoo instance for JsonRPC (default to 8069).
6261
"""
63-
super().__init__()
64-
self._logger = logging.getLogger(f"{self._logger.name}.jsonrpc")
62+
super(JsonRpcConnector, self).__init__()
6563
self.url: str = "http://%s:%d/jsonrpc" % (hostname, port)
6664
self.version = version
6765

src/odoolib/connector/json_rpcs.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#
3131
##############################################################################
3232

33-
import logging
34-
3533
from .json_rpc import JsonRpcConnector
3634

3735

@@ -49,6 +47,4 @@ def __init__(self, hostname: str, port=8069, version="2.0"):
4947
:param port: The port used by the Odoo instance for JsonRPC (default to 8069).
5048
"""
5149
super(JsonRpcsConnector, self).__init__(hostname, port, version)
52-
self._logger = logging.getLogger(
53-
f"{str.join('.', self._logger.name.split('.')[:-1])}.jsonrpcs"
54-
)
50+
self.url: str = "https://%s:%d/jsonrpc" % (hostname, port)

tests/test_json_rpc.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# -*- coding: utf-8 -*-
2+
##############################################################################
3+
#
4+
# Copyright (C) 2025 Jimmy McCann
5+
# All rights reserved.
6+
#
7+
# Redistribution and use in source and binary forms, with or without
8+
# modification, are permitted provided that the following conditions are met:
9+
#
10+
# 1. Redistributions of source code must retain the above copyright notice, this
11+
# list of conditions and the following disclaimer.
12+
# 2. Redistributions in binary form must reproduce the above copyright notice,
13+
# this list of conditions and the following disclaimer in the documentation
14+
# and/or other materials provided with the distribution.
15+
#
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
#
27+
##############################################################################
28+
29+
import json
30+
import unittest
31+
from unittest.mock import MagicMock, patch
32+
33+
from odoolib.connector import JsonRpcConnector, JsonRpcException
34+
35+
36+
class TestJsonRpcConnector(unittest.TestCase):
37+
def setUp(self):
38+
self.hostname = "localhost"
39+
self.port = 8069
40+
self.version = "2.0"
41+
self.connector = JsonRpcConnector(self.hostname, self.port, self.version)
42+
43+
def test_initialization(self):
44+
self.assertEqual(
45+
self.connector.url, f"http://{self.hostname}:{self.port}/jsonrpc"
46+
)
47+
self.assertEqual(self.connector.version, self.version)
48+
self.assertEqual(self.connector._logger.name, "odoolib.connector.jsonrpc")
49+
50+
@patch("odoolib.connector.json_rpc.requests.post")
51+
def test_send_success(self, mock_post):
52+
mock_response = MagicMock()
53+
mock_response.json.return_value = {"result": "mock_response"}
54+
mock_post.return_value = mock_response
55+
56+
response = self.connector.send("common", "some_method", "arg1", "arg2")
57+
58+
_, called_kwargs = mock_post.call_args
59+
sent_data = json.loads(
60+
called_kwargs["data"]
61+
) # Convert JSON string back to dictionary
62+
63+
# Verify all expected fields except 'id'
64+
self.assertEqual(sent_data["jsonrpc"], self.version)
65+
self.assertEqual(sent_data["method"], "call")
66+
self.assertEqual(
67+
sent_data["params"],
68+
{"service": "common", "method": "some_method", "args": ["arg1", "arg2"]},
69+
)
70+
71+
# Ensure 'id' exists and is an integer
72+
self.assertIn("id", sent_data)
73+
self.assertIsInstance(sent_data["id"], int)
74+
75+
self.assertEqual(response, "mock_response")
76+
77+
@patch("odoolib.connector.json_rpc.requests.post")
78+
def test_send_error(self, mock_post):
79+
mock_response = MagicMock()
80+
mock_response.json.return_value = {"error": "mock_error"}
81+
mock_post.return_value = mock_response
82+
83+
with self.assertRaises(JsonRpcException) as context:
84+
self.connector.send("common", "some_method", "arg1", "arg2")
85+
86+
self.assertEqual(str(context.exception), "'mock_error'")
87+
88+
89+
if __name__ == "__main__":
90+
unittest.main()

tests/test_json_rpcs.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# -*- coding: utf-8 -*-
2+
##############################################################################
3+
#
4+
# Copyright (C) 2025 Jimmy McCann
5+
# All rights reserved.
6+
#
7+
# Redistribution and use in source and binary forms, with or without
8+
# modification, are permitted provided that the following conditions are met:
9+
#
10+
# 1. Redistributions of source code must retain the above copyright notice, this
11+
# list of conditions and the following disclaimer.
12+
# 2. Redistributions in binary form must reproduce the above copyright notice,
13+
# this list of conditions and the following disclaimer in the documentation
14+
# and/or other materials provided with the distribution.
15+
#
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
#
27+
##############################################################################
28+
29+
import json
30+
import unittest
31+
from unittest.mock import MagicMock, patch
32+
33+
from odoolib.connector import JsonRpcException, JsonRpcsConnector
34+
35+
36+
class TestJsonRpcsConnector(unittest.TestCase):
37+
def setUp(self):
38+
self.hostname = "localhost"
39+
self.port = 8069
40+
self.version = "2.0"
41+
self.connector = JsonRpcsConnector(self.hostname, self.port, self.version)
42+
43+
def test_initialization(self):
44+
self.assertEqual(
45+
self.connector.url, f"https://{self.hostname}:{self.port}/jsonrpc"
46+
)
47+
self.assertEqual(self.connector.version, self.version)
48+
self.assertEqual(self.connector._logger.name, "odoolib.connector.jsonrpcs")
49+
50+
@patch("odoolib.connector.json_rpc.requests.post")
51+
def test_send_success(self, mock_post):
52+
mock_response = MagicMock()
53+
mock_response.json.return_value = {"result": "mock_response"}
54+
mock_post.return_value = mock_response
55+
56+
response = self.connector.send("common", "some_method", "arg1", "arg2")
57+
58+
_, called_kwargs = mock_post.call_args
59+
sent_data = json.loads(
60+
called_kwargs["data"]
61+
) # Convert JSON string back to dictionary
62+
63+
# Verify all expected fields except 'id'
64+
self.assertEqual(sent_data["jsonrpc"], self.version)
65+
self.assertEqual(sent_data["method"], "call")
66+
self.assertEqual(
67+
sent_data["params"],
68+
{"service": "common", "method": "some_method", "args": ["arg1", "arg2"]},
69+
)
70+
71+
# Ensure 'id' exists and is an integer
72+
self.assertIn("id", sent_data)
73+
self.assertIsInstance(sent_data["id"], int)
74+
75+
self.assertEqual(response, "mock_response")
76+
77+
@patch("odoolib.connector.json_rpc.requests.post")
78+
def test_send_error(self, mock_post):
79+
mock_response = MagicMock()
80+
mock_response.json.return_value = {"error": "mock_error"}
81+
mock_post.return_value = mock_response
82+
83+
with self.assertRaises(JsonRpcException) as context:
84+
self.connector.send("common", "some_method", "arg1", "arg2")
85+
86+
self.assertEqual(str(context.exception), "'mock_error'")
87+
88+
89+
if __name__ == "__main__":
90+
unittest.main()

0 commit comments

Comments
 (0)