[MERGE] mail: fixes and improved tests
[FIX] mail_followers: notification emails did not have 'references' correctly filled with their parent message message_id, [FIX] mail_mail: emails sent to partners now use the 'Name <email>' format for email_to, instead of just 'email' [FIX] mail_compose_message: fixed mass_mail subscribing the author to all documents, [FIX] mail_compose_message: fixed access rule on mail_compose_message not taking into account the wizard creation in mass_mail_mode (model but no res_id -> could lead to crash), [TEST] mail: cleaned a bit the tests; mail gateways related tests are now in a dedicated file; tests were added that helped triggering the previous errors bzr revid: tde@openerp.com-20130320145225-1hhp383wt507p3q3
This commit is contained in:
commit
1b2579f777
|
@ -161,11 +161,16 @@ class mail_notification(osv.Model):
|
||||||
else:
|
else:
|
||||||
email_from = msg.email_from
|
email_from = msg.email_from
|
||||||
|
|
||||||
|
references = False
|
||||||
|
if msg.parent_id:
|
||||||
|
references = msg.parent_id.message_id
|
||||||
|
|
||||||
mail_values = {
|
mail_values = {
|
||||||
'mail_message_id': msg.id,
|
'mail_message_id': msg.id,
|
||||||
'auto_delete': True,
|
'auto_delete': True,
|
||||||
'body_html': body_html,
|
'body_html': body_html,
|
||||||
'email_from': email_from,
|
'email_from': email_from,
|
||||||
|
'references': references,
|
||||||
}
|
}
|
||||||
email_notif_id = mail_mail.create(cr, uid, mail_values, context=context)
|
email_notif_id = mail_mail.create(cr, uid, mail_values, context=context)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -228,7 +228,7 @@ class mail_mail(osv.Model):
|
||||||
subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context)
|
subject = self.send_get_mail_subject(cr, uid, mail, partner=partner, context=context)
|
||||||
reply_to = self.send_get_mail_reply_to(cr, uid, mail, partner=partner, context=context)
|
reply_to = self.send_get_mail_reply_to(cr, uid, mail, partner=partner, context=context)
|
||||||
body_alternative = tools.html2plaintext(body)
|
body_alternative = tools.html2plaintext(body)
|
||||||
email_to = [partner.email] if partner else tools.email_split(mail.email_to)
|
email_to = ['%s <%s>' % (partner.name, partner.email)] if partner else tools.email_split(mail.email_to)
|
||||||
return {
|
return {
|
||||||
'body': body,
|
'body': body,
|
||||||
'body_alternative': body_alternative,
|
'body_alternative': body_alternative,
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from . import test_mail_message, test_mail_features, test_message_read, test_invite
|
from . import test_mail_message, test_mail_features, test_mail_gateway, test_message_read, test_invite
|
||||||
|
|
||||||
checks = [
|
checks = [
|
||||||
test_mail_message,
|
test_mail_message,
|
||||||
test_mail_features,
|
test_mail_features,
|
||||||
|
test_mail_gateway,
|
||||||
test_message_read,
|
test_message_read,
|
||||||
test_invite,
|
test_invite,
|
||||||
]
|
]
|
||||||
|
|
|
@ -70,9 +70,9 @@ class TestMailBase(common.TransactionCase):
|
||||||
|
|
||||||
# Test users to use through the various tests
|
# Test users to use through the various tests
|
||||||
self.user_raoul_id = self.res_users.create(cr, uid,
|
self.user_raoul_id = self.res_users.create(cr, uid,
|
||||||
{'name': 'Raoul Grosbedon', 'signature': 'Raoul', 'email': 'raoul@raoul.fr', 'login': 'raoul', 'groups_id': [(6, 0, [self.group_employee_id])]})
|
{'name': 'Raoul Grosbedon', 'signature': 'SignRaoul', 'email': 'raoul@raoul.fr', 'login': 'raoul', 'groups_id': [(6, 0, [self.group_employee_id])]})
|
||||||
self.user_bert_id = self.res_users.create(cr, uid,
|
self.user_bert_id = self.res_users.create(cr, uid,
|
||||||
{'name': 'Bert Tartignole', 'signature': 'Bert', 'email': 'bert@bert.fr', 'login': 'bert', 'groups_id': [(6, 0, [])]})
|
{'name': 'Bert Tartignole', 'signature': 'SignBert', 'email': 'bert@bert.fr', 'login': 'bert', 'groups_id': [(6, 0, [])]})
|
||||||
self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
|
self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
|
||||||
self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id)
|
self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id)
|
||||||
self.user_admin = self.res_users.browse(cr, uid, uid)
|
self.user_admin = self.res_users.browse(cr, uid, uid)
|
||||||
|
|
|
@ -20,183 +20,12 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.addons.mail.tests.test_mail_base import TestMailBase
|
from openerp.addons.mail.tests.test_mail_base import TestMailBase
|
||||||
from openerp.tools.mail import html_sanitize, append_content_to_html
|
from openerp.tools.mail import html_sanitize
|
||||||
|
|
||||||
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
|
||||||
To: {to}
|
|
||||||
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
|
||||||
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
|
||||||
From: Sylvie Lelitre <sylvie.lelitre@agrolait.com>
|
|
||||||
Subject: {subject}
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: multipart/alternative;
|
|
||||||
boundary="----=_Part_4200734_24778174.1344608186754"
|
|
||||||
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
|
||||||
Message-ID: <1198923581.41972151344608186760.JavaMail@agrolait.com>
|
|
||||||
{extra}
|
|
||||||
------=_Part_4200734_24778174.1344608186754
|
|
||||||
Content-Type: text/plain; charset=utf-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
Please call me as soon as possible this afternoon!
|
|
||||||
|
|
||||||
--
|
|
||||||
Sylvie
|
|
||||||
------=_Part_4200734_24778174.1344608186754
|
|
||||||
Content-Type: text/html; charset=utf-8
|
|
||||||
Content-Transfer-Encoding: quoted-printable
|
|
||||||
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
||||||
<html>
|
|
||||||
<head>=20
|
|
||||||
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
|
|
||||||
</head>=20
|
|
||||||
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
|
|
||||||
|
|
||||||
<p>Please call me as soon as possible this afternoon!</p>
|
|
||||||
|
|
||||||
<p>--<br/>
|
|
||||||
Sylvie
|
|
||||||
<p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
------=_Part_4200734_24778174.1344608186754--
|
|
||||||
"""
|
|
||||||
|
|
||||||
MAIL_TEMPLATE_PLAINTEXT = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
|
||||||
To: {to}
|
|
||||||
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
|
||||||
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
|
||||||
From: Sylvie Lelitre <sylvie.lelitre@agrolait.com>
|
|
||||||
Subject: {subject}
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain
|
|
||||||
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
|
||||||
Message-ID: {msg_id}
|
|
||||||
{extra}
|
|
||||||
|
|
||||||
Please call me as soon as possible this afternoon!
|
|
||||||
|
|
||||||
--
|
|
||||||
Sylvie
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class test_mail(TestMailBase):
|
class test_mail(TestMailBase):
|
||||||
|
|
||||||
def _mock_send_get_mail_body(self, *args, **kwargs):
|
def test_00_followers_function_field(self):
|
||||||
# def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
|
|
||||||
body = append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner', plaintext=False)
|
|
||||||
return body
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(test_mail, self).setUp()
|
|
||||||
|
|
||||||
# Mock send_get_mail_body to test its functionality without other addons override
|
|
||||||
self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body
|
|
||||||
self.registry('mail.mail').send_get_mail_body = self._mock_send_get_mail_body
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
# Remove mocks
|
|
||||||
self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body
|
|
||||||
super(test_mail, self).tearDown()
|
|
||||||
|
|
||||||
def test_00_message_process(self):
|
|
||||||
""" Testing incoming emails processing. """
|
|
||||||
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
|
|
||||||
|
|
||||||
# groups@.. will cause the creation of new mail groups
|
|
||||||
self.mail_group_model_id = self.ir_model.search(cr, uid, [('model', '=', 'mail.group')])[0]
|
|
||||||
self.mail_alias.create(cr, uid, {'alias_name': 'groups', 'alias_model_id': self.mail_group_model_id})
|
|
||||||
|
|
||||||
# Incoming mail creates a new mail_group "frogs"
|
|
||||||
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', 'frogs')]), [])
|
|
||||||
mail_frogs = MAIL_TEMPLATE.format(to='groups@example.com, other@gmail.com', subject='frogs', extra='')
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_frogs)
|
|
||||||
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'frogs')])
|
|
||||||
self.assertTrue(len(frog_groups) == 1)
|
|
||||||
|
|
||||||
# Previously-created group can be emailed now - it should have an implicit alias group+frogs@...
|
|
||||||
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
|
||||||
group_messages = frog_group.message_ids
|
|
||||||
self.assertTrue(len(group_messages) == 1, 'New group should only have the original message')
|
|
||||||
mail_frog_news = MAIL_TEMPLATE.format(to='Friendly Frogs <group+frogs@example.com>', subject='news', extra='')
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_frog_news)
|
|
||||||
frog_group.refresh()
|
|
||||||
self.assertTrue(len(frog_group.message_ids) == 2, 'Group should contain 2 messages now')
|
|
||||||
|
|
||||||
# Even with a wrong destination, a reply should end up in the correct thread
|
|
||||||
mail_reply = MAIL_TEMPLATE.format(to='erroneous@example.com>', subject='Re: news',
|
|
||||||
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_reply)
|
|
||||||
frog_group.refresh()
|
|
||||||
self.assertTrue(len(frog_group.message_ids) == 3, 'Group should contain 3 messages now')
|
|
||||||
|
|
||||||
# No model passed and no matching alias must raise
|
|
||||||
mail_spam = MAIL_TEMPLATE.format(to='noone@example.com', subject='spam', extra='')
|
|
||||||
self.assertRaises(Exception,
|
|
||||||
self.mail_thread.message_process,
|
|
||||||
cr, uid, None, mail_spam)
|
|
||||||
|
|
||||||
# plain text content should be wrapped and stored as html
|
|
||||||
test_msg_id = '<deadcafe.1337@smtp.agrolait.com>'
|
|
||||||
mail_text = MAIL_TEMPLATE_PLAINTEXT.format(to='groups@example.com', subject='frogs', extra='', msg_id=test_msg_id)
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_text)
|
|
||||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
|
||||||
self.assertEqual(new_mail.body, '<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>',
|
|
||||||
'plaintext mail incorrectly parsed')
|
|
||||||
|
|
||||||
# Do: post a new message, with a known partner
|
|
||||||
test_msg_id = '<deadcafe.1337-2@smtp.agrolait.com>'
|
|
||||||
TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre <sylvie.lelitre@agrolait.com>', user_raoul.email)
|
|
||||||
mail_new = TEMPLATE_MOD.format(to='Friendly Frogs <group+frogs@example.com>', subject='extra news', extra='', msg_id=test_msg_id)
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_new)
|
|
||||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
|
||||||
# Test: author_id set, not email_from
|
|
||||||
self.assertEqual(new_mail.author_id, user_raoul.partner_id, 'message process wrong author found')
|
|
||||||
self.assertEqual(new_mail.email_from, user_raoul.email, 'message process wrong email_from')
|
|
||||||
|
|
||||||
# Do: post a new message, with a unknown partner
|
|
||||||
test_msg_id = '<deadcafe.1337-3@smtp.agrolait.com>'
|
|
||||||
TEMPLATE_MOD = MAIL_TEMPLATE_PLAINTEXT.replace('Sylvie Lelitre <sylvie.lelitre@agrolait.com>', '_abcd_')
|
|
||||||
mail_new = TEMPLATE_MOD.format(to='Friendly Frogs <group+frogs@example.com>', subject='super news', extra='', msg_id=test_msg_id)
|
|
||||||
self.mail_thread.message_process(cr, uid, None, mail_new)
|
|
||||||
new_mail = self.mail_message.browse(cr, uid, self.mail_message.search(cr, uid, [('message_id', '=', test_msg_id)])[0])
|
|
||||||
# Test: author_id set, not email_from
|
|
||||||
self.assertFalse(new_mail.author_id, 'message process shnould not have found a partner for _abcd_ email address')
|
|
||||||
self.assertIn('_abcd_', new_mail.email_from, 'message process should set en email_from when not finding a partner_id')
|
|
||||||
|
|
||||||
def test_05_thread_parent_resolution(self):
|
|
||||||
"""Verify parent/child relationships are correctly established when processing incoming mails"""
|
|
||||||
cr, uid = self.cr, self.uid
|
|
||||||
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
|
||||||
msg1 = group_pigs.message_post(body='My Body', subject='1')
|
|
||||||
msg2 = group_pigs.message_post(body='My Body', subject='2')
|
|
||||||
msg1, msg2 = self.mail_message.browse(cr, uid, [msg1, msg2])
|
|
||||||
self.assertTrue(msg1.message_id, "New message should have a proper message_id")
|
|
||||||
|
|
||||||
# Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms
|
|
||||||
# 1. In-Reply-To header
|
|
||||||
reply_msg = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
|
|
||||||
extra='In-Reply-To: %s' % msg1.message_id)
|
|
||||||
self.mail_group.message_process(cr, uid, None, reply_msg)
|
|
||||||
|
|
||||||
# 2. References header
|
|
||||||
reply_msg2 = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: Re: 1',
|
|
||||||
extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id)
|
|
||||||
self.mail_group.message_process(cr, uid, None, reply_msg2)
|
|
||||||
|
|
||||||
# 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, not to mail
|
|
||||||
reply_msg3 = MAIL_TEMPLATE.format(to='Pretty Pigs <group+pigs@example.com>, other@gmail.com',
|
|
||||||
extra='', subject='Re: [%s] 1' % self.group_pigs_id)
|
|
||||||
self.mail_group.message_process(cr, uid, 'mail.group', reply_msg3)
|
|
||||||
|
|
||||||
group_pigs.refresh()
|
|
||||||
msg1.refresh()
|
|
||||||
self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages')
|
|
||||||
self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now')
|
|
||||||
|
|
||||||
def test_10_followers_function_field(self):
|
|
||||||
""" Tests designed for the many2many function field 'follower_ids'.
|
""" Tests designed for the many2many function field 'follower_ids'.
|
||||||
We will test to perform writes using the many2many commands 0, 3, 4,
|
We will test to perform writes using the many2many commands 0, 3, 4,
|
||||||
5 and 6. """
|
5 and 6. """
|
||||||
|
@ -253,7 +82,7 @@ class test_mail(TestMailBase):
|
||||||
follower_ids = set([follower.partner_id.id for follower in self.mail_followers.browse(cr, uid, fol_obj_ids)])
|
follower_ids = set([follower.partner_id.id for follower in self.mail_followers.browse(cr, uid, fol_obj_ids)])
|
||||||
self.assertEqual(follower_ids, set([partner_bert_id, user_admin.partner_id.id]), 'Bert and Admin should be the followers of dummy mail.group data')
|
self.assertEqual(follower_ids, set([partner_bert_id, user_admin.partner_id.id]), 'Bert and Admin should be the followers of dummy mail.group data')
|
||||||
|
|
||||||
def test_11_message_followers_and_subtypes(self):
|
def test_05_message_followers_and_subtypes(self):
|
||||||
""" Tests designed for the subscriber API as well as message subtypes """
|
""" Tests designed for the subscriber API as well as message subtypes """
|
||||||
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
|
||||||
# Data: message subtypes
|
# Data: message subtypes
|
||||||
|
@ -305,7 +134,7 @@ class test_mail(TestMailBase):
|
||||||
self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs')
|
self.assertTrue(subtype_data['mt_mg_nodef']['followed'], 'Admin should follow mt_mg_nodef in pigs')
|
||||||
self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs')
|
self.assertTrue(subtype_data['mt_all_nodef']['followed'], 'Admin should follow mt_all_nodef in pigs')
|
||||||
|
|
||||||
def test_20_message_quote_context(self):
|
def test_10_message_quote_context(self):
|
||||||
""" Tests designed for message_post. """
|
""" Tests designed for message_post. """
|
||||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
||||||
|
|
||||||
|
@ -323,236 +152,391 @@ class test_mail(TestMailBase):
|
||||||
self.assertNotIn('First answer, should not be displayed', result, 'Old answer should not be in quote.')
|
self.assertNotIn('First answer, should not be displayed', result, 'Old answer should not be in quote.')
|
||||||
self.assertNotIn('My answer I am propagating', result, 'Thread header content should be in quote.')
|
self.assertNotIn('My answer I am propagating', result, 'Thread header content should be in quote.')
|
||||||
|
|
||||||
def test_21_message_post(self):
|
def test_20_message_post(self):
|
||||||
""" Tests designed for message_post. """
|
""" Tests designed for message_post. """
|
||||||
cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
|
cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
|
||||||
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# Data creation
|
||||||
|
# --------------------------------------------------
|
||||||
|
# 0 - Update existing users-partners
|
||||||
|
self.res_users.write(cr, uid, [uid], {'email': 'a@a'})
|
||||||
|
self.res_users.write(cr, uid, [self.user_raoul_id], {'email': 'r@r'})
|
||||||
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
|
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
|
||||||
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
|
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
|
||||||
# 2 - Carine Poilvache, with email, should never receive emails
|
# 2 - Carine Poilvache, with email, should receive emails for emails
|
||||||
p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
|
p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
|
||||||
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
|
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
|
||||||
p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'notification_email_send': 'all'})
|
p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notification_email_send': 'all'})
|
||||||
|
# 4 - Attachments
|
||||||
# Subscribe Raoul, #1, #2
|
attach1_id = self.ir_attachment.create(cr, user_raoul.id, {
|
||||||
group_pigs.message_subscribe([self.partner_raoul_id, p_b_id, p_c_id])
|
'name': 'Attach1', 'datas_fname': 'Attach1',
|
||||||
|
'datas': 'bWlncmF0aW9uIHRlc3Q=',
|
||||||
# Mail data
|
'res_model': 'mail.compose.message', 'res_id': 0})
|
||||||
|
attach2_id = self.ir_attachment.create(cr, user_raoul.id, {
|
||||||
|
'name': 'Attach2', 'datas_fname': 'Attach2',
|
||||||
|
'datas': 'bWlncmF0aW9uIHRlc3Q=',
|
||||||
|
'res_model': 'mail.compose.message', 'res_id': 0})
|
||||||
|
attach3_id = self.ir_attachment.create(cr, user_raoul.id, {
|
||||||
|
'name': 'Attach3', 'datas_fname': 'Attach3',
|
||||||
|
'datas': 'bWlncmF0aW9uIHRlc3Q=',
|
||||||
|
'res_model': 'mail.compose.message', 'res_id': 0})
|
||||||
|
# 5 - Mail data
|
||||||
_subject = 'Pigs'
|
_subject = 'Pigs'
|
||||||
_mail_subject = 'Re: %s' % (group_pigs.name)
|
_mail_subject = 'Re: %s' % (group_pigs.name)
|
||||||
_body1 = '<p>Pigs rules</p>'
|
_body1 = '<p>Pigs rules</p>'
|
||||||
_mail_body1 = '<p>Pigs rules</p>\n<div><p>Raoul</p></div>\n'
|
_body2 = '<html>Pigs rocks</html>'
|
||||||
_mail_bodyalt1 = 'Pigs rules\nRaoul\n'
|
_attachments = [
|
||||||
_body2 = '<html>Pigs rules</html>'
|
('List1', 'My first attachment'),
|
||||||
_mail_body2 = '<div><p>Pigs rules</p></div>\n<div><p>Raoul</p></div>'
|
('List2', 'My second attachment')
|
||||||
_mail_bodyalt2 = 'Pigs rules\nRaoul'
|
]
|
||||||
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
|
|
||||||
|
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
# CASE1: post comment, body and subject specified
|
# CASE1: post comment + partners + attachments
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
# 1. Post a new comment on Pigs
|
# Data: set alias_domain to see emails with alias
|
||||||
|
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.domain', 'schlouby.fr')
|
||||||
|
|
||||||
|
# Do: subscribe Raoul
|
||||||
|
new_follower_ids = [self.partner_raoul_id]
|
||||||
|
group_pigs.message_subscribe(new_follower_ids)
|
||||||
|
# Test: group followers = Raoul + uid
|
||||||
|
group_fids = [follower.id for follower in group_pigs.message_follower_ids]
|
||||||
|
test_fids = new_follower_ids + [self.partner_admin_id]
|
||||||
|
self.assertEqual(set(test_fids), set(group_fids),
|
||||||
|
'message_subscribe: incorrect followers after subscribe')
|
||||||
|
|
||||||
|
# Do: Raoul message_post on Pigs
|
||||||
self._init_mock_build_email()
|
self._init_mock_build_email()
|
||||||
msg1_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body=_body1, subject=_subject, type='comment', subtype='mt_comment')
|
msg1_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id,
|
||||||
message1 = self.mail_message.browse(cr, uid, msg1_id)
|
body=_body1, subject=_subject, partner_ids=[p_b_id, p_c_id],
|
||||||
|
attachment_ids=[attach1_id, attach2_id], attachments=_attachments,
|
||||||
|
type='comment', subtype='mt_comment')
|
||||||
|
msg = self.mail_message.browse(cr, uid, msg1_id)
|
||||||
|
msg_message_id = msg.message_id
|
||||||
|
msg_pids = [partner.id for partner in msg.notified_partner_ids]
|
||||||
|
msg_aids = [attach.id for attach in msg.attachment_ids]
|
||||||
sent_emails = self._build_email_kwargs_list
|
sent_emails = self._build_email_kwargs_list
|
||||||
# Test: mail.mail notifications have been deleted
|
|
||||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg1_id)]), 'mail.mail notifications should have been auto-deleted!')
|
# Test: mail_message: subject and body not modified
|
||||||
# Test: mail_message: subject is _subject, body is _body1 (no formatting done)
|
self.assertEqual(_subject, msg.subject, 'message_post: mail.message subject incorrect')
|
||||||
self.assertEqual(message1.subject, _subject, 'mail.message subject incorrect')
|
self.assertEqual(_body1, msg.body, 'message_post: mail.message body incorrect')
|
||||||
self.assertEqual(message1.body, _body1, 'mail.message body incorrect')
|
# Test: mail_message: notified_partner_ids = group followers + partner_ids - author
|
||||||
# Test: sent_email: email send by server: correct subject, body, body_alternative
|
|
||||||
self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
|
|
||||||
for sent_email in sent_emails:
|
|
||||||
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
|
|
||||||
self.assertTrue(sent_email['body'] in [_mail_body1 + '\nBert Tartopoils\n', _mail_body1 + '\nAdministrator\n'],
|
|
||||||
'sent_email body incorrect')
|
|
||||||
# the html2plaintext uses etree or beautiful soup, so the result may be slighly different
|
|
||||||
# depending if you have installed beautiful soup.
|
|
||||||
self.assertTrue(sent_email['body_alternative'] in [_mail_bodyalt1 + '\nBert Tartopoils\n', _mail_bodyalt1 + '\nAdministrator\n'],
|
|
||||||
'sent_email body_alternative is incorrect')
|
|
||||||
# Test: mail_message: notified_partner_ids = group followers
|
|
||||||
message_pids = set([partner.id for partner in message1.notified_partner_ids])
|
|
||||||
test_pids = set([self.partner_admin_id, p_b_id, p_c_id])
|
test_pids = set([self.partner_admin_id, p_b_id, p_c_id])
|
||||||
self.assertEqual(test_pids, message_pids, 'mail.message notified partners incorrect')
|
self.assertEqual(test_pids, set(msg_pids), 'message_post: mail.message notified partners incorrect')
|
||||||
|
# Test: mail_message: attachments (4, attachment_ids + attachments)
|
||||||
|
test_aids = set([attach1_id, attach2_id])
|
||||||
|
msg_attach_names = set([attach.name for attach in msg.attachment_ids])
|
||||||
|
test_attach_names = set(['Attach1', 'Attach2', 'List1', 'List2'])
|
||||||
|
self.assertEqual(len(msg_aids), 4,
|
||||||
|
'message_post: mail.message wrong number of attachments')
|
||||||
|
self.assertEqual(msg_attach_names, test_attach_names,
|
||||||
|
'message_post: mail.message attachments incorrectly added')
|
||||||
|
self.assertTrue(test_aids.issubset(set(msg_aids)),
|
||||||
|
'message_post: mail.message attachments duplicated')
|
||||||
|
for attach in msg.attachment_ids:
|
||||||
|
self.assertEqual(attach.res_model, 'mail.group',
|
||||||
|
'message_post: mail.message attachments were not linked to the document')
|
||||||
|
self.assertEqual(attach.res_id, group_pigs.id,
|
||||||
|
'message_post: mail.message attachments were not linked to the document')
|
||||||
|
if 'List' in attach.name:
|
||||||
|
self.assertIn((attach.name, attach.datas.decode('base64')), _attachments,
|
||||||
|
'message_post: mail.message attachment name / data incorrect')
|
||||||
|
dl_attach = self.mail_message.download_attachment(cr, user_raoul.id, id_message=msg.id, attachment_id=attach.id)
|
||||||
|
self.assertIn((dl_attach['filename'], dl_attach['base64'].decode('base64')), _attachments,
|
||||||
|
'message_post: mail.message download_attachment is incorrect')
|
||||||
|
|
||||||
|
# Test: followers: same as before (author was already subscribed)
|
||||||
|
group_pigs.refresh()
|
||||||
|
group_fids = [follower.id for follower in group_pigs.message_follower_ids]
|
||||||
|
test_fids = new_follower_ids + [self.partner_admin_id]
|
||||||
|
self.assertEqual(set(test_fids), set(group_fids),
|
||||||
|
'message_post: wrong followers after posting')
|
||||||
|
|
||||||
|
# Test: mail_mail: notifications have been deleted
|
||||||
|
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg1_id)]),
|
||||||
|
'message_post: mail.mail notifications should have been auto-deleted!')
|
||||||
|
|
||||||
|
# Test: notifications emails: to a and b, c is email only, r is author
|
||||||
|
test_emailto = ['Administrator <a@a>', 'Bert Tartopoils <b@b>']
|
||||||
|
self.assertEqual(len(sent_emails), 2,
|
||||||
|
'message_post: notification emails wrong number of send emails')
|
||||||
|
self.assertEqual(set([m['email_to'][0] for m in sent_emails]), set(test_emailto),
|
||||||
|
'message_post: notification emails wrong recipients (email_to)')
|
||||||
|
for sent_email in sent_emails:
|
||||||
|
self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon <raoul@schlouby.fr>',
|
||||||
|
'message_post: notification email wrong email_from: should use alias of sender')
|
||||||
|
self.assertEqual(len(sent_email['email_to']), 1,
|
||||||
|
'message_post: notification email sent to more than one email address instead of a precise partner')
|
||||||
|
self.assertIn(sent_email['email_to'][0], test_emailto,
|
||||||
|
'message_post: notification email email_to incorrect')
|
||||||
|
self.assertEqual(sent_email['reply_to'], 'Followers of Pigs <group+pigs@schlouby.fr>',
|
||||||
|
'message_post: notification email reply_to incorrect')
|
||||||
|
self.assertEqual(_subject, sent_email['subject'],
|
||||||
|
'message_post: notification email subject incorrect')
|
||||||
|
self.assertIn(_body1, sent_email['body'],
|
||||||
|
'message_post: notification email body incorrect')
|
||||||
|
self.assertIn(user_raoul.signature, sent_email['body'],
|
||||||
|
'message_post: notification email body should contain the sender signature')
|
||||||
|
self.assertIn('Pigs rules', sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative should contain the body')
|
||||||
|
self.assertNotIn('<p>', sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative still contains html')
|
||||||
|
self.assertIn(user_raoul.signature, sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative should contain the sender signature')
|
||||||
|
self.assertFalse(sent_email['references'],
|
||||||
|
'message_post: references should be False when sending a message that is not a reply')
|
||||||
|
|
||||||
# Test: notification linked to this message = group followers = notified_partner_ids
|
# Test: notification linked to this message = group followers = notified_partner_ids
|
||||||
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg1_id)])
|
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg1_id)])
|
||||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
self.assertEqual(notif_pids, test_pids,
|
||||||
# Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer)
|
'message_post: mail.message created mail.notification incorrect')
|
||||||
for sent_email in sent_emails:
|
|
||||||
self.assertTrue(set(sent_email['email_to']).issubset(set(['a@a', 'b@b'])), 'sent_email email_to is incorrect')
|
|
||||||
|
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
# CASE2: post an email with attachments, parent_id, partner_ids, parent notification
|
# CASE2: reply + parent_id + parent notification
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
# 1. Post a new email comment on Pigs
|
# Data: remove alias_domain to see emails with alias
|
||||||
|
param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')])
|
||||||
|
self.registry('ir.config_parameter').unlink(cr, uid, param_ids)
|
||||||
|
|
||||||
|
# Do: Raoul message_post on Pigs
|
||||||
self._init_mock_build_email()
|
self._init_mock_build_email()
|
||||||
msg2_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body=_body2, type='email', subtype='mt_comment',
|
msg2_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id,
|
||||||
partner_ids=[p_d_id], parent_id=msg1_id, attachments=_attachments,
|
body=_body2, type='email', subtype='mt_comment',
|
||||||
context={'mail_post_autofollow': True})
|
partner_ids=[p_d_id], parent_id=msg1_id, attachment_ids=[attach3_id],
|
||||||
message2 = self.mail_message.browse(cr, uid, msg2_id)
|
context={'mail_post_autofollow': True})
|
||||||
|
msg = self.mail_message.browse(cr, uid, msg2_id)
|
||||||
|
msg_pids = [partner.id for partner in msg.notified_partner_ids]
|
||||||
|
msg_aids = [attach.id for attach in msg.attachment_ids]
|
||||||
sent_emails = self._build_email_kwargs_list
|
sent_emails = self._build_email_kwargs_list
|
||||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg2_id)]), 'mail.mail notifications should have been auto-deleted!')
|
|
||||||
# Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id
|
# Test: mail_message: subject is False, body, parent_id is msg_id
|
||||||
self.assertEqual(message2.subject, False, 'mail.message subject incorrect')
|
self.assertEqual(msg.subject, False, 'message_post: mail.message subject incorrect')
|
||||||
self.assertEqual(message2.body, html_sanitize(_body2), 'mail.message body incorrect')
|
self.assertEqual(msg.body, html_sanitize(_body2), 'message_post: mail.message body incorrect')
|
||||||
self.assertEqual(message2.parent_id.id, msg1_id, 'mail.message parent_id incorrect')
|
self.assertEqual(msg.parent_id.id, msg1_id, 'message_post: mail.message parent_id incorrect')
|
||||||
# Test: sent_email: email send by server: correct automatic subject, body, body_alternative
|
|
||||||
self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect')
|
|
||||||
for sent_email in sent_emails:
|
|
||||||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
|
||||||
self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
|
|
||||||
self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
|
|
||||||
# Test: mail_message: notified_partner_ids = group followers
|
# Test: mail_message: notified_partner_ids = group followers
|
||||||
message_pids = set([partner.id for partner in message2.notified_partner_ids])
|
test_pids = [self.partner_admin_id, p_d_id]
|
||||||
test_pids = set([self.partner_admin_id, p_b_id, p_c_id, p_d_id])
|
self.assertEqual(set(test_pids), set(msg_pids), 'message_post: mail.message partners incorrect')
|
||||||
self.assertEqual(message_pids, test_pids, 'mail.message partners incorrect')
|
# Test: mail_message: notifications linked to this message = group followers = notified_partner_ids
|
||||||
# Test: notifications linked to this message = group followers = notified_partner_ids
|
|
||||||
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg2_id)])
|
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg2_id)])
|
||||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
notif_pids = [notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)]
|
||||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
self.assertEqual(set(test_pids), set(notif_pids), 'message_post: mail.message notification partners incorrect')
|
||||||
# Test: sent_email: email_to should contain b@b, c@c, not a@a (writer)
|
|
||||||
|
# Test: mail_mail: notifications deleted
|
||||||
|
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg2_id)]), 'mail.mail notifications should have been auto-deleted!')
|
||||||
|
|
||||||
|
# Test: emails send by server (to a, b, c, d)
|
||||||
|
test_emailto = [u'Administrator <a@a>', u'Bert Tartopoils <b@b>', u'Carine Poilvache <c@c>', u'D\xe9d\xe9 Grosbedon <d@d>']
|
||||||
|
# self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect')
|
||||||
for sent_email in sent_emails:
|
for sent_email in sent_emails:
|
||||||
self.assertTrue(set(sent_email['email_to']).issubset(set(['a@a', 'b@b', 'c@c'])), 'sent_email email_to incorrect')
|
self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon <r@r>',
|
||||||
# Test: attachments
|
'message_post: notification email wrong email_from: should use email of sender when no alias domain set')
|
||||||
for attach in message2.attachment_ids:
|
self.assertEqual(len(sent_email['email_to']), 1,
|
||||||
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
|
'message_post: notification email sent to more than one email address instead of a precise partner')
|
||||||
self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.message attachment res_id incorrect')
|
self.assertIn(sent_email['email_to'][0], test_emailto,
|
||||||
self.assertIn((attach.name, attach.datas.decode('base64')), _attachments,
|
'message_post: notification email email_to incorrect')
|
||||||
'mail.message attachment name / data incorrect')
|
self.assertEqual(sent_email['reply_to'], 'Followers of Pigs <r@r>',
|
||||||
# Test: download attachments
|
'message_post: notification email reply_to incorrect: should name Followers of Pigs, and have raoul email')
|
||||||
for attach in message2.attachment_ids:
|
self.assertEqual(_mail_subject, sent_email['subject'],
|
||||||
dl_attach = self.mail_message.download_attachment(cr, user_raoul.id, id_message=message2.id, attachment_id=attach.id)
|
'message_post: notification email subject incorrect')
|
||||||
self.assertIn((dl_attach['filename'], dl_attach['base64'].decode('base64')), _attachments, 'mail.message download_attachment is incorrect')
|
self.assertIn(html_sanitize(_body2), sent_email['body'],
|
||||||
|
'message_post: notification email does not contain the body')
|
||||||
|
self.assertIn(user_raoul.signature, sent_email['body'],
|
||||||
|
'message_post: notification email body should contain the sender signature')
|
||||||
|
self.assertIn('Pigs rocks', sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative should contain the body')
|
||||||
|
self.assertNotIn('<p>', sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative still contains html')
|
||||||
|
self.assertIn(user_raoul.signature, sent_email['body_alternative'],
|
||||||
|
'message_post: notification email body alternative should contain the sender signature')
|
||||||
|
self.assertIn(msg_message_id, sent_email['references'],
|
||||||
|
'message_post: notification email references lacks parent message message_id')
|
||||||
|
# Test: attachments + download
|
||||||
|
for attach in msg.attachment_ids:
|
||||||
|
self.assertEqual(attach.res_model, 'mail.group',
|
||||||
|
'message_post: mail.message attachment res_model incorrect')
|
||||||
|
self.assertEqual(attach.res_id, self.group_pigs_id,
|
||||||
|
'message_post: mail.message attachment res_id incorrect')
|
||||||
|
|
||||||
# 2. Dédé has been notified -> should also have been notified of the parent message
|
# Test: Dédé has been notified -> should also have been notified of the parent message
|
||||||
message1.refresh()
|
msg = self.mail_message.browse(cr, uid, msg1_id)
|
||||||
message_pids = set([partner.id for partner in message1.notified_partner_ids])
|
msg_pids = set([partner.id for partner in msg.notified_partner_ids])
|
||||||
test_pids = set([self.partner_admin_id, p_b_id, p_c_id, p_d_id])
|
test_pids = set([self.partner_admin_id, p_b_id, p_c_id, p_d_id])
|
||||||
self.assertEqual(test_pids, message_pids, 'mail.message parent notification not created')
|
self.assertEqual(test_pids, msg_pids, 'message_post: mail.message parent notification not created')
|
||||||
|
|
||||||
# 3. Reply to the last message, check that its parent will be the first message
|
# Do: reply to last message
|
||||||
msg3_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body='Test', parent_id=msg2_id)
|
msg3_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body='Test', parent_id=msg2_id)
|
||||||
message = self.mail_message.browse(cr, uid, msg3_id)
|
msg = self.mail_message.browse(cr, uid, msg3_id)
|
||||||
self.assertEqual(message.parent_id.id, msg1_id, 'message_post did not flatten the thread structure')
|
# Test: check that its parent will be the first message
|
||||||
|
self.assertEqual(msg.parent_id.id, msg1_id, 'message_post did not flatten the thread structure')
|
||||||
|
|
||||||
def test_25_message_compose_wizard(self):
|
def test_25_message_compose_wizard(self):
|
||||||
""" Tests designed for the mail.compose.message wizard. """
|
""" Tests designed for the mail.compose.message wizard. """
|
||||||
cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
|
cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
|
||||||
mail_compose = self.registry('mail.compose.message')
|
mail_compose = self.registry('mail.compose.message')
|
||||||
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
|
|
||||||
group_bird_id = self.mail_group.create(cr, uid, {'name': 'Bird', 'description': 'Bird resistance'}, {'mail_create_nolog': True})
|
|
||||||
group_bird = self.mail_group.browse(cr, uid, group_bird_id)
|
|
||||||
|
|
||||||
# Mail data
|
# --------------------------------------------------
|
||||||
|
# Data creation
|
||||||
|
# --------------------------------------------------
|
||||||
|
# 0 - Update existing users-partners
|
||||||
|
self.res_users.write(cr, uid, [uid], {'email': 'a@a'})
|
||||||
|
self.res_users.write(cr, uid, [self.user_raoul_id], {'email': 'r@r'})
|
||||||
|
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
|
||||||
|
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
|
||||||
|
# 2 - Carine Poilvache, with email, should receive emails for emails
|
||||||
|
p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
|
||||||
|
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
|
||||||
|
p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'd@d', 'notification_email_send': 'all'})
|
||||||
|
# 4 - Create a Bird mail.group, that will be used to test mass mailing
|
||||||
|
group_bird_id = self.mail_group.create(cr, uid,
|
||||||
|
{
|
||||||
|
'name': 'Bird',
|
||||||
|
'description': 'Bird resistance',
|
||||||
|
}, context={'mail_create_nolog': True})
|
||||||
|
group_bird = self.mail_group.browse(cr, uid, group_bird_id)
|
||||||
|
# 5 - Mail data
|
||||||
_subject = 'Pigs'
|
_subject = 'Pigs'
|
||||||
_body = 'Pigs <b>rule</b>'
|
_body = 'Pigs <b>rule</b>'
|
||||||
_reply_subject = 'Re: Pigs'
|
_reply_subject = 'Re: %s' % _subject
|
||||||
_attachments = [
|
_attachments = [
|
||||||
{'name': 'First', 'datas_fname': 'first.txt', 'datas': 'My first attachment'.encode('base64')},
|
{'name': 'First', 'datas_fname': 'first.txt', 'datas': 'My first attachment'.encode('base64')},
|
||||||
{'name': 'Second', 'datas_fname': 'second.txt', 'datas': 'My second attachment'.encode('base64')}
|
{'name': 'Second', 'datas_fname': 'second.txt', 'datas': 'My second attachment'.encode('base64')}
|
||||||
]
|
]
|
||||||
_attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
|
_attachments_test = [('first.txt', 'My first attachment'), ('second.txt', 'My second attachment')]
|
||||||
|
# 6 - Subscribe Bert to Pigs
|
||||||
# 1 - Bert Tartopoils, with email, should receive emails for comments and emails
|
|
||||||
p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
|
|
||||||
# 2 - Carine Poilvache, with email, should never receive emails
|
|
||||||
p_c_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c', 'notification_email_send': 'email'})
|
|
||||||
# 3 - Dédé Grosbedon, without email, to test email verification; should receive emails for every message
|
|
||||||
p_d_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'notification_email_send': 'all'})
|
|
||||||
|
|
||||||
# Subscribe #1
|
|
||||||
group_pigs.message_subscribe([p_b_id])
|
group_pigs.message_subscribe([p_b_id])
|
||||||
|
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
# CASE1: comment on group_pigs
|
# CASE1: wizard + partners + context keys
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
# 1. Comment group_pigs with body_text and subject
|
# Do: Raoul wizard-composes on Pigs with auto-follow for partners, not for author
|
||||||
compose_id = mail_compose.create(cr, uid,
|
compose_id = mail_compose.create(cr, user_raoul.id,
|
||||||
{'subject': _subject, 'body': _body, 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
|
{
|
||||||
{'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id,
|
'subject': _subject,
|
||||||
'default_content_subtype': 'plaintext'})
|
'body': _body,
|
||||||
|
'partner_ids': [(4, p_c_id), (4, p_d_id)],
|
||||||
|
}, context={
|
||||||
|
'default_composition_mode': 'comment',
|
||||||
|
'default_model': 'mail.group',
|
||||||
|
'default_res_id': self.group_pigs_id,
|
||||||
|
})
|
||||||
compose = mail_compose.browse(cr, uid, compose_id)
|
compose = mail_compose.browse(cr, uid, compose_id)
|
||||||
# Test: mail.compose.message: composition_mode, model, res_id
|
|
||||||
self.assertEqual(compose.composition_mode, 'comment', 'mail.compose.message incorrect composition_mode')
|
|
||||||
self.assertEqual(compose.model, 'mail.group', 'mail.compose.message incorrect model')
|
|
||||||
self.assertEqual(compose.res_id, self.group_pigs_id, 'mail.compose.message incorrect res_id')
|
|
||||||
|
|
||||||
# 2. Post the comment, get created message
|
# Test: mail.compose.message: composition_mode, model, res_id
|
||||||
mail_compose.send_mail(cr, uid, [compose_id], {'mail_post_autofollow': True})
|
self.assertEqual(compose.composition_mode, 'comment', 'compose wizard: mail.compose.message incorrect composition_mode')
|
||||||
|
self.assertEqual(compose.model, 'mail.group', 'compose wizard: mail.compose.message incorrect model')
|
||||||
|
self.assertEqual(compose.res_id, self.group_pigs_id, 'compose wizard: mail.compose.message incorrect res_id')
|
||||||
|
|
||||||
|
# Do: Post the comment
|
||||||
|
mail_compose.send_mail(cr, user_raoul.id, [compose_id], {'mail_post_autofollow': True, 'mail_create_nosubscribe': True})
|
||||||
group_pigs.refresh()
|
group_pigs.refresh()
|
||||||
message = group_pigs.message_ids[0]
|
message = group_pigs.message_ids[0]
|
||||||
# Test: mail.message: subject, body inside pre
|
|
||||||
self.assertEqual(message.subject, _subject, 'mail.message incorrect subject')
|
# Test: mail.group: followers (c and d added by auto follow key; raoul not added by nosubscribe key)
|
||||||
self.assertEqual(message.body, '<p>%s</p>' % _body, 'mail.message incorrect body')
|
pigs_pids = [p.id for p in group_pigs.message_follower_ids]
|
||||||
# Test: mail.message: notified_partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d)
|
test_pids = [self.partner_admin_id, p_b_id, p_c_id, p_d_id]
|
||||||
|
self.assertEqual(set(pigs_pids), set(test_pids),
|
||||||
|
'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account')
|
||||||
|
|
||||||
|
# Test: mail.message: subject, body inside p
|
||||||
|
self.assertEqual(message.subject, _subject, 'compose wizard: mail.message incorrect subject')
|
||||||
|
self.assertEqual(message.body, '<p>%s</p>' % _body, 'compose wizard: mail.message incorrect body')
|
||||||
|
# Test: mail.message: notified_partner_ids = admin + bert (followers) + c + d (recipients)
|
||||||
msg_pids = [partner.id for partner in message.notified_partner_ids]
|
msg_pids = [partner.id for partner in message.notified_partner_ids]
|
||||||
test_pids = [p_b_id, p_c_id, p_d_id]
|
test_pids = [self.partner_admin_id, p_b_id, p_c_id, p_d_id]
|
||||||
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
|
self.assertEqual(set(msg_pids), set(test_pids),
|
||||||
self.assertEqual(len(notif_ids), 3, 'mail.message: too much notifications created')
|
'compose wizard: mail.message notified_partner_ids incorrect')
|
||||||
self.assertEqual(set(msg_pids), set(test_pids), 'mail.message notified_partner_ids incorrect')
|
|
||||||
|
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
# CASE2: reply to last comment with attachments
|
# CASE2: reply + attachments
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
# 1. Update last comment subject, reply with attachments
|
# Do: Reply with attachments
|
||||||
message.write({'subject': _subject})
|
compose_id = mail_compose.create(cr, user_raoul.id,
|
||||||
compose_id = mail_compose.create(cr, uid,
|
{
|
||||||
{'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]},
|
'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])]
|
||||||
{'default_composition_mode': 'reply', 'default_model': 'mail.thread', 'default_res_id': self.group_pigs_id, 'default_parent_id': message.id})
|
}, context={
|
||||||
|
'default_composition_mode': 'reply',
|
||||||
|
'default_model': 'mail.thread',
|
||||||
|
'default_res_id': self.group_pigs_id,
|
||||||
|
'default_parent_id': message.id
|
||||||
|
})
|
||||||
compose = mail_compose.browse(cr, uid, compose_id)
|
compose = mail_compose.browse(cr, uid, compose_id)
|
||||||
# Test: model, res_id, parent_id
|
|
||||||
self.assertEqual(compose.model, 'mail.group', 'mail.compose.message incorrect model')
|
# Test: mail.compose.message: model, res_id, parent_id
|
||||||
self.assertEqual(compose.res_id, self.group_pigs_id, 'mail.compose.message incorrect res_id')
|
self.assertEqual(compose.model, 'mail.group', 'compose wizard: mail.compose.message incorrect model')
|
||||||
self.assertEqual(compose.parent_id.id, message.id, 'mail.compose.message incorrect parent_id')
|
self.assertEqual(compose.res_id, self.group_pigs_id, 'compose wizard: mail.compose.message incorrect res_id')
|
||||||
# Test: mail.message: subject as Re:.., body in html, parent_id
|
self.assertEqual(compose.parent_id.id, message.id, 'compose wizard: mail.compose.message incorrect parent_id')
|
||||||
self.assertEqual(compose.subject, _reply_subject, 'mail.message incorrect subject')
|
|
||||||
# self.assertIn('Administrator wrote:<blockquote><pre>Pigs rules</pre></blockquote>', compose.body, 'mail.message body is incorrect')
|
# Test: mail.compose.message: subject as Re:.., body, parent_id
|
||||||
self.assertEqual(compose.parent_id and compose.parent_id.id, message.id, 'mail.message parent_id incorrect')
|
self.assertEqual(compose.subject, _reply_subject, 'compose wizard: mail.compose.message incorrect subject')
|
||||||
# Test: mail.message: attachments
|
self.assertFalse(compose.body, 'compose wizard: mail.compose.message body should not contain parent message body')
|
||||||
|
self.assertEqual(compose.parent_id and compose.parent_id.id, message.id, 'compose wizard: mail.compose.message parent_id incorrect')
|
||||||
|
# Test: mail.compose.message: attachments
|
||||||
for attach in compose.attachment_ids:
|
for attach in compose.attachment_ids:
|
||||||
self.assertIn((attach.datas_fname, attach.datas.decode('base64')), _attachments_test, 'mail.message attachment name / data incorrect')
|
self.assertIn((attach.datas_fname, attach.datas.decode('base64')), _attachments_test,
|
||||||
|
'compose wizard: mail.message attachment name / data incorrect')
|
||||||
|
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
# CASE3: mass_mail on Pigs and Bird
|
# CASE3: mass_mail on Pigs and Bird
|
||||||
# ----------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
# 1. mass_mail on pigs and bird
|
# Do: Compose in mass_mail_mode on pigs and bird
|
||||||
compose_id = mail_compose.create(cr, uid,
|
compose_id = mail_compose.create(cr, user_raoul.id,
|
||||||
{'subject': _subject, 'body': '${object.description}', 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
|
{
|
||||||
{'default_composition_mode': 'mass_mail', 'default_model': 'mail.group', 'default_res_id': False,
|
'subject': _subject,
|
||||||
'active_ids': [self.group_pigs_id, group_bird_id]})
|
'body': '${object.description}',
|
||||||
|
'partner_ids': [(4, p_c_id), (4, p_d_id)],
|
||||||
|
}, context={
|
||||||
|
'default_composition_mode': 'mass_mail',
|
||||||
|
'default_model': 'mail.group',
|
||||||
|
'default_res_id': False,
|
||||||
|
'active_ids': [self.group_pigs_id, group_bird_id],
|
||||||
|
})
|
||||||
compose = mail_compose.browse(cr, uid, compose_id)
|
compose = mail_compose.browse(cr, uid, compose_id)
|
||||||
|
|
||||||
# 2. Post the comment, get created message for each group
|
# D: Post the comment, get created message for each group
|
||||||
mail_compose.send_mail(cr, uid, [compose_id],
|
mail_compose.send_mail(cr, user_raoul.id, [compose_id], context={
|
||||||
context={'default_res_id': -1, 'active_ids': [self.group_pigs_id, group_bird_id]})
|
'default_res_id': -1,
|
||||||
|
'active_ids': [self.group_pigs_id, group_bird_id]
|
||||||
|
})
|
||||||
group_pigs.refresh()
|
group_pigs.refresh()
|
||||||
group_bird.refresh()
|
group_bird.refresh()
|
||||||
message1 = group_pigs.message_ids[0]
|
message1 = group_pigs.message_ids[0]
|
||||||
message2 = group_bird.message_ids[0]
|
message2 = group_bird.message_ids[0]
|
||||||
|
|
||||||
# Test: Pigs and Bird did receive their message
|
# Test: Pigs and Bird did receive their message
|
||||||
test_msg_ids = self.mail_message.search(cr, uid, [], limit=2)
|
test_msg_ids = self.mail_message.search(cr, uid, [], limit=2)
|
||||||
self.assertIn(message1.id, test_msg_ids, 'Pigs did not receive its mass mailing message')
|
self.assertIn(message1.id, test_msg_ids, 'compose wizard: Pigs did not receive its mass mailing message')
|
||||||
self.assertIn(message2.id, test_msg_ids, 'Bird did not receive its mass mailing message')
|
self.assertIn(message2.id, test_msg_ids, 'compose wizard: Bird did not receive its mass mailing message')
|
||||||
|
|
||||||
# Test: mail.message: subject, body, subtype, notified partners (nobody + specific recipients)
|
# Test: mail.message: subject, body, subtype, notified partners (nobody + specific recipients)
|
||||||
self.assertEqual(message1.subject, _subject,
|
self.assertEqual(message1.subject, _subject,
|
||||||
'message_post: mail.message in mass mail subject incorrect')
|
'compose wizard: message_post: mail.message in mass mail subject incorrect')
|
||||||
self.assertEqual(message1.body, '<p>%s</p>' % group_pigs.description,
|
self.assertEqual(message1.body, '<p>%s</p>' % group_pigs.description,
|
||||||
'message_post: mail.message in mass mail body incorrect')
|
'compose wizard: message_post: mail.message in mass mail body incorrect')
|
||||||
self.assertEqual(set([p.id for p in message1.notified_partner_ids]), set([p_c_id, p_d_id]),
|
self.assertEqual(set([p.id for p in message1.notified_partner_ids]), set([p_c_id, p_d_id]),
|
||||||
'message_post: mail.message in mass mail incorrect notified partners')
|
'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
|
||||||
self.assertEqual(message2.subject, _subject,
|
self.assertEqual(message2.subject, _subject,
|
||||||
'message_post: mail.message in mass mail subject incorrect')
|
'compose wizard: message_post: mail.message in mass mail subject incorrect')
|
||||||
self.assertEqual(message2.body, '<p>%s</p>' % group_bird.description,
|
self.assertEqual(message2.body, '<p>%s</p>' % group_bird.description,
|
||||||
'message_post: mail.message in mass mail body incorrect')
|
'compose wizard: message_post: mail.message in mass mail body incorrect')
|
||||||
self.assertEqual(set([p.id for p in message2.notified_partner_ids]), set([p_c_id, p_d_id]),
|
self.assertEqual(set([p.id for p in message2.notified_partner_ids]), set([p_c_id, p_d_id]),
|
||||||
'message_post: mail.message in mass mail incorrect notified partners')
|
'compose wizard: message_post: mail.message in mass mail incorrect notified partners')
|
||||||
|
|
||||||
|
# Test: mail.group followers: author not added as follower in mass mail mode
|
||||||
|
pigs_pids = [p.id for p in group_pigs.message_follower_ids]
|
||||||
|
test_pids = [self.partner_admin_id, p_b_id, p_c_id, p_d_id]
|
||||||
|
self.assertEqual(set(pigs_pids), set(test_pids),
|
||||||
|
'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account')
|
||||||
|
bird_pids = [p.id for p in group_bird.message_follower_ids]
|
||||||
|
test_pids = [self.partner_admin_id]
|
||||||
|
self.assertEqual(set(bird_pids), set(test_pids),
|
||||||
|
'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account')
|
||||||
|
|
||||||
def test_30_needaction(self):
|
def test_30_needaction(self):
|
||||||
""" Tests for mail.message needaction. """
|
""" Tests for mail.message needaction. """
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Business Applications
|
||||||
|
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.addons.mail.tests.test_mail_base import TestMailBase
|
||||||
|
|
||||||
|
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
||||||
|
To: {to}
|
||||||
|
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
||||||
|
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
||||||
|
From: {email_from}
|
||||||
|
Subject: {subject}
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: multipart/alternative;
|
||||||
|
boundary="----=_Part_4200734_24778174.1344608186754"
|
||||||
|
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
||||||
|
Message-ID: {msg_id}
|
||||||
|
{extra}
|
||||||
|
------=_Part_4200734_24778174.1344608186754
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
Please call me as soon as possible this afternoon!
|
||||||
|
|
||||||
|
--
|
||||||
|
Sylvie
|
||||||
|
------=_Part_4200734_24778174.1344608186754
|
||||||
|
Content-Type: text/html; charset=utf-8
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>=20
|
||||||
|
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
|
||||||
|
</head>=20
|
||||||
|
<body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20
|
||||||
|
|
||||||
|
<p>Please call me as soon as possible this afternoon!</p>
|
||||||
|
|
||||||
|
<p>--<br/>
|
||||||
|
Sylvie
|
||||||
|
<p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
------=_Part_4200734_24778174.1344608186754--
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAIL_TEMPLATE_PLAINTEXT = """Return-Path: <whatever-2a840@postmaster.twitter.com>
|
||||||
|
To: {to}
|
||||||
|
Received: by mail1.openerp.com (Postfix, from userid 10002)
|
||||||
|
id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
|
||||||
|
From: Sylvie Lelitre <sylvie.lelitre@agrolait.com>
|
||||||
|
Subject: {subject}
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain
|
||||||
|
Date: Fri, 10 Aug 2012 14:16:26 +0000
|
||||||
|
Message-ID: {msg_id}
|
||||||
|
{extra}
|
||||||
|
|
||||||
|
Please call me as soon as possible this afternoon!
|
||||||
|
|
||||||
|
--
|
||||||
|
Sylvie
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class TestMailgateway(TestMailBase):
|
||||||
|
|
||||||
|
def test_00_message_process(self):
|
||||||
|
""" Testing incoming emails processing. """
|
||||||
|
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
|
||||||
|
|
||||||
|
def format_and_process(template, to='groups@example.com, other@gmail.com', subject='Frogs',
|
||||||
|
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||||
|
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>',
|
||||||
|
model=None):
|
||||||
|
self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', subject)]), [])
|
||||||
|
mail = template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||||
|
self.mail_thread.message_process(cr, uid, model, mail)
|
||||||
|
return self.mail_group.search(cr, uid, [('name', '=', subject)])
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# Data creation
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
# groups@.. will cause the creation of new mail groups
|
||||||
|
self.mail_group_model_id = self.ir_model.search(cr, uid, [('model', '=', 'mail.group')])[0]
|
||||||
|
alias_id = self.mail_alias.create(cr, uid, {
|
||||||
|
'alias_name': 'groups',
|
||||||
|
'alias_user_id': False,
|
||||||
|
'alias_model_id': self.mail_group_model_id})
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# Test1: new record creation
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
# Do: incoming mail from an unknown partner on an alias creates a new mail_group "frogs"
|
||||||
|
self._init_mock_build_email()
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||||
|
sent_emails = self._build_email_kwargs_list
|
||||||
|
# Test: one group created by mailgateway administrator
|
||||||
|
self.assertTrue(len(frog_groups) == 1)
|
||||||
|
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||||
|
# Test: one message that is the incoming email
|
||||||
|
self.assertEqual(len(frog_group.message_ids), 1,
|
||||||
|
'message_process: newly created group should have the incoming email in message_ids')
|
||||||
|
msg = frog_group.message_ids[0]
|
||||||
|
self.assertEqual('Frogs', msg.subject,
|
||||||
|
'message_process: newly created group should have the incoming email as first message')
|
||||||
|
self.assertIn('Please call me as soon as possible this afternoon!', msg.body,
|
||||||
|
'message_process: newly created group should have the incoming email as first message')
|
||||||
|
self.assertEqual('email', msg.type,
|
||||||
|
'message_process: newly created group should have an email as first message')
|
||||||
|
self.assertEqual('Discussions', msg.subtype_id.name,
|
||||||
|
'message_process: newly created group should not have a log first message but an email')
|
||||||
|
# Test: message: unknown email address -> message has email_from, not author_id
|
||||||
|
self.assertFalse(msg.author_id,
|
||||||
|
'message_process: message on created group should not have an author_id')
|
||||||
|
self.assertIn('test.sylvie.lelitre@agrolait.com', msg.email_from,
|
||||||
|
'message_process: message on created group should have an email_from')
|
||||||
|
# Test: followers: nobody
|
||||||
|
self.assertEqual(len(frog_group.message_follower_ids), 0, 'message_process: newly create group should not have any follower')
|
||||||
|
# Test: sent emails: no-one
|
||||||
|
self.assertEqual(len(sent_emails), 0,
|
||||||
|
'message_process: should create emails without any follower added')
|
||||||
|
# Data: unlink group
|
||||||
|
frog_group.unlink()
|
||||||
|
|
||||||
|
# Do: incoming email from a known partner on an alias with known recipients, alias is owned by user that can create a group
|
||||||
|
self.mail_alias.write(cr, uid, [alias_id], {'alias_user_id': self.user_raoul_id})
|
||||||
|
p1id = self.res_partner.create(cr, uid, {'name': 'Sylvie Lelitre', 'email': 'test.sylvie.lelitre@agrolait.com'})
|
||||||
|
p2id = self.res_partner.create(cr, uid, {'name': 'Other Poilvache', 'email': 'other@gmail.com'})
|
||||||
|
self._init_mock_build_email()
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||||
|
sent_emails = self._build_email_kwargs_list
|
||||||
|
# Test: one group created by raoul
|
||||||
|
self.assertTrue(len(frog_groups) == 1)
|
||||||
|
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||||
|
# Test: one message that is the incoming email
|
||||||
|
self.assertEqual(len(frog_group.message_ids), 1,
|
||||||
|
'message_process: newly created group should have the incoming email in message_ids')
|
||||||
|
msg = frog_group.message_ids[0]
|
||||||
|
# Test: message: unknown email address -> message has email_from, not author_id
|
||||||
|
self.assertEqual(p1id, msg.author_id.id,
|
||||||
|
'message_process: message on created group should have Sylvie as author_id')
|
||||||
|
self.assertIn('Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', msg.email_from,
|
||||||
|
'message_process: message on created group should have have an email_from')
|
||||||
|
# Test: author (not recipient and and not raoul (as alias owner)) added as follower
|
||||||
|
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||||
|
self.assertEqual(frog_follower_ids, set([p1id]),
|
||||||
|
'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
|
||||||
|
# Test: sent emails: no-one, no bounce effet
|
||||||
|
self.assertEqual(len(sent_emails), 0,
|
||||||
|
'message_process: should not bounce incoming emails')
|
||||||
|
# Data: unlink group
|
||||||
|
frog_group.unlink()
|
||||||
|
|
||||||
|
# Do: incoming email from a known partner that is also an user that can create a mail.group
|
||||||
|
self.res_users.create(cr, uid, {'partner_id': p1id, 'login': 'sylvie', 'groups_id': [(6, 0, [self.group_employee_id])]})
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com')
|
||||||
|
# Test: one group created by Sylvie
|
||||||
|
self.assertTrue(len(frog_groups) == 1)
|
||||||
|
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||||
|
# Test: one message that is the incoming email
|
||||||
|
self.assertEqual(len(frog_group.message_ids), 1,
|
||||||
|
'message_process: newly created group should have the incoming email in message_ids')
|
||||||
|
# Test: author (and not recipient) added as follower
|
||||||
|
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||||
|
self.assertEqual(frog_follower_ids, set([p1id]),
|
||||||
|
'message_process: newly created group should have 1 follower (author, not creator, not recipients)')
|
||||||
|
# Test: sent emails: no-one, no bounce effet
|
||||||
|
self.assertEqual(len(sent_emails), 0,
|
||||||
|
'message_process: should not bounce incoming emails')
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# Test2: discussion update
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
# Do: even with a wrong destination, a reply should end up in the correct thread
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other@gmail.com',
|
||||||
|
to='erroneous@example.com>', subject='Re: news',
|
||||||
|
extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id)
|
||||||
|
# Test: no group 'Re: news' created, still only 1 Frogs group
|
||||||
|
self.assertEqual(len(frog_groups), 0,
|
||||||
|
'message_process: reply on Frogs should not have created a new group with new subject')
|
||||||
|
frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')])
|
||||||
|
self.assertEqual(len(frog_groups), 1,
|
||||||
|
'message_process: reply on Frogs should not have created a duplicate group with old subject')
|
||||||
|
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||||
|
# Test: one new message
|
||||||
|
self.assertTrue(len(frog_group.message_ids) == 2, 'message_process: group should contain 2 messages after reply')
|
||||||
|
# Test: author (and not recipient) added as follower
|
||||||
|
frog_follower_ids = set([p.id for p in frog_group.message_follower_ids])
|
||||||
|
self.assertEqual(frog_follower_ids, set([p1id, p2id]),
|
||||||
|
'message_process: after reply, group should have 2 followers')
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
# Test3: misc gateway features
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
# Do: incoming email with model that does not accepts incoming emails must raise
|
||||||
|
self.assertRaises(AssertionError,
|
||||||
|
format_and_process,
|
||||||
|
MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='', model='res.country')
|
||||||
|
|
||||||
|
# Do: incoming email without model and without alias must raise
|
||||||
|
self.assertRaises(AssertionError,
|
||||||
|
format_and_process,
|
||||||
|
MAIL_TEMPLATE, to='noone@example.com', subject='spam', extra='')
|
||||||
|
|
||||||
|
# Do: incoming email with model that accepting incoming emails as fallback
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE, to='noone@example.com', subject='Spammy', extra='', model='mail.group')
|
||||||
|
self.assertEqual(len(frog_groups), 1,
|
||||||
|
'message_process: erroneous email but with a fallback model should have created a new mail.group')
|
||||||
|
|
||||||
|
# Do: incoming email in plaintext should be stored as html
|
||||||
|
frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, to='groups@example.com', subject='Frogs Return', extra='', msg_id='<deadcafe.1337@smtp.agrolait.com>')
|
||||||
|
# Test: one group created with one message
|
||||||
|
self.assertTrue(len(frog_groups) == 1)
|
||||||
|
frog_group = self.mail_group.browse(cr, uid, frog_groups[0])
|
||||||
|
msg = frog_group.message_ids[0]
|
||||||
|
# Test: plain text content should be wrapped and stored as html
|
||||||
|
self.assertEqual(msg.body, '<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>',
|
||||||
|
'message_process: plaintext incoming email incorrectly parsed')
|
||||||
|
|
||||||
|
def test_10_thread_parent_resolution(self):
|
||||||
|
""" Testing parent/child relationships are correctly established when processing incoming mails """
|
||||||
|
cr, uid = self.cr, self.uid
|
||||||
|
|
||||||
|
def format(template, to='Pretty Pigs <group+pigs@example.com>, other@gmail.com', subject='Re: 1',
|
||||||
|
extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>',
|
||||||
|
msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
|
||||||
|
return template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id)
|
||||||
|
|
||||||
|
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
|
||||||
|
msg1 = group_pigs.message_post(body='My Body', subject='1')
|
||||||
|
msg2 = group_pigs.message_post(body='My Body', subject='2')
|
||||||
|
msg1, msg2 = self.mail_message.browse(cr, uid, [msg1, msg2])
|
||||||
|
self.assertTrue(msg1.message_id, "message_process: new message should have a proper message_id")
|
||||||
|
|
||||||
|
# Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms
|
||||||
|
# 0. Direct alias match
|
||||||
|
reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs <group+pigs@example.com>', extra='In-Reply-To: %s' % msg1.message_id)
|
||||||
|
self.mail_group.message_process(cr, uid, None, reply_msg1)
|
||||||
|
|
||||||
|
# 1. In-Reply-To header
|
||||||
|
reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='In-Reply-To: %s' % msg1.message_id)
|
||||||
|
self.mail_group.message_process(cr, uid, None, reply_msg2)
|
||||||
|
|
||||||
|
# 2. References header
|
||||||
|
reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id)
|
||||||
|
self.mail_group.message_process(cr, uid, None, reply_msg3)
|
||||||
|
|
||||||
|
# 3. Subject contains [<ID>] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids)
|
||||||
|
reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', extra='', subject='Re: [%s] 1' % self.group_pigs_id)
|
||||||
|
self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4)
|
||||||
|
|
||||||
|
group_pigs.refresh()
|
||||||
|
msg1.refresh()
|
||||||
|
self.assertEqual(6, len(group_pigs.message_ids), 'message_process: group should contain 6 messages')
|
||||||
|
self.assertEqual(3, len(msg1.child_ids), 'message_process: msg1 should have 3 children now')
|
||||||
|
|
||||||
|
def test_20_private_discussion(self):
|
||||||
|
""" Testing private discussion between partners. """
|
||||||
|
pass
|
|
@ -23,6 +23,7 @@ import base64
|
||||||
import re
|
import re
|
||||||
from openerp import tools
|
from openerp import tools
|
||||||
|
|
||||||
|
from openerp import SUPERUSER_ID
|
||||||
from openerp.osv import osv
|
from openerp.osv import osv
|
||||||
from openerp.osv import fields
|
from openerp.osv import fields
|
||||||
from openerp.tools.safe_eval import safe_eval as eval
|
from openerp.tools.safe_eval import safe_eval as eval
|
||||||
|
@ -126,6 +127,29 @@ class mail_compose_message(osv.TransientModel):
|
||||||
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||||
|
""" Access rules of mail.compose.message:
|
||||||
|
- create: if
|
||||||
|
- model, no res_id, I create a message in mass mail mode
|
||||||
|
- then: fall back on mail.message acces rules
|
||||||
|
"""
|
||||||
|
if isinstance(ids, (int, long)):
|
||||||
|
ids = [ids]
|
||||||
|
|
||||||
|
# Author condition (CREATE (mass_mail))
|
||||||
|
if operation == 'create' and uid != SUPERUSER_ID:
|
||||||
|
# read mail_compose_message.ids to have their values
|
||||||
|
message_values = {}
|
||||||
|
cr.execute('SELECT DISTINCT id, model, res_id FROM "%s" WHERE id = ANY (%%s) AND res_id = 0' % self._table, (ids,))
|
||||||
|
for id, rmod, rid in cr.fetchall():
|
||||||
|
message_values[id] = {'model': rmod, 'res_id': rid}
|
||||||
|
# remove from the set to check the ids that mail_compose_message accepts
|
||||||
|
author_ids = [mid for mid, message in message_values.iteritems()
|
||||||
|
if message.get('model') and not message.get('res_id')]
|
||||||
|
ids = list(set(ids) - set(author_ids))
|
||||||
|
|
||||||
|
return super(mail_compose_message, self).check_access_rule(cr, uid, ids, operation, context=context)
|
||||||
|
|
||||||
def _notify(self, cr, uid, newid, context=None):
|
def _notify(self, cr, uid, newid, context=None):
|
||||||
""" Override specific notify method of mail.message, because we do
|
""" Override specific notify method of mail.message, because we do
|
||||||
not want that feature in the wizard. """
|
not want that feature in the wizard. """
|
||||||
|
@ -218,8 +242,11 @@ class mail_compose_message(osv.TransientModel):
|
||||||
post_values.update(email_dict)
|
post_values.update(email_dict)
|
||||||
# post the message
|
# post the message
|
||||||
subtype = 'mail.mt_comment'
|
subtype = 'mail.mt_comment'
|
||||||
if is_log or mass_mail_mode:
|
if is_log: # log a note: subtype is False
|
||||||
subtype = False
|
subtype = False
|
||||||
|
elif mass_mail_mode: # mass mail: is a log pushed to recipients, author not added
|
||||||
|
subtype = False
|
||||||
|
context = dict(context, mail_create_nosubscribe=True) # add context key to avoid subscribing the author
|
||||||
msg_id = active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values)
|
msg_id = active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values)
|
||||||
# mass_mailing: notify specific partners, because subtype was False, and no-one was notified
|
# mass_mailing: notify specific partners, because subtype was False, and no-one was notified
|
||||||
if mass_mail_mode and post_values['partner_ids']:
|
if mass_mail_mode and post_values['partner_ids']:
|
||||||
|
|
Loading…
Reference in New Issue