[IMP] sms, link_tracker: clean some test helpers and add an helper to click SMS links

Clean some helpers, and add a helper to simulata a click on a shortened link
embedded in an SMS.

Task ID 2247037
Community PR #50384
This commit is contained in:
Thibault Delavallée
2020-05-26 10:35:58 +00:00
parent c13c3318b2
commit e8b1e2b7e4
4 changed files with 70 additions and 29 deletions
+3 -3
View File
@@ -31,10 +31,10 @@ class MockLinkTracker(common.BaseCase):
])
return code.link_id
def assertLinkShortened(self, body, link_info, link_params=None):
""" Usage
def assertLinkShortenedHtml(self, body, link_info, link_params=None):
""" Find shortened links in an HTML content. Usage :
self.assertLinkShortened(
self.assertLinkShortenedHtml(
message.body,
('url0', 'http://www.odoo.com', True),
{'utm_campaign': self.utm_c.name, 'utm_medium': self.utm_m.name}
@@ -252,7 +252,7 @@ Email: <a id="url5" href="mailto:test@odoo.com">test@odoo.com</a></div>""",
link_params = {'utm_medium': 'Email', 'utm_source': mailing.name}
if link_info[0] == 'url4':
link_params['baz'] = 'qux'
self.assertLinkShortened(
self.assertLinkShortenedHtml(
new_mail.mail_message_id.body,
link_info,
link_params=link_params,
+41 -7
View File
@@ -1,11 +1,42 @@
# -*- coding: utf-8 -*-
import re
import werkzeug
from odoo import tools
from odoo.addons.mass_mailing.tests.common import MassMailCommon
from odoo.addons.sms.tests.common import SMSCase, SMSCommon
class MassSMSCase(SMSCase):
# ------------------------------------------------------------
# GATEWAY TOOLS
# ------------------------------------------------------------
def gateway_sms_click(self, sent_sms):
""" Simulate a click on a sent SMS. Usage: giving a partner and/or
a number, find an SMS sent to him, find shortened links in its body
and call add_click to simulate a click. """
for url in re.findall(tools.TEXT_URL_REGEX, sent_sms['body']):
if '/r' in url: # shortened link, like 'http://localhost:8069/r/LBG/s/53'
parsed_url = werkzeug.urls.url_parse(url)
path_items = parsed_url.path.split('/')
code, sms_sms_id = path_items[2], int(path_items[4])
trace_id = self.env['mailing.trace'].sudo().search([('sms_sms_id_int', '=', sms_sms_id)]).id
self.env['link.tracker.click'].sudo().add_click(
code,
ip='100.200.300.400',
country_code='BE',
mailing_trace_id=trace_id
)
# ------------------------------------------------------------
# ASSERTS
# ------------------------------------------------------------
def assertSMSOutgoingStatistics(self, partners, numbers, records, mailing):
found_sms = self.env['sms.sms'].sudo().search([
'|', ('partner_id', 'in', partners.ids), ('number', 'in', numbers),
@@ -26,13 +57,16 @@ class MassSMSCase(SMSCase):
def assertSMSStatistics(self, recipients_info, mailing, records, check_sms=True):
""" Check content of notifications.
:param recipients_info: list[{
'partner': res.partner record (may be empty),
'number': number used for notification (may be empty, computed based on partner),
'state': outgoing / sent / ignored / exception / opened (sent by default),
'record: linked record,
'failure_type': optional: sms_number_missing / sms_number_format / sms_credit / sms_server
}, { ... }]
:param recipients_info: list[{
'partner': res.partner record (may be empty),
'number': number used for notification (may be empty, computed based on partner),
'state': outgoing / sent / ignored / exception / opened (sent by default),
'record: linked record,
'content': optional: if set, check content of sent SMS
'failure_type': optional: sms_number_missing / sms_number_format / sms_credit / sms_server
},
{ ... }
]
"""
traces = self.env['mailing.trace'].search([
('mass_mailing_id', 'in', mailing.ids),
+25 -18
View File
@@ -66,6 +66,28 @@ class SMSCase(MockSMS):
""" Main test class to use when testing SMS integrations. Contains helpers and tools related
to notification sent by SMS. """
def _find_sms_sent(self, partner, number):
if number is None and partner:
number = partner.phone_get_sanitized_number()
sent_sms = next((sms for sms in self._sms if sms['number'] == number), None)
if not sent_sms:
raise AssertionError('sent sms not found for %s (number: %s)' % (partner, number))
return sent_sms
def _find_sms_sms(self, partner, number, status):
if number is None and partner:
number = partner.phone_get_sanitized_number()
domain = [('partner_id', '=', partner.id), ('number', '=', number)]
if status:
domain += [('state', '=', status)]
sms = self.env['sms.sms'].sudo().search(domain)
if not sms:
raise AssertionError('sms.sms not found for %s (number: %s / status %s)' % (partner, number, status))
if len(sms) > 1:
raise NotImplementedError()
return sms
def assertSMSSent(self, numbers, content=None):
""" Check sent SMS. Order is not checked. Each number should have received
the same content. Useful to check batch sending.
@@ -82,12 +104,7 @@ class SMSCase(MockSMS):
def assertSMSCanceled(self, partner, number, error_code, content=None):
""" Check canceled SMS. Search is done for a pair partner / number where
partner can be an empty recordset. """
if number is None and partner:
number = partner.phone_get_sanitized_number()
sms = self.env['sms.sms'].sudo().search([
('partner_id', '=', partner.id), ('number', '=', number),
('state', '=', 'canceled')
])
sms = self._find_sms_sms(partner, number, 'canceled')
self.assertTrue(sms, 'SMS: not found canceled SMS for %s (number: %s)' % (partner, number))
self.assertEqual(sms.error_code, error_code)
if content is not None:
@@ -96,12 +113,7 @@ class SMSCase(MockSMS):
def assertSMSFailed(self, partner, number, error_code, content=None):
""" Check failed SMS. Search is done for a pair partner / number where
partner can be an empty recordset. """
if number is None and partner:
number = partner.phone_get_sanitized_number()
sms = self.env['sms.sms'].sudo().search([
('partner_id', '=', partner.id), ('number', '=', number),
('state', '=', 'error')
])
sms = self._find_sms_sms(partner, number, 'error')
self.assertTrue(sms, 'SMS: not found failed SMS for %s (number: %s)' % (partner, number))
self.assertEqual(sms.error_code, error_code)
if content is not None:
@@ -110,12 +122,7 @@ class SMSCase(MockSMS):
def assertSMSOutgoing(self, partner, number, content=None):
""" Check outgoing SMS. Search is done for a pair partner / number where
partner can be an empty recordset. """
if number is None and partner:
number = partner.phone_get_sanitized_number()
sms = self.env['sms.sms'].sudo().search([
('partner_id', '=', partner.id), ('number', '=', number),
('state', '=', 'outgoing')
])
sms = self._find_sms_sms(partner, number, 'outgoing')
self.assertTrue(sms, 'SMS: not found failed SMS for %s (number: %s)' % (partner, number))
if content is not None:
self.assertEqual(sms.body, content)