diff --git a/addons/mail/tests/test_discuss.py b/addons/mail/tests/test_discuss.py index 6e4baae8e27..ea155bf3232 100644 --- a/addons/mail/tests/test_discuss.py +++ b/addons/mail/tests/test_discuss.py @@ -1,45 +1,125 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.mail.tests.common import TestMail -from odoo.tools import mute_logger +from odoo.addons.mail.tests.common import BaseFunctionalTest, TestRecipients, MockEmails -class TestDiscuss(TestMail): - # TDE TODO: tests on the redirection controller +class TestChatterTweaks(BaseFunctionalTest, TestRecipients): - def test_alias_setup(self): - alias = self.env['mail.alias'].with_context(alias_model_name='mail.test').create({'alias_name': 'b4r+_#_R3wl$$'}) - self.assertEqual(alias.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') + def test_post_no_subscribe_author(self): + original = self.test_record.message_follower_ids + self.test_record.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( + body='Test Body', message_type='comment', subtype='mt_comment') + self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) + self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) - def test_10_cache_invalidation(self): - """ Test that creating a mail-thread record does not invalidate the whole cache. """ - # make a new record in cache - record = self.env['res.partner'].new({'name': 'Brave New Partner'}) - self.assertTrue(record.name) + def test_post_no_subscribe_recipients(self): + original = self.test_record.message_follower_ids + self.test_record.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( + body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) + self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) + self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) - # creating a mail-thread record should not invalidate the whole cache - self.env['res.partner'].create({'name': 'Actual Partner'}) - self.assertTrue(record.name) + def test_post_subscribe_recipients(self): + original = self.test_record.message_follower_ids + self.test_record.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True, 'mail_post_autofollow': True}).message_post( + body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) + self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.partner_1 | self.partner_2) + self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) + + def test_post_subscribe_recipients_partial(self): + original = self.test_record.message_follower_ids + self.test_record.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True, 'mail_post_autofollow': True, 'mail_post_autofollow_partner_ids': [self.partner_2.id]}).message_post( + body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) + self.assertEqual(self.test_record.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.partner_2) + self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) + + def test_chatter_mail_create_nolog(self): + """ Test disable of automatic chatter message at create """ + rec = self.env['mail.test.simple'].sudo(self.user_employee).with_context({'mail_create_nolog': True}).create({'name': 'Test'}) + self.assertEqual(rec.message_ids, self.env['mail.message']) + + rec = self.env['mail.test.simple'].sudo(self.user_employee).with_context({'mail_create_nolog': False}).create({'name': 'Test'}) + self.assertEqual(len(rec.message_ids), 1) + + def test_chatter_mail_notrack(self): + """ Test disable of automatic value tracking at create and write """ + rec = self.env['mail.test.track'].sudo(self.user_employee).with_context({'mail_notrack': False}).create({'name': 'Test', 'user_id': self.user_employee.id}) + self.assertEqual(len(rec.sudo().mapped('message_ids.tracking_value_ids')), 1) + + rec = self.env['mail.test.track'].sudo(self.user_employee).with_context({'mail_notrack': True}).create({'name': 'Test', 'user_id': self.user_employee.id}) + self.assertEqual(rec.sudo().mapped('message_ids.tracking_value_ids'), self.env['mail.tracking.value']) + + rec.write({'user_id': self.user_admin.id}) + self.assertEqual(rec.sudo().mapped('message_ids.tracking_value_ids'), self.env['mail.tracking.value']) + + rec.with_context({'mail_notrack': False}).write({'user_id': self.user_employee.id}) + self.assertEqual(len(rec.sudo().mapped('message_ids.tracking_value_ids')), 1) + + def test_chatter_tracking_disable(self): + """ Test disable of all chatter features at create and write """ + rec = self.env['mail.test.track'].sudo(self.user_employee).with_context({'tracking_disable': True}).create({'name': 'Test', 'user_id': self.user_employee.id}) + self.assertEqual(rec.sudo().message_ids, self.env['mail.message']) + self.assertEqual(rec.sudo().mapped('message_ids.tracking_value_ids'), self.env['mail.tracking.value']) + + rec.write({'user_id': self.user_admin.id}) + self.assertEqual(rec.sudo().mapped('message_ids.tracking_value_ids'), self.env['mail.tracking.value']) + + rec.with_context({'tracking_disable': False}).write({'user_id': self.user_employee.id}) + self.assertEqual(len(rec.sudo().mapped('message_ids.tracking_value_ids')), 1) + + rec = self.env['mail.test.track'].sudo(self.user_employee).with_context({'tracking_disable': False}).create({'name': 'Test', 'user_id': self.user_employee.id}) + self.assertEqual(len(rec.sudo().message_ids), 2) + self.assertEqual(len(rec.sudo().mapped('message_ids.tracking_value_ids')), 1) - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_needaction(self): - # needaction use Inbox notification +class TestNotifications(BaseFunctionalTest, MockEmails): + + def setUp(self): + super(TestNotifications, self).setUp() + self.partner_1 = self.env['res.partner'].with_context(self._quick_create_ctx).create({ + 'name': 'Valid Lelitre', + 'email': 'valid.lelitre@agrolait.com'}) + (self.user_employee | self.user_admin).write({'notification_type': 'inbox'}) - na_emp1_base = self.test_pigs.sudo(self.user_employee).message_needaction_counter - na_emp2_base = self.test_pigs.sudo().message_needaction_counter + def test_needaction(self): + with self.assertNotifications(partner_employee=(1, 'inbox', 'unread'), partner_admin=(0, '', '')): + self.test_record.message_post( + body='Test', message_type='comment', subtype='mail.mt_comment', + partner_ids=[self.user_employee.partner_id.id]) - self.test_pigs.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[self.user_employee.partner_id.id]) + self.test_record.message_subscribe([self.partner_1.id]) + with self.assertNotifications(partner_employee=(1, 'inbox', 'unread'), partner_admin=(0, '', ''), partner_1=(1, 'email', 'read')): + self.test_record.message_post( + body='Test', message_type='comment', subtype='mail.mt_comment', + partner_ids=[self.user_employee.partner_id.id]) - na_emp1_new = self.test_pigs.sudo(self.user_employee).message_needaction_counter - na_emp2_new = self.test_pigs.sudo().message_needaction_counter - self.assertEqual(na_emp1_new, na_emp1_base + 1) - self.assertEqual(na_emp2_new, na_emp2_base) + def test_set_message_done_user(self): + with self.assertNotifications(partner_employee=(0, '', '')): + message = self.test_record.message_post( + body='Test', message_type='comment', subtype='mail.mt_comment', + partner_ids=[self.user_employee.partner_id.id]) + message.sudo(self.user_employee).set_message_done() - def test_message_set_star(self): - msg = self.test_pigs.message_post(body='My Body', subject='1') + def test_set_message_done_portal(self): + user_portal = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'notification_type': 'inbox', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], + }) + self.partner_portal = user_portal.partner_id + + with self.assertNotifications(partner_employee=(1, 'inbox', 'unread'), partner_portal=(1, 'inbox', 'read')): + message = self.test_record.message_post( + body='Test', message_type='comment', subtype='mail.mt_comment', + partner_ids=[self.user_employee.partner_id.id, user_portal.partner_id.id]) + message.sudo(user_portal).set_message_done() + + def test_set_star(self): + msg = self.test_record.message_post(body='My Body', subject='1') msg_emp = self.env['mail.message'].sudo(self.user_employee).browse(msg.id) # Admin set as starred @@ -55,7 +135,19 @@ class TestDiscuss(TestMail): self.assertFalse(msg.starred) self.assertTrue(msg_emp.starred) - def test_60_cache_invalidation(self): - msg_cnt = len(self.test_pigs.message_ids) - self.test_pigs.message_post(body='Hi!', subject='test') - self.assertEqual(len(self.test_pigs.message_ids), msg_cnt + 1) + +class TestChatterMisc(BaseFunctionalTest): + + def test_alias_setup(self): + alias = self.env['mail.alias'].with_context(alias_model_name='mail.test').create({'alias_name': 'b4r+_#_R3wl$$'}) + self.assertEqual(alias.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') + + def test_cache_invalidation(self): + """ Test that creating a mail-thread record does not invalidate the whole cache. """ + # make a new record in cache + record = self.env['res.partner'].new({'name': 'Brave New Partner'}) + self.assertTrue(record.name) + + # creating a mail-thread record should not invalidate the whole cache + self.env['res.partner'].create({'name': 'Actual Partner'}) + self.assertTrue(record.name) diff --git a/addons/mail/tests/test_message_compose.py b/addons/mail/tests/test_message_compose.py index 791ead4ef20..043f458e33f 100644 --- a/addons/mail/tests/test_message_compose.py +++ b/addons/mail/tests/test_message_compose.py @@ -1,60 +1,83 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. + import base64 -from odoo.addons.mail.tests.common import TestMail -from odoo.addons.mail.tests.test_mail_gateway import MAIL_TEMPLATE_PLAINTEXT +from unittest.mock import patch + +from odoo.addons.mail.tests.common import BaseFunctionalTest, MockEmails, TestRecipients +from odoo.addons.mail.tests.data.test_mail_data import MAIL_TEMPLATE_PLAINTEXT +from odoo.addons.mail.tests.models.test_mail_models import MailTestSimple +from odoo.exceptions import AccessError from odoo.tools import mute_logger -class TestMessagePost(TestMail): +class TestMessagePost(BaseFunctionalTest, MockEmails, TestRecipients): - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_post_no_subscribe_author(self): - original = self.test_pigs.message_follower_ids - self.test_pigs.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment') - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) + def setUp(self): + super(TestMessagePost, self).setUp() - # TODO : the author of a message post on mail.test should not be added as follower + # configure mailing + self.alias_domain = 'schlouby.fr' + self.alias_catchall = 'test+catchall' + self.env['ir.config_parameter'].set_param('mail.catchall.domain', self.alias_domain) + self.env['ir.config_parameter'].set_param('mail.catchall.alias', self.alias_catchall) - # @mute_logger('odoo.addons.mail.models.mail_mail') - # def test_post_subscribe_author(self): - # original = self.test_pigs.message_follower_ids - # self.test_pigs.sudo(self.user_employee).message_post( - # body='Test Body', message_type='comment', subtype='mt_comment') - # self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.user_employee.partner_id) - # self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_post_no_subscribe_recipients(self): - original = self.test_pigs.message_follower_ids - self.test_pigs.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), original.mapped('partner_id')) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_post_subscribe_recipients(self): - original = self.test_pigs.message_follower_ids - self.test_pigs.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True, 'mail_post_autofollow': True}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.partner_1 | self.partner_2) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_post_subscribe_recipients_partial(self): - original = self.test_pigs.message_follower_ids - self.test_pigs.sudo(self.user_employee).with_context({'mail_create_nosubscribe': True, 'mail_post_autofollow': True, 'mail_post_autofollow_partner_ids': [self.partner_2.id]}).message_post( - body='Test Body', message_type='comment', subtype='mt_comment', partner_ids=[(4, self.partner_1.id), (4, self.partner_2.id)]) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('partner_id'), original.mapped('partner_id') | self.partner_2) - self.assertEqual(self.test_pigs.message_follower_ids.mapped('channel_id'), original.mapped('channel_id')) + # admin should not receive emails + self.user_admin.write({'notification_type': 'email'}) @mute_logger('odoo.addons.mail.models.mail_mail') def test_post_notifications(self): - _body, _body_alt = '
Test Body
', 'Test Body' - _subject = 'Test Subject' + _body, _body_alt, _subject = 'Test Body
', 'Test Body', 'Test Subject' + + # subscribe second employee to the group to test notifications + self.test_record.message_subscribe_users(user_ids=[self.user_admin.id]) + + msg = self.test_record.sudo(self.user_employee).message_post( + body=_body, subject=_subject, + message_type='comment', subtype='mt_comment', + partner_ids=[self.partner_1.id, self.partner_2.id] + ) + + # message content + self.assertEqual(msg.subject, _subject) + self.assertEqual(msg.body, _body) + self.assertEqual(msg.partner_ids, self.partner_1 | self.partner_2) + self.assertEqual(msg.needaction_partner_ids, self.user_admin.partner_id | self.partner_1 | self.partner_2) + self.assertEqual(msg.channel_ids, self.env['mail.channel']) + + # notifications emails should have been deleted + self.assertFalse(self.env['mail.mail'].search([('mail_message_id', '=', msg.id)]), + 'message_post: mail.mail notifications should have been auto-deleted') + + # notification emails + self.assertEmails( + self.user_employee.partner_id, + [[self.partner_1], [self.partner_2], [self.user_admin.partner_id]], + reply_to=msg.reply_to, subject=_subject, + body_content=_body, body_alt_content=_body_alt, + references=False) + + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_post_notifications_keep_emails(self): + self.test_record.message_subscribe_users(user_ids=[self.user_admin.id]) + + msg = self.test_record.sudo(self.user_employee).with_context(mail_auto_delete=False).message_post( + body='Test', subject='Test', + message_type='comment', subtype='mt_comment', + partner_ids=[self.partner_1.id, self.partner_2.id] + ) + + # notifications emails should not have been deleted: one for customers, one for user + self.assertEqual(len(self.env['mail.mail'].search([('mail_message_id', '=', msg.id)])), 2) + + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_post_notifications_emails_tweak(self): + pass + # we should check _notification_groups behavior, for emails and buttons + + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_post_attachments(self): _attachments = [ ('List1', b'My first attachment'), ('List2', b'My second attachment') @@ -68,113 +91,102 @@ class TestMessagePost(TestMail): 'datas': 'bWlncmF0aW9uIHRlc3Q=', 'res_model': 'mail.compose.message', 'res_id': 0}) - self.user_admin.write({'notification_type': 'email'}) + msg = self.test_record.sudo(self.user_employee).message_post( + body='Test', subject='Test', + message_type='comment', subtype='mt_comment', + attachment_ids=[_attach_1.id, _attach_2.id], + partner_ids=[self.partner_1.id], + attachments=_attachments, + ) - # subscribe second employee to the group to test notifications - self.test_pigs.message_subscribe_users(user_ids=[self.env.user.id]) - - # use aliases - _domain = 'schlouby.fr' - _catchall = 'test_catchall' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', _domain) - self.env['ir.config_parameter'].set_param('mail.catchall.alias', _catchall) - - msg = self.test_pigs.sudo(self.user_employee).message_post( - body=_body, subject=_subject, partner_ids=[self.partner_1.id, self.partner_2.id], - attachment_ids=[_attach_1.id, _attach_2.id], attachments=_attachments, - message_type='comment', subtype='mt_comment') - - # message content - self.assertEqual(msg.subject, _subject) - self.assertEqual(msg.body, _body) - self.assertEqual(msg.partner_ids, self.partner_1 | self.partner_2) - self.assertEqual(msg.needaction_partner_ids, self.env.user.partner_id | self.partner_1 | self.partner_2) - self.assertEqual(msg.channel_ids, self.env['mail.channel']) - - # attachments - self.assertEqual(set(msg.attachment_ids.mapped('res_model')), set(['mail.test']), - 'message_post: all atttachments should be linked to the mail.test model') - self.assertEqual(set(msg.attachment_ids.mapped('res_id')), set([self.test_pigs.id]), - 'message_post: all atttachments should be linked to the pigs group') + # message attachments + self.assertEqual(len(msg.attachment_ids), 4) + self.assertEqual(set(msg.attachment_ids.mapped('res_model')), set([self.test_record._name])) + self.assertEqual(set(msg.attachment_ids.mapped('res_id')), set([self.test_record.id])) self.assertEqual(set([base64.b64decode(x) for x in msg.attachment_ids.mapped('datas')]), set([b'migration test', _attachments[0][1], _attachments[1][1]])) self.assertTrue(set([_attach_1.id, _attach_2.id]).issubset(msg.attachment_ids.ids), 'message_post: mail.message attachments duplicated') - # notifications - self.assertFalse(self.env['mail.mail'].search([('mail_message_id', '=', msg.message_id)]), - 'message_post: mail.mail notifications should have been auto-deleted') - # notification emails: followers + recipients - author (user_employee) - self.assertEqual(set(m['email_from'] for m in self._mails), - set(['%s <%s>' % (self.user_employee.name, self.user_employee.email)]), - 'message_post: notification email wrong email_from: should use sender email') - self.assertEqual(set(m['email_to'][0] for m in self._mails), - set(['%s <%s>' % (self.partner_1.name, self.partner_1.email), - '%s <%s>' % (self.partner_2.name, self.partner_2.email), - '%s <%s>' % (self.env.user.name, self.env.user.email)])) - self.assertFalse(any(len(m['email_to']) != 1 for m in self._mails), - 'message_post: notification email should be sent to one partner at a time') - self.assertEqual(set(m['reply_to'] for m in self._mails), - set(['%s %s <%s@%s>' % (self.env.user.company_id.name, self.test_pigs.name, self.test_pigs.alias_name, _domain)]), - 'message_post: notification email should use group aliases and data for reply to') - self.assertTrue(all(_subject in m['subject'] for m in self._mails)) - self.assertTrue(all(_body in m['body'] for m in self._mails)) - self.assertTrue(all(_body_alt in m['body'] for m in self._mails)) - self.assertFalse(any(m['references'] for m in self._mails)) + # notification email attachments + self.assertEmails(self.user_employee.partner_id, [[self.partner_1]]) + # self.assertEqual(len(self._mails), 1) + self.assertEqual(len(self._mails[0]['attachments']), 4) + self.assertIn(('List1', b'My first attachment', 'application/octet-stream'), self._mails[0]['attachments']) + self.assertIn(('List2', b'My second attachment', 'application/octet-stream'), self._mails[0]['attachments']) + self.assertIn(('Attach1', b'migration test', 'application/octet-stream'), self._mails[0]['attachments']) + self.assertIn(('Attach2', b'migration test', 'application/octet-stream'), self._mails[0]['attachments']) @mute_logger('odoo.addons.mail.models.mail_mail') def test_post_answer(self): - _body = 'Test Body
' - _subject = 'Test Subject' - - # use aliases - _domain = 'schlouby.fr' - _catchall = 'test_catchall' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', _domain) - self.env['ir.config_parameter'].set_param('mail.catchall.alias', _catchall) - - parent_msg = self.test_pigs.sudo(self.user_employee).message_post( - body=_body, subject=_subject, + parent_msg = self.test_record.sudo(self.user_employee).message_post( + body='Test
', subject='Test Subject', message_type='comment', subtype='mt_comment') self.assertEqual(parent_msg.partner_ids, self.env['res.partner']) + self.assertEmails(self.user_employee.partner_id, []) - msg = self.test_pigs.sudo(self.user_employee).message_post( - body=_body, subject=_subject, partner_ids=[self.partner_1.id], - message_type='comment', subtype='mt_comment', parent_id=parent_msg.id) + msg = self.test_record.sudo(self.user_employee).message_post( + body='Test Answer
', + message_type='comment', subtype='mt_comment', + partner_ids=[self.partner_1.id], + parent_id=parent_msg.id) self.assertEqual(msg.parent_id.id, parent_msg.id) self.assertEqual(msg.partner_ids, self.partner_1) - # self.assertEqual(parent_msg.partner_ids, self.partner_1) # TDE FIXME: to check - self.assertTrue(all('openerp-%d-mail.test' % self.test_pigs.id in m['references'] for m in self._mails)) - new_msg = self.test_pigs.sudo(self.user_employee).message_post( - body=_body, subject=_subject, - message_type='comment', subtype='mt_comment', parent_id=msg.id) + self.assertEqual(parent_msg.partner_ids, self.env['res.partner']) + + # check notification emails: references + self.assertEmails(self.user_employee.partner_id, [[self.partner_1]], ref_content='openerp-%d-mail.test.simple' % self.test_record.id) + # self.assertTrue(all('openerp-%d-mail.test.simple' % self.test_record.id in m['references'] for m in self._mails)) + + new_msg = self.test_record.sudo(self.user_employee).message_post( + body='Test Answer Bis
', + message_type='comment', subtype='mt_comment', + parent_id=msg.id) self.assertEqual(new_msg.parent_id.id, parent_msg.id, 'message_post: flatten error') - self.assertFalse(new_msg.partner_ids) - - def test_post_portal(self): - self.test_pigs.message_subscribe((self.partner_1 | self.user_employee.partner_id).ids) - new_msg = self.test_pigs.sudo(self.user_portal).message_post( - body='Test
', subject='Subject', - message_type='comment', subtype='mt_comment') - self.assertEqual(new_msg.sudo().needaction_partner_ids, (self.partner_1 | self.user_employee.partner_id)) - - self.assertEqual( - set(m['email_to'][0] for m in self._mails), - set(['%s <%s>' % (self.partner_1.name, self.partner_1.email), - '%s <%s>' % (self.user_employee.name, self.user_employee.email)])) + self.assertEqual(new_msg.partner_ids, self.env['res.partner']) @mute_logger('odoo.addons.mail.models.mail_mail') + def test_post_portal_ok(self): + portal_user = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], + }) + + with patch.object(MailTestSimple, 'check_access_rights', return_value=True): + self.test_record.message_subscribe((self.partner_1 | self.user_employee.partner_id).ids) + new_msg = self.test_record.sudo(portal_user).message_post( + body='Test
', subject='Subject', + message_type='comment', subtype='mt_comment') + + self.assertEqual(new_msg.sudo().needaction_partner_ids, (self.partner_1 | self.user_employee.partner_id)) + self.assertEmails(portal_user.partner_id, [[self.partner_1], [self.user_employee.partner_id]]) + + def test_post_portal_crash(self): + portal_user = self.env['res.users'].with_context(self._quick_create_user_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], + }) + + with self.assertRaises(AccessError): + self.test_record.sudo(portal_user).message_post( + body='Test
', subject='Subject', + message_type='comment', subtype='mt_comment') + + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.addons.mail.models.mail_thread') def test_post_internal(self): - self.test_pigs.message_subscribe_users([self.user_admin.id]) - msg = self.test_pigs.sudo(self.user_employee).message_post( + self.test_record.message_subscribe([self.user_admin.partner_id.id]) + msg = self.test_record.sudo(self.user_employee).message_post( body='My Body', subject='My Subject', message_type='comment', subtype='mt_note') self.assertEqual(msg.partner_ids, self.env['res.partner']) self.assertEqual(msg.needaction_partner_ids, self.env['res.partner']) - self.assertEqual(self.test_pigs.message_ids, msg) self.format_and_process( MAIL_TEMPLATE_PLAINTEXT, @@ -182,86 +194,78 @@ class TestMessagePost(TestMail): msg_id='<1198923581.41972151344608186800.JavaMail.diff1@agrolait.com>', to='not_my_businesss@example.com', extra='In-Reply-To:\r\n\t%s\n' % msg.message_id) - reply = self.test_pigs.message_ids - msg + reply = self.test_record.message_ids - msg self.assertTrue(reply) self.assertEqual(reply.subtype_id, self.env.ref('mail.mt_note')) self.assertEqual(reply.needaction_partner_ids, self.user_employee.partner_id) + self.assertEqual(reply.parent_id, msg) + + +class TestComposer(BaseFunctionalTest, MockEmails, TestRecipients): + + def setUp(self): + super(TestComposer, self).setUp() + + # configure mailing + self.alias_domain = 'schlouby.fr' + self.alias_catchall = 'test+catchall' + self.env['ir.config_parameter'].set_param('mail.catchall.domain', self.alias_domain) + self.env['ir.config_parameter'].set_param('mail.catchall.alias', self.alias_catchall) + + # admin should not receive emails + self.user_admin.write({'notification_type': 'email'}) @mute_logger('odoo.addons.mail.models.mail_mail') - def test_message_compose(self): + def test_composer_comment(self): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', - 'default_model': 'mail.test', - 'default_res_id': self.test_pigs.id, + 'default_model': self.test_record._name, + 'default_res_id': self.test_record.id, }).sudo(self.user_employee).create({ 'body': 'Test Body
', 'partner_ids': [(4, self.partner_1.id), (4, self.partner_2.id)] }) - self.assertEqual(composer.composition_mode, 'comment') - self.assertEqual(composer.model, 'mail.test') - self.assertEqual(composer.subject, 'Re: %s' % self.test_pigs.name) - self.assertEqual(composer.record_name, self.test_pigs.name) - composer.send_mail() - message = self.test_pigs.message_ids[0] - composer = self.env['mail.compose.message'].with_context({ - 'default_composition_mode': 'comment', - 'default_res_id': self.test_pigs.id, - 'default_parent_id': message.id - }).sudo(self.user_employee).create({}) - - self.assertEqual(composer.model, 'mail.test') - self.assertEqual(composer.res_id, self.test_pigs.id) - self.assertEqual(composer.parent_id, message) - self.assertEqual(composer.subject, 'Re: %s' % self.test_pigs.name) - - # TODO: test attachments ? - - def test_mail_compose_access_rights(self): - test_channel = self.env['mail.channel'].create({ - 'name': 'Pigs', - 'public': 'groups', - 'group_public_id': self.env.ref('base.group_portal').id}) - port_msg = test_channel.message_post(body='Message') - - # Do: Chell comments Pigs, ok because can write on it (public group) - test_channel.sudo(self.user_portal).message_post(body='I love Pigs', message_type='comment', subtype='mail.mt_comment') - # Do: Chell creates a mail.compose.message record on Pigs, because he uses the wizard - compose = self.env['mail.compose.message'].with_context({ - 'default_composition_mode': 'comment', - 'default_model': 'mail.channel', - 'default_res_id': test_channel.id - }).sudo(self.user_portal).create({ - 'subject': 'Subject', - 'body': 'Body text', - 'partner_ids': []}) - compose.send_mail() - - # Do: Chell replies to a Pigs message using the composer - compose = self.env['mail.compose.message'].with_context({ - 'default_composition_mode': 'comment', - 'default_parent_id': port_msg.id - }).sudo(self.user_portal).create({ - 'subject': 'Subject', - 'body': 'Body text'}) - compose.send_mail() + message = self.test_record.message_ids[0] + self.assertEqual(message.body, 'Test Body
') + self.assertEqual(message.author_id, self.user_employee.partner_id) + self.assertEqual(message.subject, 'Re: %s' % self.test_record.name) + self.assertEqual(message.subtype_id, self.env.ref('mail.mt_comment')) + self.assertEqual(message.partner_ids, self.partner_1 | self.partner_2) @mute_logger('odoo.addons.mail.models.mail_mail') - def test_message_compose_mass_mail(self): + def test_composer_comment_parent(self): + parent = self.test_record.message_post(body='Test') + + self.env['mail.compose.message'].with_context({ + 'default_composition_mode': 'comment', + 'default_parent_id': parent.id + }).sudo(self.user_employee).create({ + 'body': 'Mega
', + }).send_mail() + + message = self.test_record.message_ids[0] + self.assertEqual(message.body, 'Mega
') + self.assertEqual(message.parent_id, parent) + + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_composer_mass_mail(self): + test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', - 'default_model': 'mail.test', + 'default_model': self.test_record._name, 'default_res_id': False, - 'active_ids': [self.test_pigs.id, self.test_public.id] + 'active_ids': [self.test_record.id, test_record_2.id] }).sudo(self.user_employee).create({ 'subject': 'Testing ${object.name}', - 'body': '${object.description}
', + 'body': '${object.name}
', 'partner_ids': [(4, self.partner_1.id), (4, self.partner_2.id)] }) composer.with_context({ 'default_res_id': -1, - 'active_ids': [self.test_pigs.id, self.test_public.id] + 'active_ids': [self.test_record.id, test_record_2.id] }).send_mail() # check mail_mail @@ -270,66 +274,82 @@ class TestMessagePost(TestMail): self.assertEqual(mail.recipient_ids, self.partner_1 | self.partner_2, 'compose wizard: mail_mail mass mailing: mail.mail in mass mail incorrect recipients') - # check message on test_pigs - message1 = self.test_pigs.message_ids[0] - self.assertEqual(message1.subject, 'Testing %s' % self.test_pigs.name) - self.assertEqual(message1.body, '%s
' % self.test_pigs.description) + # check message on test_record + message1 = self.test_record.message_ids[0] + self.assertEqual(message1.subject, 'Testing %s' % self.test_record.name) + self.assertEqual(message1.body, '%s
' % self.test_record.name) - # check message on test_public - message1 = self.test_public.message_ids[0] - self.assertEqual(message1.subject, 'Testing %s' % self.test_public.name) - self.assertEqual(message1.body, '%s
' % self.test_public.description) - - # # Test: Pigs and Bird did receive their message - # # check logged messages - # message1 = test_pigs.message_ids[0] - # message2 = group_bird.message_ids[0] - # # Test: Pigs and Bird did receive their message - # messages = self.MailMessage.search([], limit=2) - # mail = self.MailMail.search([('mail_message_id', '=', message2.id)], limit=1) - # self.assertTrue(mail, 'message_send: mail.mail message should have in processing mail queue') - # #check mass mail state... - # mails = self.MailMail.search([('state', '=', 'exception')]) - # self.assertNotIn(mail.id, mails.ids, 'compose wizard: Mail sending Failed!!') - # self.assertIn(message1.id, messages.ids, 'compose wizard: Pigs did not receive its mass mailing message') - # self.assertIn(message2.id, messages.ids, 'compose wizard: Bird did not receive its mass mailing message') - - # check followers ? - # Test: mail.test followers: author not added as follower in mass mail mode - # self.assertEqual(set(test_pigs.message_follower_ids.ids), set([self.partner_admin_id, p_b.id, p_c.id, p_d.id]), - # 'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account') - # self.assertEqual(set(group_bird.message_follower_ids.ids), set([self.partner_admin_id]), - # 'compose wizard: mail_post_autofollow and mail_create_nosubscribe context keys not correctly taken into account') + # check message on test_record_2 + message1 = test_record_2.message_ids[0] + self.assertEqual(message1.subject, 'Testing %s' % test_record_2.name) + self.assertEqual(message1.body, '%s
' % test_record_2.name) @mute_logger('odoo.addons.mail.models.mail_mail') - def test_message_compose_mass_mail_active_domain(self): + def test_composer_mass_mail_active_domain(self): + test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', - 'default_model': 'mail.test', + 'default_model': self.test_record._name, 'default_use_active_domain': True, - 'active_ids': [self.test_pigs.id], - 'active_domain': [('name', 'in', ['%s' % self.test_pigs.name, '%s' % self.test_public.name])], + 'active_ids': [self.test_record.id], + 'active_domain': [('name', 'in', ['%s' % self.test_record.name, '%s' % test_record_2.name])], }).sudo(self.user_employee).create({ 'subject': 'From Composer Test', - 'body': '${object.description}', + 'body': '${object.name}', }).send_mail() - self.assertEqual(self.test_pigs.message_ids[0].subject, 'From Composer Test') - self.assertEqual(self.test_public.message_ids[0].subject, 'From Composer Test') - + self.assertEqual(self.test_record.message_ids[0].subject, 'From Composer Test') + self.assertEqual(test_record_2.message_ids[0].subject, 'From Composer Test') @mute_logger('odoo.addons.mail.models.mail_mail') def test_message_compose_mass_mail_no_active_domain(self): + test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2'}) + self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', - 'default_model': 'mail.test', + 'default_model': self.test_record._name, 'default_use_active_domain': False, - 'active_ids': [self.test_pigs.id], - 'active_domain': [('name', 'in', ['%s' % self.test_pigs.name, '%s' % self.test_public.name])], + 'active_ids': [self.test_record.id], + 'active_domain': [('name', 'in', ['%s' % self.test_record.name, '%s' % test_record_2.name])], }).sudo(self.user_employee).create({ 'subject': 'From Composer Test', - 'body': '${object.description}', + 'body': '${object.name}', }).send_mail() - self.assertEqual(self.test_pigs.message_ids[0].subject, 'From Composer Test') - self.assertFalse(self.test_public.message_ids.ids) + self.assertEqual(self.test_record.message_ids[0].subject, 'From Composer Test') + self.assertFalse(test_record_2.message_ids.ids) + + @mute_logger('odoo.addons.mail.models.mail_mail') + def test_message_compose_portal_ok(self): + portal_user = self.env['res.users'].with_context(self._quick_create_ctx).create({ + 'name': 'Chell Gladys', + 'login': 'chell', + 'email': 'chell@gladys.portal', + 'groups_id': [(6, 0, [self.env.ref('base.group_portal').id])], + }) + + with patch.object(MailTestSimple, 'check_access_rights', return_value=True): + ComposerPortal = self.env['mail.compose.message'].sudo(portal_user) + + ComposerPortal.with_context({ + 'default_composition_mode': 'comment', + 'default_model': self.test_record._name, + 'default_res_id': self.test_record.id, + }).create({ + 'subject': 'Subject', + 'body': 'Body text
', + 'partner_ids': []}).send_mail() + + self.assertEqual(self.test_record.message_ids[0].body, 'Body text
') + self.assertEqual(self.test_record.message_ids[0].author_id, portal_user.partner_id) + + ComposerPortal.with_context({ + 'default_composition_mode': 'comment', + 'default_parent_id': self.test_record.message_ids.ids[0], + }).create({ + 'subject': 'Subject', + 'body': 'Body text 2
'}).send_mail() + + self.assertEqual(self.test_record.message_ids[0].body, 'Body text 2
') + self.assertEqual(self.test_record.message_ids[0].author_id, portal_user.partner_id)