odoo18/addons/sms_twilio/tests/test_sms_twilio_controller.py

120 lines
4.9 KiB
Python

from odoo.addons.sms_twilio.tests.common import MockSmsTwilio
from odoo.addons.sms_twilio.tools import sms_twilio as twilio_tools
from odoo.tools import mute_logger
from odoo.tests import tagged, users
from odoo.tests.common import HttpCase
@tagged('post_install', '-at_install', 'twilio', 'twilio_controller')
class TestSmsTwilioController(MockSmsTwilio, HttpCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls._setup_sms_twilio(cls.user_admin.company_id)
@mute_logger('odoo.addons.sms_twilio.controllers.controllers')
@users('employee')
def test_sms_twilio_controller_status(self):
"""Test that the controller correctly processes the webhook calls we
receive from Twilio"""
# All good
ok = self.webhook_ok_response.copy()
# Handle known errors (the ones that we have already mapped)
invalid_destination = {
**self.webhook_ok_response,
"SmsStatus": "undelivered",
"ErrorCode": 30005,
"ErrorMessage": "Unknown destination handset",
}
# Handle unknown errors (the ones that we not have mapped)
unknown_error = {
**self.webhook_ok_response,
"SmsStatus": "failed",
"ErrorCode": 12345,
"ErrorMessage": "Unknown error",
}
# Unknown status -> no update
wrong_status = {
**self.webhook_ok_response,
"SmsStatus": "myfakestatus",
"ErrorCode": 12345,
"ErrorMessage": "Unknown error",
}
with self.mock_sms_twilio_gateway():
for call_params, expected_data in zip(
[ok, invalid_destination, unknown_error, wrong_status],
[{
'failure_type': False,
'failure_reason': False,
'notification_status': 'sent',
}, {
'failure_type': 'sms_invalid_destination',
'failure_reason': "Unknown destination handset",
'notification_status': 'bounce',
}, {
'failure_type': 'unknown',
'failure_reason': "Unknown error",
'notification_status': 'exception',
}, {
'failure_type': False,
'failure_reason': False,
'notification_status': 'pending',
},
],
strict=True,
):
with self.subTest(call_params=call_params):
composer = self.env['sms.composer'].with_context(
active_model='res.partner',
active_id=self.valid_partner,
).create({'body': "SMS Body"})
composer._action_send_sms()
sms = self._new_sms[-1]
expected_signature = twilio_tools.generate_twilio_sms_callback_signature(
self.user_admin.company_id,
sms.uuid,
call_params,
)
# Simulate callback webhook called by Twilio
_python_versionresponse = self.url_open(
f"/sms_twilio/status/{sms.uuid}", call_params,
headers={
"X-Twilio-Signature": expected_signature,
},
)
self.assertRecordValues(sms.sms_tracker_id.mail_notification_id, [{
'notification_status': expected_data["notification_status"],
'failure_type': expected_data["failure_type"],
'failure_reason': expected_data["failure_reason"],
}])
@mute_logger('odoo.addons.sms_twilio.controllers.controllers')
@users('employee')
def test_sms_twilio_controller_status_signature(self):
""" Check X-Twilio-Signature is effectively checked """
call_params = self.webhook_ok_response.copy()
with self.mock_sms_twilio_gateway():
composer = self.env['sms.composer'].with_context(
active_model='res.partner',
active_id=self.valid_partner,
).create({'body': "Body msg"})
composer._action_send_sms()
sms = self._new_sms[-1]
# Simulate callback webhook called by Twilio
response = self.url_open(
f"/sms_twilio/status/{sms.uuid}", call_params,
headers={
"X-Twilio-Signature": "WrongSignature",
},
)
self.assertEqual(response.status_code, 404)
# SMS not updated
self.assertRecordValues(sms.sms_tracker_id.mail_notification_id, [{
'notification_status': 'pending',
'failure_type': False,
'failure_reason': False,
}])