[PATCH] Upstream patch - 27072023

This commit is contained in:
Parthiv Patel
2023-07-27 08:33:59 +00:00
parent 3ca202bd7d
commit 78406247ae
11 changed files with 275 additions and 119 deletions

View File

@@ -271,6 +271,7 @@ class Channel(models.Model):
all_emp_group = None
if all_emp_group and all_emp_group in self and not self._context.get(MODULE_UNINSTALL_FLAG):
raise UserError(_('You cannot delete those groups, as the Whole Company group is required by other modules.'))
self.env['bus.bus'].sendmany([[(self._cr.dbname, 'mail.channel', channel.id), {'info': 'delete'}] for channel in self])
return super(Channel, self).unlink()
def write(self, vals):

View File

@@ -120,6 +120,8 @@ function factory(dependencies) {
last_message_id,
partner_id,
});
case 'delete':
return this._handleNotificationChannelDelete(channelId);
case 'typing_status':
return this._handleNotificationChannelTypingStatus(channelId, data);
default:
@@ -127,6 +129,24 @@ function factory(dependencies) {
}
}
/**
* @private
* @param {integer} channelId
* @param {Object} param1
* @param {integer} param1.partner_id
* @param {string} param1.partner_name
*/
async _handleNotificationChannelDelete(channelId) {
const channel = this.env.models['mail.thread'].findFromIdentifyingData({
id: channelId,
model: 'mail.channel',
});
if (!channel) {
return;
}
channel.delete();
}
/**
* @private
* @param {integer} channelId

View File

@@ -161,16 +161,16 @@ function factory(dependencies) {
* @private
*/
_onThreadCacheChanged() {
// clear obsolete hints
this.update({ componentHintList: clear() });
this.addComponentHint('change-of-thread-cache');
if (this.threadCache) {
// clear obsolete hints
this.update({ componentHintList: clear() });
this.addComponentHint('change-of-thread-cache');
this.threadCache.update({
isCacheRefreshRequested: true,
isMarkAllAsReadRequested: true,
});
this.update({ lastVisibleMessage: [['unlink']] });
}
this.update({ lastVisibleMessage: [['unlink']] });
}
/**
@@ -194,7 +194,9 @@ function factory(dependencies) {
return;
}
this.env.browser.clearTimeout(this._loaderTimeout);
this.update({ isLoading: false, isPreparingLoading: false });
if (this.thread) {
this.update({ isLoading: false, isPreparingLoading: false });
}
}
}

View File

@@ -257,7 +257,13 @@ class MockEmail(common.BaseCase):
if mail.id == mail_id:
break
else:
raise AssertionError('mail.mail not found for ID %s' % (mail_id))
debug_info = '\n'.join(
f'From: {mail.author_id} ({mail.email_from}) - ID {mail.id} (State: {mail.state})'
for mail in filtered
)
raise AssertionError(
f'mail.mail not found for ID {mail_id} / message {mail_message} / status {status} / author {author}\n{debug_info}'
)
return mail
def _find_mail_mail_wpartners(self, recipients, status, mail_message=None, author=None):
@@ -275,7 +281,14 @@ class MockEmail(common.BaseCase):
if all(p in mail.recipient_ids for p in recipients):
break
else:
raise AssertionError('mail.mail not found for message %s / status %s / recipients %s / author %s' % (mail_message, status, recipients.ids, author))
debug_info = '\n'.join(
f'From: {mail.author_id} ({mail.email_from}) - To: {sorted(mail.recipient_ids.ids)} (State: {mail.state})'
for mail in filtered
)
recipients_info = f'Missing: {[r.name for r in recipients if r.id not in filtered.recipient_ids.ids]}'
raise AssertionError(
f'mail.mail not found for message {mail_message} / status {status} / recipients {sorted(recipients.ids)} / author {author}\n{recipients_info}\n{debug_info}'
)
return mail
def _find_mail_mail_wemail(self, email_to, status, mail_message=None, author=None):
@@ -293,7 +306,13 @@ class MockEmail(common.BaseCase):
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 / status %s in %s' % (email_to, status, repr([m.email_to for m in self._new_mails])))
debug_info = '\n'.join(
f'From: {mail.author_id} ({mail.email_from}) - To: {mail.email_to} / {sorted(mail.recipient_ids.mapped("email"))} (State: {mail.state})'
for mail in filtered
)
raise AssertionError(
f'mail.mail not found for message {mail_message} / status {status} / email_to {email_to} / author {author}\n{debug_info}'
)
return mail
def _find_mail_mail_wrecord(self, record, status=None, mail_message=None, author=None):
@@ -306,25 +325,52 @@ class MockEmail(common.BaseCase):
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])))
debug_info = '\n'.join(
f'From: {mail.author_id} ({mail.email_from}) - Model{mail.model} / ResId {mail.res_id} (State: {mail.state})'
for mail in filtered
)
raise AssertionError(
f'mail.mail not found for message {mail_message} / status {status} / record {record.model}, {record.id} / author {author}\n{debug_info}'
)
return mail
def _find_sent_email(self, email_from, emails_to, subject=None):
""" Find an outgoing email based on from / to and optional subject when
having a conflict.
:return sent_email: an outgoing email generated during the mock;
"""
sent_emails = [
mail for mail in self._mails
if set(mail['email_to']) == set(emails_to) and mail['email_from'] == email_from
]
if len(sent_emails) > 1 and subject:
# try to better filter
sent_email = next((mail for mail in sent_emails if mail['subject'] == subject), False)
else:
sent_email = sent_emails[0] if sent_emails else False
return sent_email
# ------------------------------------------------------------
# GATEWAY ASSERTS
# ------------------------------------------------------------
def assertMailMail(self, recipients, status,
check_mail_mail=True, mail_message=None, author=None,
content=None, fields_values=None, email_values=None):
""" Assert mail.mail records are created and maybe sent as emails. Allow
def _assertMailMail(self, mail, recipients_list, status,
email_to_recipients=None, author=None,
content=None, fields_values=None, email_values=None):
""" Assert mail.mail record values and maybe related emails. Allow
asserting their content. Records to check are the one generated when
using mock (mail.mail and outgoing emails). This method takes partners
as source of record fetch and assert.
using mock (mail.mail and outgoing emails).
:param recipients: a ``res.partner`` recordset. See ``_find_mail_mail_wpartners``;
:param mail: a ``mail.mail`` record;
:param recipients_list: an ``res.partner`` recordset or a list of
emails (both are supported, see ``_find_mail_mail_wpartners`` and
``_find_mail_mail_wemail``);
:param status: mail.mail state used to filter mails. If ``sent`` this method
also check that emails have been sent trough gateway;
:param mail_message: see ``_find_mail_mail_wpartners``;
:param email_to_recipients: used for assertSentEmail to find email based
on 'email_to' when doing the match directly based on recipients_list
being partners it nos easy (e.g. multi emails, ...);
:param author: see ``_find_mail_mail_wpartners``;
:param content: if given, check it is contained within mail html body;
:param fields_values: if given, should be a dictionary of field names /
@@ -336,54 +382,104 @@ class MockEmail(common.BaseCase):
:param check_mail_mail: deprecated, use ``assertSentEmail`` if False
"""
self.assertTrue(bool(mail))
if content:
self.assertIn(content, mail.body_html)
for fname, fvalue in (fields_values or {}).items():
with self.subTest(fname=fname, fvalue=fvalue):
self.assertEqual(
mail[fname], fvalue,
'Mail: expected %s for %s, got %s' % (fvalue, fname, mail[fname])
)
if status == 'sent':
if email_to_recipients:
recipients = email_to_recipients # already formatted
else:
recipients = [[r] for r in recipients_list] # one partner -> list of a single email
for recipient in recipients:
with self.subTest(recipient=recipient):
self.assertSentEmail(
email_values['email_from'] if email_values and email_values.get('email_from') else author,
recipient,
**(email_values or {})
)
def assertMailMail(self, recipients, status,
email_to_recipients=None,
check_mail_mail=True, mail_message=None, author=None,
content=None, fields_values=None, email_values=None):
""" Assert mail.mail records are created and maybe sent as emails. This
method takes partners as source to find mails and check their content.
See '_assertMailMail' for more details.
:param recipients: a ``res.partner`` recordset. See
``_find_mail_mail_wpartners``;
:param mail_message: used to find the related email;
See '_assertMailMail' for more details about other parameters.
"""
found_mail = self._find_mail_mail_wpartners(recipients, status, mail_message=mail_message, author=author)
self.assertTrue(bool(found_mail))
if content:
self.assertIn(content, found_mail.body_html)
for fname, fvalue in (fields_values or {}).items():
self.assertEqual(
found_mail[fname], fvalue,
'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname]))
if status == 'sent':
for recipient in recipients:
self.assertSentEmail(email_values['email_from'] if email_values and email_values.get('email_from') else author, [recipient], **(email_values or {}))
self._assertMailMail(
found_mail, recipients, status,
email_to_recipients=email_to_recipients,
author=author, content=content,
fields_values=fields_values, email_values=email_values,
)
return found_mail
def assertMailMailWEmails(self, emails, status,
email_to_recipients=None,
mail_message=None, author=None,
content=None, fields_values=None, email_values=None):
""" Assert mail.mail records are created and maybe sent as emails. Allow
asserting their content. Records to check are the one generated when
using mock (mail.mail and outgoing emails). This method takes emails
as source of record fetch and assert.
""" Assert mail.mail records are created and maybe sent as emails. This
method takes emails as source to find mails and check their content.
See '_assertMailMail' for more details.
:param emails: a list of emails. See ``_find_mail_mail_wemail``;
:param status: mail.mail state used to filter mails. If ``sent`` this method
also check that emails have been sent trough gateway;
:param mail_message: see ``_find_mail_mail_wemail``;
:param author: see ``_find_mail_mail_wemail``;;
:param content: if given, check it is contained within mail html body;
:param fields_values: if given, should be a dictionary of field names /
values allowing to check ``mail.mail`` additional values (subject,
reply_to, ...);
:param email_values: if given, should be a dictionary of keys / values
allowing to check sent email additional values (if any).
See ``assertSentEmail``;
:param mail_message: used to find the related email;
:param check_mail_mail: deprecated, use ``assertSentEmail`` if False
See '_assertMailMail' for more details about other parameters.
"""
found_mail = False
for email_to in emails:
found_mail = self._find_mail_mail_wemail(email_to, status, mail_message=mail_message, author=author)
if content:
self.assertIn(content, found_mail.body_html)
for fname, fvalue in (fields_values or {}).items():
self.assertEqual(
found_mail[fname], fvalue,
'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname]))
if status == 'sent':
for email_to in emails:
self.assertSentEmail(email_values['email_from'] if email_values and email_values.get('email_from') else author, [email_to], **(email_values or {}))
self.assertTrue(bool(found_mail))
self._assertMailMail(
found_mail, [email_to], status,
email_to_recipients=email_to_recipients,
author=author, content=content,
fields_values=fields_values, email_values=email_values,
)
return found_mail
def assertMailMailWRecord(self, record, recipients, status,
email_to_recipients=None,
mail_message=None, author=None,
content=None, fields_values=None, email_values=None):
""" Assert mail.mail records are created and maybe sent as emails. This
method takes a record as source to find mails and check their content
using model / res_id. See '_assertMailMail' for more details.
:param record: a record used to find emails sent related on it.
See ``_find_mail_mail_wrecord``;
:param mail_message: used to find the related email;
See '_assertMailMail' for more details about other parameters.
"""
found_mail = self._find_mail_mail_wrecord(record, mail_message=mail_message, author=author)
self.assertTrue(bool(found_mail))
self._assertMailMail(
found_mail, recipients, status,
email_to_recipients=email_to_recipients,
author=author, content=content,
fields_values=fields_values, email_values=email_values,
)
return found_mail
def assertMailMailWId(self, mail_id, status,
email_to_recipients=None,
author=None,
content=None, fields_values=None):
""" Assert mail.mail records are created and maybe sent as emails. Allow
asserting their content. Records to check are the one generated when
@@ -391,22 +487,19 @@ class MockEmail(common.BaseCase):
as source of record fetch and assert.
:param mail_id: a ``mail.mail`` DB ID. See ``_find_mail_mail_wid``;
:param status: mail.mail state to check upon found mail;
:param content: if given, check it is contained within mail html body;
:param fields_values: if given, should be a dictionary of field names /
values allowing to check ``mail.mail`` additional values (subject,
reply_to, ...);
For other parameters, see ``_assertMailMail``.
"""
found_mail = self._find_mail_mail_wid(mail_id)
self.assertTrue(bool(found_mail))
if status:
self.assertEqual(found_mail.state, status)
if content:
self.assertIn(content, found_mail.body_html)
for fname, fvalue in (fields_values or {}).items():
self.assertEqual(
found_mail[fname], fvalue,
'Mail: expected %s for %s, got %s' % (fvalue, fname, found_mail[fname]))
self._assertMailMail(
found_mail, [], # generally used when recipients are Falsy
status,
email_to_recipients=email_to_recipients,
author=author, content=content,
fields_values=fields_values,
)
return found_mail
def assertNoMail(self, recipients, mail_message=None, author=None):
""" Check no mail.mail and email was generated during gateway mock. """
@@ -455,7 +548,7 @@ class MockEmail(common.BaseCase):
"""
direct_check = ['attachments', 'body_alternative', 'email_from', 'references', 'reply_to', 'subject']
content_check = ['body_alternative_content', 'body_content', 'references_content']
other_check = ['body', 'attachments_info']
other_check = ['body', 'attachments_info', 'email_to']
expected = {}
for fname in direct_check + content_check + other_check:
@@ -470,20 +563,30 @@ class MockEmail(common.BaseCase):
else:
expected['email_from'] = author
email_to_list = []
for email_to in recipients:
if isinstance(email_to, self.env['res.partner'].__class__):
email_to_list.append(formataddr((email_to.name, email_to.email)))
else:
email_to_list.append(email_to)
if 'email_to' in values:
email_to_list = values['email_to']
else:
email_to_list = []
for email_to in recipients:
if isinstance(email_to, self.env['res.partner'].__class__):
email_to_list.append(formataddr((email_to.name, email_to.email or 'False')))
else:
email_to_list.append(email_to)
expected['email_to'] = email_to_list
sent_mail = next(
(mail for mail in self._mails
if set(mail['email_to']) == set(expected['email_to']) and mail['email_from'] == expected['email_from']
), False)
debug_info = '-'.join('From: %s-To: %s' % (mail['email_from'], mail['email_to']) for mail in self._mails) if not bool(sent_mail) else ''
self.assertTrue(bool(sent_mail), 'Expected mail from %s to %s not found in %s' % (expected['email_from'], expected['email_to'], debug_info))
# fetch mail
sent_mail = self._find_sent_email(
expected['email_from'],
expected['email_to'],
values.get('subject'),
)
debug_info = ''
if not sent_mail:
debug_info = '-'.join('From: %s-To: %s' % (mail['email_from'], mail['email_to']) for mail in self._mails)
self.assertTrue(
bool(sent_mail),
'Expected mail from %s to %s not found in %s' % (expected['email_from'], expected['email_to'], debug_info)
)
for val in direct_check:
if val in expected:
@@ -491,7 +594,11 @@ class MockEmail(common.BaseCase):
if 'attachments_info' in expected:
attachments = sent_mail['attachments']
for attachment_info in expected['attachments_info']:
attachment = next(attach for attach in attachments if attach[0] == attachment_info['name'])
attachment = next((attach for attach in attachments if attach[0] == attachment_info['name']), False)
self.assertTrue(
bool(attachment),
f'Attachment {attachment_info["name"]} not found in attachments',
)
if attachment_info.get('raw'):
self.assertEqual(attachment[1], attachment_info['raw'])
if attachment_info.get('type'):
@@ -503,6 +610,8 @@ class MockEmail(common.BaseCase):
if val in expected:
self.assertIn(expected[val], sent_mail[val[:-8]], 'Value for %s: %s does not contain %s' % (val, sent_mail[val[:-8]], expected[val]))
return sent_mail
class MailCase(MockEmail):
""" Tools, helpers and asserts for mail-related tests, including mail
@@ -803,9 +912,10 @@ class MailCase(MockEmail):
if not self.mail_unlink_sent:
self.assertMailMail(
partners, mail_status,
author=message.author_id if message.author_id else message.email_from,
author=message_info.get('fields_values', {}).get('author_id') or message.author_id or message.email_from,
mail_message=message,
email_values=email_values,
fields_values=message_info.get('fields_values'),
)
else:
for recipient in partners:

View File

@@ -32,8 +32,8 @@ class MassMailCase(MailCase, MockLinkTracker):
)
def assertMailTraces(self, recipients_info, mailing, records,
check_mail=True, sent_unlink=False, author=None,
mail_links_info=None):
check_mail=True, sent_unlink=False,
author=None, mail_links_info=None):
""" Check content of traces. Traces are fetched based on a given mailing
and records. Their content is compared to recipients_info structure that
holds expected information. Links content may be checked, notably to
@@ -48,6 +48,7 @@ class MassMailCase(MailCase, MockLinkTracker):
'record: linked record,
# MAIL.MAIL
'content': optional content that should be present in mail.mail body_html;
'email_to_recipients': optional, see '_assertMailMail';
'failure_type': optional failure reason;
}, { ... }]
@@ -79,6 +80,12 @@ class MassMailCase(MailCase, MockLinkTracker):
('mass_mailing_id', 'in', mailing.ids),
('res_id', 'in', records.ids)
])
debug_info = '\n'.join(
(
f'Trace: to {t.email} - state {t.state}'
for t in traces
)
)
# ensure trace coherency
self.assertTrue(all(s.model == records._name for s in traces))
@@ -90,6 +97,7 @@ class MassMailCase(MailCase, MockLinkTracker):
for recipient_info, link_info, record in zip(recipients_info, mail_links_info, records):
partner = recipient_info.get('partner', self.env['res.partner'])
email = recipient_info.get('email')
email_to_recipients = recipient_info.get('email_to_recipients')
state = recipient_info.get('state', 'sent')
record = record or recipient_info.get('record')
content = recipient_info.get('content')
@@ -97,33 +105,57 @@ class MassMailCase(MailCase, MockLinkTracker):
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)
lambda t: (t.email == email or (not email and not t.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))
'MailTrace: email %s (recipient %s, state: %s, record: %s): found %s records (1 expected)\n%s' % (
email, partner, state, record,
len(recipient_trace), debug_info)
)
self.assertTrue(bool(recipient_trace.mail_mail_id_int))
if 'failure_type' in recipient_info or state in ('ignored', 'exception', 'canceled', 'bounced'):
self.assertEqual(recipient_trace.failure_type, recipient_info['failure_type'])
if check_mail:
if author is None:
author = self.env.user.partner_id
fields_values = {'mailing_id': mailing}
if 'failure_type' in recipient_info:
fields_values['failure_type'] = recipient_info['failure_type']
if 'failure_reason' in recipient_info:
fields_values['failure_reason'] = recipient_info['failure_reason']
# specific for partner: email_formatted is used
if partner:
if state == 'sent' and sent_unlink:
self.assertSentEmail(author, [partner])
else:
self.assertMailMail(partner, state_mapping[state], author=author, content=content, fields_values=fields_values)
self.assertMailMail(
partner, state_mapping[state],
author=author,
content=content,
email_to_recipients=email_to_recipients,
fields_values=fields_values,
)
# specific if email is False -> could have troubles finding it if several falsy traces
elif not email and state in ('ignored', 'canceled', 'bounced'):
self.assertMailMailWId(recipient_trace.mail_mail_id_int, state_mapping[state], content=content, fields_values=fields_values)
self.assertMailMailWId(
recipient_trace.mail_mail_id_int, state_mapping[state],
author=author,
content=content,
email_to_recipients=email_to_recipients,
fields_values=fields_values,
)
else:
self.assertMailMailWEmails([email], state_mapping[state], author=author, content=content, fields_values=fields_values)
self.assertMailMailWEmails(
[email], state_mapping[state],
author=author,
content=content,
email_to_recipients=email_to_recipients,
fields_values=fields_values,
)
if link_info:
trace_mail = self._find_mail_mail_wrecord(record)

View File

@@ -4,9 +4,11 @@
from ast import literal_eval
from flectra.addons.mass_mailing.tests.common import MassMailCommon
from flectra.tests.common import users, Form
from flectra.tests.common import users, Form, tagged
from flectra.tools import formataddr, mute_logger
@tagged('mass_mailing')
class TestMassMailValues(MassMailCommon):
@classmethod
@@ -122,6 +124,7 @@ class TestMassMailValues(MassMailCommon):
self.assertEqual(mailing_form.mailing_model_real, 'res.partner')
@tagged('mass_mailing')
class TestMassMailFeatures(MassMailCommon):
@classmethod
@@ -274,7 +277,7 @@ class TestMassMailFeatures(MassMailCommon):
self.assertMailTraces(
[{'partner': partner_a},
{'partner': partner_b, 'state': 'ignored'}],
{'partner': partner_b, 'state': 'ignored', 'failure_type': False}],
mailing, partner_a + partner_b, check_mail=True
)

View File

@@ -119,7 +119,7 @@ class PhoneBlackList(models.Model):
def phone_action_blacklist_remove(self):
return {
'name': 'Are you sure you want to unblacklist this Phone Number?',
'name': _('Are you sure you want to unblacklist this Phone Number?'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'phone.blacklist.remove',

View File

@@ -695,21 +695,10 @@ class TestComposerResultsMass(TestMailComposer):
self.assertEqual(len(self._new_mails), 2, 'Should have created 1 mail.mail per record')
self.assertEqual(len(self._mails), 10, 'Should have sent 5 emails per record')
# hack to use assertEmails: filtering on from/to only is not sufficient to distinguish emails
_mails_records = [
[mail for mail in self._mails if '%s-%s' % (record.id, record._name) in mail['message_id']]
for record in self.test_records
]
for record, _mails in zip(self.test_records, _mails_records):
# message copy is kept
message = record.message_ids[0]
for record in self.test_records:
# template is sent only to partners (email_to are transformed)
self._mails = _mails
self.assertMailMail(record.customer_id + new_partners + self.partner_admin,
'sent',
mail_message=message,
author=self.partner_employee,
email_values={
'attachments_info': [
@@ -732,6 +721,7 @@ class TestComposerResultsMass(TestMailComposer):
f'{self.alias_catchall}@{self.alias_domain}'
)),
},
mail_message=record.message_ids[0], # message copy is kept
)
# test without catchall filling reply-to
@@ -745,15 +735,8 @@ class TestComposerResultsMass(TestMailComposer):
self.env['ir.config_parameter'].sudo().set_param("mail.catchall.domain", None)
composer.send_mail()
# hack to use assertEmails: filtering on from/to only is not sufficient to distinguish emails
_mails_records = [
[mail for mail in self._mails if '%s-%s' % (record.id, record._name) in mail['message_id']]
for record in self.test_records
]
for record, _mails in zip(self.test_records, _mails_records):
for record in self.test_records:
# template is sent only to partners (email_to are transformed)
self._mails = _mails
self.assertMailMail(record.customer_id + new_partners + self.partner_admin,
'sent',
mail_message=record.message_ids[0],

View File

@@ -51,18 +51,23 @@ class TestMassMailing(TestMailFullCommon):
'content': 'Hello %s' % recipient.name}
# opt-out: ignored (cancel mail)
if recipient in recipients[1] | recipients[2]:
recipient_info['failure_type'] = False
recipient_info['state'] = 'ignored'
# blacklisted: ignored (cancel mail)
elif recipient in recipients[3] | recipients[4]:
recipient_info['failure_type'] = False
recipient_info['state'] = 'ignored'
# duplicates: ignored (cancel mail)
elif recipient == recipient_dup_1:
recipient_info['failure_type'] = False
recipient_info['state'] = 'ignored'
# void: ignored (cancel mail)
elif recipient == recipient_void_1:
recipient_info['failure_type'] = False
recipient_info['state'] = 'ignored'
# falsy: ignored (cancel mail)
elif recipient == recipient_falsy_1:
recipient_info['failure_type'] = False
recipient_info['state'] = 'ignored'
recipient_info['email'] = recipient.email_from # normalized is False but email should be falsymail
else:

View File

@@ -78,6 +78,6 @@ class TestAutoBlacklist(common.TestMassMailCommon):
with self.mock_mail_gateway(mail_unlink_sent=False):
new_mailing._process_mass_mailing_queue()
self.assertMailTraces(
[{'email': 'test.record.00@test.example.com', 'state': 'ignored'}],
[{'email': 'test.record.00@test.example.com', 'state': 'ignored', 'failure_type': False}],
new_mailing, target, check_mail=True
)

View File

@@ -245,8 +245,8 @@ class TestMassMailing(TestMassMailCommon):
[{'email': 'test.record.00@test.example.com'},
{'email': 'test.record.01@test.example.com'},
{'email': 'test.record.02@test.example.com'},
{'email': 'test.record.03@test.example.com', 'state': 'ignored'},
{'email': 'test.record.04@test.example.com', 'state': 'ignored'}],
{'email': 'test.record.03@test.example.com', 'state': 'ignored', 'failure_type': False},
{'email': 'test.record.04@test.example.com', 'state': 'ignored', 'failure_type': False}],
mailing, recipients, check_mail=True
)
self.assertEqual(mailing.ignored, 2)
@@ -271,11 +271,11 @@ class TestMassMailing(TestMassMailCommon):
mailing._process_mass_mailing_queue()
self.assertMailTraces(
[{'email': 'test.record.00@test.example.com', 'state': 'ignored'},
{'email': 'test.record.01@test.example.com', 'state': 'ignored'},
[{'email': 'test.record.00@test.example.com', 'state': 'ignored', 'failure_type': False},
{'email': 'test.record.01@test.example.com', 'state': 'ignored', 'failure_type': False},
{'email': 'test.record.02@test.example.com'},
{'email': 'test.record.03@test.example.com'},
{'email': 'test.record.04@test.example.com', 'state': 'ignored'}],
{'email': 'test.record.04@test.example.com', 'state': 'ignored', 'failure_type': False}],
mailing, recipients, check_mail=True
)
self.assertEqual(mailing.ignored, 3)
@@ -369,10 +369,10 @@ class TestMassMailing(TestMassMailCommon):
self.assertMailTraces(
[{'email': 'test@test.example.com', 'state': 'sent'},
{'email': 'test@test.example.com', 'state': 'ignored'},
{'email': 'test@test.example.com', 'state': 'ignored', 'failure_type': False},
{'email': 'test3@test.example.com'},
{'email': 'test4@test.example.com'},
{'email': 'test5@test.example.com', 'state': 'ignored'}],
{'email': 'test5@test.example.com', 'state': 'ignored', 'failure_type': False}],
mailing,
mailing_contact_1 + mailing_contact_2 + mailing_contact_3 + mailing_contact_4 + mailing_contact_5,
check_mail=True