diff options
| author | Thibault Delavallée <tde@odoo.com> | 2019-05-23 10:09:35 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2019-07-12 14:54:11 +0000 |
| commit | bdebcab0cea467e070c1936fed16173247abafdd (patch) | |
| tree | fab225a6f198dd49cd65f22fbbbda8e6c5ee44ab /addons/test_mail_full | |
| parent | 488a5d5af5418ed5c223af5b61aea0b3100508c1 (diff) | |
[REF] sms: refactor message_post using SMS notifications
Purpose of this commit is to better include SMS notifications when posting a
message. SMS is now just another way of notifying people along with Inbox and
email. Following recent mail merge improving notification mechanism [1] we
have to define a _notify_record_by_sms method on mail.thread.
When a message_post is done using message_type being ``sms`` notification type
of customers is set to sms. Customers can be computed on model (generally based
on partner_id field) or directly set usign partner°ids. Notification model is
updated to store this information directly inside the notification itself.
An new ``_message_sms`` helper method is introduced in SMS module allowing
to send messages using sms type and notification with a reduced parameters
number. It is just a shortcut to message_post, easier to use. Either it
computes default recipients on the record set, either it is based on given
partners and numbers to notify.
The following use cases are notably supported
* default computation: find customer, notify by sms;
* force recipients to notify by sms (partner_ids);
* give a set of numbers to notify by sms (sms_nubmers), not necessarily
linked to existing partners;
* force number / customer relationship independently of mobile number defined
on customer (for example when sending an SMS directly from a mobile field
on a lead linked to a customer);
Tests are updated accordingly. Performance tests are added in order to have
some insights on queries generated when sending SMS, like already done for
mail.thread alone.
Related to task 1922163
Linked to PR #33510
[1] see be2795513644f09f6b443f462bb67cc5a0762e8d: performance and notification code improvements
Co-Authored-By: Thibault Delavallee <tde@odoo.com>
Co-Authored-By: Pierre Rousseau <pro@odoo.com>
Diffstat (limited to 'addons/test_mail_full')
| -rw-r--r-- | addons/test_mail_full/__manifest__.py | 2 | ||||
| -rw-r--r-- | addons/test_mail_full/models/test_mail_models.py | 18 | ||||
| -rw-r--r-- | addons/test_mail_full/security/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/__init__.py | 2 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/common.py | 8 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_sms_composer.py | 22 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_sms_performance.py | 88 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_sms_post.py | 297 | ||||
| -rw-r--r-- | addons/test_mail_full/tests/test_sms_sms.py | 59 |
9 files changed, 453 insertions, 45 deletions
diff --git a/addons/test_mail_full/__manifest__.py b/addons/test_mail_full/__manifest__.py index dab4550230a..3f6c16e5639 100644 --- a/addons/test_mail_full/__manifest__.py +++ b/addons/test_mail_full/__manifest__.py @@ -15,7 +15,7 @@ real applications. """, 'mail', 'mail_bot', # 'snailmail', - 'mass_mailing', + # 'mass_mailing', 'phone_validation', 'sms', ], diff --git a/addons/test_mail_full/models/test_mail_models.py b/addons/test_mail_full/models/test_mail_models.py index b351ba8ce45..d0d58e0467a 100644 --- a/addons/test_mail_full/models/test_mail_models.py +++ b/addons/test_mail_full/models/test_mail_models.py @@ -10,6 +10,7 @@ class MailTestSMS(models.Model): _description = 'Chatter Model for SMS Gateway' _name = 'mail.test.sms' _inherit = ['mail.thread'] + _order = 'name asc, id asc' name = fields.Char() subject = fields.Char() @@ -18,6 +19,19 @@ class MailTestSMS(models.Model): mobile_nbr = fields.Char() customer_id = fields.Many2one('res.partner', 'Customer') - @api.multi - def _get_default_sms_recipients(self): + def _sms_get_default_partners(self): return self.mapped('customer_id') + + def _sms_get_number_fields(self): + return ['phone_nbr', 'mobile_nbr'] + + +class MailTestSMSSoLike(models.Model): + """ A model like sale order having only a customer, not specific phone + or mobile fields. """ + _description = 'Chatter Model for SMS Gateway (Partner only)' + _name = 'mail.test.sms.partner' + _inherit = ['mail.thread'] + + name = fields.Char() + partner_id = fields.Many2one('res.partner', 'Customer') diff --git a/addons/test_mail_full/security/ir.model.access.csv b/addons/test_mail_full/security/ir.model.access.csv index 2506e6ac804..186986eef83 100644 --- a/addons/test_mail_full/security/ir.model.access.csv +++ b/addons/test_mail_full/security/ir.model.access.csv @@ -1,3 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_mail_test_sms_all,mail.test.sms.all,model_mail_test_sms,,0,0,0,0 access_mail_test_sms_user,mail.test.sms.user,model_mail_test_sms,base.group_user,1,1,1,1 +access_mail_test_sms_partner_all,mail.test.sms.partner.all,model_mail_test_sms_partner,,0,0,0,0 +access_mail_test_sms_partner_user,mail.test.sms.partner.user,model_mail_test_sms_partner,base.group_user,1,1,1,1 diff --git a/addons/test_mail_full/tests/__init__.py b/addons/test_mail_full/tests/__init__.py index 3eac1b648f9..b5c867844ba 100644 --- a/addons/test_mail_full/tests/__init__.py +++ b/addons/test_mail_full/tests/__init__.py @@ -2,4 +2,6 @@ from . import common from . import test_sms_composer +from . import test_sms_performance from . import test_sms_post +from . import test_sms_sms diff --git a/addons/test_mail_full/tests/common.py b/addons/test_mail_full/tests/common.py index b9abbbec7dc..448ad44ade1 100644 --- a/addons/test_mail_full/tests/common.py +++ b/addons/test_mail_full/tests/common.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.test_mail.tests import common as test_mail_common @@ -12,3 +13,10 @@ class BaseFunctionalTest(test_mail_common.BaseFunctionalTest): # update country to belgium in order to test sanitization of numbers cls.user_employee.company_id.write({'country_id': cls.env.ref('base.be').id}) + + # some numbers for testing + cls.random_numbers_str = '+32456998877, 0456665544' + cls.random_numbers = cls.random_numbers_str.split(', ') + cls.random_numbers_san = [phone_validation.phone_format(number, 'BE', '32', force_format='E164') for number in cls.random_numbers] + cls.test_numbers = ['+32456010203', '0456 04 05 06'] + cls.test_numbers_san = [phone_validation.phone_format(number, 'BE', '32', force_format='E164') for number in cls.test_numbers] diff --git a/addons/test_mail_full/tests/test_sms_composer.py b/addons/test_mail_full/tests/test_sms_composer.py index bcdcbd32f1e..dd2aaf64ae7 100644 --- a/addons/test_mail_full/tests/test_sms_composer.py +++ b/addons/test_mail_full/tests/test_sms_composer.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.sms.tests import common as sms_common from odoo.addons.test_mail.tests import common as test_mail_common from odoo.addons.test_mail_full.tests import common as test_mail_full_common -from odoo.addons.phone_validation.tools.phone_validation import phone_format class TestSMSComposer(test_mail_full_common.BaseFunctionalTest, sms_common.MockSMS, test_mail_common.MockEmails, test_mail_common.TestRecipients): @@ -14,11 +14,9 @@ class TestSMSComposer(test_mail_full_common.BaseFunctionalTest, sms_common.MockS super(TestSMSComposer, cls).setUpClass() cls._test_body = 'VOID CONTENT' cls.partner_numbers = [ - phone_format(partner.mobile, partner.country_id.code, partner.country_id.phone_code, force_format='E164') + phone_validation.phone_format(partner.mobile, partner.country_id.code, partner.country_id.phone_code, force_format='E164') for partner in (cls.partner_1 | cls.partner_2) ] - cls.random_numbers_str = '+32475998877, 0475997788' - cls.random_numbers = [phone_format(number, 'BE', '32', force_format='E164') for number in ['+32475998877', '0475997788']] def test_composer_no_model(self): composer = self.env['sms.composer'].with_context().create({ @@ -62,13 +60,13 @@ class TestSMSComposer(test_mail_full_common.BaseFunctionalTest, sms_common.MockS 'mobile': 'coincoin', }) partners = self.partner_1 | self.partner_2 | partner_incorrect - composer = self.env['sms.composer'].with_context( - active_model='res.partner', - active_domain=[('id', 'in', partners.ids)] - ).create({ - 'message': self._test_body, - }) + # composer = self.env['sms.composer'].with_context( + # active_model='res.partner', + # active_domain=[('id', 'in', partners.ids)] + # ).create({ + # 'message': self._test_body, + # }) - with self.mockSMSGateway(): - composer.action_send_sms() + # with self.mockSMSGateway(): + # composer.action_send_sms() # self.assertSMSSent((self.partner_1 | self.partner_2).mapped('mobile'), test_body) # TDE FIXME: actually sanitizer does not work in current master (saas 12.23))
\ No newline at end of file diff --git a/addons/test_mail_full/tests/test_sms_performance.py b/addons/test_mail_full/tests/test_sms_performance.py new file mode 100644 index 00000000000..65c9e2cb4b5 --- /dev/null +++ b/addons/test_mail_full/tests/test_sms_performance.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.sms.tests import common as sms_common +from odoo.addons.test_mail.tests.test_performance import BaseMailPerformance +from odoo.tests.common import users, warmup +from odoo.tests import tagged +from odoo.tools import mute_logger + + +@tagged('mail_performance') +class TestSMSPerformance(BaseMailPerformance, sms_common.MockSMS): + + def setUp(self): + super(TestSMSPerformance, self).setUp() + self.user_employee.write({ + 'login': 'employee', + }) + self.admin = self.env.user + + self.customer = self.env['res.partner'].with_context(self._quick_create_ctx).create({ + 'name': 'Test Customer', + 'email': 'test@example.com', + 'mobile': '0456123456', + 'country_id': self.env.ref('base.be').id, + }) + self.test_record = self.env['mail.test.sms'].with_context(self._quick_create_ctx).create({ + 'name': 'Test', + 'customer_id': self.customer.id, + 'phone_nbr': '0456999999', + }) + + # prepare recipients to test for more realistic workload + Partners = self.env['res.partner'].with_context(self._quick_create_ctx) + self.partners = self.env['res.partner'] + for x in range(0, 10): + self.partners |= Partners.create({ + 'name': 'Test %s' % x, + 'email': 'test%s@example.com' % x, + 'mobile': '0456%s%s0000' % (x, x), + 'country_id': self.env.ref('base.be').id, + }) + + # patch registry to simulate a ready environment + self.patch(self.env.registry, 'ready', True) + + @mute_logger('odoo.addons.sms.models.sms_sms') + @users('employee') + @warmup + def test_message_sms_record_1_partner(self): + record = self.test_record.with_user(self.env.user) + pids = self.customer.ids + with self.mockSMSGateway(), self.assertQueryCount(employee=22): # test_mail_enterprise: 22 + messages = record._message_sms( + body='Performance Test', + partner_ids=pids, + ) + + self.assertEqual(record.message_ids[0].body, '<p>Performance Test</p>') + self.assertSMSNotification([{'partner': self.customer}], 'Performance Test', messages) + + @mute_logger('odoo.addons.sms.models.sms_sms') + @users('employee') + @warmup + def test_message_sms_record_10_partners(self): + record = self.test_record.with_user(self.env.user) + pids = self.partners.ids + with self.mockSMSGateway(), self.assertQueryCount(employee=40): # test_mail_enterprise: 40 + messages = record._message_sms( + body='Performance Test', + partner_ids=pids, + ) + + self.assertEqual(record.message_ids[0].body, '<p>Performance Test</p>') + self.assertSMSNotification([{'partner': partner} for partner in self.partners], 'Performance Test', messages) + + @mute_logger('odoo.addons.sms.models.sms_sms') + @users('employee') + @warmup + def test_message_sms_record_default(self): + record = self.test_record.with_user(self.env.user) + with self.mockSMSGateway(), self.assertQueryCount(employee=26): # test_mail_enterprise: 26 + messages = record._message_sms( + body='Performance Test', + ) + + self.assertEqual(record.message_ids[0].body, '<p>Performance Test</p>') + self.assertSMSNotification([{'partner': self.customer}], 'Performance Test', messages) diff --git a/addons/test_mail_full/tests/test_sms_post.py b/addons/test_mail_full/tests/test_sms_post.py index a12855341a0..f1e7d91b1d0 100644 --- a/addons/test_mail_full/tests/test_sms_post.py +++ b/addons/test_mail_full/tests/test_sms_post.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.phone_validation.tools import phone_validation from odoo.addons.sms.tests import common as sms_common from odoo.addons.test_mail.tests import common as test_mail_common from odoo.addons.test_mail_full.tests import common as test_mail_full_common @@ -11,44 +12,280 @@ class TestSMSPost(test_mail_full_common.BaseFunctionalTest, sms_common.MockSMS, @classmethod def setUpClass(cls): super(TestSMSPost, cls).setUpClass() + cls._test_body = 'VOID CONTENT' + + cls.partner_numbers = [ + phone_validation.phone_format(partner.mobile, partner.country_id.code, partner.country_id.phone_code, force_format='E164') + for partner in (cls.partner_1 | cls.partner_2) + ] + cls.test_record = cls.env['mail.test.sms'].with_context(**cls._test_context).create({ 'name': 'Test', 'customer_id': cls.partner_1.id, + 'mobile_nbr': cls.test_numbers[0], + 'phone_nbr': cls.test_numbers[1], }) cls.test_record = cls._reset_mail_context(cls.test_record) - def test_message_post_with_sms_on_partners(self): - test_body = 'Void body' - with self.mockSMSGateway(): - (self.partner_1 | self.partner_2).message_post_send_sms(test_body) - self.assertSMSSent((self.partner_1 | self.partner_2).mapped('mobile'), test_body) + def test_message_sms_internals_body(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms('<p>Mega SMS<br/>Top moumoutte</p>', partner_ids=self.partner_1.ids) - def test_message_post_with_sms_w_default(self): - test_body = 'Void body' - with self.mockSMSGateway(): - self.test_record.message_post_send_sms(test_body) - self.assertSMSSent(self.partner_1.mapped('mobile'), test_body) - self.assertIn(test_body, self.test_record.message_ids.body) + self.assertEqual(messages.body, '<p>Mega SMS<br>Top moumoutte</p>') + self.assertSMSNotification([{'partner': self.partner_1}], 'Mega SMS\nTop moumoutte', messages) - def test_message_post_with_sms_w_numbers(self): - test_body = 'Void body' - test_numbers = ['0475114477', '0475225588'] - with self.mockSMSGateway(): - self.test_record.message_post_send_sms(test_body, numbers=test_numbers) - self.assertSMSSent(test_numbers, test_body) - self.assertIn(test_body, self.test_record.message_ids.body) + def test_message_sms_internals_check_existing(self): + with self.sudo('employee'), self.mockSMSGateway(sim_error='wrong_format_number'): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=self.partner_1.ids) - def test_message_post_with_sms_w_numbers_duplicate(self): - test_body = 'Void body' - test_numbers = ['0475114477', '0475225588', '0475114477'] - with self.mockSMSGateway(): - self.test_record.message_post_send_sms(test_body, numbers=test_numbers) - self.assertSMSSent(test_numbers, test_body) - self.assertIn(test_body, self.test_record.message_ids.body) + self.assertSMSNotification([{'partner': self.partner_1, 'state': 'exception', 'failure_type': 'sms_number_format'}], self._test_body, messages) + + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + test_record._notify_record_by_sms(messages, {'partners': [{'id': self.partner_1.id, 'notif': 'sms'}]}, check_existing=True) + self.assertSMSNotification([{'partner': self.partner_1}], self._test_body, messages) + + def test_message_sms_internals_sms_numbers(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=self.partner_1.ids, sms_numbers=self.random_numbers) + + self.assertSMSNotification([{'partner': self.partner_1}, {'number': self.random_numbers_san[0]}, {'number': self.random_numbers_san[1]}], self._test_body, messages) + + def test_message_sms_internals_pid_to_number(self): + pid_to_number = { + self.partner_1.id: self.random_numbers[0], + self.partner_2.id: self.random_numbers[1], + } + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2).ids, sms_pid_to_number=pid_to_number) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'number': self.random_numbers_san[0]}, + {'partner': self.partner_2, 'number': self.random_numbers_san[1]}], + self._test_body, messages) + + def test_message_sms_model_partner(self): + with self.sudo('employee'), self.mockSMSGateway(): + messages = self.partner_1._message_sms(self._test_body) + messages |= self.partner_2._message_sms(self._test_body) + self.assertSMSNotification([{'partner': self.partner_1}, {'partner': self.partner_2}], self._test_body, messages) + + def test_message_sms_model_partner_fallback(self): + self.partner_1.write({'mobile': False, 'phone': self.random_numbers[0]}) - def test_message_post_with_sms_w_partners(self): - test_body = 'Void body' with self.mockSMSGateway(): - self.test_record.message_post_send_sms(test_body, partners=self.partner_1 | self.partner_2) - self.assertSMSSent((self.partner_1 | self.partner_2).mapped('mobile'), test_body) - self.assertIn(test_body, self.test_record.message_ids.body) + messages = self.partner_1._message_sms(self._test_body) + messages |= self.partner_2._message_sms(self._test_body) + + self.assertSMSNotification([{'partner': self.partner_1, 'number': self.random_numbers_san[0]}, {'partner': self.partner_2}], self._test_body, messages) + + def test_message_sms_model_w_partner_only(self): + with self.sudo('employee'): + record = self.env['mail.test.sms.partner'].create({'partner_id': self.partner_1.id}) + + with self.mockSMSGateway(): + messages = record._message_sms(self._test_body) + + self.assertSMSNotification([{'partner': self.partner_1}], self._test_body, messages) + + def test_message_sms_model_w_partner_only_void(self): + with self.sudo('employee'): + record = self.env['mail.test.sms.partner'].create({'partner_id': False}) + + with self.mockSMSGateway(): + messages = record._message_sms(self._test_body) + + # should not crash but no sms / no recipients + notifs = self.env['mail.notification'].search([('mail_message_id', 'in', messages.ids)]) + self.assertFalse(notifs) + + def test_message_sms_on_field_w_partner(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, number_field='mobile_nbr') + + self.assertSMSNotification([{'partner': self.partner_1, 'number': self.test_record.mobile_nbr}], self._test_body, messages) + + def test_message_sms_on_field_wo_partner(self): + self.test_record.write({'customer_id': False}) + + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, number_field='mobile_nbr') + + self.assertSMSNotification([{'number': self.test_record.mobile_nbr}], self._test_body, messages) + + def test_message_sms_on_field_wo_partner_default_field(self): + self.test_record.write({'customer_id': False}) + + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body) + + self.assertSMSNotification([{'number': self.test_numbers_san[1]}], self._test_body, messages) + + def test_message_sms_on_field_wo_partner_default_field_2(self): + self.test_record.write({'customer_id': False, 'phone_nbr': False}) + + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body) + + self.assertSMSNotification([{'number': self.test_numbers_san[0]}], self._test_body, messages) + + def test_message_sms_on_numbers(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, sms_numbers=self.random_numbers_san) + self.assertSMSNotification([{'number': self.random_numbers_san[0]}, {'number': self.random_numbers_san[1]}], self._test_body, messages) + + def test_message_sms_on_numbers_sanitization(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, sms_numbers=self.random_numbers) + self.assertSMSNotification([{'number': self.random_numbers_san[0]}, {'number': self.random_numbers_san[1]}], self._test_body, messages) + + def test_message_sms_on_partner_ids(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2).ids) + + self.assertSMSNotification([{'partner': self.partner_1}, {'partner': self.partner_2}], self._test_body, messages) + + def test_message_sms_on_partner_ids_default(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body) + + self.assertSMSNotification([{'partner': self.test_record.customer_id, 'number': self.test_numbers_san[1]}], self._test_body, messages) + + def test_message_sms_on_partner_ids_w_numbers(self): + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=self.partner_1.ids, sms_numbers=self.random_numbers[:1]) + + self.assertSMSNotification([{'partner': self.partner_1}, {'number': self.random_numbers_san[0]}], self._test_body, messages) + + +class TestSMSPostException(test_mail_full_common.BaseFunctionalTest, sms_common.MockSMS, test_mail_common.MockEmails, test_mail_common.TestRecipients): + + @classmethod + def setUpClass(cls): + super(TestSMSPostException, cls).setUpClass() + cls._test_body = 'VOID CONTENT' + + cls.test_record = cls.env['mail.test.sms'].with_context(**cls._test_context).create({ + 'name': 'Test', + 'customer_id': cls.partner_1.id, + }) + cls.test_record = cls._reset_mail_context(cls.test_record) + cls.partner_3 = cls.env['res.partner'].with_context({ + 'mail_create_nolog': True, + 'mail_create_nosubscribe': True, + 'mail_notrack': True, + 'no_reset_password': True, + }).create({ + 'name': 'Ernestine Loubine', + 'email': 'ernestine.loubine@agrolait.com', + 'country_id': cls.env.ref('base.be').id, + 'mobile': '0475556644', + }) + + def test_message_sms_w_numbers_invalid(self): + random_numbers = self.random_numbers + ['6988754'] + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, sms_numbers=random_numbers) + + # invalid numbers are still given to IAP currently as they are + self.assertSMSNotification([{'number': self.random_numbers_san[0]}, {'number': self.random_numbers_san[1]}, {'number': random_numbers[2]}], self._test_body, messages) + + def test_message_sms_w_partners_nocountry(self): + self.test_record.customer_id.write({ + 'mobile': self.random_numbers[0], + 'phone': self.random_numbers[1], + 'country_id': False, + }) + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=self.test_record.customer_id.ids) + + self.assertSMSNotification([{'partner': self.test_record.customer_id}], self._test_body, messages) + + def test_message_sms_w_partners_falsy(self): + # TDE FIXME: currently sent to IAP + self.test_record.customer_id.write({ + 'mobile': 'youpie', + 'phone': 'youpla', + }) + with self.sudo('employee'), self.mockSMSGateway(): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=self.test_record.customer_id.ids) + + # self.assertSMSNotification({self.test_record.customer_id: {}}, {}, self._test_body, messages) + + def test_message_sms_w_numbers_sanitization_duplicate(self): + pass + # TDE FIXME: not sure + # random_numbers = self.random_numbers + [self.random_numbers[1]] + # random_numbers_san = self.random_numbers_san + [self.random_numbers_san[1]] + # with self.sudo('employee'), self.mockSMSGateway(): + # messages = self.test_record._message_sms(self._test_body, sms_numbers=random_numbers) + # self.assertSMSNotification({}, {random_numbers_san[0]: {}, random_numbers_san[1]: {}, random_numbers_san[2]: {}}, self._test_body, messages) + + def test_message_sms_crash_credit(self): + with self.sudo('employee'), self.mockSMSGateway(sim_error='credit'): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2).ids) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'state': 'exception', 'failure_type': 'sms_credit'}, + {'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_credit'}, + ], self._test_body, messages) + + def test_message_sms_crash_credit_single(self): + with self.sudo('employee'), self.mockSMSGateway(nbr_t_error={phone_validation.phone_get_sanitized_record_number(self.partner_2): 'credit'}): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2 | self.partner_3).ids) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'state': 'sent'}, + {'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_credit'}, + {'partner': self.partner_3, 'state': 'sent'}, + ], self._test_body, messages) + + def test_message_sms_crash_server_crash(self): + with self.sudo('employee'), self.mockSMSGateway(sim_error='jsonrpc_exception'): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2 | self.partner_3).ids) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'state': 'exception', 'failure_type': 'sms_server'}, + {'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_server'}, + {'partner': self.partner_3, 'state': 'exception', 'failure_type': 'sms_server'}, + ], self._test_body, messages) + + def test_message_sms_crash_wrong_number(self): + with self.sudo('employee'), self.mockSMSGateway(sim_error='wrong_format_number'): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2).ids) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'state': 'exception', 'failure_type': 'sms_number_format'}, + {'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_number_format'}, + ], self._test_body, messages) + + def test_message_sms_crash_wrong_number_single(self): + with self.sudo('employee'), self.mockSMSGateway(nbr_t_error={phone_validation.phone_get_sanitized_record_number(self.partner_2): 'wrong_format_number'}): + test_record = self.env['mail.test.sms'].browse(self.test_record.id) + messages = test_record._message_sms(self._test_body, partner_ids=(self.partner_1 | self.partner_2 | self.partner_3).ids) + + self.assertSMSNotification([ + {'partner': self.partner_1, 'state': 'sent'}, + {'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_number_format'}, + {'partner': self.partner_3, 'state': 'sent'}, + ], self._test_body, messages) diff --git a/addons/test_mail_full/tests/test_sms_sms.py b/addons/test_mail_full/tests/test_sms_sms.py new file mode 100644 index 00000000000..46149f559a8 --- /dev/null +++ b/addons/test_mail_full/tests/test_sms_sms.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from unittest.mock import patch +from unittest.mock import DEFAULT + +from odoo import exceptions +from odoo.addons.sms.models.sms_sms import SmsSms as SmsSms +from odoo.addons.sms.tests import common as sms_common +from odoo.addons.test_mail.tests import common as test_mail_common +from odoo.addons.test_mail_full.tests import common as test_mail_full_common + + +class TestSMSPost(test_mail_full_common.BaseFunctionalTest, sms_common.MockSMS, test_mail_common.MockEmails, test_mail_common.TestRecipients): + + @classmethod + def setUpClass(cls): + super(TestSMSPost, cls).setUpClass() + cls._test_body = 'VOID CONTENT' + + cls.sms_all = cls.env['sms.sms'] + for x in range(10): + cls.sms_all |= cls.env['sms.sms'].create({ + 'number': '+324560000%s%s' % (x, x), + 'body': cls._test_body, + }) + + def test_sms_send_batch_size(self): + self.count = 0 + + def _send(sms_self, delete_all=False, raise_exception=False): + self.count += 1 + return DEFAULT + + self.env['ir.config_parameter'].set_param('sms.session.batch.size', '3') + with patch.object(SmsSms, '_send', autospec=True, side_effect=_send) as send_mock: + self.env['sms.sms'].browse(self.sms_all.ids).send() + + self.assertEqual(self.count, 4) + + def test_sms_send_crash_employee(self): + with self.assertRaises(exceptions.AccessError): + self.env['sms.sms'].with_user(self.user_employee).browse(self.sms_all.ids).send() + + def test_sms_send_delete_all(self): + with self.mockSMSGateway(sim_error='jsonrpc_exception'): + self.env['sms.sms'].browse(self.sms_all.ids).send(delete_all=True, raise_exception=False) + self.assertFalse(len(self.sms_all.exists())) + + def test_sms_send_raise(self): + with self.assertRaises(exceptions.AccessError): + with self.mockSMSGateway(sim_error='jsonrpc_exception'): + self.env['sms.sms'].browse(self.sms_all.ids).send(raise_exception=True) + self.assertEqual(set(self.sms_all.mapped('state')), set(['outgoing'])) + + def test_sms_send_raise_catch(self): + with self.mockSMSGateway(sim_error='jsonrpc_exception'): + self.env['sms.sms'].browse(self.sms_all.ids).send(raise_exception=False) + self.assertEqual(set(self.sms_all.mapped('state')), set(['error'])) |
