Files
odoo_source/addons/mass_mailing/tests/common.py
T
Thibault Delavallée 7946b42ef5 [IMP] link_tracker, (test_)mass_mailing: improve test tools and clean existing tests
URPOSE

Prepare code cleaning and optimization in mail, mass_mailing and SMS by
cleaning models for readability and code complexity and footprint reduction.

SPECIFICATIONS

Add tool methods and asserts for link tracker tests.

Add tool methods and assets for mass mailing tests, notably about mailing
traces and their link with emails.

Merge existing and duplicated tests and rewrite them a bit.

Rename and improve test_mass_mailing models.

LINKS

Prepares task ID 2238597 (notification and trace models cleaning)
Task ID 1906925 (mass mailing tests cleaning)
PR #50169

Related: odoo/enterprise#10180
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2020-04-24 15:35:43 +00:00

137 lines
6.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.link_tracker.tests.common import MockLinkTracker
from odoo.addons.mail.tests.common import MailCase, mail_new_test_user
from odoo.tests.common import SavepointCase
class MassMailCase(MailCase, MockLinkTracker):
def _find_mail_mail_wemail(self, email_to, state, author=None):
for mail in self._new_mails:
if author is not None and mail.author_id != author:
continue
if mail.state != state:
continue
if (mail.email_to == email_to and not mail.recipient_ids) or (not mail.email_to and mail.recipient_ids.email) == email_to:
break
else:
raise AssertionError('mail.mail not found for email_to %s / state %s in %s' % (email_to, state, repr([m.email_to for m in self._new_mails])))
return mail
def _find_mail_mail_wrecord(self, record):
for mail in self._new_mails:
if mail.model == record._name and mail.res_id == record.id:
break
else:
raise AssertionError('mail.mail not found for record %s in %s' % (record, repr([m.email_to for m in self._new_mails])))
return mail
def assertMailMailWEmails(self, emails, state, content, fields_values=None):
""" Will check in self._new_mails to find a sent mail.mail. To use with
mail gateway mock.
:param emails: list of emails;
:param state: state of mail.mail;
:param content: content to check for each email;
:param fields_values: specific value to check on the mail.mail record;
"""
for email_to in emails:
sent_mail = self._find_mail_mail_wemail(email_to, state)
if content:
self.assertIn(content, sent_mail.body_html)
for fname, fvalue in (fields_values or {}).items():
self.assertEqual(sent_mail[fname], fvalue)
def assertMailTraces(self, recipients_info, mailing, records, check_mail=True):
""" Check content of traces.
:param recipients_info: list[{
'partner': res.partner record (may be empty),
'email': email used when sending email (may be empty, computed based on partner),
'state': outgoing / sent / open / reply / error / cancel (sent by default),
'record: linked record,
'content': UDPATE ME
'failure_type': optional: UPDATE ME
}, { ... }]
"""
traces = self.env['mailing.trace'].search([
('mass_mailing_id', 'in', mailing.ids),
('res_id', 'in', records.ids)
])
# ensure trace coherency
self.assertTrue(all(s.model == records._name for s in traces))
self.assertEqual(set(s.res_id for s in traces), set(records.ids))
# check each traces
for recipient_info in recipients_info:
partner = recipient_info.get('partner', self.env['res.partner'])
email = recipient_info.get('email')
state = recipient_info.get('state', 'sent')
record = recipient_info.get('record')
content = recipient_info.get('content')
if email is None and partner:
email = partner.email_normalized
recipient_trace = traces.filtered(
lambda t: t.email == email and t.state == state and (t.res_id == record.id if record else True)
)
self.assertTrue(
len(recipient_trace) == 1,
'MailTrace: email %s (recipient %s, state: %s, record: %s): found %s records (1 expected)' % (email, partner, state, record, len(recipient_trace))
)
if check_mail:
fields_values = {'mailing_id': mailing}
if 'failure_type' in recipient_info:
fields_values['failure_type'] = recipient_info['failure_type']
if state == 'sent':
self.assertMailMailWEmails([email], 'sent', content, fields_values=fields_values)
elif state == 'ignored':
self.assertMailMailWEmails([email], 'cancel', content, fields_values=fields_values)
elif state == 'exception':
self.assertMailMailWEmails([email], 'exception', content, fields_values=fields_values)
elif state == 'canceled':
self.assertMailMailWEmails([email], 'canceled', content, fields_values=fields_values)
else:
raise NotImplementedError()
class TestMassMailCommon(SavepointCase, MassMailCase):
@classmethod
def setUpClass(cls):
super(TestMassMailCommon, cls).setUpClass()
cls.user_marketing = mail_new_test_user(
cls.env, login='user_marketing',
groups='base.group_user,base.group_partner_manager,mass_mailing.group_mass_mailing_user',
name='Martial Marketing', signature='--\nMartial')
cls.email_reply_to = 'MyCompany SomehowAlias <test.alias@test.mycompany.com>'
@classmethod
def _create_mailing_list(cls):
""" Shortcut to create mailing lists. Currently hardcoded, maybe evolve
in a near future. """
cls.mailing_list_1 = cls.env['mailing.list'].with_context(cls._test_context).create({
'name': 'List1',
'contact_ids': [
(0, 0, {'name': 'Déboulonneur', 'email': 'fleurus@example.com'}),
(0, 0, {'name': 'Gorramts', 'email': 'gorramts@example.com'}),
(0, 0, {'name': 'Ybrant', 'email': 'ybrant@example.com'}),
]
})
cls.mailing_list_2 = cls.env['mailing.list'].with_context(cls._test_context).create({
'name': 'List2',
'contact_ids': [
(0, 0, {'name': 'Gilberte', 'email': 'gilberte@example.com'}),
(0, 0, {'name': 'Gilberte En Mieux', 'email': 'gilberte@example.com'}),
(0, 0, {'name': 'Norbert', 'email': 'norbert@example.com'}),
(0, 0, {'name': 'Ybrant', 'email': 'ybrant@example.com'}),
]
})