diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index 130e63deefd..f3cf5ce9e57 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -149,7 +149,6 @@ class mail_mail(osv.Model): reply_to = self._get_reply_to(cr, uid, values, context=context) if reply_to: self.write(cr, uid, [mail_id], {'reply_to': reply_to}, context=context) - return mail_id def unlink(self, cr, uid, ids, context=None): diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index f03f1239bd8..58d9de3db8f 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -682,6 +682,12 @@ class mail_thread(osv.AbstractModel): assert thread_id == 0, 'Routing: posting a message without model should be with a null res_id (private message).' _warn('posting a message without model should be with a null res_id (private message), resetting thread_id') thread_id = 0 + # Private message: should have a parent_id (only answers) + if not model and not message_dict.get('parent_id'): + if assert_model: + assert message_dict.get('parent_id'), 'Routing: posting a message without model should be with a parent_id (private mesage).' + _warn('posting a message without model should be with a parent_id (private mesage), skipping') + return () # Existing Document: check if exists; if not, fallback on create if allowed if thread_id and not model_pool.exists(cr, uid, thread_id): @@ -695,7 +701,7 @@ class mail_thread(osv.AbstractModel): return () # Existing Document: check model accepts the mailgateway - if thread_id and not hasattr(model_pool, 'message_update'): + if thread_id and model and not hasattr(model_pool, 'message_update'): if create_fallback: _warn('model %s does not accept document update, fall back on document creation' % model) thread_id = None diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py index 2e0ba336dc4..fade38869f1 100644 --- a/addons/mail/tests/test_mail_gateway.py +++ b/addons/mail/tests/test_mail_gateway.py @@ -20,7 +20,7 @@ ############################################################################## from openerp.addons.mail.tests.test_mail_base import TestMailBase -from openerp.tools import mute_logger, email_split +from openerp.tools import mute_logger MAIL_TEMPLATE = """Return-Path: To: {to} @@ -101,9 +101,9 @@ class TestMailgateway(TestMailBase): # Do: find partner with email -> first partner should be found partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0] self.assertEqual(partner_info['full_name'], 'Maybe Raoul ', - 'mail_thread: message_partner_info_from_emails did not handle email') + 'mail_thread: message_partner_info_from_emails did not handle email') self.assertEqual(partner_info['partner_id'], p_a_id, - 'mail_thread: message_partner_info_from_emails wrong partner found') + 'mail_thread: message_partner_info_from_emails wrong partner found') # Data: add some data about partners # 2 - User BRaoul @@ -112,7 +112,7 @@ class TestMailgateway(TestMailBase): # Do: find partner with email -> first user should be found partner_info = self.mail_thread.message_partner_info_from_emails(cr, uid, None, ['Maybe Raoul '], link_mail=False)[0] self.assertEqual(partner_info['partner_id'], p_b_id, - 'mail_thread: message_partner_info_from_emails wrong partner found') + 'mail_thread: message_partner_info_from_emails wrong partner found') # -------------------------------------------------- # CASE1: with object @@ -122,7 +122,7 @@ class TestMailgateway(TestMailBase): self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id]) partner_info = self.mail_group.message_partner_info_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul '], link_mail=False)[0] self.assertEqual(partner_info['partner_id'], p_b_id, - 'mail_thread: message_partner_info_from_emails wrong partner found') + 'mail_thread: message_partner_info_from_emails wrong partner found') def test_05_mail_message_mail_mail(self): """ Tests designed for testing email values based on mail.message, aliases, ... """ @@ -146,46 +146,46 @@ class TestMailgateway(TestMailBase): msg = self.mail_message.browse(cr, user_raoul_id, msg_id) # Test: message content self.assertIn('reply_to', msg.message_id, - 'mail_message: message_id should be specific to a mail_message with a given reply_to') + 'mail_message: message_id should be specific to a mail_message with a given reply_to') self.assertEqual(msg.reply_to, reply_to1, - 'mail_message: incorrect reply_to: should come from values') + 'mail_message: incorrect reply_to: should come from values') self.assertEqual(msg.email_from, email_from1, - 'mail_message: incorrect email_from: should come from values') + 'mail_message: incorrect email_from: should come from values') # Do: create a mail_mail with the previous mail_message mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'}) mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, reply_to1, - 'mail_mail: incorrect reply_to: should come from mail.message') + 'mail_mail: incorrect reply_to: should come from mail.message') self.assertEqual(mail.email_from, email_from1, - 'mail_mail: incorrect email_from: should come from mail.message') + 'mail_mail: incorrect email_from: should come from mail.message') # Do: create a mail_mail with the previous mail_message + specified reply_to mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel', 'reply_to': reply_to2}) mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, reply_to2, - 'mail_mail: incorrect reply_to: should come from values') + 'mail_mail: incorrect reply_to: should come from values') self.assertEqual(mail.email_from, email_from1, - 'mail_mail: incorrect email_from: should come from mail.message') + 'mail_mail: incorrect email_from: should come from mail.message') # Do: mail_message attached to a document msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id}) msg = self.mail_message.browse(cr, user_raoul_id, msg_id) # Test: message content self.assertIn('mail.group', msg.message_id, - 'mail_message: message_id should contain model') + 'mail_message: message_id should contain model') self.assertIn('%s' % self.group_pigs_id, msg.message_id, - 'mail_message: message_id should contain res_id') + 'mail_message: message_id should contain res_id') self.assertFalse(msg.reply_to, - 'mail_message: incorrect reply_to: should not be generated if not specified') + 'mail_message: incorrect reply_to: should not be generated if not specified') self.assertEqual(msg.email_from, raoul_from, - 'mail_message: incorrect email_from: should be Raoul') + 'mail_message: incorrect email_from: should be Raoul') # Do: create a mail_mail based on the previous mail_message mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'}) mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, raoul_reply, - 'mail_mail: incorrect reply_to: should be Raoul') + 'mail_mail: incorrect reply_to: should be Raoul') # Data: set catchall domain self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', alias_domain) @@ -199,7 +199,7 @@ class TestMailgateway(TestMailBase): mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, raoul_reply_alias, - 'mail_mail: incorrect reply_to: should be Pigs alias') + 'mail_mail: incorrect reply_to: should be Pigs alias') # Update message: test alias on email_from msg_id = self.mail_message.create(cr, user_raoul_id, {}) @@ -209,7 +209,7 @@ class TestMailgateway(TestMailBase): mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, raoul_from_alias, - 'mail_mail: incorrect reply_to: should be message email_from using Raoul alias') + 'mail_mail: incorrect reply_to: should be message email_from using Raoul alias') # Update message self.mail_message.write(cr, user_raoul_id, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr', 'reply_to': False}) @@ -219,7 +219,7 @@ class TestMailgateway(TestMailBase): mail = self.mail_mail.browse(cr, user_raoul_id, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, msg.email_from, - 'mail_mail: incorrect reply_to: should be message email_from') + 'mail_mail: incorrect reply_to: should be message email_from') # Data: set catchall alias self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.alias', 'gateway') @@ -232,21 +232,21 @@ class TestMailgateway(TestMailBase): mail = self.mail_mail.browse(cr, uid, mail_id) # Test: mail_mail Content-Type self.assertEqual(mail.reply_to, 'gateway@schlouby.fr', - 'mail_mail: reply_to should equal the catchall email alias') + 'mail_mail: reply_to should equal the catchall email alias') # Do: create a mail_mail mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel'}) mail = self.mail_mail.browse(cr, uid, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, 'gateway@schlouby.fr', - 'mail_mail: reply_to should equal the catchall email alias') + 'mail_mail: reply_to should equal the catchall email alias') # Do: create a mail_mail mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel', 'reply_to': 'someone@example.com'}) mail = self.mail_mail.browse(cr, uid, mail_id) # Test: mail_mail content self.assertEqual(mail.reply_to, 'someone@example.com', - 'mail_mail: reply_to should equal the rpely_to given to create') + 'mail_mail: reply_to should equal the rpely_to given to create') @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') def test_10_message_process(self): @@ -254,9 +254,9 @@ class TestMailgateway(TestMailBase): cr, uid, user_raoul = self.cr, self.uid, self.user_raoul def format_and_process(template, to='groups@example.com, other@gmail.com', subject='Frogs', - extra='', email_from='Sylvie Lelitre ', - msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>', - model=None): + extra='', email_from='Sylvie Lelitre ', + msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>', + model=None): self.assertEqual(self.mail_group.search(cr, uid, [('name', '=', subject)]), []) mail = template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id) self.mail_thread.message_process(cr, uid, model, mail) @@ -289,29 +289,29 @@ class TestMailgateway(TestMailBase): frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) self.assertEqual(res[0].get('create_uid'), uid, - 'message_process: group should have been created by uid as alias_user__id is False on the alias') + 'message_process: group should have been created by uid as alias_user__id is False on the alias') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, - 'message_process: newly created group should have the incoming email in message_ids') + 'message_process: newly created group should have the incoming email in message_ids') msg = frog_group.message_ids[0] self.assertEqual('Frogs', msg.subject, - 'message_process: newly created group should have the incoming email as first message') + 'message_process: newly created group should have the incoming email as first message') self.assertIn('Please call me as soon as possible this afternoon!', msg.body, - 'message_process: newly created group should have the incoming email as first message') + 'message_process: newly created group should have the incoming email as first message') self.assertEqual('email', msg.type, - 'message_process: newly created group should have an email as first message') + 'message_process: newly created group should have an email as first message') self.assertEqual('Discussions', msg.subtype_id.name, - 'message_process: newly created group should not have a log first message but an email') + 'message_process: newly created group should not have a log first message but an email') # Test: message: unknown email address -> message has email_from, not author_id self.assertFalse(msg.author_id, - 'message_process: message on created group should not have an author_id') + 'message_process: message on created group should not have an author_id') self.assertIn('test.sylvie.lelitre@agrolait.com', msg.email_from, - 'message_process: message on created group should have an email_from') + 'message_process: message on created group should have an email_from') # Test: followers: nobody self.assertEqual(len(frog_group.message_follower_ids), 0, 'message_process: newly create group should not have any follower') # Test: sent emails: no-one self.assertEqual(len(sent_emails), 0, - 'message_process: should create emails without any follower added') + 'message_process: should create emails without any follower added') # Data: unlink group frog_group.unlink() @@ -324,11 +324,11 @@ class TestMailgateway(TestMailBase): # Test: email bounced sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 1, - 'message_process: incoming email on Partners alias should send a bounce email') + 'message_process: incoming email on Partners alias should send a bounce email') self.assertIn('Frogs', sent_emails[0].get('subject'), - 'message_process: bounce email on Partners alias should contain the original subject') + 'message_process: bounce email on Partners alias should contain the original subject') self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'), - 'message_process: bounce email on Partners alias should have original email sender as recipient') + 'message_process: bounce email on Partners alias should have original email sender as recipient') # Do: incoming email from an unknown partner on a Followers only alias -> bounce self._init_mock_build_email() @@ -339,11 +339,11 @@ class TestMailgateway(TestMailBase): # Test: email bounced sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 1, - 'message_process: incoming email on Followers alias should send a bounce email') + 'message_process: incoming email on Followers alias should send a bounce email') self.assertIn('Frogs', sent_emails[0].get('subject'), - 'message_process: bounce email on Followers alias should contain the original subject') + 'message_process: bounce email on Followers alias should contain the original subject') self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to'), - 'message_process: bounce email on Followers alias should have original email sender as recipient') + 'message_process: bounce email on Followers alias should have original email sender as recipient') # Do: incoming email from a known partner on a Partners alias -> ok (+ test on alias.user_id) self.mail_alias.write(cr, uid, [alias_id], {'alias_user_id': self.user_raoul_id, 'alias_contact': 'partners'}) @@ -357,24 +357,24 @@ class TestMailgateway(TestMailBase): frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) res = self.mail_group.perm_read(cr, uid, [frog_group.id], details=False) self.assertEqual(res[0].get('create_uid'), self.user_raoul_id, - 'message_process: group should have been created by alias_user_id') + 'message_process: group should have been created by alias_user_id') # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, - 'message_process: newly created group should have the incoming email in message_ids') + 'message_process: newly created group should have the incoming email in message_ids') msg = frog_group.message_ids[0] # Test: message: author found self.assertEqual(p1id, msg.author_id.id, - 'message_process: message on created group should have Sylvie as author_id') + 'message_process: message on created group should have Sylvie as author_id') self.assertIn('Sylvie Lelitre ', msg.email_from, - 'message_process: message on created group should have have an email_from') + 'message_process: message on created group should have have an email_from') # Test: author (not recipient and not Raoul (as alias owner)) added as follower frog_follower_ids = set([p.id for p in frog_group.message_follower_ids]) self.assertEqual(frog_follower_ids, set([p1id]), - 'message_process: newly created group should have 1 follower (author, not creator, not recipients)') + 'message_process: newly created group should have 1 follower (author, not creator, not recipients)') # Test: sent emails: no-one, no bounce effet sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 0, - 'message_process: should not bounce incoming emails') + 'message_process: should not bounce incoming emails') # Data: unlink group frog_group.unlink() @@ -387,7 +387,7 @@ class TestMailgateway(TestMailBase): # Test: email bounced sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 1, - 'message_process: incoming email on Partners alias should send a bounce email') + 'message_process: incoming email on Partners alias should send a bounce email') # Do: incoming email from a parent document follower on a Followers only alias -> ok self._init_mock_build_email() @@ -398,15 +398,15 @@ class TestMailgateway(TestMailBase): frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one message that is the incoming email self.assertEqual(len(frog_group.message_ids), 1, - 'message_process: newly created group should have the incoming email in message_ids') + 'message_process: newly created group should have the incoming email in message_ids') # Test: author (and not recipient) added as follower frog_follower_ids = set([p.id for p in frog_group.message_follower_ids]) self.assertEqual(frog_follower_ids, set([p1id]), - 'message_process: newly created group should have 1 follower (author, not creator, not recipients)') + 'message_process: newly created group should have 1 follower (author, not creator, not recipients)') # Test: sent emails: no-one, no bounce effet sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 0, - 'message_process: should not bounce incoming emails') + 'message_process: should not bounce incoming emails') # -------------------------------------------------- # Test2: update-like alias @@ -416,43 +416,43 @@ class TestMailgateway(TestMailBase): self._init_mock_build_email() self.mail_group.write(cr, uid, [frog_group.id], {'alias_name': 'frogs', 'alias_contact': 'followers', 'alias_force_thread_id': frog_group.id}) frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com', - msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', - to='frogs@example.com>', subject='Re: news') + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', + to='frogs@example.com>', subject='Re: news') # Test: no group 'Re: news' created, still only 1 Frogs group self.assertEqual(len(frog_groups), 0, - 'message_process: reply on Frogs should not have created a new group with new subject') + 'message_process: reply on Frogs should not have created a new group with new subject') frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) self.assertEqual(len(frog_groups), 1, - 'message_process: reply on Frogs should not have created a duplicate group with old subject') + 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: email bounced sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 1, - 'message_process: incoming email on Followers alias should send a bounce email') + 'message_process: incoming email on Followers alias should send a bounce email') self.assertIn('Re: news', sent_emails[0].get('subject'), - 'message_process: bounce email on Followers alias should contain the original subject') + 'message_process: bounce email on Followers alias should contain the original subject') # Do: Pigs alias is restricted, should accept Followers self._init_mock_build_email() self.mail_group.message_subscribe(cr, uid, [frog_group.id], [p2id]) frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com', - msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>', - to='frogs@example.com>', subject='Re: cats') + msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>', + to='frogs@example.com>', subject='Re: cats') # Test: no group 'Re: news' created, still only 1 Frogs group self.assertEqual(len(frog_groups), 0, - 'message_process: reply on Frogs should not have created a new group with new subject') + 'message_process: reply on Frogs should not have created a new group with new subject') frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) self.assertEqual(len(frog_groups), 1, - 'message_process: reply on Frogs should not have created a duplicate group with old subject') + 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one new message self.assertEqual(len(frog_group.message_ids), 2, 'message_process: group should contain 2 messages after reply') # Test: sent emails: 1 (Sylvie copy of the incoming email, but no bounce) sent_emails = self._build_email_kwargs_list self.assertEqual(len(sent_emails), 1, - 'message_process: one email should have been generated') + 'message_process: one email should have been generated') self.assertIn('test.sylvie.lelitre@agrolait.com', sent_emails[0].get('email_to')[0], - 'message_process: email should be sent to Sylvie') + 'message_process: email should be sent to Sylvie') self.mail_group.message_unsubscribe(cr, uid, [frog_group.id], [p2id]) # -------------------------------------------------- @@ -461,40 +461,40 @@ class TestMailgateway(TestMailBase): # Do: even with a wrong destination, a reply should end up in the correct thread frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com', - msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', - to='erroneous@example.com>', subject='Re: news', - extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', + to='erroneous@example.com>', subject='Re: news', + extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) # Test: no group 'Re: news' created, still only 1 Frogs group self.assertEqual(len(frog_groups), 0, - 'message_process: reply on Frogs should not have created a new group with new subject') + 'message_process: reply on Frogs should not have created a new group with new subject') frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) self.assertEqual(len(frog_groups), 1, - 'message_process: reply on Frogs should not have created a duplicate group with old subject') + 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: one new message self.assertEqual(len(frog_group.message_ids), 3, 'message_process: group should contain 2 messages after reply') # Test: author (and not recipient) added as follower frog_follower_ids = set([p.id for p in frog_group.message_follower_ids]) self.assertEqual(frog_follower_ids, set([p1id, p2id]), - 'message_process: after reply, group should have 2 followers') + 'message_process: after reply, group should have 2 followers') # Do: due to some issue, same email goes back into the mailgateway frog_groups = format_and_process(MAIL_TEMPLATE, email_from='other4@gmail.com', - msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', - subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + msg_id='<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>', + subject='Re: news', extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) # Test: no group 'Re: news' created, still only 1 Frogs group self.assertEqual(len(frog_groups), 0, - 'message_process: reply on Frogs should not have created a new group with new subject') + 'message_process: reply on Frogs should not have created a new group with new subject') frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) self.assertEqual(len(frog_groups), 1, - 'message_process: reply on Frogs should not have created a duplicate group with old subject') + 'message_process: reply on Frogs should not have created a duplicate group with old subject') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: no new message self.assertEqual(len(frog_group.message_ids), 3, 'message_process: message with already existing message_id should not have been duplicated') # Test: message_id is still unique msg_ids = self.mail_message.search(cr, uid, [('message_id', 'ilike', '<1198923581.41972151344608186760.JavaMail.diff1@agrolait.com>')]) self.assertEqual(len(msg_ids), 1, - 'message_process: message with already existing message_id should not have been duplicated') + 'message_process: message with already existing message_id should not have been duplicated') # -------------------------------------------------- # Test4: email_from and partner finding @@ -505,28 +505,28 @@ class TestMailgateway(TestMailBase): # Do: post a new message, with a known partner -> duplicate emails -> partner format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', - to='erroneous@example.com>', subject='Re: news (2)', - msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>', - extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + to='erroneous@example.com>', subject='Re: news (2)', + msg_id='<1198923581.41972151344608186760.JavaMail.new1@agrolait.com>', + extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: author is A-Raoul (only existing) self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id, - 'message_process: email_from -> author_id wrong') + 'message_process: email_from -> author_id wrong') # Do: post a new message, with a known partner -> duplicate emails -> user frog_group.message_unsubscribe([extra_partner_id]) raoul_email = self.user_raoul.email self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', - to='erroneous@example.com>', subject='Re: news (3)', - msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>', - extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new2@agrolait.com>', + extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: author is Raoul (user), not A-Raoul self.assertEqual(frog_group.message_ids[0].author_id.id, self.partner_raoul_id, - 'message_process: email_from -> author_id wrong') + 'message_process: email_from -> author_id wrong') # Do: post a new message, with a known partner -> duplicate emails -> partner because is follower frog_group.message_unsubscribe([self.partner_raoul_id]) @@ -534,14 +534,14 @@ class TestMailgateway(TestMailBase): raoul_email = self.user_raoul.email self.res_users.write(cr, uid, self.user_raoul_id, {'email': 'test_raoul@email.com'}) format_and_process(MAIL_TEMPLATE, email_from='Lombrik Lubrik ', - to='erroneous@example.com>', subject='Re: news (3)', - msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>', - extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) + to='erroneous@example.com>', subject='Re: news (3)', + msg_id='<1198923581.41972151344608186760.JavaMail.new3@agrolait.com>', + extra='In-Reply-To: <12321321-openerp-%d-mail.group@example.com>\n' % frog_group.id) frog_groups = self.mail_group.search(cr, uid, [('name', '=', 'Frogs')]) frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) # Test: author is Raoul (user), not A-Raoul self.assertEqual(frog_group.message_ids[0].author_id.id, extra_partner_id, - 'message_process: email_from -> author_id wrong') + 'message_process: email_from -> author_id wrong') self.res_users.write(cr, uid, self.user_raoul_id, {'email': raoul_email}) @@ -551,37 +551,37 @@ class TestMailgateway(TestMailBase): # Do: incoming email with model that does not accepts incoming emails must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, - to='noone@example.com', subject='spam', extra='', model='res.country', - msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', model='res.country', + msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>') # Do: incoming email without model and without alias must raise self.assertRaises(AssertionError, - format_and_process, - MAIL_TEMPLATE, - to='noone@example.com', subject='spam', extra='', - msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>') + format_and_process, + MAIL_TEMPLATE, + to='noone@example.com', subject='spam', extra='', + msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>') # Do: incoming email with model that accepting incoming emails as fallback frog_groups = format_and_process(MAIL_TEMPLATE, - to='noone@example.com', - subject='Spammy', extra='', model='mail.group', - msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>') + to='noone@example.com', + subject='Spammy', extra='', model='mail.group', + msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>') self.assertEqual(len(frog_groups), 1, - 'message_process: erroneous email but with a fallback model should have created a new mail.group') + 'message_process: erroneous email but with a fallback model should have created a new mail.group') # Do: incoming email in plaintext should be stored as html frog_groups = format_and_process(MAIL_TEMPLATE_PLAINTEXT, - to='groups@example.com', subject='Frogs Return', extra='', - msg_id='') + to='groups@example.com', subject='Frogs Return', extra='', + msg_id='') # Test: one group created with one message self.assertEqual(len(frog_groups), 1, 'message_process: a new mail.group should have been created') frog_group = self.mail_group.browse(cr, uid, frog_groups[0]) msg = frog_group.message_ids[0] # Test: plain text content should be wrapped and stored as html self.assertIn('
\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n
', msg.body, - 'message_process: plaintext incoming email incorrectly parsed') + 'message_process: plaintext incoming email incorrectly parsed') @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm') def test_20_thread_parent_resolution(self): @@ -602,26 +602,26 @@ class TestMailgateway(TestMailBase): # Reply to msg1, make sure the reply is properly attached using the various reply identification mechanisms # 0. Direct alias match reply_msg1 = format(MAIL_TEMPLATE, to='Pretty Pigs ', - extra='In-Reply-To: %s' % msg1.message_id, - msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>') + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.2@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg1) # 1. In-Reply-To header reply_msg2 = format(MAIL_TEMPLATE, to='erroneous@example.com', - extra='In-Reply-To: %s' % msg1.message_id, - msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>') + extra='In-Reply-To: %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.3@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg2) # 2. References header reply_msg3 = format(MAIL_TEMPLATE, to='erroneous@example.com', - extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id, - msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>') + extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % msg1.message_id, + msg_id='<1198923581.41972151344608186760.JavaMail.4@agrolait.com>') self.mail_group.message_process(cr, uid, None, reply_msg3) # 3. Subject contains [] + model passed to message+process -> only attached to group, but not to mail (not in msg1.child_ids) reply_msg4 = format(MAIL_TEMPLATE, to='erroneous@example.com', - extra='', subject='Re: [%s] 1' % self.group_pigs_id, - msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>') + extra='', subject='Re: [%s] 1' % self.group_pigs_id, + msg_id='<1198923581.41972151344608186760.JavaMail.5@agrolait.com>') self.mail_group.message_process(cr, uid, 'mail.group', reply_msg4) group_pigs.refresh() @@ -633,12 +633,19 @@ class TestMailgateway(TestMailBase): """ Testing private discussion between partners. """ cr, uid = self.cr, self.uid + def format(template, to='Pretty Pigs , other@gmail.com', subject='Re: 1', + extra='', email_from='Sylvie Lelitre ', + msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'): + return template.format(to=to, subject=subject, extra=extra, email_from=email_from, msg_id=msg_id) + # Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account msg1_pids = [self.partner_admin_id, self.partner_bert_id] - msg1_id = self.mail_thread.message_post(cr, self.user_raoul_id, False, - partner_ids=msg1_pids, - subtype='mail.mt_comment', - context={'thread_model': 'mail.group'}) + msg1_id = self.mail_thread.message_post( + cr, self.user_raoul_id, False, + partner_ids=msg1_pids, + subtype='mail.mt_comment', + context={'thread_model': 'mail.group'} + ) # Test: message recipients msg = self.mail_message.browse(cr, uid, msg1_id) @@ -647,16 +654,26 @@ class TestMailgateway(TestMailBase): test_pids = msg1_pids test_nids = msg1_pids self.assertEqual(set(msg_pids), set(test_pids), - 'message_post: private discussion: incorrect recipients') + 'message_post: private discussion: incorrect recipients') self.assertEqual(set(msg_nids), set(test_nids), - 'message_post: private discussion: incorrect notified recipients') + 'message_post: private discussion: incorrect notified recipients') self.assertEqual(msg.model, False, - 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id') + 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id') + # Test: message reply_to and message-id + self.assertFalse(msg.reply_to, + 'message_post: private discussion: initial message should not have any reply_to specified') + self.assertIn('openerp-private', msg.message_id, + 'message_post: private discussion: message-id should contain the private keyword') # Do: Bert replies through mailgateway (is a customer) - msg2_id = self.mail_thread.message_post(cr, uid, False, - author_id=self.partner_bert_id, - parent_id=msg1_id, subtype='mail.mt_comment') + reply_message = format(MAIL_TEMPLATE, to='not_important@mydomain.com', + email_from='bert@bert.fr', + extra='In-Reply-To: %s' % msg.message_id, + msg_id='') + self.mail_thread.message_process(cr, uid, None, reply_message) + + # Test: last mail_message created + msg2_id = self.mail_message.search(cr, uid, [], limit=1)[0] # Test: message recipients msg = self.mail_message.browse(cr, uid, msg2_id) @@ -664,14 +681,32 @@ class TestMailgateway(TestMailBase): msg_nids = [p.id for p in msg.notified_partner_ids] test_pids = [self.partner_admin_id, self.partner_raoul_id] test_nids = test_pids + self.assertEqual(msg.author_id.id, self.partner_bert_id, + 'message_post: private discussion: wrong author through mailgatewya based on email') self.assertEqual(set(msg_pids), set(test_pids), - 'message_post: private discussion: incorrect recipients when replying') + 'message_post: private discussion: incorrect recipients when replying') self.assertEqual(set(msg_nids), set(test_nids), - 'message_post: private discussion: incorrect notified recipients when replying') + 'message_post: private discussion: incorrect notified recipients when replying') + + # Do: Bert replies through chatter (is a customer) + msg3_id = self.mail_thread.message_post( + cr, uid, False, + author_id=self.partner_bert_id, + parent_id=msg1_id, subtype='mail.mt_comment') + + # Test: message recipients + msg = self.mail_message.browse(cr, uid, msg3_id) + msg_pids = [p.id for p in msg.partner_ids] + msg_nids = [p.id for p in msg.notified_partner_ids] + test_pids = [self.partner_admin_id, self.partner_raoul_id] + test_nids = test_pids + self.assertEqual(set(msg_pids), set(test_pids), + 'message_post: private discussion: incorrect recipients when replying') + self.assertEqual(set(msg_nids), set(test_nids), + 'message_post: private discussion: incorrect notified recipients when replying') # Do: Administrator replies - msg3_id = self.mail_thread.message_post(cr, uid, False, - parent_id=msg2_id, subtype='mail.mt_comment') + msg3_id = self.mail_thread.message_post(cr, uid, False, parent_id=msg3_id, subtype='mail.mt_comment') # Test: message recipients msg = self.mail_message.browse(cr, uid, msg3_id) @@ -680,6 +715,6 @@ class TestMailgateway(TestMailBase): test_pids = [self.partner_bert_id, self.partner_raoul_id] test_nids = test_pids self.assertEqual(set(msg_pids), set(test_pids), - 'message_post: private discussion: incorrect recipients when replying') + 'message_post: private discussion: incorrect recipients when replying') self.assertEqual(set(msg_nids), set(test_nids), - 'message_post: private discussion: incorrect notified recipients when replying') + 'message_post: private discussion: incorrect notified recipients when replying')