[IMP] *: add generic make_jsonrpc method in tests
*: bus, crm_livechat, crm_mail_plugin, im_livechat, payment, payment_demo, pos_online_payment, test_discuss_full, test_mail_full, tests, website_livechat, website_sale. Several python tests have their own way to make jsonrpc requests. This PR adds a generic `make_jsonrpc_request` method to the `HttpCase` in order to provide a generic way to do so. At the same time, calls to `_open_livechat_channel` are removed in favor of jsonrpc request to `get_session`. This makes the tests more realistics (some incoherences were present like passing `country_id` to the open channel method while the user country id is not set...) Finally, this will ease the diff in the PR introducing livechat visitors as mail guests. part of task-3332628 closes odoo/odoo#130036 Related: odoo/enterprise#44840 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
@@ -2,32 +2,19 @@
|
||||
|
||||
import json
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tests import common, JsonRpcException
|
||||
|
||||
|
||||
class TestWebsocketController(common.HttpCase):
|
||||
def _make_rpc(self, route, params, headers=None):
|
||||
data = json.dumps({
|
||||
'id': 0,
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'call',
|
||||
'params': params,
|
||||
}).encode()
|
||||
headers = headers or {}
|
||||
headers['Content-Type'] = 'application/json'
|
||||
return self.url_open(route, data, headers=headers)
|
||||
|
||||
def test_websocket_peek(self):
|
||||
response = json.loads(
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': True,
|
||||
}).content.decode()
|
||||
)
|
||||
result = self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': True,
|
||||
})
|
||||
|
||||
# Response containing channels/notifications is retrieved and is
|
||||
# conform to excpectations.
|
||||
result = response.get('result')
|
||||
self.assertIsNotNone(result)
|
||||
channels = result.get('channels')
|
||||
self.assertIsNotNone(channels)
|
||||
@@ -36,20 +23,19 @@ class TestWebsocketController(common.HttpCase):
|
||||
self.assertIsNotNone(notifications)
|
||||
self.assertIsInstance(notifications, list)
|
||||
|
||||
response = json.loads(
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': False,
|
||||
}).content.decode()
|
||||
)
|
||||
result = self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': False,
|
||||
})
|
||||
|
||||
# Reponse is received as long as the session is valid.
|
||||
self.assertIn('result', response)
|
||||
self.assertIsNotNone(result)
|
||||
|
||||
def test_websocket_peek_session_expired_login(self):
|
||||
session = self.authenticate(None, None)
|
||||
# first rpc should be fine
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': True,
|
||||
@@ -58,21 +44,17 @@ class TestWebsocketController(common.HttpCase):
|
||||
self.authenticate('admin', 'admin')
|
||||
# rpc with outdated session should lead to error.
|
||||
headers = {'Cookie': f'session_id={session.sid};'}
|
||||
response = json.loads(
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
with self.assertRaises(JsonRpcException, msg='odoo.http.SessionExpiredException'):
|
||||
self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': False,
|
||||
}, headers=headers).content.decode()
|
||||
)
|
||||
error = response.get('error')
|
||||
self.assertIsNotNone(error, 'Sending a poll with an outdated session should lead to error')
|
||||
self.assertEqual('odoo.http.SessionExpiredException', error['data']['name'])
|
||||
}, headers=headers)
|
||||
|
||||
def test_websocket_peek_session_expired_logout(self):
|
||||
session = self.authenticate('demo', 'demo')
|
||||
# first rpc should be fine
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': True,
|
||||
@@ -80,13 +62,9 @@ class TestWebsocketController(common.HttpCase):
|
||||
self.url_open('/web/session/logout')
|
||||
# rpc with outdated session should lead to error.
|
||||
headers = {'Cookie': f'session_id={session.sid};'}
|
||||
response = json.loads(
|
||||
self._make_rpc('/websocket/peek_notifications', {
|
||||
with self.assertRaises(JsonRpcException, msg='odoo.http.SessionExpiredException'):
|
||||
self.make_jsonrpc_request('/websocket/peek_notifications', {
|
||||
'channels': [],
|
||||
'last': 0,
|
||||
'is_first_poll': False,
|
||||
}, headers=headers).content.decode()
|
||||
)
|
||||
error = response.get('error')
|
||||
self.assertIsNotNone(error, 'Sending a poll with an outdated session should lead to error')
|
||||
self.assertEqual('odoo.http.SessionExpiredException', error['data']['name'])
|
||||
}, headers=headers)
|
||||
|
||||
@@ -33,8 +33,12 @@ class CrmChatbotCase(chatbot_common.CrmChatbotCase):
|
||||
self.assertEqual(created_lead.type, 'lead')
|
||||
|
||||
def _chatbot_create_lead(self, user):
|
||||
channel_info = self.livechat_channel._open_livechat_discuss_channel(
|
||||
anonymous_name='Test Visitor', chatbot_script=self.chatbot_script, user_id=user.id)
|
||||
channel_info = self.make_jsonrpc_request("/im_livechat/get_session", {
|
||||
'anonymous_name': 'Test Visitor',
|
||||
'channel_id': self.livechat_channel.id,
|
||||
'chatbot_script_id': self.chatbot_script.id,
|
||||
'user_id': user.id,
|
||||
})
|
||||
discuss_channel = self.env['discuss.channel'].sudo().browse(channel_info['id'])
|
||||
|
||||
self._post_answer_and_trigger_next_step(
|
||||
|
||||
@@ -15,7 +15,7 @@ class TestCrmMailPlugin(TestMailPluginControllerCommon):
|
||||
{"name": "Partner 2"},
|
||||
])
|
||||
|
||||
result = self._make_rpc_call("/mail_plugin/partner/get", {"partner_id": partner.id})
|
||||
result = self.make_jsonrpc_request("/mail_plugin/partner/get", {"partner_id": partner.id})
|
||||
|
||||
self.assertNotIn("leads", result,
|
||||
msg="The user has no access to crm.lead, the leads section should not be visible")
|
||||
@@ -27,7 +27,7 @@ class TestCrmMailPlugin(TestMailPluginControllerCommon):
|
||||
{"name": "Lead Partner 2", "partner_id": partner_2.id},
|
||||
])
|
||||
|
||||
result = self._make_rpc_call("/mail_plugin/partner/get", {"partner_id": partner.id})
|
||||
result = self.make_jsonrpc_request("/mail_plugin/partner/get", {"partner_id": partner.id})
|
||||
|
||||
self.assertIn(
|
||||
"leads",
|
||||
@@ -71,7 +71,7 @@ class TestCrmMailPlugin(TestMailPluginControllerCommon):
|
||||
'email_subject': 'test subject',
|
||||
}
|
||||
|
||||
result = self._make_rpc_call('/mail_plugin/lead/create', params)
|
||||
result = self.make_jsonrpc_request('/mail_plugin/lead/create', params)
|
||||
|
||||
# Check that the created lead record has the correct company and return the lead_id
|
||||
self.assertIn(
|
||||
@@ -87,27 +87,3 @@ class TestCrmMailPlugin(TestMailPluginControllerCommon):
|
||||
company_b,
|
||||
msg='The created record should belong to company_B',
|
||||
)
|
||||
|
||||
def _make_rpc_call(self, url, params):
|
||||
"""
|
||||
Makes an RPC call to the specified URL with the given parameters, and returns the 'result' key from the response.
|
||||
|
||||
:param params (dict): A dictionary containing the parameters to send in the RPC call.
|
||||
:param url (str): The URL to send the RPC call to.
|
||||
:return (dict): The 'result' key from the response.
|
||||
"""
|
||||
|
||||
data = {
|
||||
'id': 0,
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'call',
|
||||
'params': params,
|
||||
}
|
||||
|
||||
response = self.url_open(
|
||||
url,
|
||||
data=json.dumps(data).encode(),
|
||||
headers={'Content-Type': 'application/json'}
|
||||
).json()
|
||||
|
||||
return response['result']
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class ChatbotCase(common.TransactionCase):
|
||||
class ChatbotCase(common.HttpCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
class TestImLivechatCommon(TransactionCase):
|
||||
class TestImLivechatCommon(HttpCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.password = 'Pl1bhD@2!kXZ'
|
||||
cls.operators = cls.env['res.users'].create([{
|
||||
'name': 'Michel',
|
||||
'login': 'michel',
|
||||
'password': cls.password,
|
||||
'livechat_username': "Michel Operator",
|
||||
'email': 'michel@example.com',
|
||||
}, {
|
||||
|
||||
@@ -44,8 +44,11 @@ class ChatbotCase(chatbot_common.ChatbotCase):
|
||||
"Only step 'step_no_one_available' should be flagged as forward operator child.")
|
||||
|
||||
def test_chatbot_steps(self):
|
||||
channel_info = self.livechat_channel._open_livechat_discuss_channel(
|
||||
anonymous_name='Test Visitor', chatbot_script=self.chatbot_script)
|
||||
channel_info = self.make_jsonrpc_request("/im_livechat/get_session", {
|
||||
'anonymous_name': 'Test Visitor',
|
||||
'chatbot_script_id': self.chatbot_script.id,
|
||||
'channel_id': self.livechat_channel.id,
|
||||
})
|
||||
discuss_channel = self.env['discuss.channel'].browse(channel_info['id'])
|
||||
|
||||
self.assertEqual(discuss_channel.chatbot_current_step_id, self.step_dispatch)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from datetime import timedelta
|
||||
from freezegun import freeze_time
|
||||
from unittest.mock import patch, PropertyMock
|
||||
|
||||
from odoo import fields
|
||||
from odoo.addons.im_livechat.tests.common import TestImLivechatCommon
|
||||
@@ -22,11 +23,20 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
def test_channel_get_livechat_visitor_info(self):
|
||||
belgium = self.env.ref('base.be')
|
||||
public_user = self.env.ref('base.public_user')
|
||||
test_user = self.env['res.users'].create({'name': 'Roger', 'login': 'roger', 'country_id': belgium.id})
|
||||
test_user = self.env['res.users'].create({'name': 'Roger', 'login': 'roger', 'password': self.password, 'country_id': belgium.id})
|
||||
|
||||
# ensure visitor info are correct with anonymous
|
||||
operator = self.operators[0]
|
||||
channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_discuss_channel(anonymous_name='Visitor 22', previous_operator_id=operator.partner_id.id, country_id=belgium.id)
|
||||
with patch('odoo.http.GeoIP.country_code', new_callable=PropertyMock(return_value=belgium.code)):
|
||||
channel_info = self.make_jsonrpc_request(
|
||||
'/im_livechat/get_session',
|
||||
{
|
||||
'anonymous_name': 'Visitor 22',
|
||||
'previous_operator_id': operator.partner_id.id,
|
||||
'channel_id': self.livechat_channel.id,
|
||||
'country_id': belgium.id,
|
||||
},
|
||||
)
|
||||
self.assertEqual(channel_info['channel']['anonymous_name'], "Visitor 22")
|
||||
self.assertEqual(channel_info['channel']['anonymous_country'], {'code': 'BE', 'id': belgium.id, 'name': 'Belgium'})
|
||||
|
||||
@@ -34,7 +44,7 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
# shape of channelMembers is [('insert', data...)], [0][1] accesses the data
|
||||
self.assertEqual(sorted(map(lambda m: m['persona']['partner'], channel_info['channel']['channelMembers'][0][1]), key=lambda m: m['id']), sorted([{
|
||||
'active': True,
|
||||
'country': [('clear',)],
|
||||
'country': [['clear']],
|
||||
'id': operator.partner_id.id,
|
||||
'is_bot': False,
|
||||
'is_public': False,
|
||||
@@ -48,17 +58,23 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
}], key=lambda m: m['id']))
|
||||
|
||||
# ensure visitor info are correct with real user
|
||||
channel_info = self.livechat_channel.with_user(test_user).sudo()._open_livechat_discuss_channel(anonymous_name='whatever', previous_operator_id=operator.partner_id.id, user_id=test_user.id)
|
||||
self.authenticate(test_user.login, self.password)
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {
|
||||
'anonymous_name': 'whatever',
|
||||
'previous_operator_id': operator.partner_id.id,
|
||||
'user_id': test_user.id,
|
||||
'channel_id': self.livechat_channel.id,
|
||||
})
|
||||
self.assertFalse(channel_info['channel']['anonymous_name'])
|
||||
self.assertEqual(channel_info['channel']['anonymous_country'], [('clear',)])
|
||||
self.assertEqual(channel_info['channel']['channelMembers'], [('insert', [
|
||||
self.assertEqual(channel_info['channel']['anonymous_country'], {'code': 'BE', 'id': belgium.id, 'name': 'Belgium'})
|
||||
self.assertEqual(channel_info['channel']['channelMembers'], [['insert', [
|
||||
{
|
||||
'channel': {'id': channel_info['id']},
|
||||
'id': self.env['discuss.channel.member'].search([('channel_id', '=', channel_info['id']), ('partner_id', '=', operator.partner_id.id)]).id,
|
||||
'persona': {
|
||||
'partner': {
|
||||
'active': True,
|
||||
'country': [('clear',)],
|
||||
'country': [['clear']],
|
||||
'id': operator.partner_id.id,
|
||||
'is_bot': False,
|
||||
'is_public': False,
|
||||
@@ -84,22 +100,28 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
},
|
||||
},
|
||||
},
|
||||
])])
|
||||
]]])
|
||||
|
||||
# ensure visitor info are correct when operator is testing themselves
|
||||
operator = self.operators[0]
|
||||
channel_info = self.livechat_channel.with_user(operator)._open_livechat_discuss_channel(anonymous_name='whatever', previous_operator_id=operator.partner_id.id, user_id=operator.id)
|
||||
self.assertEqual(channel_info['operator_pid'], (operator.partner_id.id, "Michel Operator"))
|
||||
self.authenticate(operator.login, self.password)
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {
|
||||
'anonymous_name': 'whatever',
|
||||
'previous_operator_id': operator.partner_id.id,
|
||||
'user_id': operator.id,
|
||||
'channel_id': self.livechat_channel.id,
|
||||
})
|
||||
self.assertEqual(channel_info['operator_pid'], [operator.partner_id.id, "Michel Operator"])
|
||||
self.assertFalse(channel_info['channel']['anonymous_name'])
|
||||
self.assertEqual(channel_info['channel']['anonymous_country'], [('clear',)])
|
||||
self.assertEqual(channel_info['channel']['channelMembers'], [('insert', [
|
||||
self.assertEqual(channel_info['channel']['anonymous_country'], [['clear']])
|
||||
self.assertEqual(channel_info['channel']['channelMembers'], [['insert', [
|
||||
{
|
||||
'channel': {'id': channel_info['id']},
|
||||
'id': self.env['discuss.channel.member'].search([('channel_id', '=', channel_info['id']), ('partner_id', '=', operator.partner_id.id)]).id,
|
||||
'persona': {
|
||||
'partner': {
|
||||
'active': True,
|
||||
'country': [('clear',)],
|
||||
'country': [['clear']],
|
||||
'id': operator.partner_id.id,
|
||||
'is_bot': False,
|
||||
'is_public': False,
|
||||
@@ -107,13 +129,13 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
},
|
||||
},
|
||||
},
|
||||
])])
|
||||
]]])
|
||||
|
||||
def _open_livechat_discuss_channel(self):
|
||||
discuss_channels = []
|
||||
|
||||
for i in range(5):
|
||||
discuss_channel = self.livechat_channel._open_livechat_discuss_channel('Anonymous')
|
||||
discuss_channel = self.make_jsonrpc_request('/im_livechat/get_session', {'anonymous_name': 'Anonymous', 'channel_id': self.livechat_channel.id})
|
||||
discuss_channels.append(discuss_channel)
|
||||
# send a message to mark this channel as 'active'
|
||||
self.env['discuss.channel'].browse(discuss_channel['id']).message_post(body='cc')
|
||||
@@ -122,7 +144,7 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
|
||||
def test_channel_not_pinned_for_operator_before_first_message(self):
|
||||
public_user = self.env.ref('base.public_user')
|
||||
channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_discuss_channel(anonymous_name='whatever')
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {'anonymous_name': 'whatever', 'channel_id': self.livechat_channel.id})
|
||||
operator_channel_member = self.env['discuss.channel.member'].search([('channel_id', '=', channel_info['id']), ('partner_id', 'in', self.operators.partner_id.ids)])
|
||||
self.assertEqual(len(operator_channel_member), 1, "operator should be member of channel")
|
||||
self.assertFalse(operator_channel_member.is_pinned, "channel should not be pinned for operator initially")
|
||||
@@ -139,7 +161,7 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
'email': 'michel@example.com',
|
||||
'livechat_username': 'Michel at your service',
|
||||
})
|
||||
channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_discuss_channel(anonymous_name='whatever')
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {'anonymous_name': 'whatever', 'channel_id': self.livechat_channel.id})
|
||||
channel = self.env['discuss.channel'].browse(channel_info['id'])
|
||||
channel.with_user(operator).message_post(body='Hello', message_type='comment', subtype_xmlid='mail.mt_comment')
|
||||
message_formats = channel.with_user(public_user).sudo()._channel_fetch_message()
|
||||
@@ -150,7 +172,7 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
|
||||
def test_read_channel_unpined_for_operator_after_one_day(self):
|
||||
public_user = self.env.ref('base.public_user')
|
||||
channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_discuss_channel(anonymous_name='visitor')
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {'anonymous_name': 'visitor', 'channel_id': self.livechat_channel.id})
|
||||
member_of_operator = self.env['discuss.channel.member'].search([('channel_id', '=', channel_info['id']), ('partner_id', 'in', self.operators.partner_id.ids)])
|
||||
message = self.env['discuss.channel'].browse(channel_info['id']).message_post(body='cc')
|
||||
member_of_operator.channel_id.with_user(self.operators.filtered(
|
||||
@@ -162,7 +184,7 @@ class TestGetDiscussChannel(TestImLivechatCommon):
|
||||
|
||||
def test_unread_channel_not_unpined_for_operator_after_autovacuum(self):
|
||||
public_user = self.env.ref('base.public_user')
|
||||
channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_discuss_channel(anonymous_name='visitor')
|
||||
channel_info = self.make_jsonrpc_request('/im_livechat/get_session', {'anonymous_name': 'visitor', 'channel_id': self.livechat_channel.id})
|
||||
member_of_operator = self.env['discuss.channel.member'].search([('channel_id', '=', channel_info['id']), ('partner_id', 'in', self.operators.partner_id.ids)])
|
||||
self.env['discuss.channel'].browse(channel_info['id']).message_post(body='cc')
|
||||
with freeze_time(fields.Datetime.to_string(fields.datetime.now() + timedelta(days=1))):
|
||||
|
||||
@@ -7,31 +7,30 @@ from odoo.addons.im_livechat.tests.common import TestImLivechatCommon
|
||||
|
||||
|
||||
class TestImLivechatReport(TestImLivechatCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env['discuss.channel'].search([('livechat_channel_id', '!=', False)]).unlink()
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.env['discuss.channel'].search([('livechat_channel_id', '!=', False)]).unlink()
|
||||
|
||||
def _compute_available_operator_ids(channel_self):
|
||||
for record in channel_self:
|
||||
record.available_operator_ids = cls.operators
|
||||
record.available_operator_ids = self.operators
|
||||
|
||||
with patch.object(type(cls.env['im_livechat.channel']), '_compute_available_operator_ids', _compute_available_operator_ids):
|
||||
channel_id = cls.livechat_channel._open_livechat_discuss_channel('Anonymous')['id']
|
||||
with patch.object(type(self.env['im_livechat.channel']), '_compute_available_operator_ids', _compute_available_operator_ids):
|
||||
channel_id = self.make_jsonrpc_request("/im_livechat/get_session", {'anonymous_name': 'Anonymous', 'channel_id': self.livechat_channel.id})['id']
|
||||
|
||||
channel = cls.env['discuss.channel'].browse(channel_id)
|
||||
cls.operator = channel.livechat_operator_id
|
||||
channel = self.env['discuss.channel'].browse(channel_id)
|
||||
self.operator = channel.livechat_operator_id
|
||||
|
||||
cls._create_message(channel, cls.visitor_user.partner_id, '2023-03-17 06:05:54')
|
||||
cls._create_message(channel, cls.operator, '2023-03-17 08:15:54')
|
||||
cls._create_message(channel, cls.operator, '2023-03-17 08:45:54')
|
||||
self._create_message(channel, self.visitor_user.partner_id, '2023-03-17 06:05:54')
|
||||
self._create_message(channel, self.operator, '2023-03-17 08:15:54')
|
||||
self._create_message(channel, self.operator, '2023-03-17 08:45:54')
|
||||
|
||||
# message with the same record id, but with a different model
|
||||
# should not be taken into account for statistics
|
||||
partner_message = cls._create_message(channel, cls.operator, '2023-03-17 05:05:54')
|
||||
partner_message |= cls._create_message(channel, cls.operator, '2023-03-17 09:15:54')
|
||||
partner_message = self._create_message(channel, self.operator, '2023-03-17 05:05:54')
|
||||
partner_message |= self._create_message(channel, self.operator, '2023-03-17 09:15:54')
|
||||
partner_message.model = 'res.partner'
|
||||
cls.env['mail.message'].flush_model()
|
||||
self.env['mail.message'].flush_model()
|
||||
|
||||
def test_im_livechat_report_channel(self):
|
||||
report = self.env['im_livechat.report.channel'].search([('livechat_channel_id', '=', self.livechat_channel.id)])
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
from markupsafe import Markup
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests.common import users, tagged, TransactionCase
|
||||
from odoo.tests.common import users, tagged, HttpCase
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestImLivechatMessage(TransactionCase):
|
||||
class TestImLivechatMessage(HttpCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.password = 'Pl1bhD@2!kXZ'
|
||||
self.users = self.env['res.users'].create([
|
||||
{
|
||||
'email': 'e.e@example.com',
|
||||
@@ -21,14 +22,20 @@ class TestImLivechatMessage(TransactionCase):
|
||||
'odoobot_state': 'disabled',
|
||||
'signature': '--\nErnest',
|
||||
},
|
||||
{'name': 'test1', 'login': 'test1', 'email': 'test1@example.com'},
|
||||
{'name': 'test1', 'login': 'test1', 'password': self.password, 'email': 'test1@example.com'},
|
||||
])
|
||||
|
||||
@users('emp')
|
||||
def test_message_format(self):
|
||||
im_livechat_channel = self.env['im_livechat.channel'].sudo().create({'name': 'support', 'user_ids': [Command.link(self.users[0].id)]})
|
||||
self.env['bus.presence'].create({'user_id': self.users[0].id, 'status': 'online'}) # make available for livechat (ignore leave)
|
||||
channel_livechat_1 = self.env['discuss.channel'].browse(im_livechat_channel._open_livechat_discuss_channel(anonymous_name='anon 1', previous_operator_id=self.users[0].partner_id.id, user_id=self.users[1].id, country_id=self.env.ref('base.in').id)['id'])
|
||||
self.authenticate(self.users[1].login, self.password)
|
||||
channel_livechat_1 = self.env['discuss.channel'].browse(self.make_jsonrpc_request("/im_livechat/get_session", {
|
||||
'anonymous_name': 'anon 1',
|
||||
'previous_operator_id': self.users[0].partner_id.id,
|
||||
'country_id': self.env.ref('base.in').id,
|
||||
'channel_id': im_livechat_channel.id,
|
||||
})['id'])
|
||||
record_rating = self.env['rating.rating'].create({
|
||||
'res_model_id': self.env['ir.model']._get('discuss.channel').id,
|
||||
'res_id': channel_livechat_1.id,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import json
|
||||
from contextlib import contextmanager
|
||||
from uuid import uuid4
|
||||
|
||||
from lxml import etree, objectify
|
||||
from werkzeug import urls
|
||||
|
||||
from odoo.tests import HttpCase
|
||||
from odoo.tests import HttpCase, JsonRpcException
|
||||
|
||||
from odoo.addons.payment.tests.common import PaymentCommon
|
||||
|
||||
@@ -69,20 +70,11 @@ class PaymentHttpCommon(PaymentCommon, HttpCase):
|
||||
"""
|
||||
return self.opener.post(url, json=data)
|
||||
|
||||
def _make_json_rpc_request(self, url, data=None):
|
||||
""" Make a JSON-RPC request to the provided URL.
|
||||
|
||||
:param str url: The URL to make the request to
|
||||
:param dict data: The data to be send in the request body in JSON-RPC 2.0 format
|
||||
:return: The response of the request
|
||||
:rtype: :class:`requests.models.Response`
|
||||
"""
|
||||
return self.opener.post(url, json={
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'call',
|
||||
'id': str(uuid4()),
|
||||
'params': data,
|
||||
})
|
||||
@contextmanager
|
||||
def _assertNotFound(self):
|
||||
with self.assertRaises(JsonRpcException) as cm:
|
||||
yield
|
||||
self.assertEqual(cm.exception.code, 404)
|
||||
|
||||
def _get_tx_context(self, response, form_name):
|
||||
"""Extracts txContext & other form info (provider & token ids)
|
||||
@@ -226,15 +218,7 @@ class PaymentHttpCommon(PaymentCommon, HttpCase):
|
||||
"""
|
||||
uri = '/payment/transaction'
|
||||
url = self._build_url(uri)
|
||||
response = self._make_json_rpc_request(url, route_kwargs)
|
||||
self.assertEqual(response.status_code, 200) # Check the request went through.
|
||||
|
||||
return response
|
||||
return self.make_jsonrpc_request(url, route_kwargs)
|
||||
|
||||
def _get_processing_values(self, **route_kwargs):
|
||||
response = self._portal_transaction(**route_kwargs)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
resp_content = json.loads(response.content)
|
||||
return resp_content['result']
|
||||
return self._portal_transaction(**route_kwargs)
|
||||
|
||||
@@ -5,7 +5,7 @@ from unittest.mock import patch
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests import tagged, JsonRpcException
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
from odoo.addons.payment.controllers.portal import PaymentPortal
|
||||
@@ -287,22 +287,19 @@ class TestFlows(PaymentHttpCommon):
|
||||
'landing_route': 'whatever',
|
||||
})
|
||||
# Transaction step with a wrong flow --> UserError
|
||||
with mute_logger('odoo.http'):
|
||||
response = self._portal_transaction(**transaction_values)
|
||||
self.assertIn(
|
||||
"odoo.exceptions.UserError: The payment should either be direct, with redirection, or made by a token.",
|
||||
response.text)
|
||||
with mute_logger("odoo.http"), self.assertRaises(
|
||||
JsonRpcException,
|
||||
msg='odoo.exceptions.UserError: The payment should either be direct, with redirection, or made by a token.',
|
||||
):
|
||||
self._portal_transaction(**transaction_values)
|
||||
|
||||
def test_transaction_wrong_token(self):
|
||||
route_values = self._prepare_pay_values()
|
||||
route_values['access_token'] = "abcde"
|
||||
|
||||
# Transaction step with a wrong access token --> ValidationError
|
||||
with mute_logger('odoo.http'):
|
||||
response = self._portal_transaction(**route_values)
|
||||
self.assertIn(
|
||||
"odoo.exceptions.ValidationError: The access token is invalid.",
|
||||
response.text)
|
||||
with mute_logger('odoo.http'), self.assertRaises(JsonRpcException, msg='odoo.exceptions.ValidationError: The access token is invalid.'):
|
||||
self._portal_transaction(**route_values)
|
||||
|
||||
def test_access_disabled_providers_tokens(self):
|
||||
self.partner = self.portal_partner
|
||||
|
||||
@@ -128,6 +128,6 @@ class TestMultiCompanyFlows(PaymentHttpCommon):
|
||||
|
||||
# Archive token in company A
|
||||
url = self._build_url('/payment/archive_token')
|
||||
self._make_json_rpc_request(url, {'token_id': token.id})
|
||||
self.make_jsonrpc_request(url, {'token_id': token.id})
|
||||
|
||||
self.assertFalse(token.active)
|
||||
|
||||
@@ -20,5 +20,5 @@ class TestProcessingFlows(PaymentDemoCommon, PaymentHttpCommon):
|
||||
'odoo.addons.payment.models.payment_transaction.PaymentTransaction'
|
||||
'._handle_notification_data'
|
||||
) as handle_notification_data_mock:
|
||||
self._make_json_rpc_request(url, data=self.notification_data)
|
||||
self.make_jsonrpc_request(url, params=self.notification_data)
|
||||
self.assertEqual(handle_notification_data_mock.call_count, 1)
|
||||
|
||||
@@ -23,10 +23,7 @@ class OnlinePaymentCommon(PaymentHttpCommon):
|
||||
def _fake_request_pos_order_pay_transaction_page(self, pos_order_id, route_values):
|
||||
uri = f'/pos/pay/transaction/{pos_order_id}'
|
||||
url = self._build_url(uri)
|
||||
response = self._make_json_rpc_request(url, route_values)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
resp_content = json.loads(response.content)
|
||||
return resp_content['result']
|
||||
return self.make_jsonrpc_request(url, route_values)
|
||||
|
||||
def _fake_open_pos_order_pay_confirmation_page(self, pos_order_id, access_token, tx_id):
|
||||
self._fake_http_get_request(PaymentPortal._get_landing_route(pos_order_id, access_token, tx_id=tx_id))
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
|
||||
from datetime import date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from unittest.mock import patch, PropertyMock
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests.common import users, tagged, TransactionCase, warmup
|
||||
from odoo.tests.common import users, tagged, HttpCase, warmup
|
||||
from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestDiscussFullPerformance(TransactionCase):
|
||||
class TestDiscussFullPerformance(HttpCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.group_user = self.env.ref('base.group_user')
|
||||
self.password = 'Pl1bhD@2!kXZ'
|
||||
self.users = self.env['res.users'].create([
|
||||
{
|
||||
'email': 'e.e@example.com',
|
||||
@@ -24,7 +26,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'odoobot_state': 'disabled',
|
||||
'signature': '--\nErnest',
|
||||
},
|
||||
{'name': 'test1', 'login': 'test1', 'email': 'test1@example.com'},
|
||||
{'name': 'test1', 'login': 'test1', 'password': self.password, 'email': 'test1@example.com', 'country_id': self.env.ref('base.in').id},
|
||||
{'name': 'test2', 'login': 'test2', 'email': 'test2@example.com'},
|
||||
{'name': 'test3', 'login': 'test3'},
|
||||
{'name': 'test4', 'login': 'test4'},
|
||||
@@ -82,9 +84,20 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
# create livechats
|
||||
im_livechat_channel = self.env['im_livechat.channel'].sudo().create({'name': 'support', 'user_ids': [Command.link(self.users[0].id)]})
|
||||
self.env['bus.presence'].create({'user_id': self.users[0].id, 'status': 'online'}) # make available for livechat (ignore leave)
|
||||
self.channel_livechat_1 = self.env['discuss.channel'].browse(im_livechat_channel._open_livechat_discuss_channel(anonymous_name='anon 1', previous_operator_id=self.users[0].partner_id.id, user_id=self.users[1].id, country_id=self.env.ref('base.in').id)['id'])
|
||||
self.authenticate('test1', self.password)
|
||||
self.channel_livechat_1 = self.env['discuss.channel'].browse(self.make_jsonrpc_request("/im_livechat/get_session", {
|
||||
'anonymous_name': 'anon 1',
|
||||
'channel_id': im_livechat_channel.id,
|
||||
'previous_operator_id': self.users[0].partner_id.id,
|
||||
})['id'])
|
||||
self.channel_livechat_1.with_user(self.users[1]).message_post(body="test")
|
||||
self.channel_livechat_2 = self.env['discuss.channel'].browse(im_livechat_channel.with_user(self.env.ref('base.public_user'))._open_livechat_discuss_channel(anonymous_name='anon 2', previous_operator_id=self.users[0].partner_id.id, country_id=self.env.ref('base.be').id)['id'])
|
||||
self.authenticate(None, None)
|
||||
with patch("odoo.http.GeoIP.country_code", new_callable=PropertyMock(return_value=self.env.ref('base.be').code)):
|
||||
self.channel_livechat_2 = self.env['discuss.channel'].browse(self.make_jsonrpc_request("/im_livechat/get_session", {
|
||||
'anonymous_name': 'anon 2',
|
||||
'channel_id': im_livechat_channel.id,
|
||||
'previous_operator_id': self.users[0].partner_id.id,
|
||||
})['id'])
|
||||
self.channel_livechat_2.with_user(self.env.ref('base.public_user')).sudo().message_post(body="test")
|
||||
# add needaction
|
||||
self.users[0].notification_type = 'inbox'
|
||||
@@ -830,7 +843,11 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'persona': {
|
||||
'partner': {
|
||||
'active': True,
|
||||
'country': [('clear',)],
|
||||
'country': {
|
||||
'code': 'IN',
|
||||
'id': self.env.ref('base.in').id,
|
||||
'name': 'India',
|
||||
},
|
||||
'id': self.users[1].partner_id.id,
|
||||
'is_bot': False,
|
||||
'is_public': False,
|
||||
@@ -844,7 +861,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'memberCount': 2,
|
||||
'message_unread_counter': 0,
|
||||
},
|
||||
'create_uid': self.env.user.id,
|
||||
'create_uid': self.users[1].id,
|
||||
'defaultDisplayMode': False,
|
||||
'description': False,
|
||||
'group_based_subscription': False,
|
||||
@@ -1016,4 +1033,4 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
Returns the expected query count.
|
||||
The point of having a separate getter is to allow it to be overriden.
|
||||
"""
|
||||
return 68
|
||||
return 71
|
||||
|
||||
@@ -81,24 +81,13 @@ class TestPortalControllers(TestPortal):
|
||||
"""Test retrieving chatter messages through the portal controller"""
|
||||
self.authenticate(None, None)
|
||||
message_fetch_url = '/mail/chatter_fetch'
|
||||
payload = json.dumps({
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'call',
|
||||
'id': 0,
|
||||
'params': {
|
||||
|
||||
def get_chatter_message_count():
|
||||
return self.make_jsonrpc_request(message_fetch_url, {
|
||||
'res_model': 'mail.test.portal',
|
||||
'res_id': self.record_portal.id,
|
||||
'token': self.record_portal.access_token,
|
||||
},
|
||||
})
|
||||
|
||||
def get_chatter_message_count():
|
||||
res = self.url_open(
|
||||
url=message_fetch_url,
|
||||
data=payload,
|
||||
headers={'Content-Type': 'application/json'}
|
||||
)
|
||||
return res.json().get('result', {}).get('message_count', 0)
|
||||
}).get('message_count', 0)
|
||||
|
||||
self.assertEqual(get_chatter_message_count(), 0)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from odoo.addons.website_livechat.tests.common import TestLivechatCommon
|
||||
|
||||
|
||||
@tests.tagged('post_install', '-at_install')
|
||||
class TestLivechatChatbotUI(tests.HttpCase, TestLivechatCommon, ChatbotCase):
|
||||
class TestLivechatChatbotUI(TestLivechatCommon, ChatbotCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.env['im_livechat.channel'].search([
|
||||
|
||||
@@ -11,6 +11,7 @@ from odoo.tests import tagged
|
||||
|
||||
from odoo.addons.base.tests.common import HttpCaseWithUserDemo
|
||||
from odoo.addons.website_sale.controllers.delivery import WebsiteSaleDelivery as WebsiteSaleDeliveryController
|
||||
from odoo.addons.website_sale.controllers.main import WebsiteSale
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
@@ -107,31 +108,6 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'state': self.user_demo.partner_id.state_id.code,
|
||||
}
|
||||
|
||||
def _make_json_rpc_request(self, url, data=None):
|
||||
""" Make a JSON-RPC request to the provided URL.
|
||||
|
||||
:param str url: The URL to make the request to
|
||||
:param dict data: The data to be send in the request body in JSON-RPC 2.0 format
|
||||
:return dict: The result of the JSON-RPC request
|
||||
"""
|
||||
rpc_request = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "call",
|
||||
"id": str(uuid4()),
|
||||
"params": data,
|
||||
}
|
||||
|
||||
result = self.url_open(
|
||||
url,
|
||||
data=json.dumps(rpc_request).encode(),
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
|
||||
if not result.ok:
|
||||
return {}
|
||||
|
||||
return result.json().get("result", {})
|
||||
|
||||
def test_express_checkout_public_user_shipping_address_change(self):
|
||||
""" Test that when using express checkout as a public user and selecting a shipping address,
|
||||
a new partner is created if the partner of the SO is the public partner.
|
||||
@@ -143,10 +119,10 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values)
|
||||
}
|
||||
)
|
||||
@@ -175,18 +151,18 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values)
|
||||
}
|
||||
)
|
||||
new_partner = self.sale_order.partner_shipping_id
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values_2)
|
||||
}
|
||||
)
|
||||
@@ -213,10 +189,10 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values)
|
||||
}
|
||||
)
|
||||
@@ -235,10 +211,10 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values)
|
||||
}
|
||||
)
|
||||
@@ -269,18 +245,18 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values)
|
||||
}
|
||||
)
|
||||
new_partner = self.sale_order.partner_shipping_id
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_shipping_values_2)
|
||||
}
|
||||
)
|
||||
@@ -325,16 +301,16 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'odoo.addons.delivery.models.delivery_carrier.DeliveryCarrier.rate_shipment',
|
||||
return_value=self.rate_shipment_result
|
||||
):
|
||||
shipping_options = self._make_json_rpc_request(
|
||||
shipping_options = self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_demo_shipping_values)
|
||||
}
|
||||
)
|
||||
self.assertEqual(self.sale_order.partner_id.id, self.user_demo.partner_id.id)
|
||||
|
||||
self._make_json_rpc_request(urls.url_join(self.base_url(), '/shop/express'), data={
|
||||
self.make_jsonrpc_request(urls.url_join(self.base_url(), WebsiteSale._express_checkout_route), params={
|
||||
'billing_address': dict(self.express_checkout_billing_values),
|
||||
'shipping_address': dict(self.express_checkout_demo_shipping_values),
|
||||
'shipping_option': shipping_options[0],
|
||||
@@ -355,10 +331,10 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
):
|
||||
# Won't create a new partner because the partial information are the same the an
|
||||
# exisiting partner linked to the SO
|
||||
shipping_options = self._make_json_rpc_request(
|
||||
shipping_options = self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleDeliveryController._express_checkout_shipping_route
|
||||
), data={
|
||||
), params={
|
||||
'partial_shipping_address': dict(self.express_checkout_anonymized_demo_shipping_values)
|
||||
}
|
||||
)
|
||||
@@ -366,11 +342,11 @@ class TestWebsiteSaleDeliveryExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
|
||||
# Will create a new partner because the complete shipping information are different than
|
||||
# the partner actually selected.
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(),
|
||||
WebsiteSaleDeliveryController._express_checkout_route
|
||||
), data={
|
||||
), params={
|
||||
'billing_address': dict(self.express_checkout_billing_values),
|
||||
'shipping_address': dict(self.express_checkout_demo_shipping_values_2),
|
||||
'shipping_option': shipping_options[0],
|
||||
|
||||
@@ -47,41 +47,16 @@ class TestWebsiteSaleExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
'state': 'AL',
|
||||
}
|
||||
|
||||
def _make_json_rpc_request(self, url, data=None):
|
||||
""" Make a JSON-RPC request to the provided URL.
|
||||
|
||||
:param str url: The URL to make the request to
|
||||
:param dict data: The data to be send in the request body in JSON-RPC 2.0 format
|
||||
:return dict: The result of the JSON-RPC request
|
||||
"""
|
||||
rpc_request = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "call",
|
||||
"id": str(uuid4()),
|
||||
"params": data,
|
||||
}
|
||||
|
||||
result = self.url_open(
|
||||
url,
|
||||
data=json.dumps(rpc_request).encode(),
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
|
||||
if not result.ok:
|
||||
return {}
|
||||
|
||||
return result.json().get("result", {})
|
||||
|
||||
def test_express_checkout_public_user(self):
|
||||
""" Test that when using express checkout as a public user, a new partner is created. """
|
||||
session = self.authenticate(None, None)
|
||||
session['sale_order_id'] = self.sale_order.id
|
||||
root.session_store.save(session)
|
||||
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleController._express_checkout_route
|
||||
), data={
|
||||
), params={
|
||||
'billing_address': dict(self.express_checkout_billing_values)
|
||||
}
|
||||
)
|
||||
@@ -105,10 +80,10 @@ class TestWebsiteSaleExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
session['sale_order_id'] = self.sale_order.id
|
||||
root.session_store.save(session)
|
||||
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleController._express_checkout_route
|
||||
), data={
|
||||
), params={
|
||||
'billing_address': {
|
||||
'name': self.user_demo.partner_id.name,
|
||||
'email': self.user_demo.partner_id.email,
|
||||
@@ -152,10 +127,10 @@ class TestWebsiteSaleExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
session['sale_order_id'] = self.sale_order.id
|
||||
root.session_store.save(session)
|
||||
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleController._express_checkout_route
|
||||
), data={
|
||||
), params={
|
||||
'billing_address': dict(self.express_checkout_billing_values)
|
||||
}
|
||||
)
|
||||
@@ -173,10 +148,10 @@ class TestWebsiteSaleExpressCheckoutFlows(HttpCaseWithUserDemo):
|
||||
session['sale_order_id'] = self.sale_order.id
|
||||
root.session_store.save(session)
|
||||
|
||||
self._make_json_rpc_request(
|
||||
self.make_jsonrpc_request(
|
||||
urls.url_join(
|
||||
self.base_url(), WebsiteSaleController._express_checkout_route
|
||||
), data={
|
||||
), params={
|
||||
'billing_address': dict(self.express_checkout_billing_values)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1610,6 +1610,12 @@ class Transport(xmlrpclib.Transport):
|
||||
return super().request(*args, **kwargs)
|
||||
|
||||
|
||||
class JsonRpcException(Exception):
|
||||
def __init__(self, code, message):
|
||||
super().__init__(message)
|
||||
self.code = code
|
||||
|
||||
|
||||
class HttpCase(TransactionCase):
|
||||
""" Transactional HTTP TestCase with url_open and Chrome headless helpers. """
|
||||
registry_test_mode = True
|
||||
@@ -1812,6 +1818,34 @@ class HttpCase(TransactionCase):
|
||||
return sup.profile(description=request.httprequest.full_path)
|
||||
return profiler.Nested(_profiler, patch('odoo.http.Request._get_profiler_context_manager', route_profiler))
|
||||
|
||||
def make_jsonrpc_request(self, route, params=None, headers=None):
|
||||
"""Make a JSON-RPC request to the server.
|
||||
|
||||
:param str route: the route to request
|
||||
:param dict params: the parameters to send
|
||||
:raises requests.HTTPError: if one occurred
|
||||
:raises JsonRpcException: if the response contains an error
|
||||
:return: The 'result' key from the response if any.
|
||||
"""
|
||||
data = json.dumps({
|
||||
'id': 0,
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'call',
|
||||
'params': params,
|
||||
}).encode()
|
||||
headers = headers or {}
|
||||
headers['Content-Type'] = 'application/json'
|
||||
response = self.url_open(route, data, headers=headers)
|
||||
response.raise_for_status()
|
||||
decoded_response = response.json()
|
||||
if 'result' in decoded_response:
|
||||
return decoded_response['result']
|
||||
if 'error' in decoded_response:
|
||||
raise JsonRpcException(
|
||||
code=decoded_response['error']['code'],
|
||||
message=decoded_response['error']['data']['name']
|
||||
)
|
||||
|
||||
|
||||
def no_retry(arg):
|
||||
"""Disable auto retry on decorated test method or test class"""
|
||||
|
||||
Reference in New Issue
Block a user