mirror of
https://github.com/bringout/oca-ocb-mail.git
synced 2026-04-19 09:02:09 +02:00
Initial commit: Mail packages
This commit is contained in:
commit
4e53507711
1948 changed files with 751201 additions and 0 deletions
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_mail_thread_phone
|
||||
from . import test_phone_blacklist
|
||||
from . import test_sms_composer
|
||||
from . import test_sms_management
|
||||
from . import test_sms_mixin
|
||||
from . import test_sms_performance
|
||||
from . import test_sms_post
|
||||
from . import test_sms_server_actions
|
||||
from . import test_sms_sms
|
||||
from . import test_sms_template
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# -*- 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.common import SMSCommon
|
||||
from odoo.addons.test_mail.tests.common import TestMailCommon, TestRecipients
|
||||
|
||||
|
||||
class TestSMSCommon(SMSCommon, TestMailCommon):
|
||||
""" Main entry point for functional tests. Kept to ease backward
|
||||
compatibility and updating common. """
|
||||
|
||||
|
||||
class TestSMSRecipients(TestRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSRecipients, cls).setUpClass()
|
||||
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)
|
||||
]
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import tagged, users
|
||||
|
||||
|
||||
@tagged('mail_thread')
|
||||
class TestSMSActionsCommon(TestSMSCommon, TestSMSRecipients):
|
||||
""" Test mail.thread.phone mixin, its tools and API """
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.test_phone_records, cls.test_phone_partners = cls._create_records_for_batch(
|
||||
'mail.test.sms.bl',
|
||||
5,
|
||||
)
|
||||
cls.test_phone_records += cls.env['mail.test.sms.bl'].create([
|
||||
{
|
||||
'phone_nbr': '+32475110505',
|
||||
'mobile_nbr': '+32475000505',
|
||||
}, {
|
||||
'phone_nbr': '0032475110606',
|
||||
'mobile_nbr': '0032475000606',
|
||||
}, {
|
||||
'phone_nbr': '0032475110707',
|
||||
'mobile_nbr': False,
|
||||
}, {
|
||||
'phone_nbr': False,
|
||||
'mobile_nbr': False,
|
||||
},
|
||||
])
|
||||
|
||||
def test_initial_data(self):
|
||||
""" Test initial data for this class, allowing to be sure of I/O of tests. """
|
||||
self.assertEqual(
|
||||
self.test_phone_records.mapped('mobile_nbr'),
|
||||
['0475000000', '0475000101', '0475000202', '0475000303', '0475000404',
|
||||
'+32475000505', '0032475000606',
|
||||
False, False,
|
||||
]
|
||||
)
|
||||
self.assertEqual(
|
||||
self.test_phone_records.mapped('phone_nbr'),
|
||||
[False] * 5 + ['+32475110505', '0032475110606', '0032475110707', False]
|
||||
)
|
||||
|
||||
@users('employee')
|
||||
def test_search_phone_mobile_search_boolean(self):
|
||||
test_phone_records = self.test_phone_records.with_env(self.env)
|
||||
|
||||
# test Falsy -> is set / is not set
|
||||
for test_values in [False, '', ' ']:
|
||||
# test is not set -> both fields should be not set
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', test_values)])
|
||||
self.assertEqual(results, test_phone_records[-1],
|
||||
'Search on phone_mobile_search: = False: record with two void values')
|
||||
# test is set -> at least one field should be set
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '!=', test_values)])
|
||||
self.assertEqual(results, test_phone_records[:-1],
|
||||
'Search on phone_mobile_search: != False: record at least one value set')
|
||||
|
||||
# test Truthy -> is set / is not set
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', True)])
|
||||
self.assertEqual(results, test_phone_records[:-1],
|
||||
'Search on phone_mobile_search: = True: record at least one value set')
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '!=', True)])
|
||||
self.assertEqual(results, test_phone_records[-1],
|
||||
'Search on phone_mobile_search: != True: record with two void values')
|
||||
|
||||
@users('employee')
|
||||
def test_search_phone_mobile_search_equal(self):
|
||||
""" Test searching by phone/mobile with direct search """
|
||||
test_phone_records = self.test_phone_records.with_env(self.env)
|
||||
|
||||
# test "=" search
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', '0475')])
|
||||
self.assertFalse(results, 'Search on phone_mobile_search: = should return only matching results')
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', '0475000000')])
|
||||
self.assertEqual(results, test_phone_records[0])
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', '0032475110606')])
|
||||
self.assertEqual(results, test_phone_records[6])
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', '=', '+32475110606')])
|
||||
self.assertEqual(results, test_phone_records[6])
|
||||
|
||||
@users('employee')
|
||||
def test_search_phone_mobile_search_ilike(self):
|
||||
""" Test searching by phone/mobile on various ilike combinations """
|
||||
test_phone_records = self.test_phone_records.with_env(self.env)
|
||||
|
||||
# test ilike search
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'ilike', '0475')])
|
||||
self.assertEqual(results, test_phone_records[:5])
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'ilike', '101')])
|
||||
self.assertEqual(results, test_phone_records[1])
|
||||
|
||||
# test search using +32/0032
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'ilike', '+32475')])
|
||||
self.assertEqual(results, test_phone_records[5:8],
|
||||
'Search on phone_mobile_search: +32/0032 likeliness')
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'ilike', '0032475')])
|
||||
self.assertEqual(results, test_phone_records[5:8],
|
||||
'Search on phone_mobile_search: +32/0032 likeliness')
|
||||
|
||||
# test inverse ilike search
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'not ilike', '0475')])
|
||||
self.assertEqual(results, test_phone_records - test_phone_records[:5])
|
||||
results = self.env['mail.test.sms.bl'].search([('phone_mobile_search', 'not ilike', '101')])
|
||||
self.assertEqual(results, test_phone_records - test_phone_records[1])
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestPhoneBlacklist(TestSMSCommon, TestSMSRecipients):
|
||||
""" Test phone blacklist management """
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestPhoneBlacklist, cls).setUpClass()
|
||||
cls._test_body = 'VOID CONTENT'
|
||||
|
||||
cls.test_record = cls.env['mail.test.sms.bl'].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_phone_blacklist_create_unblacklisted(self):
|
||||
"""Ensure that the API allows creating unblacklisted records."""
|
||||
phone_number = self.test_numbers[0]
|
||||
unblacklisted_record = self.env['phone.blacklist'].sudo().create([{'number': phone_number, 'active': False}])
|
||||
self.assertFalse(unblacklisted_record.active, "Creating an unblacklisted record resulted in a blacklisted one")
|
||||
|
||||
# Make sure that an attempt to re-create unblacklisted number will leave the number as it was (unblacklisted)
|
||||
still_unblacklisted_record = self.env['phone.blacklist'].sudo().create([{'number': phone_number, 'active': False}])
|
||||
self.assertFalse(still_unblacklisted_record.active, "Attempt to re-create the unblacklisted record made it blacklisted")
|
||||
|
||||
def test_phone_blacklist_internals(self):
|
||||
with self.with_user('employee'):
|
||||
test_record = self.env['mail.test.sms.bl'].browse(self.test_record.id)
|
||||
self.assertEqual(test_record.phone_sanitized, self.test_numbers_san[1])
|
||||
self.assertFalse(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
bl_record = self.env['phone.blacklist'].sudo().create([{'number': self.test_numbers_san[1]}])
|
||||
test_record.invalidate_recordset()
|
||||
self.assertTrue(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
self.env['phone.blacklist'].sudo().remove(self.test_numbers_san[1])
|
||||
self.assertFalse(bl_record.active)
|
||||
test_record.invalidate_recordset()
|
||||
self.assertFalse(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
self.env['phone.blacklist'].sudo().add(self.test_numbers_san[1])
|
||||
self.assertTrue(bl_record.active)
|
||||
test_record.invalidate_recordset()
|
||||
self.assertTrue(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
bl_record_2 = self.env['phone.blacklist'].sudo().create([{'number': self.test_numbers_san[1]}])
|
||||
self.assertEqual(bl_record, bl_record_2)
|
||||
|
||||
rec = self.env['mail.test.sms.bl'].search([('phone_sanitized_blacklisted', '=', True)])
|
||||
self.assertEqual(rec, test_record)
|
||||
|
||||
bl_record.unlink()
|
||||
rec = self.env['mail.test.sms.bl'].search([('phone_sanitized_blacklisted', '=', True)])
|
||||
self.assertEqual(rec, self.env['mail.test.sms.bl'])
|
||||
|
||||
def test_phone_blacklist_unblacklisted(self):
|
||||
""" This test check for scenario where user:
|
||||
1. Blacklists a number -> creating new active record)
|
||||
2. Unblacklists it -> making record unactive (archived)
|
||||
3. Blacklists it again (by attempting to create new record)
|
||||
Last step should just make existing record active again, and this test checks it.
|
||||
"""
|
||||
phone_number = self.test_numbers[0]
|
||||
bl_record = self.env['phone.blacklist'].sudo().create([{'number': phone_number, 'active': True}])
|
||||
num_of_records = self.env['phone.blacklist'].with_context(active_test=False).search_count([])
|
||||
|
||||
bl_record.action_archive()
|
||||
|
||||
# Attempt to blacklist unblacklisted
|
||||
self.env['phone.blacklist'].sudo().create([{'number': phone_number}])
|
||||
|
||||
self.assertTrue(bl_record.active, "Attempting to blacklist already-unblacklisted, should make the record active again")
|
||||
self.assertEqual(num_of_records, self.env['phone.blacklist'].with_context(active_test=False).search_count([]),
|
||||
"Number of records shouldn't change. (Records probably were recreated, instead of activated)")
|
||||
|
||||
def test_phone_sanitize_api(self):
|
||||
with self.with_user('employee'):
|
||||
test_record = self.env['mail.test.sms.bl'].browse(self.test_record.id)
|
||||
self.assertFalse(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
test_record._phone_set_blacklisted()
|
||||
test_record.invalidate_recordset()
|
||||
self.assertTrue(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
test_record._phone_reset_blacklisted()
|
||||
test_record.invalidate_recordset()
|
||||
self.assertFalse(test_record.phone_sanitized_blacklisted)
|
||||
|
||||
def test_phone_sanitize_internals(self):
|
||||
with self.with_user('employee'):
|
||||
test_record = self.env['mail.test.sms.bl'].browse(self.test_record.id)
|
||||
self.assertEqual(test_record.phone_nbr, self.test_numbers[1])
|
||||
self.assertEqual(test_record.phone_sanitized, self.test_numbers_san[1])
|
||||
|
||||
test_record.write({'phone_nbr': 'incorrect'})
|
||||
self.assertEqual(test_record.phone_nbr, 'incorrect')
|
||||
self.assertEqual(test_record.phone_sanitized, self.test_numbers_san[0])
|
||||
|
||||
test_record.write({'mobile_nbr': 'incorrect'})
|
||||
self.assertEqual(test_record.mobile_nbr, 'incorrect')
|
||||
self.assertEqual(test_record.phone_sanitized, False)
|
||||
|
||||
test_record.write({'phone_nbr': self.test_numbers[1]})
|
||||
self.assertEqual(test_record.phone_nbr, self.test_numbers[1])
|
||||
self.assertEqual(test_record.phone_sanitized, self.test_numbers_san[1])
|
||||
|
|
@ -0,0 +1,625 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged('sms_composer')
|
||||
class TestSMSComposerComment(TestSMSCommon, TestSMSRecipients):
|
||||
""" TODO LIST
|
||||
|
||||
* add test for default_res_model / default_res_id and stuff like that;
|
||||
* add test for comment put in queue;
|
||||
* add test for language support (set template lang context);
|
||||
* add test for sanitized / wrong numbers;
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSComposerComment, 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,
|
||||
'mobile_nbr': cls.test_numbers[0],
|
||||
'phone_nbr': cls.test_numbers[1],
|
||||
})
|
||||
cls.test_record = cls._reset_mail_context(cls.test_record)
|
||||
|
||||
cls.sms_template = cls.env['sms.template'].create({
|
||||
'name': 'Test Template',
|
||||
'model_id': cls.env['ir.model']._get('mail.test.sms').id,
|
||||
'body': 'Dear {{ object.display_name }} this is an SMS.',
|
||||
})
|
||||
|
||||
def test_composer_comment_not_mail_thread(self):
|
||||
with self.with_user('employee'):
|
||||
record = self.env['test_performance.base'].create({'name': 'TestBase'})
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='test_performance.base', active_id=record.id
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'numbers': ','.join(self.random_numbers),
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer._action_send_sms()
|
||||
|
||||
# use sms.api directly, does not create sms.sms
|
||||
self.assertNoSMS()
|
||||
self.assertSMSIapSent(self.random_numbers_san, self._test_body)
|
||||
|
||||
def test_composer_comment_default(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertSMSNotification([{'partner': self.test_record.customer_id, 'number': self.test_numbers_san[1]}], self._test_body, messages)
|
||||
|
||||
def test_composer_comment_field_1(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'number_field_name': 'mobile_nbr',
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertSMSNotification([{'partner': self.test_record.customer_id, 'number': self.test_numbers_san[0]}], self._test_body, messages)
|
||||
|
||||
def test_composer_comment_field_2(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'number_field_name': 'phone_nbr',
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertSMSNotification([{'partner': self.test_record.customer_id, 'number': self.test_numbers_san[1]}], self._test_body, messages)
|
||||
|
||||
def test_composer_comment_field_w_numbers(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id,
|
||||
default_number_field_name='mobile_nbr',
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'numbers': ','.join(self.random_numbers),
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.test_record.customer_id, 'number': self.test_record.mobile_nbr},
|
||||
{'number': self.random_numbers_san[0]}, {'number': self.random_numbers_san[1]}], self._test_body, messages)
|
||||
|
||||
def test_composer_comment_field_w_template(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id,
|
||||
default_template_id=self.sms_template.id,
|
||||
default_number_field_name='mobile_nbr',
|
||||
).create({})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertSMSNotification([{'partner': self.test_record.customer_id, 'number': self.test_record.mobile_nbr}], 'Dear %s this is an SMS.' % self.test_record.display_name, messages)
|
||||
|
||||
def test_composer_comment_invalid_field(self):
|
||||
""" Test the Send Message in SMS Composer when a Model does not contain a number field name """
|
||||
test_record = self.env['mail.test.sms.partner'].create({
|
||||
'name': 'Test',
|
||||
'customer_id': self.partner_1.id,
|
||||
})
|
||||
sms_composer = self.env['sms.composer'].create({
|
||||
'body': self._test_body,
|
||||
'number_field_name': 'phone_nbr',
|
||||
'recipient_single_number_itf': self.random_numbers_san[0],
|
||||
'res_id': test_record.id,
|
||||
'res_model': 'mail.test.sms.partner'
|
||||
})
|
||||
|
||||
self.assertNotIn(','.join(test_record._fields), 'phone_nbr')
|
||||
with self.mockSMSGateway():
|
||||
sms_composer._action_send_sms()
|
||||
self.assertSMSNotification([{'number': self.random_numbers_san[0]}], self._test_body)
|
||||
|
||||
def test_composer_comment_nofield(self):
|
||||
""" Test the Send Message in SMS Composer when a Model does not contain any phone number related field """
|
||||
test_record = self.env['mail.test.sms.partner'].create({'name': 'Test'})
|
||||
sms_composer = self.env['sms.composer'].create({
|
||||
'body': self._test_body,
|
||||
'recipient_single_number_itf': self.random_numbers_san[0],
|
||||
'res_id': test_record.id,
|
||||
'res_model': 'mail.test.sms.partner'
|
||||
})
|
||||
with self.mockSMSGateway():
|
||||
sms_composer._action_send_sms()
|
||||
self.assertSMSNotification([{'number': self.random_numbers_san[0]}], self._test_body)
|
||||
|
||||
def test_composer_default_recipient(self):
|
||||
""" Test default description of SMS composer must be partner name"""
|
||||
self.test_record.write({
|
||||
'phone_nbr': '0123456789',
|
||||
})
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_res_model='mail.test.sms', default_res_id=self.test_record.id,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'number_field_name': 'phone_nbr',
|
||||
})
|
||||
|
||||
self.assertEqual(composer.recipient_single_description, self.test_record.customer_id.display_name)
|
||||
|
||||
def test_composer_nofield_w_customer(self):
|
||||
""" Test SMS composer without number field, the number on partner must be used instead"""
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_res_model='mail.test.sms', default_res_id=self.test_record.id,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
})
|
||||
|
||||
self.assertTrue(composer.recipient_single_valid)
|
||||
self.assertEqual(composer.recipient_single_number, self.test_numbers_san[1])
|
||||
self.assertEqual(composer.recipient_single_number_itf, self.test_numbers_san[1])
|
||||
|
||||
def test_composer_internals(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_res_model='mail.test.sms', default_res_id=self.test_record.id,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'number_field_name': 'phone_nbr',
|
||||
})
|
||||
|
||||
self.assertEqual(composer.res_model, self.test_record._name)
|
||||
self.assertEqual(composer.res_id, self.test_record.id)
|
||||
self.assertEqual(composer.number_field_name, 'phone_nbr')
|
||||
self.assertTrue(composer.comment_single_recipient)
|
||||
self.assertEqual(composer.recipient_single_description, self.test_record.customer_id.display_name)
|
||||
self.assertEqual(composer.recipient_single_number, self.test_numbers_san[1])
|
||||
self.assertEqual(composer.recipient_single_number_itf, self.test_numbers_san[1])
|
||||
self.assertTrue(composer.recipient_single_valid)
|
||||
self.assertEqual(composer.recipient_valid_count, 1)
|
||||
self.assertEqual(composer.recipient_invalid_count, 0)
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer.update({'recipient_single_number_itf': '0123456789'})
|
||||
|
||||
self.assertFalse(composer.recipient_single_valid)
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer.update({'recipient_single_number_itf': self.random_numbers[0]})
|
||||
|
||||
self.assertTrue(composer.recipient_single_valid)
|
||||
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
self.test_record.flush_recordset()
|
||||
self.assertEqual(self.test_record.phone_nbr, self.random_numbers[0])
|
||||
|
||||
def test_composer_comment_wo_partner_wo_value_update(self):
|
||||
""" Test record without partner and without phone values: should allow updating first found phone field """
|
||||
self.test_record.write({
|
||||
'customer_id': False,
|
||||
'phone_nbr': False,
|
||||
'mobile_nbr': False,
|
||||
})
|
||||
default_field_name = self.env['mail.test.sms']._sms_get_number_fields()[0]
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
active_model='mail.test.sms', active_id=self.test_record.id,
|
||||
default_composition_mode='comment',
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
})
|
||||
self.assertFalse(composer.recipient_single_number_itf)
|
||||
self.assertFalse(composer.recipient_single_number)
|
||||
self.assertEqual(composer.number_field_name, default_field_name)
|
||||
|
||||
composer.write({
|
||||
'recipient_single_number_itf': self.random_numbers_san[0],
|
||||
})
|
||||
self.assertEqual(composer.recipient_single_number_itf, self.random_numbers_san[0])
|
||||
self.assertFalse(composer.recipient_single_number)
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
self.assertEqual(self.test_record[default_field_name], self.random_numbers_san[0])
|
||||
self.assertSMSNotification([{'partner': self.env['res.partner'], 'number': self.random_numbers_san[0]}], self._test_body, messages)
|
||||
|
||||
def test_composer_numbers_no_model(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='numbers'
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'numbers': ','.join(self.random_numbers),
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer._action_send_sms()
|
||||
|
||||
# use sms.api directly, does not create sms.sms
|
||||
self.assertNoSMS()
|
||||
self.assertSMSIapSent(self.random_numbers_san, self._test_body)
|
||||
|
||||
def test_composer_sending_with_no_number_field(self):
|
||||
test_record = self.env['mail.test.sms.partner'].create({'name': 'Test'})
|
||||
sms_composer = self.env['sms.composer'].create({
|
||||
'body': self._test_body,
|
||||
'composition_mode': 'comment',
|
||||
'mass_force_send': False,
|
||||
'mass_keep_log': True,
|
||||
'number_field_name': False,
|
||||
'numbers': False,
|
||||
'recipient_single_number_itf': self.random_numbers_san[0],
|
||||
'res_id': test_record.id,
|
||||
'res_model': 'mail.test.sms.partner'
|
||||
})
|
||||
with self.mockSMSGateway():
|
||||
sms_composer._action_send_sms()
|
||||
self.assertSMSNotification([{'number': self.random_numbers_san[0]}], self._test_body)
|
||||
|
||||
|
||||
@tagged('sms_composer')
|
||||
class TestSMSComposerBatch(TestSMSCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSComposerBatch, cls).setUpClass()
|
||||
cls._test_body = 'Hello {{ object.name }} zizisse an SMS.'
|
||||
|
||||
cls._create_records_for_batch('mail.test.sms', 3)
|
||||
cls.sms_template = cls._create_sms_template('mail.test.sms')
|
||||
|
||||
def test_composer_batch_active_ids(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='comment',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
for record, message in zip(self.records, messages):
|
||||
self.assertSMSNotification(
|
||||
[{'partner': record.customer_id}],
|
||||
'Hello %s zizisse an SMS.' % record.name,
|
||||
message
|
||||
)
|
||||
|
||||
def test_composer_batch_res_ids(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='comment',
|
||||
default_res_model='mail.test.sms',
|
||||
default_res_ids=repr(self.records.ids),
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
for record, message in zip(self.records, messages):
|
||||
self.assertSMSNotification(
|
||||
[{'partner': record.customer_id}],
|
||||
'Hello %s zizisse an SMS.' % record.name,
|
||||
message
|
||||
)
|
||||
|
||||
|
||||
@tagged('sms_composer')
|
||||
class TestSMSComposerMass(TestSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSComposerMass, cls).setUpClass()
|
||||
cls._test_body = 'Hello {{ object.name }} zizisse an SMS.'
|
||||
|
||||
cls._create_records_for_batch('mail.test.sms', 10)
|
||||
cls.sms_template = cls._create_sms_template('mail.test.sms')
|
||||
|
||||
def test_composer_mass_active_ids(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': False,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for partner, record in zip(self.partners, self.records):
|
||||
self.assertSMSOutgoing(
|
||||
partner, None,
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_w_blacklist(self):
|
||||
self.env['phone.blacklist'].create([{
|
||||
'number': p.phone_sanitized,
|
||||
'active': True,
|
||||
} for p in self.partners[:5]])
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': False,
|
||||
'mass_use_blacklist': True,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for partner, record in zip(self.partners[5:], self.records[5:]):
|
||||
self.assertSMSOutgoing(
|
||||
partner, partner.phone_sanitized,
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
for partner, record in zip(self.partners[:5], self.records[:5]):
|
||||
self.assertSMSCanceled(
|
||||
partner, partner.phone_sanitized,
|
||||
failure_type='sms_blacklist',
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_wo_blacklist(self):
|
||||
self.env['phone.blacklist'].create([{
|
||||
'number': p.phone_sanitized,
|
||||
'active': True,
|
||||
} for p in self.partners[:5]])
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': False,
|
||||
'mass_use_blacklist': False,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for partner, record in zip(self.partners, self.records):
|
||||
self.assertSMSOutgoing(
|
||||
partner, partner.phone_sanitized,
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_w_blacklist_and_done(self):
|
||||
""" Create some duplicates + blacklist. record[5] will have duplicated
|
||||
number on 6 and 7. """
|
||||
self.env['phone.blacklist'].create([{
|
||||
'number': p.phone_sanitized,
|
||||
'active': True,
|
||||
} for p in self.partners[:5]])
|
||||
for p in self.partners[5:8]:
|
||||
p.mobile = self.partners[5].mobile
|
||||
self.assertEqual(p.phone_sanitized, self.partners[5].phone_sanitized)
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': False,
|
||||
'mass_use_blacklist': True,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
self.assertSMSOutgoing(
|
||||
self.partners[5], self.partners[5].phone_sanitized,
|
||||
content='Hello %s zizisse an SMS.' % self.records[5].name
|
||||
)
|
||||
for partner, record in zip(self.partners[8:], self.records[8:]):
|
||||
self.assertSMSOutgoing(
|
||||
partner, partner.phone_sanitized,
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
# duplicates
|
||||
for partner, record in zip(self.partners[6:8], self.records[6:8]):
|
||||
self.assertSMSCanceled(
|
||||
partner, partner.phone_sanitized,
|
||||
failure_type='sms_duplicate',
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
# blacklist
|
||||
for partner, record in zip(self.partners[:5], self.records[:5]):
|
||||
self.assertSMSCanceled(
|
||||
partner, partner.phone_sanitized,
|
||||
failure_type='sms_blacklist',
|
||||
content='Hello %s zizisse an SMS.' % record.name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_w_template(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
default_template_id=self.sms_template.id,
|
||||
).create({
|
||||
'mass_keep_log': False,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(
|
||||
record.customer_id, None,
|
||||
content='Dear %s this is an SMS.' % record.display_name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_w_template_and_lang(self):
|
||||
self.env['res.lang']._activate_lang('fr_FR')
|
||||
self.sms_template.with_context(lang='fr_FR').body = 'Cher·e· {{ object.display_name }} ceci est un SMS.'
|
||||
# set template to try to use customer lang
|
||||
self.sms_template.write({
|
||||
'lang': '{{ object.customer_id.lang }}',
|
||||
})
|
||||
# set one customer as french speaking
|
||||
self.partners[2].write({'lang': 'fr_FR'})
|
||||
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
default_template_id=self.sms_template.id,
|
||||
).create({
|
||||
'mass_keep_log': False,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for record in self.records:
|
||||
if record.customer_id == self.partners[2]:
|
||||
self.assertSMSOutgoing(
|
||||
record.customer_id, None,
|
||||
content='Cher·e· %s ceci est un SMS.' % record.display_name
|
||||
)
|
||||
else:
|
||||
self.assertSMSOutgoing(
|
||||
record.customer_id, None,
|
||||
content='Dear %s this is an SMS.' % record.display_name
|
||||
)
|
||||
|
||||
def test_composer_mass_active_ids_w_template_and_log(self):
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
default_template_id=self.sms_template.id,
|
||||
).create({
|
||||
'mass_keep_log': True,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(
|
||||
record.customer_id, None,
|
||||
content='Dear %s this is an SMS.' % record.display_name
|
||||
)
|
||||
self.assertSMSLogged(record, 'Dear %s this is an SMS.' % record.display_name)
|
||||
|
||||
def test_composer_template_context_action(self):
|
||||
""" Test the context action from a SMS template (Add context action button)
|
||||
and the usage with the sms composer """
|
||||
# Create the lang info
|
||||
self.env['res.lang']._activate_lang('fr_FR')
|
||||
self.sms_template.with_context(lang='fr_FR').body = 'Hello {{ object.display_name }} ceci est en français.'
|
||||
# set template to try to use customer lang
|
||||
self.sms_template.write({
|
||||
'lang': '{{ object.customer_id.lang }}',
|
||||
})
|
||||
# create a second record linked to a customer in another language
|
||||
self.partners[2].write({'lang': 'fr_FR'})
|
||||
test_record_2 = self.env['mail.test.sms'].create({
|
||||
'name': 'Test',
|
||||
'customer_id': self.partners[2].id,
|
||||
})
|
||||
test_record_1 = self.env['mail.test.sms'].create({
|
||||
'name': 'Test',
|
||||
'customer_id': self.partners[1].id,
|
||||
})
|
||||
# Composer creation with context from a template context action (simulate) - comment (single recipient)
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
sms_composition_mode='guess',
|
||||
default_res_ids=[test_record_2.id],
|
||||
default_res_id=test_record_2.id,
|
||||
active_ids=[test_record_2.id],
|
||||
active_id=test_record_2.id,
|
||||
active_model='mail.test.sms',
|
||||
default_template_id=self.sms_template.id,
|
||||
).create({
|
||||
'mass_keep_log': False,
|
||||
})
|
||||
self.assertEqual(composer.composition_mode, "comment")
|
||||
self.assertEqual(composer.body, "Hello %s ceci est en français." % test_record_2.display_name)
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = composer._action_send_sms()
|
||||
|
||||
number = self.partners[2].phone_get_sanitized_number()
|
||||
self.assertSMSNotification(
|
||||
[{'partner': test_record_2.customer_id, 'number': number}],
|
||||
"Hello %s ceci est en français." % test_record_2.display_name, messages
|
||||
)
|
||||
|
||||
# Composer creation with context from a template context action (simulate) - mass (multiple recipient)
|
||||
with self.with_user('employee'):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
sms_composition_mode='guess',
|
||||
default_res_ids=[test_record_1.id, test_record_2.id],
|
||||
default_res_id=test_record_1.id,
|
||||
active_ids=[test_record_1.id, test_record_2.id],
|
||||
active_id=test_record_1.id,
|
||||
active_model='mail.test.sms',
|
||||
default_template_id=self.sms_template.id,
|
||||
).create({
|
||||
'mass_keep_log': True,
|
||||
})
|
||||
self.assertEqual(composer.composition_mode, "mass")
|
||||
# In english because by default but when sinding depending of record
|
||||
self.assertEqual(composer.body, "Dear {{ object.display_name }} this is an SMS.")
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer.action_send_sms()
|
||||
|
||||
self.assertSMSOutgoing(
|
||||
test_record_1.customer_id, None,
|
||||
content='Dear %s this is an SMS.' % test_record_1.display_name
|
||||
)
|
||||
self.assertSMSOutgoing(
|
||||
test_record_2.customer_id, None,
|
||||
content="Hello %s ceci est en français." % test_record_2.display_name
|
||||
)
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestSMSActionsCommon(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSActionsCommon, cls).setUpClass()
|
||||
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.msg = cls.test_record.message_post(body='TEST BODY', author_id=cls.partner_employee.id)
|
||||
cls.sms_p1 = cls.env['sms.sms'].create({
|
||||
'body': 'TEST BODY',
|
||||
'failure_type': 'sms_number_format',
|
||||
'mail_message_id': cls.msg.id,
|
||||
'number': cls.partner_1.mobile,
|
||||
'partner_id': cls.partner_1.id,
|
||||
'state': 'error',
|
||||
})
|
||||
cls.notif_p1 = cls.env['mail.notification'].create({
|
||||
'author_id': cls.msg.author_id.id,
|
||||
'mail_message_id': cls.msg.id,
|
||||
'res_partner_id': cls.partner_1.id,
|
||||
'sms_id': cls.sms_p1.id,
|
||||
'sms_number': cls.partner_1.mobile,
|
||||
'notification_type': 'sms',
|
||||
'notification_status': 'exception',
|
||||
'failure_type': 'sms_number_format',
|
||||
})
|
||||
cls.sms_p2 = cls.env['sms.sms'].create({
|
||||
'body': 'TEST BODY',
|
||||
'failure_type': 'sms_credit',
|
||||
'mail_message_id': cls.msg.id,
|
||||
'number': cls.partner_2.mobile,
|
||||
'partner_id': cls.partner_2.id,
|
||||
'state': 'error',
|
||||
})
|
||||
cls.notif_p2 = cls.env['mail.notification'].create({
|
||||
'author_id': cls.msg.author_id.id,
|
||||
'mail_message_id': cls.msg.id,
|
||||
'res_partner_id': cls.partner_2.id,
|
||||
'sms_id': cls.sms_p2.id,
|
||||
'sms_number': cls.partner_2.mobile,
|
||||
'notification_type': 'sms',
|
||||
'notification_status': 'exception',
|
||||
'failure_type': 'sms_credit',
|
||||
})
|
||||
|
||||
|
||||
@tagged('sms_management')
|
||||
class TestSMSActions(TestSMSActionsCommon):
|
||||
|
||||
def test_sms_notify_cancel(self):
|
||||
self._reset_bus()
|
||||
|
||||
with self.with_user('employee'):
|
||||
self.test_record.with_user(self.env.user).notify_cancel_by_type('sms')
|
||||
self.assertEqual((self.notif_p1 | self.notif_p2).mapped('notification_status'), ['canceled', 'canceled'])
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
def test_sms_set_cancel(self):
|
||||
self._reset_bus()
|
||||
self.sms_p1.action_set_canceled()
|
||||
self.assertEqual(self.sms_p1.state, 'canceled')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'canceled', 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'exception', 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
self._reset_bus()
|
||||
self.sms_p2.with_context(sms_skip_msg_notification=True).action_set_canceled()
|
||||
self.assertEqual(self.sms_p2.state, 'canceled')
|
||||
|
||||
self.assertEqual(self.env['bus.bus'].search([]), self.env['bus.bus'], 'SMS: no bus notifications unless asked')
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'canceled', 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'canceled', 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
|
||||
def test_sms_set_error(self):
|
||||
self._reset_bus()
|
||||
(self.sms_p1 + self.sms_p2).with_context(sms_skip_msg_notification=True).action_set_canceled()
|
||||
self.assertEqual(self.sms_p1.state, 'canceled')
|
||||
self.assertEqual(self.sms_p2.state, 'canceled')
|
||||
self.assertEqual(self.env['bus.bus'].search([]), self.env['bus.bus'], 'SMS: no bus notifications unless asked')
|
||||
|
||||
(self.sms_p1 + self.sms_p2).action_set_error('sms_server')
|
||||
self.assertEqual(self.sms_p1.state, 'error')
|
||||
self.assertEqual(self.sms_p2.state, 'error')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'exception', 'failure_type': 'sms_server'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'exception', 'failure_type': 'sms_server'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
def test_sms_set_outgoing(self):
|
||||
self._reset_bus()
|
||||
(self.sms_p1 + self.sms_p2).action_set_outgoing()
|
||||
self.assertEqual(self.sms_p1.state, 'outgoing')
|
||||
self.assertEqual(self.sms_p2.state, 'outgoing')
|
||||
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'number': self.notif_p1.sms_number, 'state': 'ready'},
|
||||
{'partner': self.partner_2, 'number': self.notif_p2.sms_number, 'state': 'ready'}
|
||||
], 'TEST BODY', self.msg, check_sms=False) # do not check new sms as they already exist
|
||||
|
||||
|
||||
@tagged('sms_management')
|
||||
class TestSMSWizards(TestSMSActionsCommon):
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend(self):
|
||||
self._reset_bus()
|
||||
|
||||
with self.with_user('employee'):
|
||||
wizard = self.env['sms.resend'].with_context(default_mail_message_id=self.msg.id).create({})
|
||||
wizard.write({'recipient_ids': [(1, r.id, {'resend': True}) for r in wizard.recipient_ids]})
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_resend()
|
||||
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'state': 'sent'},
|
||||
{'partner': self.partner_2, 'state': 'sent'}
|
||||
], 'TEST BODY', self.msg, check_sms=True)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_update_number(self):
|
||||
self._reset_bus()
|
||||
|
||||
with self.with_user('employee'):
|
||||
wizard = self.env['sms.resend'].with_context(default_mail_message_id=self.msg.id).create({})
|
||||
wizard.write({'recipient_ids': [(1, r.id, {'resend': True, 'sms_number': self.random_numbers[idx]}) for idx, r in enumerate(wizard.recipient_ids.sorted())]})
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_resend()
|
||||
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'state': 'sent', 'number': self.random_numbers_san[0]},
|
||||
{'partner': self.partner_2, 'state': 'sent', 'number': self.random_numbers_san[1]}
|
||||
], 'TEST BODY', self.msg, check_sms=True)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
def test_sms_resend_cancel(self):
|
||||
self._reset_bus()
|
||||
|
||||
with self.with_user('employee'):
|
||||
wizard = self.env['sms.resend'].with_context(default_mail_message_id=self.msg.id).create({})
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_cancel()
|
||||
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'state': 'canceled', 'number': self.notif_p1.sms_number, 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'state': 'canceled', 'number': self.notif_p2.sms_number, 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_internals(self):
|
||||
self._reset_bus()
|
||||
self.assertSMSNotification([
|
||||
{'partner': self.partner_1, 'state': 'exception', 'number': self.notif_p1.sms_number, 'failure_type': 'sms_number_format'},
|
||||
{'partner': self.partner_2, 'state': 'exception', 'number': self.notif_p2.sms_number, 'failure_type': 'sms_credit'}
|
||||
], 'TEST BODY', self.msg, check_sms=False)
|
||||
|
||||
with self.with_user('employee'):
|
||||
wizard = self.env['sms.resend'].with_context(default_mail_message_id=self.msg.id).create({})
|
||||
self.assertTrue(wizard.has_insufficient_credit)
|
||||
self.assertEqual(set(wizard.mapped('recipient_ids.partner_name')), set((self.partner_1 | self.partner_2).mapped('display_name')))
|
||||
wizard.write({'recipient_ids': [(1, r.id, {'resend': True}) for r in wizard.recipient_ids]})
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_resend()
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_sms_resend_w_cancel(self):
|
||||
self._reset_bus()
|
||||
|
||||
with self.with_user('employee'):
|
||||
wizard = self.env['sms.resend'].with_context(default_mail_message_id=self.msg.id).create({})
|
||||
wizard.write({'recipient_ids': [(1, r.id, {'resend': True if r.partner_id == self.partner_1 else False}) for r in wizard.recipient_ids]})
|
||||
with self.mockSMSGateway():
|
||||
wizard.action_resend()
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1, 'state': 'sent'}], 'TEST BODY', self.msg, check_sms=True)
|
||||
self.assertSMSNotification([{'partner': self.partner_2, 'state': 'canceled', 'number': self.notif_p2.sms_number, 'failure_type': 'sms_credit'}], 'TEST BODY', self.msg, check_sms=False)
|
||||
self.assertMessageBusNotifications(self.msg)
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import Form, tagged
|
||||
|
||||
|
||||
@tagged('sms_composer')
|
||||
class TestSMSNoThread(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls._test_body_dyn = 'Hello {{ object.name }} zizisse an SMS.'
|
||||
cls._test_body_sta = 'Hello Zboing'
|
||||
cls.test_nothreads = cls.env['sms.test.nothread'].create([
|
||||
{
|
||||
'name': 'Test',
|
||||
'customer_id': cls.partner_1.id,
|
||||
}, {
|
||||
'name': 'Test',
|
||||
'customer_id': cls.partner_2.id,
|
||||
}, {
|
||||
'name': 'Test (no partner)',
|
||||
'customer_id': False,
|
||||
},
|
||||
])
|
||||
cls.sms_template = cls._create_sms_template(
|
||||
cls.test_nothreads._name,
|
||||
body=cls._test_body_dyn,
|
||||
)
|
||||
|
||||
def test_composer_comment(self):
|
||||
with self.with_user('employee'):
|
||||
test_record = self.test_nothreads[0].with_env(self.env)
|
||||
composer_form = Form(self.env['sms.composer'].with_context(
|
||||
default_res_id=test_record.id,
|
||||
default_res_model=test_record._name,
|
||||
))
|
||||
composer_form.body = self._test_body_sta
|
||||
composer = composer_form.save()
|
||||
self.assertTrue(composer.comment_single_recipient)
|
||||
self.assertEqual(composer.composition_mode, 'comment')
|
||||
self.assertEqual(composer.recipient_valid_count, 0)
|
||||
self.assertEqual(composer.recipient_invalid_count, 1)
|
||||
self.assertEqual(composer.recipient_single_description, self.partner_1.name)
|
||||
self.assertEqual(composer.recipient_single_number, '+32456001122')
|
||||
self.assertEqual(composer.recipient_single_number_itf, '+32456001122')
|
||||
self.assertTrue(composer.recipient_single_valid)
|
||||
self.assertEqual(composer.number_field_name, 'mobile')
|
||||
self.assertFalse(composer.numbers)
|
||||
self.assertFalse(composer.sanitized_numbers)
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer._action_send_sms()
|
||||
|
||||
def test_composer_comment_res_ids(self):
|
||||
with self.with_user('employee'):
|
||||
test_record = self.test_nothreads[0].with_env(self.env)
|
||||
composer_form = Form(self.env['sms.composer'].with_context(
|
||||
default_res_ids=test_record.ids,
|
||||
default_res_model=test_record._name,
|
||||
))
|
||||
composer_form.body = self._test_body_sta
|
||||
composer = composer_form.save()
|
||||
# TDE FIXME: mono/mass mode should be fixed
|
||||
self.assertFalse(composer.comment_single_recipient)
|
||||
self.assertEqual(composer.composition_mode, 'comment')
|
||||
self.assertEqual(composer.recipient_valid_count, 1)
|
||||
self.assertEqual(composer.recipient_invalid_count, 0)
|
||||
self.assertFalse(composer.recipient_single_description)
|
||||
self.assertFalse(composer.recipient_single_number)
|
||||
self.assertFalse(composer.recipient_single_number_itf)
|
||||
self.assertFalse(composer.recipient_single_valid)
|
||||
self.assertFalse(composer.number_field_name)
|
||||
self.assertFalse(composer.numbers)
|
||||
self.assertFalse(composer.sanitized_numbers)
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer._action_send_sms()
|
||||
|
||||
def test_composer_comment_res_users(self):
|
||||
for ctx, expected in [
|
||||
({}, {}),
|
||||
({'default_number_field_name': 'mobile'}, {}),
|
||||
]:
|
||||
with self.subTest(ctx=ctx):
|
||||
with self.with_user('employee'):
|
||||
ctx['default_res_id'] = self.user_admin.id
|
||||
ctx['default_res_model'] = self.user_admin._name
|
||||
composer_form = Form(self.env['sms.composer'].with_context(**ctx))
|
||||
composer_form.body = self._test_body_sta
|
||||
composer = composer_form.save()
|
||||
self.assertTrue(composer.comment_single_recipient)
|
||||
self.assertEqual(composer.composition_mode, 'comment')
|
||||
if ctx.get('default_number_field_name') == 'mobile':
|
||||
self.assertEqual(composer.recipient_valid_count, 0)
|
||||
self.assertEqual(composer.recipient_invalid_count, 1)
|
||||
else:
|
||||
self.assertEqual(composer.recipient_valid_count, 1)
|
||||
self.assertEqual(composer.recipient_invalid_count, 0)
|
||||
self.assertEqual(composer.recipient_single_description, self.user_admin.name)
|
||||
self.assertEqual(composer.recipient_single_number, '+32455135790')
|
||||
self.assertEqual(composer.recipient_single_number_itf, '+32455135790')
|
||||
self.assertTrue(composer.recipient_single_valid)
|
||||
self.assertEqual(composer.number_field_name, ctx.get('default_number_field_name', 'phone'))
|
||||
self.assertFalse(composer.numbers)
|
||||
self.assertFalse(composer.sanitized_numbers)
|
||||
|
||||
with self.mockSMSGateway():
|
||||
composer._action_send_sms()
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
# -*- 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', 'post_install', '-at_install')
|
||||
class TestSMSPerformance(BaseMailPerformance, sms_common.SMSCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSMSPerformance, self).setUp()
|
||||
|
||||
self.test_record = self.env['mail.test.sms'].with_context(self._test_context).create({
|
||||
'name': 'Test',
|
||||
'customer_id': self.customer.id,
|
||||
'phone_nbr': '0456999999',
|
||||
})
|
||||
|
||||
# prepare recipients to test for more realistic workload
|
||||
self.partners = self.env['res.partner'].with_context(self._test_context).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,
|
||||
} for x in range(0, 10)
|
||||
])
|
||||
|
||||
@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(sms_allow_unlink=True), self.assertQueryCount(employee=26):
|
||||
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, sent_unlink=True)
|
||||
|
||||
@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(sms_allow_unlink=True), self.assertQueryCount(employee=26):
|
||||
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, sent_unlink=True)
|
||||
|
||||
@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(sms_allow_unlink=True), self.assertQueryCount(employee=28):
|
||||
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, sent_unlink=True)
|
||||
|
||||
|
||||
@tagged('mail_performance', 'post_install', '-at_install')
|
||||
class TestSMSMassPerformance(BaseMailPerformance, sms_common.MockSMS):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSMSMassPerformance, self).setUp()
|
||||
be_country_id = self.env.ref('base.be').id
|
||||
|
||||
self._test_body = 'MASS SMS'
|
||||
|
||||
records = self.env['mail.test.sms']
|
||||
partners = self.env['res.partner']
|
||||
for x in range(50):
|
||||
partners += self.env['res.partner'].with_context(**self._test_context).create({
|
||||
'name': 'Partner_%s' % (x),
|
||||
'email': '_test_partner_%s@example.com' % (x),
|
||||
'country_id': be_country_id,
|
||||
'mobile': '047500%02d%02d' % (x, x)
|
||||
})
|
||||
records += self.env['mail.test.sms'].with_context(**self._test_context).create({
|
||||
'name': 'Test_%s' % (x),
|
||||
'customer_id': partners[x].id,
|
||||
})
|
||||
self.partners = partners
|
||||
self.records = records
|
||||
|
||||
self.sms_template = self.env['sms.template'].create({
|
||||
'name': 'Test Template',
|
||||
'model_id': self.env['ir.model']._get('mail.test.sms').id,
|
||||
'body': 'Dear {{ object.display_name }} this is an SMS.',
|
||||
})
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
@users('employee')
|
||||
@warmup
|
||||
def test_sms_composer_mass(self):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': False,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=56):
|
||||
composer.action_send_sms()
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
@users('employee')
|
||||
@warmup
|
||||
def test_sms_composer_mass_w_log(self):
|
||||
composer = self.env['sms.composer'].with_context(
|
||||
default_composition_mode='mass',
|
||||
default_res_model='mail.test.sms',
|
||||
active_ids=self.records.ids,
|
||||
).create({
|
||||
'body': self._test_body,
|
||||
'mass_keep_log': True,
|
||||
})
|
||||
|
||||
with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=58):
|
||||
composer.action_send_sms()
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestSMSPost(TestSMSCommon, TestSMSRecipients):
|
||||
""" TODO
|
||||
|
||||
* add tests for new mail.message and mail.thread fields;
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSPost, 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,
|
||||
'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_sms_internals_body(self):
|
||||
with self.with_user('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)
|
||||
|
||||
self.assertEqual(messages.body, '<p><p>Mega SMS<br/>Top moumoutte</p></p>') # html should not be interpreted
|
||||
self.assertEqual(messages.subtype_id, self.env.ref('mail.mt_note'))
|
||||
self.assertSMSNotification([{'partner': self.partner_1}], '<p>Mega SMS<br/>Top moumoutte</p>', messages)
|
||||
|
||||
def test_message_sms_internals_resend_existingd(self):
|
||||
with self.with_user('employee'), self.mockSMSGateway(sim_error='wrong_number_format'):
|
||||
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)
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1, 'state': 'exception', 'failure_type': 'sms_number_format'}], self._test_body, messages)
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
test_record._notify_thread_by_sms(messages, [{'id': self.partner_1.id, 'notif': 'sms'}], resend_existing=True)
|
||||
self.assertSMSNotification([{'partner': self.partner_1}], self._test_body, messages)
|
||||
|
||||
def test_message_sms_internals_sms_numbers(self):
|
||||
with self.with_user('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_sms_numbers_duplicate(self):
|
||||
""" _message_sms ( which uses _notify_thread_by_sms) allows for specifying additional number to send sms to
|
||||
This test checks for situation where this additional number is the same as partner telephone number.
|
||||
In that case sms shall NOT be sent twice."""
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
additional_number_same_as_partner_number = self.partner_1.mobile
|
||||
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
|
||||
test_record._message_sms(
|
||||
body=self._test_body,
|
||||
partner_ids=self.partner_1.ids,
|
||||
subtype_id=subtype_id,
|
||||
sms_numbers=[additional_number_same_as_partner_number],
|
||||
number_field='mobile'
|
||||
)
|
||||
self.assertEqual(len(self._new_sms.filtered(lambda s: s.number == self.partner_numbers[0])), 1,
|
||||
"There should be one message sent if additional number is the same as partner number")
|
||||
|
||||
def test_message_sms_internals_subtype(self):
|
||||
with self.with_user('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>', subtype_id=self.env.ref('mail.mt_comment').id, partner_ids=self.partner_1.ids)
|
||||
|
||||
self.assertEqual(messages.body, '<p><p>Mega SMS<br/>Top moumoutte</p></p>') # html should not be interpreted
|
||||
self.assertEqual(messages.subtype_id, self.env.ref('mail.mt_comment'))
|
||||
self.assertSMSNotification([{'partner': self.partner_1}], '<p>Mega SMS<br/>Top moumoutte</p>', 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.with_user('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.with_user('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]})
|
||||
|
||||
with 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, '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.with_user('employee'):
|
||||
record = self.env['mail.test.sms.partner'].create({'customer_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.with_user('employee'):
|
||||
record = self.env['mail.test.sms.partner'].create({'customer_id': False})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = record._message_sms(self._test_body)
|
||||
|
||||
# should not crash but have a failed notification
|
||||
self.assertSMSNotification([{'partner': self.env['res.partner'], 'number': False, 'state': 'exception', 'failure_type': 'sms_number_missing'}], self._test_body, messages)
|
||||
|
||||
def test_message_sms_model_w_partner_m2m_only(self):
|
||||
with self.with_user('employee'):
|
||||
record = self.env['mail.test.sms.partner.2many'].create({'customer_ids': [(4, self.partner_1.id)]})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = record._message_sms(self._test_body)
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1}], self._test_body, messages)
|
||||
|
||||
# TDE: should take first found one according to partner ordering
|
||||
with self.with_user('employee'):
|
||||
record = self.env['mail.test.sms.partner.2many'].create({'customer_ids': [(4, self.partner_1.id), (4, self.partner_2.id)]})
|
||||
|
||||
with self.mockSMSGateway():
|
||||
messages = record._message_sms(self._test_body)
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_2}], self._test_body, messages)
|
||||
|
||||
def test_message_sms_on_field_w_partner(self):
|
||||
with self.with_user('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.with_user('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_wo_value(self):
|
||||
""" Test record without a partner and without phone values. """
|
||||
self.test_record.write({
|
||||
'customer_id': False,
|
||||
'phone_nbr': False,
|
||||
'mobile_nbr': False,
|
||||
})
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
messages = test_record._message_sms(self._test_body)
|
||||
|
||||
# should not crash but have a failed notification
|
||||
self.assertSMSNotification([{'partner': self.env['res.partner'], 'number': False, 'state': 'exception', 'failure_type': 'sms_number_missing'}], self._test_body, messages)
|
||||
|
||||
def test_message_sms_on_field_wo_partner_default_field(self):
|
||||
self.test_record.write({'customer_id': False})
|
||||
|
||||
with self.with_user('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.with_user('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.with_user('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.with_user('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.with_user('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.with_user('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.with_user('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)
|
||||
|
||||
def test_message_sms_with_template(self):
|
||||
sms_template = self.env['sms.template'].create({
|
||||
'name': 'Test Template',
|
||||
'model_id': self.env['ir.model']._get('mail.test.sms').id,
|
||||
'body': 'Dear {{ object.display_name }} this is an SMS.',
|
||||
})
|
||||
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
messages = test_record._message_sms_with_template(template=sms_template)
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1, 'number': self.test_numbers_san[1]}], 'Dear %s this is an SMS.' % self.test_record.display_name, messages)
|
||||
|
||||
def test_message_sms_with_template_fallback(self):
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
messages = test_record._message_sms_with_template(template_xmlid='test_mail_full.this_should_not_exists', template_fallback='Fallback for {{ object.id }}')
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1, 'number': self.test_numbers_san[1]}], 'Fallback for %s' % self.test_record.id, messages)
|
||||
|
||||
def test_message_sms_with_template_xmlid(self):
|
||||
sms_template = self.env['sms.template'].create({
|
||||
'name': 'Test Template',
|
||||
'model_id': self.env['ir.model']._get('mail.test.sms').id,
|
||||
'body': 'Dear {{ object.display_name }} this is an SMS.',
|
||||
})
|
||||
self.env['ir.model.data'].create({
|
||||
'name': 'this_should_exists',
|
||||
'module': 'test_mail_full',
|
||||
'model': sms_template._name,
|
||||
'res_id': sms_template.id,
|
||||
})
|
||||
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
test_record = self.env['mail.test.sms'].browse(self.test_record.id)
|
||||
messages = test_record._message_sms_with_template(template_xmlid='test_mail_full.this_should_exists')
|
||||
|
||||
self.assertSMSNotification([{'partner': self.partner_1, 'number': self.test_numbers_san[1]}], 'Dear %s this is an SMS.' % self.test_record.display_name, messages)
|
||||
|
||||
|
||||
class TestSMSPostException(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@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.with_user('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.with_user('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.with_user('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.with_user('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.with_user('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.with_user('employee'), self.mockSMSGateway(nbr_t_error={self.partner_2.phone_get_sanitized_number(): '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.with_user('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_unregistered(self):
|
||||
with self.with_user('employee'), self.mockSMSGateway(sim_error='unregistered'):
|
||||
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_acc'},
|
||||
{'partner': self.partner_2, 'state': 'exception', 'failure_type': 'sms_acc'},
|
||||
], self._test_body, messages)
|
||||
|
||||
def test_message_sms_crash_unregistered_single(self):
|
||||
with self.with_user('employee'), self.mockSMSGateway(nbr_t_error={self.partner_2.phone_get_sanitized_number(): 'unregistered'}):
|
||||
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_acc'},
|
||||
{'partner': self.partner_3, 'state': 'sent'},
|
||||
], self._test_body, messages)
|
||||
|
||||
def test_message_sms_crash_wrong_number(self):
|
||||
with self.with_user('employee'), self.mockSMSGateway(sim_error='wrong_number_format'):
|
||||
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.with_user('employee'), self.mockSMSGateway(nbr_t_error={self.partner_2.phone_get_sanitized_number(): 'wrong_number_format'}):
|
||||
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)
|
||||
|
||||
|
||||
class TestSMSApi(TestSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSApi, cls).setUpClass()
|
||||
cls._test_body = 'Zizisse an SMS.'
|
||||
|
||||
cls._create_records_for_batch('mail.test.sms', 3)
|
||||
cls.sms_template = cls._create_sms_template('mail.test.sms')
|
||||
|
||||
def test_message_schedule_sms(self):
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
self.env['mail.test.sms'].browse(self.records.ids)._message_sms_schedule_mass(body=self._test_body, mass_keep_log=False)
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(record.customer_id, None, content=self._test_body)
|
||||
|
||||
def test_message_schedule_sms_w_log(self):
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
self.env['mail.test.sms'].browse(self.records.ids)._message_sms_schedule_mass(body=self._test_body, mass_keep_log=True)
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(record.customer_id, None, content=self._test_body)
|
||||
self.assertSMSLogged(record, self._test_body)
|
||||
|
||||
def test_message_schedule_sms_w_template(self):
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
self.env['mail.test.sms'].browse(self.records.ids)._message_sms_schedule_mass(template=self.sms_template, mass_keep_log=False)
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
|
||||
|
||||
def test_message_schedule_sms_w_template_and_log(self):
|
||||
with self.with_user('employee'):
|
||||
with self.mockSMSGateway():
|
||||
self.env['mail.test.sms'].browse(self.records.ids)._message_sms_schedule_mass(template=self.sms_template, mass_keep_log=True)
|
||||
|
||||
for record in self.records:
|
||||
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
|
||||
self.assertSMSLogged(record, 'Dear %s this is an SMS.' % record.display_name)
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@tagged('ir_actions')
|
||||
class TestServerAction(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestServerAction, cls).setUpClass()
|
||||
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_2 = cls.env['mail.test.sms'].with_context(**cls._test_context).create({
|
||||
'name': 'Test Record 2',
|
||||
'customer_id': False,
|
||||
'phone_nbr': cls.test_numbers[0],
|
||||
})
|
||||
|
||||
cls.sms_template = cls._create_sms_template('mail.test.sms')
|
||||
cls.action = cls.env['ir.actions.server'].create({
|
||||
'name': 'Test SMS Action',
|
||||
'model_id': cls.env['ir.model']._get('mail.test.sms').id,
|
||||
'state': 'sms',
|
||||
'sms_method': 'sms',
|
||||
'sms_template_id': cls.sms_template.id,
|
||||
'groups_id': cls.env.ref('base.group_user'),
|
||||
})
|
||||
|
||||
def test_action_sms(self):
|
||||
context = {
|
||||
'active_model': 'mail.test.sms',
|
||||
'active_ids': (self.test_record | self.test_record_2).ids,
|
||||
}
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
self.action.with_user(self.env.user).with_context(**context).run()
|
||||
|
||||
self.assertSMSOutgoing(self.test_record.customer_id, None, content='Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
self.assertSMSOutgoing(self.env['res.partner'], self.test_numbers_san[0], content='Dear %s this is an SMS.' % self.test_record_2.display_name)
|
||||
|
||||
def test_action_sms_single(self):
|
||||
context = {
|
||||
'active_model': 'mail.test.sms',
|
||||
'active_id': self.test_record.id,
|
||||
}
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
self.action.with_user(self.env.user).with_context(**context).run()
|
||||
self.assertSMSOutgoing(self.test_record.customer_id, None, content='Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
|
||||
def test_action_sms_w_log(self):
|
||||
self.action.sms_method = 'note'
|
||||
context = {
|
||||
'active_model': 'mail.test.sms',
|
||||
'active_ids': (self.test_record | self.test_record_2).ids,
|
||||
}
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
self.action.with_user(self.env.user).with_context(**context).run()
|
||||
|
||||
self.assertSMSOutgoing(self.test_record.customer_id, None, content='Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
self.assertSMSLogged(self.test_record, 'Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
|
||||
self.assertSMSOutgoing(self.env['res.partner'], self.test_numbers_san[0], content='Dear %s this is an SMS.' % self.test_record_2.display_name)
|
||||
self.assertSMSLogged(self.test_record_2, 'Dear %s this is an SMS.' % self.test_record_2.display_name)
|
||||
|
||||
@mute_logger('odoo.addons.sms.models.sms_sms')
|
||||
def test_action_sms_w_post(self):
|
||||
self.action.sms_method = 'comment'
|
||||
context = {
|
||||
'active_model': 'mail.test.sms',
|
||||
'active_ids': (self.test_record | self.test_record_2).ids,
|
||||
}
|
||||
|
||||
with self.with_user('employee'), self.mockSMSGateway():
|
||||
self.action.with_user(self.env.user).with_context(**context).run()
|
||||
|
||||
self.assertSMSNotification(
|
||||
[{'partner': self.test_record.customer_id}],
|
||||
'Dear %s this is an SMS.' % self.test_record.display_name,
|
||||
messages=self.test_record.message_ids[-1]
|
||||
)
|
||||
self.assertSMSNotification(
|
||||
[{'partner': self.env['res.partner'],
|
||||
'number': self.test_numbers_san[0]}],
|
||||
'Dear %s this is an SMS.' % self.test_record_2.display_name,
|
||||
messages=self.test_record_2.message_ids[-1]
|
||||
)
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
# -*- 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.link_tracker.tests.common import MockLinkTracker
|
||||
from odoo.addons.sms.models.sms_sms import SmsSms as SmsModel
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged('link_tracker')
|
||||
class TestSMSPost(TestSMSCommon, MockLinkTracker):
|
||||
|
||||
@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, unlink_failed=False, unlink_sent=True, raise_exception=False):
|
||||
self.count += 1
|
||||
return DEFAULT
|
||||
|
||||
self.env['ir.config_parameter'].set_param('sms.session.batch.size', '3')
|
||||
with patch.object(SmsModel, '_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(sms_allow_unlink=True, sim_error='jsonrpc_exception'):
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send(unlink_failed=True, unlink_sent=True, raise_exception=False)
|
||||
self.assertFalse(len(self.sms_all.exists()))
|
||||
|
||||
def test_sms_send_delete_default(self):
|
||||
""" Test default send behavior: keep failed SMS, remove sent. """
|
||||
with self.mockSMSGateway(sms_allow_unlink=True, nbr_t_error={
|
||||
'+32456000011': 'wrong_number_format',
|
||||
'+32456000022': 'credit',
|
||||
'+32456000033': 'server_error',
|
||||
'+32456000044': 'unregistered',
|
||||
}):
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send(raise_exception=False)
|
||||
remaining = self.sms_all.exists()
|
||||
self.assertEqual(len(remaining), 4)
|
||||
self.assertTrue(all(sms.state == 'error') for sms in remaining)
|
||||
|
||||
def test_sms_send_delete_failed(self):
|
||||
with self.mockSMSGateway(sms_allow_unlink=True, nbr_t_error={
|
||||
'+32456000011': 'wrong_number_format',
|
||||
'+32456000022': 'wrong_number_format',
|
||||
}):
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send(unlink_failed=True, unlink_sent=False, raise_exception=False)
|
||||
remaining = self.sms_all.exists()
|
||||
self.assertEqual(len(remaining), 8)
|
||||
self.assertTrue(all(sms.state == 'sent') for sms in remaining)
|
||||
|
||||
def test_sms_send_delete_none(self):
|
||||
with self.mockSMSGateway(sms_allow_unlink=True, nbr_t_error={
|
||||
'+32456000011': 'wrong_number_format',
|
||||
'+32456000022': 'wrong_number_format',
|
||||
}):
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send(unlink_failed=False, unlink_sent=False, raise_exception=False)
|
||||
self.assertEqual(len(self.sms_all.exists()), 10)
|
||||
success_sms = self.sms_all[:1] + self.sms_all[3:]
|
||||
error_sms = self.sms_all[1:3]
|
||||
self.assertTrue(all(sms.state == 'sent') for sms in success_sms)
|
||||
self.assertTrue(all(sms.state == 'error') for sms in error_sms)
|
||||
|
||||
def test_sms_send_delete_sent(self):
|
||||
with self.mockSMSGateway(sms_allow_unlink=True, nbr_t_error={
|
||||
'+32456000011': 'wrong_number_format',
|
||||
'+32456000022': 'wrong_number_format',
|
||||
}):
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send(unlink_failed=False, unlink_sent=True, raise_exception=False)
|
||||
remaining = self.sms_all.exists()
|
||||
self.assertEqual(len(remaining), 2)
|
||||
self.assertTrue(all(sms.state == 'error') for sms in remaining)
|
||||
|
||||
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']))
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestSmsTemplate(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSmsTemplate, cls).setUpClass()
|
||||
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.body_en = 'Dear {{ object.display_name }} this is an SMS.'
|
||||
cls.body_fr = u"Hello {{ object.display_name }} ceci est en français."
|
||||
cls.sms_template = cls._create_sms_template('mail.test.sms', body=cls.body_en)
|
||||
|
||||
def test_sms_template_render(self):
|
||||
rendered_body = self.sms_template._render_template(self.sms_template.body, self.sms_template.model, self.test_record.ids)
|
||||
self.assertEqual(rendered_body[self.test_record.id], 'Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
|
||||
rendered_body = self.sms_template._render_field('body', self.test_record.ids)
|
||||
self.assertEqual(rendered_body[self.test_record.id], 'Dear %s this is an SMS.' % self.test_record.display_name)
|
||||
|
||||
def test_sms_template_lang(self):
|
||||
self.env['res.lang']._activate_lang('fr_FR')
|
||||
self.user_admin.write({'lang': 'en_US'})
|
||||
self.sms_template.update_field_translations('body', {
|
||||
'fr_FR': self.body_fr
|
||||
})
|
||||
# set template to try to use customer lang
|
||||
self.sms_template.write({
|
||||
'lang': '{{ object.customer_id.lang }}',
|
||||
})
|
||||
# create a second record linked to a customer in another language
|
||||
self.partner_2.write({
|
||||
'lang': 'fr_FR',
|
||||
})
|
||||
test_record_2 = self.env['mail.test.sms'].create({
|
||||
'name': 'Test',
|
||||
'customer_id': self.partner_2.id,
|
||||
})
|
||||
|
||||
self.assertEqual(self.sms_template.body, self.body_en)
|
||||
self.assertEqual(self.sms_template.with_context(lang='fr_FR').body, self.body_fr)
|
||||
|
||||
rid_to_lang = self.sms_template._render_lang((self.test_record | test_record_2).ids)
|
||||
self.assertEqual(set(rid_to_lang.keys()), set((self.test_record | test_record_2).ids))
|
||||
for rid, lang in rid_to_lang.items():
|
||||
# TDE FIXME: False or en_US ?
|
||||
if rid == self.test_record.id:
|
||||
self.assertEqual(lang, 'en_US')
|
||||
elif rid == test_record_2.id:
|
||||
self.assertEqual(lang, 'fr_FR')
|
||||
else:
|
||||
self.assertTrue(False)
|
||||
|
||||
tpl_to_rids = self.sms_template._classify_per_lang((self.test_record | test_record_2).ids)
|
||||
for lang, (tpl, rids) in tpl_to_rids.items():
|
||||
# TDE FIXME: False or en_US ?
|
||||
if lang == 'en_US':
|
||||
self.assertEqual(rids, self.test_record.ids)
|
||||
elif lang == 'fr_FR':
|
||||
self.assertEqual(rids, test_record_2.ids)
|
||||
else:
|
||||
self.assertTrue(False, 'Should not return lang %s' % lang)
|
||||
|
||||
def test_sms_template_create_and_unlink_sidebar_action(self):
|
||||
ActWindow = self.env['ir.actions.act_window']
|
||||
self.sms_template.action_create_sidebar_action()
|
||||
action_id = self.sms_template.sidebar_action_id.id
|
||||
|
||||
self.assertNotEqual(action_id, False)
|
||||
self.assertEqual(ActWindow.search_count([('id', '=', action_id)]), 1)
|
||||
|
||||
self.sms_template.action_unlink_sidebar_action()
|
||||
self.assertEqual(ActWindow.search_count([('id', '=', action_id)]), 0)
|
||||
|
||||
def test_sms_template_unlink_with_action(self):
|
||||
ActWindow = self.env['ir.actions.act_window']
|
||||
self.sms_template.action_create_sidebar_action()
|
||||
action_id = self.sms_template.sidebar_action_id.id
|
||||
|
||||
self.sms_template.unlink()
|
||||
self.assertEqual(ActWindow.search_count([('id', '=', action_id)]), 0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue