[REF][MOV] test(_mass)_mail(_sms): move sms tests in their own addon
In this commit we introduce a new module ``test_mail_sms`` that holds the tests for sms application, like ``test_mail`` does for mail. Currently all sms tests are inside ``test_mail_full``. After this commit code is moved from ``test_mail_full`` into that module. Full testing module should be used mainly to test integrations with a lot of submodules and for performance tests, not testing details of SMS implementation. We also add ``mass_mailing_sms`` as dependency of ``test_mass_mailing`` so that both mailing types are tested in the same module. It eases maintenance and writing of tests. Mass mailing SMS tests from `test_mail_full`` are therefore moved in ``test_mass_mailing``. This commit also allows some cleaning in classes used in tests, to have classes in ``test_mail_sms`` and ``test_mail_full`` that contain everything necessary to test mail features. Task-2890111 (Test Mail/Mass Mailing: SMS tests reorganization and move) Part-of: odoo/odoo#96223
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import Form, users
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.addons.mail.tests.common import MailCommon
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests import Form, users
|
||||
|
||||
|
||||
class TestMailTemplate(MailCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMailTemplate, cls).setUpClass()
|
||||
|
||||
@@ -6,11 +6,12 @@ import re
|
||||
import werkzeug
|
||||
|
||||
from odoo import tools
|
||||
from odoo.addons.link_tracker.tests.common import MockLinkTracker
|
||||
from odoo.addons.mass_mailing.tests.common import MassMailCommon
|
||||
from odoo.addons.sms.tests.common import SMSCase, SMSCommon
|
||||
|
||||
|
||||
class MassSMSCase(SMSCase):
|
||||
class MassSMSCase(SMSCase, MockLinkTracker):
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# ASSERTS
|
||||
@@ -155,7 +156,7 @@ class MassSMSCase(SMSCase):
|
||||
)
|
||||
|
||||
|
||||
class MassSMSCommon(MassMailCommon, SMSCommon, MassSMSCase):
|
||||
class MassSMSCommon(SMSCommon, MassSMSCase, MassMailCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
@@ -249,7 +249,7 @@ class SMSCase(MockSMS):
|
||||
self.assertEqual(tools.html2plaintext(message.body).rstrip('\n'), body)
|
||||
|
||||
|
||||
class SMSCommon(MailCommon, MockSMS):
|
||||
class SMSCommon(MailCommon, SMSCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
@@ -11,8 +11,6 @@ and mail-related sub modules. Those tests are present in a separate module as it
|
||||
contains models used only to perform tests independently to functional aspects of
|
||||
real applications. """,
|
||||
'depends': [
|
||||
'test_mail',
|
||||
'test_mass_mailing',
|
||||
'mail',
|
||||
'mail_bot',
|
||||
'portal',
|
||||
@@ -22,6 +20,9 @@ real applications. """,
|
||||
'mass_mailing_sms', # adds portal
|
||||
'phone_validation',
|
||||
'sms',
|
||||
'test_mail',
|
||||
'test_mail_sms',
|
||||
'test_mass_mailing',
|
||||
],
|
||||
'data': [
|
||||
'data/mail_message_subtype_data.xml',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_mail_models_mail
|
||||
from . import test_mail_models_sms
|
||||
|
||||
@@ -4,15 +4,3 @@ access_mail_test_portal_user,mail.test.portal.user,model_mail_test_portal,base.g
|
||||
access_mail_test_rating_all,mail.test.rating.all,model_mail_test_rating,,0,0,0,0
|
||||
access_mail_test_rating_portal,mail.test.rating.portal,model_mail_test_rating,base.group_portal,1,0,0,0
|
||||
access_mail_test_rating_user,mail.test.rating.user,model_mail_test_rating,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_all,mail.test.sms.all,model_mail_test_sms,,0,0,0,0
|
||||
access_mail_test_sms_user,mail.test.sms.user,model_mail_test_sms,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_all,mail.test.sms.bl.all,model_mail_test_sms_bl,,0,0,0,0
|
||||
access_mail_test_sms_bl_user,mail.test.sms.bl.user,model_mail_test_sms_bl,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_activity_all,mail.test.sms.bl.activity.all,model_mail_test_sms_bl_activity,,0,0,0,0
|
||||
access_mail_test_sms_bl_activity_user,mail.test.sms.bl.activity.user,model_mail_test_sms_bl_activity,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_optout_all,mail.test.sms.bl.optout.all,model_mail_test_sms_bl_optout,,0,0,0,0
|
||||
access_mail_test_sms_bl_optout_user,mail.test.sms.bl.optout.user,model_mail_test_sms_bl_optout,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_partner_all,mail.test.sms.partner.all,model_mail_test_sms_partner,,0,0,0,0
|
||||
access_mail_test_sms_partner_user,mail.test.sms.partner.user,model_mail_test_sms_partner,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_partner_2many_all,mail.test.sms.partner.2many.all,model_mail_test_sms_partner_2many,,0,0,0,0
|
||||
access_mail_test_sms_partner_2many_user,mail.test.sms.partner.2many.user,model_mail_test_sms_partner_2many,base.group_user,1,1,1,1
|
||||
|
||||
|
@@ -1,19 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
from . import test_odoobot
|
||||
from . import test_mail_performance
|
||||
from . import test_phone_blacklist
|
||||
from . import test_mass_mailing
|
||||
from . import test_mass_mailing_statistics
|
||||
from . import test_mass_sms
|
||||
from . import test_portal
|
||||
from . import test_rating
|
||||
from . import test_res_users
|
||||
from . import test_sms_composer
|
||||
from . import test_sms_management
|
||||
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
|
||||
|
||||
@@ -1,56 +1,8 @@
|
||||
# -*- 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.mass_mailing_sms.tests.common import MassSMSCommon
|
||||
from odoo.addons.test_mail.tests import common
|
||||
from odoo.addons.test_mass_mailing.tests.common import TestMassMailCommon
|
||||
|
||||
|
||||
class TestMailFullCommon(TestMassMailCommon, MassSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMailFullCommon, cls).setUpClass()
|
||||
|
||||
cls.mailing_sms = cls.env['mailing.mailing'].with_user(cls.user_marketing).create({
|
||||
'name': 'XMas SMS',
|
||||
'subject': 'Xmas SMS for {object.name}',
|
||||
'mailing_model_id': cls.env['ir.model']._get('mail.test.sms').id,
|
||||
'mailing_type': 'sms',
|
||||
'mailing_domain': '%s' % repr([('name', 'ilike', 'MassSMSTest')]),
|
||||
'body_plaintext': 'Dear {{object.display_name}} this is a mass SMS with two links http://www.odoo.com/smstest and http://www.odoo.com/smstest/{{object.id}}',
|
||||
'sms_force_send': True,
|
||||
'sms_allow_unsubscribe': True,
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def _create_mailing_sms_test_records(cls, model='mail.test.sms', partners=None, count=1):
|
||||
""" Helper to create data. Currently simple, to be improved. """
|
||||
Model = cls.env[model]
|
||||
phone_field = 'phone_nbr' if 'phone_nbr' in Model else 'phone'
|
||||
partner_field = 'customer_id' if 'customer_id' in Model else 'partner_id'
|
||||
|
||||
vals_list = []
|
||||
for idx in range(count):
|
||||
vals = {
|
||||
'name': 'MassSMSTestRecord_%02d' % idx,
|
||||
phone_field: '045600%02d%02d' % (idx, idx)
|
||||
}
|
||||
if partners:
|
||||
vals[partner_field] = partners[idx % len(partners)]
|
||||
|
||||
vals_list.append(vals)
|
||||
|
||||
return cls.env[model].create(vals_list)
|
||||
|
||||
|
||||
class TestMailFullRecipients(common.TestRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMailFullRecipients, 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)
|
||||
]
|
||||
class TestMailFullCommon(TestMassMailCommon):
|
||||
""" Keep a single entry point, notably for backward compatibility """
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
import json
|
||||
|
||||
from odoo import http
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSRecipients
|
||||
from odoo.tests import tagged, users
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
@tagged('portal')
|
||||
class TestPortal(HttpCase, TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestPortal(HttpCase, TestMailFullCommon, TestSMSRecipients):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortal, self).setUp()
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSRecipients
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import HttpCase, users, warmup
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestRatingCommon(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestRatingCommon(TestMailFullCommon, TestSMSRecipients):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestRatingCommon, cls).setUpClass()
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.mail.tests.common import MailCommon, mail_new_test_user
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon
|
||||
|
||||
|
||||
class TestResUsers(MailCommon):
|
||||
class TestResUsers(TestMailFullCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
{
|
||||
'name': 'SMS Tests',
|
||||
'version': '1.0',
|
||||
'category': 'Hidden',
|
||||
'sequence': 9876,
|
||||
'summary': 'SMS Tests: performances and tests specific to SMS',
|
||||
'description': """This module contains tests related to SMS. Those are
|
||||
present in a separate module as it contains models used only to perform
|
||||
tests independently to functional aspects of other models. """,
|
||||
'depends': [
|
||||
'mail',
|
||||
'sms',
|
||||
'test_performance',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
'installable': True,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_mail_sms_models
|
||||
@@ -0,0 +1,13 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_mail_test_sms_all,mail.test.sms.all,model_mail_test_sms,,0,0,0,0
|
||||
access_mail_test_sms_user,mail.test.sms.user,model_mail_test_sms,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_all,mail.test.sms.bl.all,model_mail_test_sms_bl,,0,0,0,0
|
||||
access_mail_test_sms_bl_user,mail.test.sms.bl.user,model_mail_test_sms_bl,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_activity_all,mail.test.sms.bl.activity.all,model_mail_test_sms_bl_activity,,0,0,0,0
|
||||
access_mail_test_sms_bl_activity_user,mail.test.sms.bl.activity.user,model_mail_test_sms_bl_activity,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_bl_optout_all,mail.test.sms.bl.optout.all,model_mail_test_sms_bl_optout,,0,0,0,0
|
||||
access_mail_test_sms_bl_optout_user,mail.test.sms.bl.optout.user,model_mail_test_sms_bl_optout,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_partner_all,mail.test.sms.partner.all,model_mail_test_sms_partner,,0,0,0,0
|
||||
access_mail_test_sms_partner_user,mail.test.sms.partner.user,model_mail_test_sms_partner,base.group_user,1,1,1,1
|
||||
access_mail_test_sms_partner_2many_all,mail.test.sms.partner.2many.all,model_mail_test_sms_partner_2many,,0,0,0,0
|
||||
access_mail_test_sms_partner_2many_user,mail.test.sms.partner.2many.user,model_mail_test_sms_partner_2many,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_phone_blacklist
|
||||
from . import test_sms_composer
|
||||
from . import test_sms_management
|
||||
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)
|
||||
]
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestPhoneBlacklist(TestMailFullCommon, TestMailFullRecipients):
|
||||
""" TODO """
|
||||
class TestPhoneBlacklist(TestSMSCommon, TestSMSRecipients):
|
||||
""" Test phone blacklist management """
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestSMSComposerComment(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSMSComposerComment(TestSMSCommon, TestSMSRecipients):
|
||||
""" TODO LIST
|
||||
|
||||
* add test for default_res_model / default_res_id and stuff like that;
|
||||
@@ -206,7 +206,7 @@ class TestSMSComposerComment(TestMailFullCommon, TestMailFullRecipients):
|
||||
self.assertSMSIapSent(self.random_numbers_san, self._test_body)
|
||||
|
||||
|
||||
class TestSMSComposerBatch(TestMailFullCommon):
|
||||
class TestSMSComposerBatch(TestSMSCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSMSComposerBatch, cls).setUpClass()
|
||||
@@ -248,7 +248,7 @@ class TestSMSComposerBatch(TestMailFullCommon):
|
||||
self.assertSMSNotification([{'partner': r.customer_id} for r in self.records], 'Zizisse an SMS.', messages)
|
||||
|
||||
|
||||
class TestSMSComposerMass(TestMailFullCommon):
|
||||
class TestSMSComposerMass(TestSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestSMSActionsCommon(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSMSActionsCommon(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestSMSPost(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSMSPost(TestSMSCommon, TestSMSRecipients):
|
||||
""" TODO
|
||||
|
||||
* add tests for new mail.message and mail.thread fields;
|
||||
@@ -251,7 +251,7 @@ class TestSMSPost(TestMailFullCommon, TestMailFullRecipients):
|
||||
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(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSMSPostException(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -392,7 +392,7 @@ class TestSMSPostException(TestMailFullCommon, TestMailFullRecipients):
|
||||
], self._test_body, messages)
|
||||
|
||||
|
||||
class TestSMSApi(TestMailFullCommon):
|
||||
class TestSMSApi(TestSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestServerAction(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestServerAction(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -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']))
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon, TestSMSRecipients
|
||||
|
||||
|
||||
class TestSmsTemplate(TestMailFullCommon, TestMailFullRecipients):
|
||||
class TestSmsTemplate(TestSMSCommon, TestSMSRecipients):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -9,7 +9,12 @@
|
||||
'description': """This module contains tests related to mass mailing. Those
|
||||
are present in a separate module to use specific test models defined in
|
||||
test_mail. """,
|
||||
'depends': ['test_mail', 'mass_mailing'],
|
||||
'depends': [
|
||||
'mass_mailing',
|
||||
'mass_mailing_sms',
|
||||
'test_mail',
|
||||
'test_mail_sms',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
|
||||
@@ -5,8 +5,11 @@ from . import test_blacklist
|
||||
from . import test_blacklist_behavior
|
||||
from . import test_blacklist_mixin
|
||||
from . import test_link_tracker
|
||||
from . import test_link_tracker_sms
|
||||
from . import test_mailing
|
||||
from . import test_mailing_server
|
||||
from . import test_mailing_sms
|
||||
from . import test_mailing_statistics
|
||||
from . import test_mailing_statistics_sms
|
||||
from . import test_mailing_test
|
||||
from . import test_performance
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.mass_mailing.tests.common import MassMailCommon
|
||||
from odoo.addons.test_mail.tests.common import TestMailCommon
|
||||
from odoo.addons.phone_validation.tools import phone_validation
|
||||
|
||||
from odoo.addons.mass_mailing_sms.tests.common import MassSMSCommon
|
||||
from odoo.addons.test_mail_sms.tests.common import TestSMSCommon
|
||||
|
||||
|
||||
class TestMassMailCommon(MassMailCommon, TestMailCommon):
|
||||
class TestMassMailCommon(MassSMSCommon, TestSMSCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -43,11 +45,42 @@ class TestMassMailCommon(MassMailCommon, TestMailCommon):
|
||||
'reply_to_mode': 'update',
|
||||
})
|
||||
|
||||
cls.mailing_sms = cls.env['mailing.mailing'].with_user(cls.user_marketing).create({
|
||||
'name': 'XMas SMS',
|
||||
'subject': 'Xmas SMS for {object.name}',
|
||||
'mailing_model_id': cls.env['ir.model']._get('mail.test.sms').id,
|
||||
'mailing_type': 'sms',
|
||||
'mailing_domain': '%s' % repr([('name', 'ilike', 'MassSMSTest')]),
|
||||
'body_plaintext': 'Dear {{object.display_name}} this is a mass SMS with two links http://www.odoo.com/smstest and http://www.odoo.com/smstest/{{object.id}}',
|
||||
'sms_force_send': True,
|
||||
'sms_allow_unsubscribe': True,
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def _create_test_blacklist_records(cls, model='mailing.test.blacklist', count=1):
|
||||
""" Deprecated, remove in 14.4 """
|
||||
return cls.__create_mailing_test_records(model=model, count=count)
|
||||
|
||||
@classmethod
|
||||
def _create_mailing_sms_test_records(cls, model='mail.test.sms', partners=None, count=1):
|
||||
""" Helper to create data. Currently simple, to be improved. """
|
||||
Model = cls.env[model]
|
||||
phone_field = 'phone_nbr' if 'phone_nbr' in Model else 'phone'
|
||||
partner_field = 'customer_id' if 'customer_id' in Model else 'partner_id'
|
||||
|
||||
vals_list = []
|
||||
for idx in range(count):
|
||||
vals = {
|
||||
'name': 'MassSMSTestRecord_%02d' % idx,
|
||||
phone_field: '045600%02d%02d' % (idx, idx)
|
||||
}
|
||||
if partners:
|
||||
vals[partner_field] = partners[idx % len(partners)]
|
||||
|
||||
vals_list.append(vals)
|
||||
|
||||
return cls.env[model].create(vals_list)
|
||||
|
||||
@classmethod
|
||||
def _create_mailing_test_records(cls, model='mailing.test.blacklist', partners=None, count=1):
|
||||
""" Helper to create data. Currently simple, to be improved. """
|
||||
@@ -67,3 +100,43 @@ class TestMassMailCommon(MassMailCommon, TestMailCommon):
|
||||
vals_list.append(vals)
|
||||
|
||||
return cls.env[model].create(vals_list)
|
||||
|
||||
|
||||
class TestMassSMSCommon(TestMassMailCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMassSMSCommon, cls).setUpClass()
|
||||
cls._test_body = 'Mass SMS in your face'
|
||||
|
||||
records = cls.env['mail.test.sms']
|
||||
partners = cls.env['res.partner']
|
||||
country_be_id = cls.env.ref('base.be').id
|
||||
_country_us_id = cls.env.ref('base.us').id
|
||||
|
||||
for x in range(10):
|
||||
partners += cls.env['res.partner'].with_context(**cls._test_context).create({
|
||||
'name': 'Partner_%s' % (x),
|
||||
'email': '_test_partner_%s@example.com' % (x),
|
||||
'country_id': country_be_id,
|
||||
'mobile': '045600%s%s99' % (x, x)
|
||||
})
|
||||
records += cls.env['mail.test.sms'].with_context(**cls._test_context).create({
|
||||
'name': 'MassSMSTest_%s' % (x),
|
||||
'customer_id': partners[x].id,
|
||||
'phone_nbr': '045600%s%s44' % (x, x)
|
||||
})
|
||||
cls.records = cls._reset_mail_context(records)
|
||||
cls.records_numbers = [phone_validation.phone_format(r.phone_nbr, 'BE', '32', force_format='E164') for r in cls.records]
|
||||
cls.partners = partners
|
||||
|
||||
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 a mass SMS.',
|
||||
})
|
||||
|
||||
cls.partner_numbers = [
|
||||
phone_validation.phone_format(partner.mobile, partner.country_id.code, partner.country_id.phone_code, force_format='E164')
|
||||
for partner in partners
|
||||
]
|
||||
|
||||
+2
-88
@@ -1,20 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import werkzeug
|
||||
|
||||
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 SmsSms
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon
|
||||
from odoo.addons.test_mass_mailing.tests.common import TestMassMailCommon
|
||||
from odoo.tests import tagged
|
||||
|
||||
|
||||
@tagged('link_tracker')
|
||||
class TestSMSPost(TestMailFullCommon, MockLinkTracker):
|
||||
class TestSMSPost(TestMassMailCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -121,81 +113,3 @@ class TestSMSPost(TestMailFullCommon, MockLinkTracker):
|
||||
self.assertEqual(
|
||||
res[sms_4.id],
|
||||
f'Welcome to {self._web_base_url}/r/RAOUL/s/{sms_4.id}\nAnd again,\n{self._web_base_url}/r/RAOUL/s/{sms_4.id}')
|
||||
|
||||
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(SmsSms, '_send', autospec=True, side_effect=_send) as send_mock:
|
||||
self.env['sms.sms'].browse(self.sms_all.ids).send()
|
||||
|
||||
self.assertEqual(self.count, 4)
|
||||
|
||||
def test_sms_send_crash_employee(self):
|
||||
with self.assertRaises(exceptions.AccessError):
|
||||
self.env['sms.sms'].with_user(self.user_employee).browse(self.sms_all.ids).send()
|
||||
|
||||
def test_sms_send_delete_all(self):
|
||||
with self.mockSMSGateway(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']))
|
||||
+2
-43
@@ -4,55 +4,14 @@
|
||||
from ast import literal_eval
|
||||
|
||||
from odoo.addons.phone_validation.tools import phone_validation
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon
|
||||
from odoo.addons.test_mass_mailing.tests.common import TestMassSMSCommon
|
||||
from odoo import exceptions
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import users
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@tagged('mass_mailing')
|
||||
class TestMassSMSCommon(TestMailFullCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestMassSMSCommon, cls).setUpClass()
|
||||
cls._test_body = 'Mass SMS in your face'
|
||||
|
||||
records = cls.env['mail.test.sms']
|
||||
partners = cls.env['res.partner']
|
||||
country_be_id = cls.env.ref('base.be').id,
|
||||
country_us_id = cls.env.ref('base.us').id,
|
||||
|
||||
for x in range(10):
|
||||
partners += cls.env['res.partner'].with_context(**cls._test_context).create({
|
||||
'name': 'Partner_%s' % (x),
|
||||
'email': '_test_partner_%s@example.com' % (x),
|
||||
'country_id': country_be_id,
|
||||
'mobile': '045600%s%s99' % (x, x)
|
||||
})
|
||||
records += cls.env['mail.test.sms'].with_context(**cls._test_context).create({
|
||||
'name': 'MassSMSTest_%s' % (x),
|
||||
'customer_id': partners[x].id,
|
||||
'phone_nbr': '045600%s%s44' % (x, x)
|
||||
})
|
||||
cls.records = cls._reset_mail_context(records)
|
||||
cls.records_numbers = [phone_validation.phone_format(r.phone_nbr, 'BE', '32', force_format='E164') for r in cls.records]
|
||||
cls.partners = partners
|
||||
|
||||
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 a mass SMS.',
|
||||
})
|
||||
|
||||
cls.partner_numbers = [
|
||||
phone_validation.phone_format(partner.mobile, partner.country_id.code, partner.country_id.phone_code, force_format='E164')
|
||||
for partner in partners
|
||||
]
|
||||
|
||||
|
||||
@tagged('mass_mailing')
|
||||
@tagged('mass_mailing', 'mass_mailing_sms')
|
||||
class TestMassSMSInternals(TestMassSMSCommon):
|
||||
|
||||
@users('user_marketing')
|
||||
@@ -11,7 +11,7 @@ from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@tagged('digest')
|
||||
@tagged('digest', 'mass_mailing')
|
||||
class TestMailingStatistics(TestMassMailCommon):
|
||||
|
||||
@classmethod
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@
|
||||
from lxml import html
|
||||
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.test_mail_full.tests.test_mass_sms import TestMassSMSCommon
|
||||
from odoo.addons.test_mass_mailing.tests.common import TestMassSMSCommon
|
||||
from odoo.tests.common import users
|
||||
from odoo.tests import tagged
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
@tagged('digest', 'mass_mailing')
|
||||
@tagged('digest', 'mass_mailing', 'mass_mailing_sms')
|
||||
class TestMailingStatistics(TestMassSMSCommon):
|
||||
|
||||
@classmethod
|
||||
@@ -46,14 +46,14 @@ class TestMassMailPerformance(TestMassMailPerformanceBase):
|
||||
'mailing_domain': [('id', 'in', self.mm_recs.ids)],
|
||||
})
|
||||
|
||||
# runbot needs +1 compared to local
|
||||
with self.assertQueryCount(__system__=425, marketing=426):
|
||||
# runbot needs +2 compared to local
|
||||
with self.assertQueryCount(__system__=426, marketing=427):
|
||||
mailing.action_send_mail()
|
||||
|
||||
self.assertEqual(mailing.sent, 50)
|
||||
self.assertEqual(mailing.delivered, 50)
|
||||
|
||||
# runbot needs +2 compared to local
|
||||
# runbot needs +3 compared to local
|
||||
with self.assertQueryCount(__system__=69, marketing=67):
|
||||
self.env['mail.mail'].sudo().search([('to_delete', '=', True)]).unlink()
|
||||
|
||||
@@ -93,14 +93,14 @@ class TestMassMailBlPerformance(TestMassMailPerformanceBase):
|
||||
'mailing_domain': [('id', 'in', self.mm_recs.ids)],
|
||||
})
|
||||
|
||||
# runbot needs +1 compared to local
|
||||
with self.assertQueryCount(__system__=487, marketing=488):
|
||||
# runbot needs +2 compared to local
|
||||
with self.assertQueryCount(__system__=488, marketing=489):
|
||||
mailing.action_send_mail()
|
||||
|
||||
self.assertEqual(mailing.sent, 50)
|
||||
self.assertEqual(mailing.delivered, 50)
|
||||
|
||||
# runbot needs +2 compared to local
|
||||
# runbot needs +3 compared to local
|
||||
with self.assertQueryCount(__system__=69, marketing=67):
|
||||
self.env['mail.mail'].sudo().search([('to_delete', '=', True)]).unlink()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user