summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2012-12-11 15:46:50 +0100
committerThibault Delavallée <tde@openerp.com>2012-12-11 15:46:50 +0100
commitdb32d98b7ab4c033b6ddd2ae5cf5f900e971b682 (patch)
tree6fa5b3901f4944f567cee008228babf3d7bf6706
parent45e1682327b3b844e1542abf49c31a2192856bb1 (diff)
[REF] [TESTS] mail, portal: refactored a bit the various mail and invite tests: moved some tests into dedicated files, added some new tests, removed duplicates.
bzr revid: tde@openerp.com-20121211144650-kpy7noe082e3xvoo
-rw-r--r--addons/mail/tests/__init__.py8
-rw-r--r--addons/mail/tests/test_invite.py48
-rw-r--r--addons/mail/tests/test_mail_base.py89
-rw-r--r--addons/mail/tests/test_mail_features.py (renamed from addons/mail/tests/test_mail.py)454
-rw-r--r--addons/mail/tests/test_mail_message.py (renamed from addons/mail/tests/test_mail_access_rights.py)197
-rw-r--r--addons/mail/tests/test_mail_mockup.py54
-rw-r--r--addons/mail/tests/test_message_read.py184
-rw-r--r--addons/portal/tests/test_portal.py45
8 files changed, 595 insertions, 484 deletions
diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py
index 3dcddf769e8..b945da54655 100644
--- a/addons/mail/tests/__init__.py
+++ b/addons/mail/tests/__init__.py
@@ -19,11 +19,13 @@
#
##############################################################################
-from . import test_mail, test_mail_access_rights
+from . import test_mail_message, test_mail_features, test_message_read, test_invite
checks = [
- test_mail,
- test_mail_access_rights,
+ test_mail_message,
+ test_mail_features,
+ test_message_read,
+ test_invite,
]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mail/tests/test_invite.py b/addons/mail/tests/test_invite.py
new file mode 100644
index 00000000000..4f97a56cac2
--- /dev/null
+++ b/addons/mail/tests/test_invite.py
@@ -0,0 +1,48 @@
+# -*- 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
+
+
+class test_invite(TestMailBase):
+
+ def test_00_basic_invite(self):
+ cr, uid = self.cr, self.uid
+ mail_invite = self.registry('mail.wizard.invite')
+
+ # Do: create a mail_wizard_invite, validate it
+ self._init_mock_build_email()
+ context = {'default_res_model': 'mail.group', 'default_res_id': self.group_pigs_id}
+ mail_invite_id = mail_invite.create(cr, self.user_raoul_id, {'partner_ids': [(4, self.partner_bert_id)]}, context)
+ mail_invite.add_followers(cr, self.user_raoul_id, [mail_invite_id], {'default_model': 'mail.group', 'default_res_id': 0})
+
+ # Test: Pigs followers should contain Admin, Bert
+ self.group_pigs.refresh()
+ follower_ids = [follower.id for follower in self.group_pigs.message_follower_ids]
+ self.assertEqual(set(follower_ids), set([self.partner_admin_id, self.partner_bert_id]), 'Pigs followers after invite is incorrect')
+
+ # Test: (pretend to) send email and check subject, body
+ self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
+ for sent_email in self._build_email_kwargs_list:
+ self.assertEqual(sent_email.get('subject'), 'Invitation to follow Pigs',
+ 'subject of invitation email is incorrect')
+ self.assertTrue('You have been invited to follow Pigs' in sent_email.get('body'),
+ 'body of invitation email is incorrect')
diff --git a/addons/mail/tests/test_mail_base.py b/addons/mail/tests/test_mail_base.py
new file mode 100644
index 00000000000..7811f676232
--- /dev/null
+++ b/addons/mail/tests/test_mail_base.py
@@ -0,0 +1,89 @@
+# -*- 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.tests import common
+
+
+class TestMailBase(common.TransactionCase):
+
+ def _mock_smtp_gateway(self, *args, **kwargs):
+ return True
+
+ def _init_mock_build_email(self):
+ self._build_email_args_list = []
+ self._build_email_kwargs_list = []
+
+ def _mock_build_email(self, *args, **kwargs):
+ """ Mock build_email to be able to test its values. Store them into
+ some internal variable for latter processing. """
+ self._build_email_args_list.append(args)
+ self._build_email_kwargs_list.append(kwargs)
+ return self._build_email(*args, **kwargs)
+
+ def setUp(self):
+ super(TestMailBase, self).setUp()
+ cr, uid = self.cr, self.uid
+ # Install mock SMTP gateway
+ self._init_mock_build_email()
+ self._build_email = self.registry('ir.mail_server').build_email
+ self.registry('ir.mail_server').build_email = self._mock_build_email
+ self._send_email = self.registry('ir.mail_server').send_email
+ self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
+
+ # Usefull models
+ self.ir_model = self.registry('ir.model')
+ self.mail_alias = self.registry('mail.alias')
+ self.mail_thread = self.registry('mail.thread')
+ self.mail_group = self.registry('mail.group')
+ self.mail_mail = self.registry('mail.mail')
+ self.mail_message = self.registry('mail.message')
+ self.mail_notification = self.registry('mail.notification')
+ self.mail_followers = self.registry('mail.followers')
+ self.mail_message_subtype = self.registry('mail.message.subtype')
+ self.res_users = self.registry('res.users')
+ self.res_partner = self.registry('res.partner')
+
+ # Find Employee group
+ group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
+ self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
+
+ # Test users to use through the various tests
+ 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])]})
+ 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, [])]})
+ 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_admin = self.res_users.browse(cr, uid, uid)
+ self.partner_admin_id = self.user_admin.partner_id.id
+ self.partner_raoul_id = self.user_raoul.partner_id.id
+ self.partner_bert_id = self.user_bert.partner_id.id
+
+ # Test 'pigs' group to use through the various tests
+ self.group_pigs_id = self.mail_group.create(cr, uid,
+ {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
+ self.group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
+
+ def tearDown(self):
+ # Remove mocks
+ self.registry('ir.mail_server').build_email = self._build_email
+ self.registry('ir.mail_server').send_email = self._send_email
+ super(TestMailBase, self).tearDown()
diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail_features.py
index 466b47fd4a7..45142934775 100644
--- a/addons/mail/tests/test_mail.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -19,10 +19,8 @@
#
##############################################################################
-import tools
-
-from openerp.addons.mail.tests import test_mail_mockup
-from openerp.tools.mail import html_sanitize
+from openerp.addons.mail.tests.test_mail_base import TestMailBase
+from openerp.tools.mail import html_sanitize, append_content_to_html
MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com>
To: {to}
@@ -84,50 +82,20 @@ Sylvie
"""
-class test_mail(test_mail_mockup.TestMailMockups):
+class test_mail(TestMailBase):
def _mock_send_get_mail_body(self, *args, **kwargs):
# def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
- body = tools.append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner', plaintext=False)
+ 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()
- cr, uid = self.cr, self.uid
- self.ir_model = self.registry('ir.model')
- self.mail_alias = self.registry('mail.alias')
- self.mail_thread = self.registry('mail.thread')
- self.mail_group = self.registry('mail.group')
- self.mail_mail = self.registry('mail.mail')
- self.mail_message = self.registry('mail.message')
- self.mail_notification = self.registry('mail.notification')
- self.mail_followers = self.registry('mail.followers')
- self.mail_message_subtype = self.registry('mail.message.subtype')
- self.res_users = self.registry('res.users')
- self.res_partner = self.registry('res.partner')
-
- # Find Employee group
- group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
- group_employee_id = group_employee_ref and group_employee_ref[1] or False
- # Test users
- self.user_raoul_id = self.res_users.create(cr, uid,
- {'name': 'Raoul Grosbedon', 'email': 'raoul@raoul.fr', 'login': 'raoul', 'groups_id': [(6, 0, [group_employee_id])]})
- self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
- self.user_admin = self.res_users.browse(cr, uid, uid)
# 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
- # 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})
- # create a 'pigs' group that will be used through the various tests
- self.group_pigs_id = self.mail_group.create(cr, uid,
- {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
- self.group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
-
def tearDown(self):
# Remove mocks
self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body
@@ -136,6 +104,11 @@ class test_mail(test_mail_mockup.TestMailMockups):
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='')
@@ -193,14 +166,42 @@ class test_mail(test_mail_mockup.TestMailMockups):
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'.
We will test to perform writes using the many2many commands 0, 3, 4,
5 and 6. """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
+ cr, uid, user_admin, partner_bert_id, group_pigs = self.cr, self.uid, self.user_admin, self.partner_bert_id, self.group_pigs
- # Data: create partner Bert Poilu
- partner_bert_id = self.res_partner.create(cr, uid, {'name': 'Bert Poilu'})
# Data: create 'disturbing' values in mail.followers: same res_id, other res_model; same res_model, other res_id
group_dummy_id = self.mail_group.create(cr, uid,
{'name': 'Dummy group'})
@@ -254,10 +255,7 @@ class test_mail(test_mail_mockup.TestMailMockups):
def test_11_message_followers_and_subtypes(self):
""" Tests designed for the subscriber API as well as message subtypes """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
- # Data: user Raoul
- user_raoul_id = self.user_raoul_id
- user_raoul = self.res_users.browse(cr, uid, user_raoul_id)
+ cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
# Data: message subtypes
self.mail_message_subtype.create(cr, uid, {'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.group'})
self.mail_message_subtype.create(cr, uid, {'name': 'mt_other_def', 'default': True, 'res_model': 'crm.lead'})
@@ -271,8 +269,8 @@ class test_mail(test_mail_mockup.TestMailMockups):
# ----------------------------------------
# Do: Subscribe Raoul three times (niak niak) through message_subscribe_users
- group_pigs.message_subscribe_users([user_raoul_id, user_raoul_id])
- group_pigs.message_subscribe_users([user_raoul_id])
+ group_pigs.message_subscribe_users([user_raoul.id, user_raoul.id])
+ group_pigs.message_subscribe_users([user_raoul.id])
group_pigs.refresh()
# Test: 2 followers (Admin and Raoul)
follower_ids = [follower.id for follower in group_pigs.message_follower_ids]
@@ -284,7 +282,7 @@ class test_mail(test_mail_mockup.TestMailMockups):
self.assertEqual(set(fol_subtype_ids), set(default_group_subtypes), 'subscription subtypes are incorrect')
# Do: Unsubscribe Raoul twice through message_unsubscribe_users
- group_pigs.message_unsubscribe_users([user_raoul_id, user_raoul_id])
+ group_pigs.message_unsubscribe_users([user_raoul.id, user_raoul.id])
group_pigs.refresh()
# Test: 1 follower (Admin)
follower_ids = [follower.id for follower in group_pigs.message_follower_ids]
@@ -327,7 +325,7 @@ class test_mail(test_mail_mockup.TestMailMockups):
def test_21_message_post(self):
""" Tests designed for message_post. """
- 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
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
# 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'})
@@ -336,18 +334,18 @@ class test_mail(test_mail_mockup.TestMailMockups):
# 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, #2
- group_pigs.message_subscribe([p_b_id, p_c_id])
+ # Subscribe Raoul, #1, #2
+ group_pigs.message_subscribe([self.partner_raoul_id, p_b_id, p_c_id])
# Mail data
_subject = 'Pigs'
- _mail_subject = '%s posted on %s' % (user_admin.name, group_pigs.name)
+ _mail_subject = '%s posted on %s' % (user_raoul.name, group_pigs.name)
_body1 = 'Pigs rules'
- _mail_body1 = 'Pigs rules\n<div><p>Admin</p></div>\n'
- _mail_bodyalt1 = 'Pigs rules\nAdmin\n'
+ _mail_body1 = 'Pigs rules\n<div><p>Raoul</p></div>\n'
+ _mail_bodyalt1 = 'Pigs rules\nRaoul\n'
_body2 = '<html>Pigs rules</html>'
- _mail_body2 = html_sanitize('<html>Pigs rules\n<div><p>Admin</p></div>\n</html>')
- _mail_bodyalt2 = 'Pigs rules\nAdmin'
+ _mail_body2 = html_sanitize('<html>Pigs rules\n<div><p>Raoul</p></div>\n</html>')
+ _mail_bodyalt2 = 'Pigs rules\nRaoul'
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
# ----------------------------------------
@@ -356,108 +354,85 @@ class test_mail(test_mail_mockup.TestMailMockups):
# 1. Post a new comment on Pigs
self._init_mock_build_email()
- msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment', subtype='mt_comment')
- message = self.mail_message.browse(cr, uid, msg_id)
+ msg1_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body=_body1, subject=_subject, type='comment', subtype='mt_comment')
+ message1 = self.mail_message.browse(cr, uid, msg1_id)
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', '=', msg_id)]), 'mail.mail notifications should have been auto-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 is _subject, body is _body1 (no formatting done)
- self.assertEqual(message.subject, _subject, 'mail.message subject incorrect')
- self.assertEqual(message.body, _body1, 'mail.message body incorrect')
+ self.assertEqual(message1.subject, _subject, 'mail.message subject incorrect')
+ self.assertEqual(message1.body, _body1, 'mail.message body incorrect')
# 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.assertEqual(sent_email['body'], _mail_body1 + '\nBert Tartopoils\n', 'sent_email body 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.assertIn(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils\n', 'sent_email body_alternative is incorrect')
+ 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 message.notified_partner_ids])
- test_pids = set([p_b_id, p_c_id])
- self.assertEqual(test_pids, message_pids, 'mail.message partners incorrect')
+ 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])
+ self.assertEqual(test_pids, message_pids, 'mail.message notified partners incorrect')
# Test: notification linked to this message = group followers = notified_partner_ids
- notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.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)])
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
# Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer)
for sent_email in sent_emails:
- self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
+ 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
+ # CASE2: post an email with attachments, parent_id, partner_ids, parent notification
# ----------------------------------------
# 1. Post a new email comment on Pigs
self._init_mock_build_email()
- msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email', subtype='mt_comment',
- partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
- message = self.mail_message.browse(cr, uid, msg_id2)
+ msg2_id = self.mail_group.message_post(cr, user_raoul.id, self.group_pigs_id, body=_body2, type='email', subtype='mt_comment',
+ partner_ids=[(6, 0, [p_d_id])], parent_id=msg1_id, attachments=_attachments)
+ message2 = self.mail_message.browse(cr, uid, msg2_id)
sent_emails = self._build_email_kwargs_list
- self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!')
+ 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
- self.assertEqual(message.subject, False, 'mail.message subject incorrect')
- self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect')
- self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect')
+ self.assertEqual(message2.subject, False, 'mail.message subject incorrect')
+ self.assertEqual(message2.body, html_sanitize(_body2), 'mail.message body incorrect')
+ self.assertEqual(message2.parent_id.id, msg1_id, 'mail.message parent_id incorrect')
# Test: sent_email: email send by server: correct automatic subject, body, body_alternative
- self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
+ 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
- message_pids = set([partner.id for partner in message.notified_partner_ids])
- test_pids = set([p_b_id, p_c_id, p_d_id])
+ message_pids = set([partner.id for partner in message2.notified_partner_ids])
+ test_pids = set([self.partner_admin_id, p_b_id, p_c_id, p_d_id])
self.assertEqual(message_pids, test_pids, 'mail.message partners incorrect')
# Test: notifications linked to this message = group followers = notified_partner_ids
- notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.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)])
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
# Test: sent_email: email_to should contain b@b, c@c, not a@a (writer)
for sent_email in sent_emails:
- self.assertTrue(set(sent_email['email_to']).issubset(set(['b@b', 'c@c'])), 'sent_email email_to incorrect')
+ self.assertTrue(set(sent_email['email_to']).issubset(set(['a@a', 'b@b', 'c@c'])), 'sent_email email_to incorrect')
# Test: attachments
- for attach in message.attachment_ids:
+ for attach in message2.attachment_ids:
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
self.assertEqual(attach.res_id, self.group_pigs_id, 'mail.message attachment res_id incorrect')
self.assertIn((attach.name, attach.datas.decode('base64')), _attachments,
'mail.message attachment name / data incorrect')
- # 3. Reply to the last message, check that its parent will be the first message
- msg_id3 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Test', parent_id=msg_id2)
- message = self.mail_message.browse(cr, uid, msg_id3)
- self.assertEqual(message.parent_id.id, msg_id, 'message_post did not flatten the thread structure')
+ # 2. Dédé has been notified -> should also have been notified of the parent message
+ message1.refresh()
+ 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, p_d_id])
+ self.assertEqual(test_pids, message_pids, 'mail.message parent notification not created')
- def test_22_message_post_notification(self):
- """ Tests designed for message_post. """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
- self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
- # 1 - Bert Tartopoils, without email, should receive emails for every message
- p_b_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b', 'notification_email_send': 'all'})
- # 2 - Dédé Grosbedon, without email, should receive emails for every message
- p_c_id = self.res_partner.create(cr, uid, {'name': 'Dédé Grosbedon', 'email': 'c@c','notification_email_send': 'all'})
- # Data: comment subtype for mail.message creation
- ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'mail', 'mt_comment')
- subtype_id = ref and ref[1] or False
-
- msg_id1 = self.mail_message.create(cr, uid, {'body': 'Test', 'subtype_id': subtype_id})
- msg_id2 = self.mail_message.create(cr, uid, {'body': 'Test', 'subtype_id': subtype_id, 'parent_id': msg_id1 })
- msg_id3 = self.mail_message.create(cr, uid, {'body': 'Test', 'subtype_id': subtype_id, 'parent_id': msg_id1, 'partner_ids': [(4, p_b_id)] , 'notified_partner_ids': [(4, p_c_id)] })
-
- test_pids = set([p_b_id, p_c_id])
-
- # Test: p_b_id is notified for the current message
- message = self.mail_message.browse(cr, uid, msg_id3)
- message_pids = set([partner.id for partner in message.notified_partner_ids] + [partner.id for partner in message.partner_ids])
- self.assertEqual(test_pids, message_pids, 'mail.message : the partner is not notified for his message')
- # Test: p_b_id is not notified for the others messages of this thread
- message = self.mail_message.browse(cr, uid, msg_id2)
- message_pids = set([partner.id for partner in message.notified_partner_ids] + [partner.id for partner in message.partner_ids])
- self.assertFalse(message_pids, 'mail.message the partner is notified for an other message')
- # Test: p_b_id is notified for the parented message
- message = self.mail_message.browse(cr, uid, msg_id1)
- message_pids = set([partner.id for partner in message.notified_partner_ids] + [partner.id for partner in message.partner_ids])
-
- self.assertEqual(test_pids, message_pids, 'mail.message the partner is not notified for the parented message')
+ # 3. Reply to the last message, check that its parent will be the first message
+ 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)
+ self.assertEqual(message.parent_id.id, msg1_id, 'message_post did not flatten the thread structure')
def test_25_message_compose_wizard(self):
""" Tests designed for the mail.compose.message wizard. """
@@ -537,7 +512,7 @@ class test_mail(test_mail_mockup.TestMailMockups):
# Test: mail.message: attachments
for attach in compose.attachment_ids:
self.assertIn((attach.datas_fname, attach.datas.decode('base64')), _attachments_test, 'mail.message attachment name / data incorrect')
-
+
# ----------------------------------------
# CASE3: mass_mail on Pigs and Bird
# ----------------------------------------
@@ -566,169 +541,9 @@ class test_mail(test_mail_mockup.TestMailMockups):
self.assertEqual(message2.subject, _subject, 'mail.message subject incorrect')
self.assertEqual(message2.body, group_bird.description, 'mail.message body incorrect')
- def test_30_message_read(self):
- """ Tests for message_read and expandables. """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
- pigs_domain = [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]
-
- # Data: create a discussion in Pigs (3 threads, with respectively 0, 4 and 4 answers)
- msg_id0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
- msg_id1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
- msg_id2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
- msg_id3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=msg_id1)
- msg_id4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=msg_id2)
- msg_id5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=msg_id1)
- msg_id6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=msg_id2)
- msg_id7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
- msg_id8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
- msg_id9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
- msg_id10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
- msg_ids = [msg_id10, msg_id9, msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0]
- ordered_msg_ids = [msg_id2, msg_id4, msg_id6, msg_id8, msg_id10, msg_id1, msg_id3, msg_id5, msg_id7, msg_id9, msg_id0]
-
- # Test: read some specific ids
- read_msg_list = self.mail_message.message_read(cr, uid, ids=msg_ids[2:4], domain=[('body', 'like', 'dummy')])
- read_msg_ids = [msg.get('id') for msg in read_msg_list]
- self.assertEqual(msg_ids[2:4], read_msg_ids, 'message_read with direct ids should read only the requested ids')
-
- # Test: read messages of Pigs through a domain, being thread or not threaded
- read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=200)
- read_msg_ids = [msg.get('id') for msg in read_msg_list]
- self.assertEqual(msg_ids, read_msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
- read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=200, thread_level=1)
- read_msg_ids = [msg.get('id') for msg in read_msg_list]
- self.assertEqual(ordered_msg_ids, read_msg_ids,
- 'message_read threaded with domain on Pigs should equal all messages of Pigs, and sort them with newer thread first, last message last in thread')
-
- # ----------------------------------------
- # CASE1: message_read with domain, threaded
- # We simulate an entire flow, using the expandables to test them
- # ----------------------------------------
-
- # Do: read last message, threaded
- read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=1, thread_level=1)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # TDE TODO: test expandables order
- type_list = map(lambda item: item.get('type'), read_msg_list)
- # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
- self.assertEqual(len(read_msg_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
- self.assertEqual(set([msg_id2, msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
- self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
- # Data: get expandables
- new_threads_exp, new_msg_exp = None, None
- for msg in read_msg_list:
- if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
- new_threads_exp = msg
- elif msg.get('type') == 'expandable':
- new_msg_exp = msg
-
- # Do: fetch new messages in first thread, domain from expandable
- self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
- domain = new_msg_exp.get('domain', [])
- # Test: expandable, conditions in domain
- self.assertIn(('id', 'child_of', msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
- self.assertIn(('id', '>=', msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
- self.assertIn(('id', '<=', msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
- self.assertEqual(new_msg_exp.get('parent_id'), msg_id2, 'new messages expandable should have parent_id set to the thread header')
- # Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS), 2 messages
- read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=2, thread_level=0, parent_id=msg_id2)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- new_msg_exp = [msg for msg in read_msg_list if msg.get('type') == 'expandable'][0]
- # Test: structure content, 2 messages and 1 thread expandable
- self.assertEqual(len(read_msg_list), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
- self.assertEqual(set([msg_id6, msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
- # Do: read the last message
- read_msg_list = self.mail_message.message_read(cr, uid, domain=new_msg_exp.get('domain'), limit=2, thread_level=0, parent_id=msg_id2)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: structure content, 1 message
- self.assertEqual(len(read_msg_list), 1, 'message_read in Pigs thread should return 1 message')
- self.assertEqual(set([msg_id4]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
-
- # Do: fetch a new thread, domain from expandable
- self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
- domain = new_threads_exp.get('domain', [])
- # Test: expandable, conditions in domain
- for condition in pigs_domain:
- self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
- self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an parent_id')
- # Do: message_read with domain, thread_level=1 (should be imposed by JS)
- read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
- self.assertEqual(len(read_msg_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
- self.assertEqual(set([msg_id1, msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
- self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
- # Data: get expandables
- new_threads_exp, new_msg_exp = None, None
- for msg in read_msg_list:
- if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
- new_threads_exp = msg
- elif msg.get('type') == 'expandable':
- new_msg_exp = msg
-
- # Do: fetch new messages in second thread, domain from expandable
- self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
- domain = new_msg_exp.get('domain', [])
- # Test: expandable, conditions in domain
- self.assertIn(('id', 'child_of', msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
- self.assertIn(('id', '>=', msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
- self.assertIn(('id', '<=', msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
- self.assertEqual(new_msg_exp.get('parent_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
- # Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
- read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id1)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: other message in thread have been fetch
- self.assertEqual(set([msg_id3, msg_id5, msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
-
- # Test: fetch a new thread, domain from expandable
- self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
- domain = new_threads_exp.get('domain', [])
- # Test: expandable, conditions in domain
- for condition in pigs_domain:
- self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
- # Do: message_read with domain, thread_level=1 (should be imposed by JS)
- read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
- self.assertEqual(len(read_msg_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
- self.assertEqual([msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
-
- # ----------------------------------------
- # CASE2: message_read with domain, flat
- # ----------------------------------------
-
- # Do: read 2 lasts message, flat
- read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=2, thread_level=0)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
- self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
- self.assertEqual(set([msg_id9, msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
- self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
- self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
- # Data: get expandables
- new_threads_exp, new_msg_exp = None, None
- for msg in read_msg_list:
- if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
- new_threads_exp = msg
-
- # Do: fetch new messages, domain from expandable
- self.assertIsNotNone(new_threads_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
- domain = new_threads_exp.get('domain', [])
- # Test: expandable, conditions in domain
- for condition in pigs_domain:
- self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
- # Do: message_read with domain, thread_level=0 (should be imposed by JS)
- read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=20, thread_level=0)
- read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
- # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
- self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
- self.assertEqual([msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0], read_msg_ids,
- 'message_read, More on flat, should return all remaning messages')
-
- def test_40_needaction(self):
+ def test_30_needaction(self):
""" Tests for mail.message needaction. """
- cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
- user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
+ cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
group_pigs_demo = self.mail_group.browse(cr, self.user_raoul_id, self.group_pigs_id)
na_admin_base = self.mail_message._needaction_count(cr, uid, domain=[])
na_demo_base = self.mail_message._needaction_count(cr, user_raoul.id, domain=[])
@@ -767,86 +582,3 @@ class test_mail(test_mail_mockup.TestMailMockups):
na_demo_group = self.mail_message._needaction_count(cr, user_raoul.id, domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)])
self.assertEqual(na_demo, na_demo_base + 0, 'Demo should have 0 new needaction')
self.assertEqual(na_demo_group, 0, 'Demo should have 0 needaction related to Pigs')
-
- def test_50_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')
- # TDE note: python test + debug because of the random error we see with the next assert
- if len(msg1.child_ids) != 2:
- msg_ids = self.mail_message.search(cr, uid, [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)], limit=10)
- for new_msg in self.mail_message.browse(cr, uid, msg_ids):
- print new_msg.subject, '(id', new_msg.id, ')', 'parent_id:', new_msg.parent_id
- print '\tchild_ids', [child.id for child in new_msg.child_ids]
- self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now')
-
- def test_60_message_vote(self):
- """ Test designed for the vote/unvote feature. """
- cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
- # Data: post a message on Pigs
- msg_id = group_pigs.message_post(body='My Body', subject='1')
- msg = self.mail_message.browse(cr, uid, msg_id)
-
- # Do: Admin vote for msg
- self.mail_message.vote_toggle(cr, uid, [msg.id])
- msg.refresh()
- # Test: msg has Admin as voter
- self.assertEqual(set(msg.vote_user_ids), set([user_admin]), 'mail_message vote: after voting, Admin should be in the voter')
- # Do: Bert vote for msg
- self.mail_message.vote_toggle(cr, user_raoul.id, [msg.id])
- msg.refresh()
- # Test: msg has Admin and Bert as voters
- self.assertEqual(set(msg.vote_user_ids), set([user_admin, user_raoul]), 'mail_message vote: after voting, Admin and Bert should be in the voters')
- # Do: Admin unvote for msg
- self.mail_message.vote_toggle(cr, uid, [msg.id])
- msg.refresh()
- # Test: msg has Bert as voter
- self.assertEqual(set(msg.vote_user_ids), set([user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
-
- def test_70_message_star(self):
- """ Tests for favorites. """
- cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
- # Data: post a message on Pigs
- msg_id = group_pigs.message_post(body='My Body', subject='1')
- msg = self.mail_message.browse(cr, uid, msg_id)
-
- # Do: Admin stars msg
- self.mail_message.set_message_starred(cr, uid, [msg.id], True)
- msg.refresh()
- # Test: msg starred by Admin
- self.assertTrue(msg.starred, 'mail_message starred failed')
- # Do: Bert stars msg
- self.mail_message.set_message_starred(cr, user_raoul.id, [msg.id], True)
- msg.refresh()
- # Test: msg starred by Admin and Raoul
- # self.assertTrue(msg.starred, set([user_admin, user_raoul]), 'mail_message favorite: after starring, Admin and Raoul should be in favorite_user_ids')
- # Do: Admin unvote for msg
- self.mail_message.set_message_starred(cr, uid, [msg.id], False)
- msg.refresh()
- # Test: msg starred by Raoul
- self.assertFalse(msg.starred, 'mail_message starred failed')
- # self.assertEqual(set(msg.favorite_user_ids), set([user_raoul]), 'mail_message favorite: after unstarring, Raoul should be in favorite_user_ids')
diff --git a/addons/mail/tests/test_mail_access_rights.py b/addons/mail/tests/test_mail_message.py
index 183615a65f3..17508e0c522 100644
--- a/addons/mail/tests/test_mail_access_rights.py
+++ b/addons/mail/tests/test_mail_message.py
@@ -19,41 +19,53 @@
#
##############################################################################
-from openerp.addons.mail.tests import test_mail_mockup
+from openerp.addons.mail.tests.test_mail_base import TestMailBase
from openerp.osv.orm import except_orm
from openerp.tools import mute_logger
-class test_mail_access_rights(test_mail_mockup.TestMailMockups):
+class test_mail_access_rights(TestMailBase):
def setUp(self):
super(test_mail_access_rights, self).setUp()
cr, uid = self.cr, self.uid
- self.mail_group = self.registry('mail.group')
- self.mail_message = self.registry('mail.message')
- self.mail_notification = self.registry('mail.notification')
- self.res_users = self.registry('res.users')
- self.res_groups = self.registry('res.groups')
- self.res_partner = self.registry('res.partner')
-
- # create a 'pigs' group that will be used through the various tests
- self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
- {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
-
- # Find Employee group
- group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
- self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
-
- # Create Bert (without groups) and Raoul( employee)
- self.user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert Tartopoils', 'login': 'bert', 'groups_id': [(6, 0, [])]})
- self.user_raoul_id = self.res_users.create(cr, uid, {'name': 'Raoul Grosbedon', 'login': 'raoul', 'groups_id': [(6, 0, [self.group_employee_id])]})
- self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id)
- self.partner_bert_id = self.user_bert.partner_id.id
- self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
- self.partner_raoul_id = self.user_raoul.partner_id.id
-
- @mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm')
- def test_00_mail_message_search_access_rights(self):
+
+ # Test mail.group: public to provide access to everyone
+ self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
+ # Test mail.group: private to restrict access
+ self.group_priv_id = self.mail_group.create(cr, uid, {'name': 'Private', 'public': 'private'})
+
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ def test_00_mail_group_access_rights(self):
+ """ Test mail_group access rights """
+ cr, uid, user_bert_id, user_raoul_id = self.cr, self.uid, self.user_bert_id, self.user_raoul_id
+
+ # Do: Bert reads Jobs -> ok, public
+ self.mail_group.read(cr, user_bert_id, [self.group_jobs_id])
+ # Do: Bert read Pigs -> ko, restricted to employees
+ self.assertRaises(except_orm, self.mail_group.read,
+ cr, user_bert_id, [self.group_pigs_id])
+ # Do: Raoul read Pigs -> ok, belong to employees
+ self.mail_group.read(cr, user_raoul_id, [self.group_pigs_id])
+
+ # Do: Bert creates a group -> ko, no access rights
+ self.assertRaises(except_orm, self.mail_group.create,
+ cr, user_bert_id, {'name': 'Test'})
+ # Do: Raoul creates a restricted group -> ok
+ new_group_id = self.mail_group.create(cr, user_raoul_id, {'name': 'Test'})
+ # Do: Bert added in followers, read -> ok, in followers
+ self.mail_group.message_subscribe_users(cr, uid, [new_group_id], [user_bert_id])
+ self.mail_group.read(cr, user_bert_id, [new_group_id])
+
+ # Do: Raoul reads Priv -> ko, private
+ self.assertRaises(except_orm, self.mail_group.read,
+ cr, user_raoul_id, [self.group_priv_id])
+ # Do: Raoul added in follower, read -> ok, in followers
+ self.mail_group.message_subscribe_users(cr, uid, [self.group_priv_id], [user_raoul_id])
+ self.mail_group.read(cr, user_raoul_id, [self.group_priv_id])
+
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ def test_10_mail_message_search_access_rights(self):
""" Test mail_message search override about access rights. """
cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
@@ -86,19 +98,18 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups):
msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')])
self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
- #@mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm')
- def test_05_mail_message_read_access_rights(self):
- """ Test basic mail_message read access rights. """
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ def test_15_mail_message_check_access_rule(self):
+ """ Test mail_message check_access_rule. """
cr, uid = self.cr, self.uid
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
# Prepare groups: Pigs (employee), Jobs (public)
self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
- self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
# ----------------------------------------
- # CASE1: Bert, basic mail.message read access
+ # CASE1: read
# ----------------------------------------
# Do: create a new mail.message
@@ -134,10 +145,126 @@ class test_mail_access_rights(test_mail_mockup.TestMailMockups):
self.assertRaises(except_orm, self.mail_message.read,
cr, user_bert_id, message_id)
+ # ----------------------------------------
+ # CASE2: create
+ # ----------------------------------------
+
+ # Do: Bert creates a message on Pigs -> crash, no write access on related document
+ self.assertRaises(except_orm, self.mail_message.create,
+ cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_pigs_id, 'body': 'Test'})
+ # Do: Bert create a message on Jobs -> ko, no write access to related document
+ self.assertRaises(except_orm, self.mail_message.create,
+ cr, user_bert_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
+ # Do: Raoul creates a message on Jobs -> ok, write access to the related document
+ self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_jobs_id, 'body': 'Test'})
+ # Do: Bert create a private message -> ok
+ self.mail_message.create(cr, user_bert_id, {'body': 'Test'})
+
+ def test_20_message_set_star(self):
+ """ Tests for starring messages and its related access rights """
+ cr, uid = self.cr, self.uid
+ # Data: post a message on Pigs
+ msg_id = self.group_pigs.message_post(body='My Body', subject='1')
+ msg = self.mail_message.browse(cr, uid, msg_id)
+ msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
+
+ # Do: Admin stars msg
+ self.mail_message.set_message_starred(cr, uid, [msg.id], True)
+ msg.refresh()
+ # Test: notification exists
+ notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_admin_id), ('message_id', '=', msg.id)])
+ self.assertEqual(len(notif_ids), 1, 'mail_message set_message_starred: more than one notification created')
+ # Test: notification starred
+ notif = self.mail_notification.browse(cr, uid, notif_ids[0])
+ self.assertTrue(notif.starred, 'mail_notification starred failed')
+ self.assertTrue(msg.starred, 'mail_message starred failed')
+
+ # Do: Raoul stars msg
+ self.mail_message.set_message_starred(cr, self.user_raoul_id, [msg.id], True)
+ msg_raoul.refresh()
+ # Test: notification exists
+ notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_raoul_id), ('message_id', '=', msg.id)])
+ self.assertEqual(len(notif_ids), 1, 'mail_message set_message_starred: more than one notification created')
+ # Test: notification starred
+ notif = self.mail_notification.browse(cr, uid, notif_ids[0])
+ self.assertTrue(notif.starred, 'mail_notification starred failed')
+ self.assertTrue(msg_raoul.starred, 'mail_message starred failed')
+
+ # Do: Admin unstars msg
+ self.mail_message.set_message_starred(cr, uid, [msg.id], False)
+ msg.refresh()
+ msg_raoul.refresh()
+ # Test: msg unstarred for Admin, starred for Raoul
+ self.assertFalse(msg.starred, 'mail_message starred failed')
+ self.assertTrue(msg_raoul.starred, 'mail_message starred failed')
+
+ def test_30_message_set_read(self):
+ """ Tests for reading messages and its related access rights """
+ cr, uid = self.cr, self.uid
+ # Data: post a message on Pigs
+ msg_id = self.group_pigs.message_post(body='My Body', subject='1')
+ msg = self.mail_message.browse(cr, uid, msg_id)
+ msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
+
+ # Do: Admin reads msg
+ self.mail_message.set_message_read(cr, uid, [msg.id], True)
+ msg.refresh()
+ # Test: notification exists
+ notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_admin_id), ('message_id', '=', msg.id)])
+ self.assertEqual(len(notif_ids), 1, 'mail_message set_message_read: more than one notification created')
+ # Test: notification read
+ notif = self.mail_notification.browse(cr, uid, notif_ids[0])
+ self.assertTrue(notif.read, 'mail_notification read failed')
+ self.assertFalse(msg.to_read, 'mail_message read failed')
+
+ # Do: Raoul reads msg
+ self.mail_message.set_message_read(cr, self.user_raoul_id, [msg.id], True)
+ msg_raoul.refresh()
+ # Test: notification exists
+ notif_ids = self.mail_notification.search(cr, uid, [('partner_id', '=', self.partner_raoul_id), ('message_id', '=', msg.id)])
+ self.assertEqual(len(notif_ids), 1, 'mail_message set_message_read: more than one notification created')
+ # Test: notification read
+ notif = self.mail_notification.browse(cr, uid, notif_ids[0])
+ self.assertTrue(notif.read, 'mail_notification starred failed')
+ self.assertFalse(msg_raoul.to_read, 'mail_message starred failed')
+
+ # Do: Admin unreads msg
+ self.mail_message.set_message_read(cr, uid, [msg.id], False)
+ msg.refresh()
+ msg_raoul.refresh()
+ # Test: msg unread for Admin, read for Raoul
+ self.assertTrue(msg.to_read, 'mail_message read failed')
+ self.assertFalse(msg_raoul.to_read, 'mail_message read failed')
+
+ def test_40_message_vote(self):
+ """ Test designed for the vote/unvote feature. """
+ cr, uid = self.cr, self.uid
+ # Data: post a message on Pigs
+ msg_id = self.group_pigs.message_post(body='My Body', subject='1')
+ msg = self.mail_message.browse(cr, uid, msg_id)
+ msg_raoul = self.mail_message.browse(cr, self.user_raoul_id, msg_id)
+
+ # Do: Admin vote for msg
+ self.mail_message.vote_toggle(cr, uid, [msg.id])
+ msg.refresh()
+ # Test: msg has Admin as voter
+ self.assertEqual(set(msg.vote_user_ids), set([self.user_admin]), 'mail_message vote: after voting, Admin should be in the voter')
+ # Do: Bert vote for msg
+ self.mail_message.vote_toggle(cr, self.user_raoul_id, [msg.id])
+ msg_raoul.refresh()
+ # Test: msg has Admin and Bert as voters
+ self.assertEqual(set(msg_raoul.vote_user_ids), set([self.user_admin, self.user_raoul]), 'mail_message vote: after voting, Admin and Bert should be in the voters')
+ # Do: Admin unvote for msg
+ self.mail_message.vote_toggle(cr, uid, [msg.id])
+ msg.refresh()
+ msg_raoul.refresh()
+ # Test: msg has Bert as voter
+ self.assertEqual(set(msg.vote_user_ids), set([self.user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
+ self.assertEqual(set(msg_raoul.vote_user_ids), set([self.user_raoul]), 'mail_message vote: after unvoting, Bert should be in the voter')
- @mute_logger('openerp.addons.base.ir.ir_model','openerp.osv.orm')
- def test_10_mail_flow_access_rights(self):
- """ Test a Chatter-looks alike flow. """
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.osv.orm')
+ def test_50_mail_flow_access_rights(self):
+ """ Test a Chatter-looks alike flow to test access rights """
cr, uid = self.cr, self.uid
mail_compose = self.registry('mail.compose.message')
partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
diff --git a/addons/mail/tests/test_mail_mockup.py b/addons/mail/tests/test_mail_mockup.py
deleted file mode 100644
index cba04a0c6b3..00000000000
--- a/addons/mail/tests/test_mail_mockup.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- 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.tests import common
-
-
-class TestMailMockups(common.TransactionCase):
-
- def _mock_smtp_gateway(self, *args, **kwargs):
- return True
-
- def _init_mock_build_email(self):
- self._build_email_args_list = []
- self._build_email_kwargs_list = []
-
- def _mock_build_email(self, *args, **kwargs):
- """ Mock build_email to be able to test its values. Store them into
- some internal variable for latter processing. """
- self._build_email_args_list.append(args)
- self._build_email_kwargs_list.append(kwargs)
- return self._build_email(*args, **kwargs)
-
- def setUp(self):
- super(TestMailMockups, self).setUp()
- # Install mock SMTP gateway
- self._init_mock_build_email()
- self._build_email = self.registry('ir.mail_server').build_email
- self.registry('ir.mail_server').build_email = self._mock_build_email
- self._send_email = self.registry('ir.mail_server').send_email
- self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
-
- def tearDown(self):
- # Remove mocks
- self.registry('ir.mail_server').build_email = self._build_email
- self.registry('ir.mail_server').send_email = self._send_email
- super(TestMailMockups, self).tearDown()
diff --git a/addons/mail/tests/test_message_read.py b/addons/mail/tests/test_message_read.py
new file mode 100644
index 00000000000..ebb39c92a02
--- /dev/null
+++ b/addons/mail/tests/test_message_read.py
@@ -0,0 +1,184 @@
+# -*- 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
+
+
+class test_mail_access_rights(TestMailBase):
+
+ def test_00_message_read(self):
+ """ Tests for message_read and expandables. """
+ cr, uid, user_admin, group_pigs = self.cr, self.uid, self.user_admin, self.group_pigs
+ pigs_domain = [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]
+
+ # Data: create a discussion in Pigs (3 threads, with respectively 0, 4 and 4 answers)
+ msg_id0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
+ msg_id1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
+ msg_id2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
+ msg_id3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=msg_id1)
+ msg_id4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=msg_id2)
+ msg_id5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=msg_id1)
+ msg_id6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=msg_id2)
+ msg_id7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
+ msg_id8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
+ msg_id9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
+ msg_id10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
+ msg_ids = [msg_id10, msg_id9, msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0]
+ ordered_msg_ids = [msg_id2, msg_id4, msg_id6, msg_id8, msg_id10, msg_id1, msg_id3, msg_id5, msg_id7, msg_id9, msg_id0]
+
+ # Test: read some specific ids
+ read_msg_list = self.mail_message.message_read(cr, uid, ids=msg_ids[2:4], domain=[('body', 'like', 'dummy')])
+ read_msg_ids = [msg.get('id') for msg in read_msg_list]
+ self.assertEqual(msg_ids[2:4], read_msg_ids, 'message_read with direct ids should read only the requested ids')
+
+ # Test: read messages of Pigs through a domain, being thread or not threaded
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=200)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list]
+ self.assertEqual(msg_ids, read_msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=200, thread_level=1)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list]
+ self.assertEqual(ordered_msg_ids, read_msg_ids,
+ 'message_read threaded with domain on Pigs should equal all messages of Pigs, and sort them with newer thread first, last message last in thread')
+
+ # ----------------------------------------
+ # CASE1: message_read with domain, threaded
+ # We simulate an entire flow, using the expandables to test them
+ # ----------------------------------------
+
+ # Do: read last message, threaded
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=1, thread_level=1)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # TDE TODO: test expandables order
+ type_list = map(lambda item: item.get('type'), read_msg_list)
+ # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
+ self.assertEqual(len(read_msg_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
+ self.assertEqual(set([msg_id2, msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
+ self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
+ # Data: get expandables
+ new_threads_exp, new_msg_exp = None, None
+ for msg in read_msg_list:
+ if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
+ new_threads_exp = msg
+ elif msg.get('type') == 'expandable':
+ new_msg_exp = msg
+
+ # Do: fetch new messages in first thread, domain from expandable
+ self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
+ domain = new_msg_exp.get('domain', [])
+ # Test: expandable, conditions in domain
+ self.assertIn(('id', 'child_of', msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
+ self.assertIn(('id', '>=', msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
+ self.assertIn(('id', '<=', msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
+ self.assertEqual(new_msg_exp.get('parent_id'), msg_id2, 'new messages expandable should have parent_id set to the thread header')
+ # Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS), 2 messages
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=2, thread_level=0, parent_id=msg_id2)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ new_msg_exp = [msg for msg in read_msg_list if msg.get('type') == 'expandable'][0]
+ # Test: structure content, 2 messages and 1 thread expandable
+ self.assertEqual(len(read_msg_list), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
+ self.assertEqual(set([msg_id6, msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
+ # Do: read the last message
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=new_msg_exp.get('domain'), limit=2, thread_level=0, parent_id=msg_id2)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: structure content, 1 message
+ self.assertEqual(len(read_msg_list), 1, 'message_read in Pigs thread should return 1 message')
+ self.assertEqual(set([msg_id4]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
+
+ # Do: fetch a new thread, domain from expandable
+ self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
+ domain = new_threads_exp.get('domain', [])
+ # Test: expandable, conditions in domain
+ for condition in pigs_domain:
+ self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
+ self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an parent_id')
+ # Do: message_read with domain, thread_level=1 (should be imposed by JS)
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
+ self.assertEqual(len(read_msg_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
+ self.assertEqual(set([msg_id1, msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
+ self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
+ # Data: get expandables
+ new_threads_exp, new_msg_exp = None, None
+ for msg in read_msg_list:
+ if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
+ new_threads_exp = msg
+ elif msg.get('type') == 'expandable':
+ new_msg_exp = msg
+
+ # Do: fetch new messages in second thread, domain from expandable
+ self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
+ domain = new_msg_exp.get('domain', [])
+ # Test: expandable, conditions in domain
+ self.assertIn(('id', 'child_of', msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
+ self.assertIn(('id', '>=', msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
+ self.assertIn(('id', '<=', msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
+ self.assertEqual(new_msg_exp.get('parent_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
+ # Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id1)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: other message in thread have been fetch
+ self.assertEqual(set([msg_id3, msg_id5, msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
+
+ # Test: fetch a new thread, domain from expandable
+ self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
+ domain = new_threads_exp.get('domain', [])
+ # Test: expandable, conditions in domain
+ for condition in pigs_domain:
+ self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
+ # Do: message_read with domain, thread_level=1 (should be imposed by JS)
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
+ self.assertEqual(len(read_msg_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
+ self.assertEqual([msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
+
+ # ----------------------------------------
+ # CASE2: message_read with domain, flat
+ # ----------------------------------------
+
+ # Do: read 2 lasts message, flat
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=2, thread_level=0)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
+ self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
+ self.assertEqual(set([msg_id9, msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
+ self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
+ self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
+ # Data: get expandables
+ new_threads_exp, new_msg_exp = None, None
+ for msg in read_msg_list:
+ if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
+ new_threads_exp = msg
+
+ # Do: fetch new messages, domain from expandable
+ self.assertIsNotNone(new_threads_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
+ domain = new_threads_exp.get('domain', [])
+ # Test: expandable, conditions in domain
+ for condition in pigs_domain:
+ self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
+ # Do: message_read with domain, thread_level=0 (should be imposed by JS)
+ read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=20, thread_level=0)
+ read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
+ # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
+ self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
+ self.assertEqual([msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0], read_msg_ids,
+ 'message_read, More on flat, should return all remaning messages')
diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py
index 0a2772c9cfe..99ece6cc36d 100644
--- a/addons/portal/tests/test_portal.py
+++ b/addons/portal/tests/test_portal.py
@@ -19,27 +19,16 @@
#
##############################################################################
-from openerp.addons.mail.tests import test_mail_mockup
+from openerp.addons.mail.tests.test_mail_base import TestMailBase
from openerp.osv.orm import except_orm
from openerp.tools.misc import mute_logger
-class test_portal(test_mail_mockup.TestMailMockups):
+class test_portal(TestMailBase):
def setUp(self):
super(test_portal, self).setUp()
cr, uid = self.cr, self.uid
- self.ir_model = self.registry('ir.model')
- self.mail_group = self.registry('mail.group')
- self.mail_mail = self.registry('mail.mail')
- self.mail_message = self.registry('mail.message')
- self.mail_invite = self.registry('mail.wizard.invite')
- self.res_users = self.registry('res.users')
- self.res_partner = self.registry('res.partner')
-
- # create a 'pigs' group that will be used through the various tests
- self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
- {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
# Find Portal group
group_portal = self.registry('ir.model.data').get_object(cr, uid, 'portal', 'group_portal')
@@ -82,34 +71,28 @@ class test_portal(test_mail_mockup.TestMailMockups):
def test_50_mail_invite(self):
cr, uid = self.cr, self.uid
- user_admin = self.res_users.browse(cr, uid, uid)
+ mail_invite = self.registry('mail.wizard.invite')
base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='')
- # 0 - Admin
- partner_admin_id = user_admin.partner_id.id
- # 1 - Bert Tartopoils, with email, should receive emails for comments and emails
- partner_bert_id = self.res_partner.create(cr, uid, {'name': 'Bert Tartopoils', 'email': 'b@b'})
-
- # ----------------------------------------
- # CASE: invite Bert to follow Pigs
- # ----------------------------------------
+ # Carine Poilvache, with email, should receive emails for comments and emails
+ partner_carine_id = self.res_partner.create(cr, uid, {'name': 'Carine Poilvache', 'email': 'c@c'})
# Do: create a mail_wizard_invite, validate it
self._init_mock_build_email()
context = {'default_res_model': 'mail.group', 'default_res_id': self.group_pigs_id}
- mail_invite_id = self.mail_invite.create(cr, uid, {'partner_ids': [(4, partner_bert_id)]}, context)
- self.mail_invite.add_followers(cr, uid, [mail_invite_id])
+ mail_invite_id = mail_invite.create(cr, uid, {'partner_ids': [(4, partner_carine_id)]}, context)
+ mail_invite.add_followers(cr, uid, [mail_invite_id])
# Test: Pigs followers should contain Admin and Bert
group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
follower_ids = [follower.id for follower in group_pigs.message_follower_ids]
- self.assertEqual(set(follower_ids), set([partner_admin_id, partner_bert_id]), 'Pigs followers after invite is incorrect')
+ self.assertEqual(set(follower_ids), set([self.partner_admin_id, partner_carine_id]), 'Pigs followers after invite is incorrect')
# Test: partner must have been prepared for signup
- partner_bert = self.res_partner.browse(cr, uid, partner_bert_id)
- self.assertTrue(partner_bert.signup_valid, 'partner has not been prepared for signup')
- self.assertTrue(base_url in partner_bert.signup_url, 'signup url is incorrect')
- self.assertTrue(cr.dbname in partner_bert.signup_url, 'signup url is incorrect')
- self.assertTrue(partner_bert.signup_token in partner_bert.signup_url, 'signup url is incorrect')
+ partner_carine = self.res_partner.browse(cr, uid, partner_carine_id)
+ self.assertTrue(partner_carine.signup_valid, 'partner has not been prepared for signup')
+ self.assertTrue(base_url in partner_carine.signup_url, 'signup url is incorrect')
+ self.assertTrue(cr.dbname in partner_carine.signup_url, 'signup url is incorrect')
+ self.assertTrue(partner_carine.signup_token in partner_carine.signup_url, 'signup url is incorrect')
# Test: (pretend to) send email and check subject, body
self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
@@ -118,5 +101,5 @@ class test_portal(test_mail_mockup.TestMailMockups):
'subject of invitation email is incorrect')
self.assertTrue('You have been invited to follow Pigs' in sent_email.get('body'),
'body of invitation email is incorrect')
- self.assertTrue(partner_bert.signup_url in sent_email.get('body'),
+ self.assertTrue(partner_carine.signup_url in sent_email.get('body'),
'body of invitation email does not contain signup url')