diff options
| author | Thibault Delavallée <tde@odoo.com> | 2017-11-21 13:34:51 +0100 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2017-11-29 10:11:15 +0100 |
| commit | d040bfde89fca1c702e6e95c3b808e0b48c2267a (patch) | |
| tree | 78f4d11e9d1194c878f89be61a4a4b8140b7e5da /addons/mail/tests | |
| parent | 7a136d6acc3467504e7d6deed7482395e4d55bd8 (diff) | |
[MOV] (test_)mail: move tests into their dedicated module
Purpose: avoid having useless tables for test models in a
production environment.
Diffstat (limited to 'addons/mail/tests')
| -rw-r--r-- | addons/mail/tests/__init__.py | 15 | ||||
| -rw-r--r-- | addons/mail/tests/common.py | 222 | ||||
| -rw-r--r-- | addons/mail/tests/data/__init__.py | 3 | ||||
| -rw-r--r-- | addons/mail/tests/data/test_mail_data.py | 280 | ||||
| -rw-r--r-- | addons/mail/tests/models/__init__.py | 3 | ||||
| -rw-r--r-- | addons/mail/tests/models/test_mail_models.py | 97 | ||||
| -rw-r--r-- | addons/mail/tests/test_discuss.py | 153 | ||||
| -rw-r--r-- | addons/mail/tests/test_invite.py | 29 | ||||
| -rw-r--r-- | addons/mail/tests/test_ir_actions.py | 36 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_activity.py | 67 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_channel.py | 197 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_followers.py | 199 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_gateway.py | 512 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_mail.py | 45 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_message.py | 276 | ||||
| -rw-r--r-- | addons/mail/tests/test_mail_template.py | 203 | ||||
| -rw-r--r-- | addons/mail/tests/test_message_compose.py | 355 | ||||
| -rw-r--r-- | addons/mail/tests/test_message_track.py | 137 | ||||
| -rw-r--r-- | addons/mail/tests/test_update_notification.py | 11 |
19 files changed, 0 insertions, 2840 deletions
diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py deleted file mode 100644 index bf46d383f92..00000000000 --- a/addons/mail/tests/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import test_mail_activity -from . import test_mail_followers -from . import test_mail_message -from . import test_mail_mail -from . import test_mail_channel -from . import test_mail_gateway -from . import test_mail_template -from . import test_message_compose -from . import test_message_track -from . import test_invite -from . import test_ir_actions -from . import test_update_notification -from . import test_discuss diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py deleted file mode 100644 index 5ff9f42954d..00000000000 --- a/addons/mail/tests/common.py +++ /dev/null @@ -1,222 +0,0 @@ -# -*- coding: utf-8 -*- - -from contextlib import contextmanager -from email.utils import formataddr - -from odoo import api -from odoo.tests import common - - -class BaseFunctionalTest(common.SavepointCase): - - @classmethod - def setUpClass(cls): - super(BaseFunctionalTest, cls).setUpClass() - cls._quick_create_ctx = { - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - } - cls._quick_create_user_ctx = dict(cls._quick_create_ctx, no_reset_password=True) - - user_group_employee = cls.env.ref('base.group_user') - cls.user_employee = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Ernest Employee', - 'login': 'ernest', - 'email': 'e.e@example.com', - 'signature': '--\nErnest', - 'notification_type': 'email', - 'groups_id': [(6, 0, [user_group_employee.id])]}) - cls.partner_employee = cls.user_employee.partner_id - cls.user_admin = cls.env.user - cls.partner_admin = cls.user_admin.partner_id - - cls.channel_listen = cls.env['mail.channel'].with_context(cls._quick_create_ctx).create({'name': 'Listener'}) - - cls.test_record = cls.env['mail.test.simple'].with_context(cls._quick_create_ctx).create({'name': 'Test', 'email_from': 'ignasse@example.com'}) - - @contextmanager - def assertNotifications(self, **counters): - """ Counters: 'partner_attribute': 'inbox' or 'email' """ - try: - init_messages = self.test_record.message_ids - init = {} - partners = self.env['res.partner'] - for partner_attribute in counters.keys(): - partner = getattr(self, partner_attribute) - partners |= partner - if partner.user_ids: - init[partner] = { - 'na_counter': self.test_record.sudo(partner.user_ids[0]).message_needaction_counter, - } - yield - finally: - new_messages = self.test_record.sudo().message_ids - init_messages - new_notifications = self.env['mail.notification'].search([ - ('res_partner_id', 'in', partners.ids), - ('mail_message_id', 'in', new_messages.ids) - ]) - - for partner_attribute in counters.keys(): - counter, notif_type, notif_read = counters[partner_attribute] - partner = getattr(self, partner_attribute) - partner_notif = new_notifications.filtered(lambda n: n.res_partner_id == partner) - - self.assertEqual(len(partner_notif), counter) - - if partner.user_ids: - expected = init[partner]['na_counter'] + counter if notif_read == 'unread' else init[partner]['na_counter'] - self.assertEqual(expected, self.test_record.sudo(partner.user_ids[0]).message_needaction_counter, - 'Invalid number of notification for %s: %s instead of %s' % - (partner.name, expected, self.test_record.sudo(partner.user_ids[0]).message_needaction_counter)) - if partner_notif: - self.assertTrue(all(n.is_email == (notif_type == 'email') for n in partner_notif)) - self.assertTrue(all(n.is_read == (notif_read == 'read') for n in partner_notif), - 'Invalid read status for %s' % partner.name) - - # for simplification, limitate to single message asserts - if hasattr(self, 'assertEmails') and len(new_messages) == 1: - self.assertEmails(new_messages.author_id, new_notifications.filtered(lambda n: n.is_email).mapped('res_partner_id')) - - @contextmanager - def sudoAs(self, login): - old_uid = self.uid - try: - user = self.env['res.users'].sudo().search([('login', '=', login)]) - self.test_record_old = self.test_record - # switch user - self.uid = user.id - self.env = self.env(user=self.uid) - self.test_record = self.test_record.sudo(self.uid) - yield - finally: - # back - self.uid = old_uid - self.env = self.env(user=self.uid) - self.test_record = self.test_record_old - - -class TestRecipients(common.SavepointCase): - - @classmethod - def setUpClass(cls): - super(TestRecipients, cls).setUpClass() - Partner = cls.env['res.partner'].with_context({ - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - 'no_reset_password': True, - }) - cls.partner_1 = Partner.create({ - 'name': 'Valid Lelitre', - 'email': 'valid.lelitre@agrolait.com'}) - cls.partner_2 = Partner.create({ - 'name': 'Valid Poilvache', - 'email': 'valid.other@gmail.com'}) - - -class MockEmails(common.SingleTransactionCase): - - def setUp(self): - super(MockEmails, self).setUp() - self._mails_args[:] = [] - self._mails[:] = [] - - @classmethod - def setUpClass(cls): - super(MockEmails, cls).setUpClass() - cls._mails_args = [] - cls._mails = [] - - def build_email(self, *args, **kwargs): - cls._mails_args.append(args) - cls._mails.append(kwargs) - return build_email.origin(self, *args, **kwargs) - - @api.model - def send_email(self, message, *args, **kwargs): - return message['Message-Id'] - - cls.env['ir.mail_server']._patch_method('build_email', build_email) - cls.env['ir.mail_server']._patch_method('send_email', send_email) - - def assertEmails(self, partner_from, recipients, **values): - """ Tools method to ease the check of send emails """ - expected_email_values = [] - for partners in recipients: - expected = { - 'email_from': formataddr((partner_from.name, partner_from.email)), - 'email_to': [formataddr((partner.name, partner.email)) for partner in partners] - } - if 'reply_to' in values: - expected['reply_to'] = values['reply_to'] - if 'subject' in values: - expected['subject'] = values['subject'] - if 'attachments' in values: - expected['attachments'] = values['attachments'] - if 'body' in values: - expected['body'] = values['body'] - if 'body_content' in values: - expected['body_content'] = values['body_content'] - if 'body_alt_content' in values: - expected['body_alternative_content'] = values['body_alt_content'] - if 'references' in values: - expected['references'] = values['references'] - if 'ref_content' in values: - expected['references_content'] = values['ref_content'] - expected_email_values.append(expected) - - self.assertEqual(len(self._mails), len(expected_email_values)) - for expected in expected_email_values: - sent_mail = next((mail for mail in self._mails if set(mail['email_to']) == set(expected['email_to'])), False) - self.assertTrue(bool(sent_mail), 'Expected mail to %s not found' % expected['email_to']) - for val in ['email_from', 'reply_to', 'subject', 'body', 'references', 'attachments']: - if val in expected: - self.assertEqual(expected[val], sent_mail[val], 'Value for %s: expected %s, received %s' % (val, expected[val], sent_mail[val])) - for val in ['body_content', 'body_alternative', 'references_content']: - if val in expected: - self.assertIn(expected[val], sent_mail[val[:-8]], 'Value for %s: %s does not contain %s' % (val, sent_mail[val[:-8]], expected[val])) - - def assertHtmlEqual(self, value, expected, message=None): - from lxml import html - - tree = html.fragment_fromstring(value, parser=html.HTMLParser(encoding='utf-8'), create_parent='body') - - # mass mailing: add base tag we have to remove - for base_node in tree.xpath('//base'): - base_node.getparent().remove(base_node) - - # chatter: read more / read less TODO - - # mass mailing: add base tag we have to remove - expected_node = html.fragment_fromstring(expected, create_parent='body') - - if message: - self.assertEqual(tree, expected_node, message) - else: - self.assertEqual(tree, expected_node) - - @classmethod - def tearDownClass(cls): - # Remove mocks - cls.env['ir.mail_server']._revert_method('build_email') - cls.env['ir.mail_server']._revert_method('send_email') - super(MockEmails, cls).tearDownClass() - - def _init_mock_build_email(self): - self._mails_args[:] = [] - self._mails[:] = [] - - def format(self, template, to='groups@example.com, other@gmail.com', subject='Frogs', - extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', - cc='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'): - return template.format(to=to, subject=subject, cc=cc, extra=extra, email_from=email_from, msg_id=msg_id) - - def format_and_process(self, template, to='groups@example.com, other@gmail.com', subject='Frogs', - extra='', email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>', - cc='', msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>', - model=None, target_model='mail.test.simple', target_field='name'): - self.assertFalse(self.env[target_model].search([(target_field, '=', subject)])) - mail = self.format(template, to=to, subject=subject, cc=cc, extra=extra, email_from=email_from, msg_id=msg_id) - self.env['mail.thread'].with_context(mail_channel_noautofollow=True).message_process(model, mail) - return self.env[target_model].search([(target_field, '=', subject)]) diff --git a/addons/mail/tests/data/__init__.py b/addons/mail/tests/data/__init__.py deleted file mode 100644 index 3c2bb4e3324..00000000000 --- a/addons/mail/tests/data/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import test_mail_data diff --git a/addons/mail/tests/data/test_mail_data.py b/addons/mail/tests/data/test_mail_data.py deleted file mode 100644 index e516964dc3d..00000000000 --- a/addons/mail/tests/data/test_mail_data.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -MAIL_TEMPLATE = """Return-Path: <whatever-2a840@postmaster.twitter.com> -To: {to} -cc: {cc} -Received: by mail1.openerp.com (Postfix, from userid 10002) - id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST) -From: {email_from} -Subject: {subject} -MIME-Version: 1.0 -Content-Type: multipart/alternative; - boundary="----=_Part_4200734_24778174.1344608186754" -Date: Fri, 10 Aug 2012 14:16:26 +0000 -Message-ID: {msg_id} -{extra} -------=_Part_4200734_24778174.1344608186754 -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: quoted-printable - -Please call me as soon as possible this afternoon! - --- -Sylvie -------=_Part_4200734_24778174.1344608186754 -Content-Type: text/html; charset=utf-8 -Content-Transfer-Encoding: quoted-printable - -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> -<html> - <head>=20 - <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" /> - </head>=20 - <body style=3D"margin: 0; padding: 0; background: #ffffff;-webkit-text-size-adjust: 100%;">=20 - - <p>Please call me as soon as possible this afternoon!</p> - - <p>--<br/> - Sylvie - <p> - </body> -</html> -------=_Part_4200734_24778174.1344608186754-- -""" - -MAIL_TEMPLATE_PLAINTEXT = """Return-Path: <whatever-2a840@postmaster.twitter.com> -To: {to} -Received: by mail1.openerp.com (Postfix, from userid 10002) - id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST) -From: {email_from} -Subject: {subject} -MIME-Version: 1.0 -Content-Type: text/plain -Date: Fri, 10 Aug 2012 14:16:26 +0000 -Message-ID: {msg_id} -{extra} - -Please call me as soon as possible this afternoon! - --- -Sylvie -""" - -MAIL_MULTIPART_MIXED = """Return-Path: <ignasse.carambar@gmail.com> -X-Original-To: raoul@grosbedon.fr -Delivered-To: raoul@grosbedon.fr -Received: by mail1.grosbedon.com (Postfix, from userid 10002) - id E8166BFACA; Fri, 23 Aug 2013 13:18:01 +0200 (CEST) -X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail1.grosbedon.com -X-Spam-Level: -X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, - HTML_MESSAGE,RCVD_IN_DNSWL_LOW autolearn=unavailable version=3.3.1 -Received: from mail-ie0-f173.google.com (mail-ie0-f173.google.com [209.85.223.173]) - by mail1.grosbedon.com (Postfix) with ESMTPS id 9BBD7BFAAA - for <raoul@openerp.fr>; Fri, 23 Aug 2013 13:17:55 +0200 (CEST) -Received: by mail-ie0-f173.google.com with SMTP id qd12so575130ieb.4 - for <raoul@grosbedon.fr>; Fri, 23 Aug 2013 04:17:54 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20120113; - h=mime-version:date:message-id:subject:from:to:content-type; - bh=dMNHV52EC7GAa7+9a9tqwT9joy9z+1950J/3A6/M/hU=; - b=DGuv0VjegdSrEe36ADC8XZ9Inrb3Iu+3/52Bm+caltddXFH9yewTr0JkCRQaJgMwG9 - qXTQgP8qu/VFEbCh6scu5ZgU1hknzlNCYr3LT+Ih7dAZVUEHUJdwjzUU1LFV95G2RaCd - /Lwff6CibuUvrA+0CBO7IRKW0Sn5j0mukYu8dbaKsm6ou6HqS8Nuj85fcXJfHSHp6Y9u - dmE8jBh3fHCHF/nAvU+8aBNSIzl1FGfiBYb2jCoapIuVFitKR4q5cuoodpkH9XqqtOdH - DG+YjEyi8L7uvdOfN16eMr7hfUkQei1yQgvGu9/5kXoHg9+Gx6VsZIycn4zoaXTV3Nhn - nu4g== -MIME-Version: 1.0 -X-Received: by 10.50.124.65 with SMTP id mg1mr1144467igb.43.1377256674216; - Fri, 23 Aug 2013 04:17:54 -0700 (PDT) -Received: by 10.43.99.71 with HTTP; Fri, 23 Aug 2013 04:17:54 -0700 (PDT) -Date: Fri, 23 Aug 2013 13:17:54 +0200 -Message-ID: <CAP76m_V4BY2F7DWHzwfjteyhW8L2LJswVshtmtVym+LUJ=rASQ@mail.gmail.com> -Subject: Test mail multipart/mixed -From: =?ISO-8859-1?Q?Raoul Grosbedon=E9e?= <ignasse.carambar@gmail.com> -To: Followers of ASUSTeK-Joseph-Walters <raoul@grosbedon.fr> -Content-Type: multipart/mixed; boundary=089e01536c4ed4d17204e49b8e96 - ---089e01536c4ed4d17204e49b8e96 -Content-Type: multipart/alternative; boundary=089e01536c4ed4d16d04e49b8e94 - ---089e01536c4ed4d16d04e49b8e94 -Content-Type: text/plain; charset=ISO-8859-1 - -Should create a multipart/mixed: from gmail, *bold*, with attachment. - --- -Marcel Boitempoils. - ---089e01536c4ed4d16d04e49b8e94 -Content-Type: text/html; charset=ISO-8859-1 - -<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>-- <br>Marcel Boitempoils.</div> - ---089e01536c4ed4d16d04e49b8e94-- ---089e01536c4ed4d17204e49b8e96 -Content-Type: text/plain; charset=US-ASCII; name="test.txt" -Content-Disposition: attachment; filename="test.txt" -Content-Transfer-Encoding: base64 -X-Attachment-Id: f_hkpb27k00 - -dGVzdAo= ---089e01536c4ed4d17204e49b8e96--""" - -MAIL_MULTIPART_MIXED_TWO = """X-Original-To: raoul@grosbedon.fr -Delivered-To: raoul@grosbedon.fr -Received: by mail1.grosbedon.com (Postfix, from userid 10002) - id E8166BFACA; Fri, 23 Aug 2013 13:18:01 +0200 (CEST) -From: "Bruce Wayne" <bruce@wayneenterprises.com> -Content-Type: multipart/alternative; - boundary="Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227" -Message-Id: <6BB1FAB2-2104-438E-9447-07AE2C8C4A92@sexample.com> -Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) - ---Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset=us-ascii - -First and second part - ---Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227 -Content-Type: multipart/mixed; - boundary="Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F" - ---Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F -Content-Transfer-Encoding: 7bit -Content-Type: text/html; - charset=us-ascii - -<html><head></head><body>First part</body></html> - ---Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F -Content-Disposition: inline; - filename=thetruth.pdf -Content-Type: application/pdf; - name="thetruth.pdf" -Content-Transfer-Encoding: base64 - -SSBhbSB0aGUgQmF0TWFuCg== - ---Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F -Content-Transfer-Encoding: 7bit -Content-Type: text/html; - charset=us-ascii - -<html><head></head><body>Second part</body></html> ---Apple-Mail=_CA6C687E-6AA0-411E-B0FE-F0ABB4CFED1F-- - ---Apple-Mail=_9331E12B-8BD2-4EC7-B53E-01F3FBEC9227-- -""" - - -MAIL_MULTIPART_IMAGE = """X-Original-To: raoul@example.com -Delivered-To: micheline@example.com -Received: by mail1.example.com (Postfix, from userid 99999) - id 9DFB7BF509; Thu, 17 Dec 2015 15:22:56 +0100 (CET) -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.example.com -X-Spam-Level: * -X-Spam-Status: No, score=1.1 required=5.0 tests=FREEMAIL_FROM, - HTML_IMAGE_ONLY_08,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3, - RCVD_IN_MSPIKE_WL,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 -Received: from mail-lf0-f44.example.com (mail-lf0-f44.example.com [209.85.215.44]) - by mail1.example.com (Postfix) with ESMTPS id 1D80DBF509 - for <micheline@example.com>; Thu, 17 Dec 2015 15:22:56 +0100 (CET) -Authentication-Results: mail1.example.com; dkim=pass - reason="2048-bit key; unprotected key" - header.d=example.com header.i=@example.com header.b=kUkTIIlt; - dkim-adsp=pass; dkim-atps=neutral -Received: by mail-lf0-f44.example.com with SMTP id z124so47959461lfa.3 - for <micheline@example.com>; Thu, 17 Dec 2015 06:22:56 -0800 (PST) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=example.com; s=20120113; - h=mime-version:date:message-id:subject:from:to:content-type; - bh=GdrEuMrz6vxo/Z/F+mJVho/1wSe6hbxLx2SsP8tihzw=; - b=kUkTIIlt6fe4dftKHPNBkdHU2rO052o684R0e2bqH7roGUQFb78scYE+kqX0wo1zlk - zhKPVBR1TqTsYlqcHu+D3aUzai7L/Q5m40sSGn7uYGkZJ6m1TwrWNqVIgTZibarqvy94 - NWhrjjK9gqd8segQdSjCgTipNSZME4bJCzPyBg/D5mqe07FPBJBGoF9SmIzEBhYeqLj1 - GrXjb/D8J11aOyzmVvyt+bT+oeLUJI8E7qO5g2eQkMncyu+TyIXaRofOOBA14NhQ+0nS - w5O9rzzqkKuJEG4U2TJ2Vi2nl2tHJW2QPfTtFgcCzGxQ0+5n88OVlbGTLnhEIJ/SYpem - O5EA== -MIME-Version: 1.0 -X-Received: by 10.25.167.197 with SMTP id q188mr22222517lfe.129.1450362175493; - Thu, 17 Dec 2015 06:22:55 -0800 (PST) -Received: by 10.25.209.145 with HTTP; Thu, 17 Dec 2015 06:22:55 -0800 (PST) -Date: Thu, 17 Dec 2015 15:22:55 +0100 -Message-ID: <CAP76m_UB=aLqWEFccnq86AhkpwRB3aZoGL9vMffX7co3YEro_A@mail.gmail.com> -Subject: {subject} -From: =?UTF-8?Q?Thibault_Delavall=C3=A9e?= <raoul@example.com> -To: {to} -Content-Type: multipart/related; boundary=001a11416b9e9b229a05272b7052 - ---001a11416b9e9b229a05272b7052 -Content-Type: multipart/alternative; boundary=001a11416b9e9b229805272b7051 - ---001a11416b9e9b229805272b7051 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -Premi=C3=A8re image, orang=C3=A9e. - -[image: Inline image 1] - -Seconde image, rosa=C3=A7=C3=A9e. - -[image: Inline image 2] - -Troisi=C3=A8me image, verte!=C2=B5 - -[image: Inline image 3] - -J'esp=C3=A8re que tout se passera bien. ---=20 -Thibault Delavall=C3=A9e - ---001a11416b9e9b229805272b7051 -Content-Type: text/html; charset=UTF-8 -Content-Transfer-Encoding: quoted-printable - -<div dir=3D"ltr"><div>Premi=C3=A8re image, orang=C3=A9e.</div><div><br></di= -v><div><img src=3D"cid:ii_151b519fc025fdd3" alt=3D"Inline image 1" width=3D= -"2" height=3D"2"><br></div><div><br></div><div>Seconde image, rosa=C3=A7=C3= -=A9e.</div><div><br></div><div><img src=3D"cid:ii_151b51a290ed6a91" alt=3D"= -Inline image 2" width=3D"2" height=3D"2"></div><div><br></div><div>Troisi= -=C3=A8me image, verte!=C2=B5</div><div><br></div><div><img src=3D"cid:ii_15= -1b51a37e5eb7a6" alt=3D"Inline image 3" width=3D"10" height=3D"10"><br></div= -><div><br></div><div>J'esp=C3=A8re que tout se passera bien.</div>-- <b= -r><div class=3D"gmail_signature">Thibault Delavall=C3=A9e</div> -</div> - ---001a11416b9e9b229805272b7051-- ---001a11416b9e9b229a05272b7052 -Content-Type: image/gif; name="=?UTF-8?B?b3JhbmfDqWUuZ2lm?=" -Content-Disposition: inline; filename="=?UTF-8?B?b3JhbmfDqWUuZ2lm?=" -Content-Transfer-Encoding: base64 -Content-ID: <ii_151b519fc025fdd3> -X-Attachment-Id: ii_151b519fc025fdd3 - -R0lGODdhAgACALMAAAAAAP///wAAAP//AP8AAP+AAAD/AAAAAAAA//8A/wAAAAAAAAAAAAAAAAAA -AAAAACwAAAAAAgACAAAEA7DIEgA7 ---001a11416b9e9b229a05272b7052 -Content-Type: image/gif; name="=?UTF-8?B?dmVydGUhwrUuZ2lm?=" -Content-Disposition: inline; filename="=?UTF-8?B?dmVydGUhwrUuZ2lm?=" -Content-Transfer-Encoding: base64 -Content-ID: <ii_151b51a37e5eb7a6> -X-Attachment-Id: ii_151b51a37e5eb7a6 - -R0lGODlhCgAKALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD/ -/////ywAAAAACgAKAAAEClDJSau9OOvNe44AOw== ---001a11416b9e9b229a05272b7052 -Content-Type: image/gif; name="=?UTF-8?B?cm9zYcOnw6llLmdpZg==?=" -Content-Disposition: inline; filename="=?UTF-8?B?cm9zYcOnw6llLmdpZg==?=" -Content-Transfer-Encoding: base64 -Content-ID: <ii_151b51a290ed6a91> -X-Attachment-Id: ii_151b51a290ed6a91 - -R0lGODdhAgACALMAAAAAAP///wAAAP//AP8AAP+AAAD/AAAAAAAA//8A/wAAAP+AgAAAAAAAAAAA -AAAAACwAAAAAAgACAAAEA3DJFQA7 ---001a11416b9e9b229a05272b7052-- -"""
\ No newline at end of file diff --git a/addons/mail/tests/models/__init__.py b/addons/mail/tests/models/__init__.py deleted file mode 100644 index 420d064776c..00000000000 --- a/addons/mail/tests/models/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import test_mail_models
\ No newline at end of file diff --git a/addons/mail/tests/models/test_mail_models.py b/addons/mail/tests/models/test_mail_models.py deleted file mode 100644 index a45602bf6d5..00000000000 --- a/addons/mail/tests/models/test_mail_models.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import fields, models - - -class MailTestSimple(models.Model): - """ A very simple model only inheriting from mail.thread when only - communication history is necessary. """ - _description = 'Simple Chatter Model' - _name = 'mail.test.simple' - _inherit = ['mail.thread'] - - name = fields.Char() - email_from = fields.Char() - - -class MailTestStandard(models.Model): - """ This model can be used in tests when automatic subscription and simple - tracking is necessary. Most features are present in a simple way. """ - _description = 'Standard Chatter Model' - _name = 'mail.test.track' - _inherit = ['mail.thread'] - - name = fields.Char() - email_from = fields.Char() - user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange') - umbrella_id = fields.Many2one('mail.test', track_visibility='onchange') - - -class MailTestActivity(models.Model): - """ This model can be used to test activities in addition to simple chatter - features. """ - _description = 'Activity Model' - _name = 'mail.test.activity' - _inherit = ['mail.thread', 'mail.activity.mixin'] - - name = fields.Char() - email_from = fields.Char() - - -class MailTestFull(models.Model): - """ This model can be used in tests when complex chatter features are - required like modeling tasks or tickets. """ - _description = 'Full Chatter Model' - _name = 'mail.test.full' - _inherit = ['mail.thread'] - - name = fields.Char() - email_from = fields.Char(track_visibility='always') - count = fields.Integer(default=1) - datetime = fields.Datetime(default=fields.Datetime.now) - mail_template = fields.Many2one('mail.template', 'Template') - customer_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange') - user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange') - umbrella_id = fields.Many2one('mail.test', track_visibility='onchange') - - def _track_template(self, tracking): - res = super(MailTestFull, self)._track_template(tracking) - record = self[0] - changes, tracking_value_ids = tracking[record.id] - if 'customer_id' in changes and record.mail_template: - res['customer_id'] = (record.mail_template, {'composition_mode': 'mass_mail'}) - elif 'datetime' in changes: - res['datetime'] = ('mail.track_template', {'composition_mode': 'mass_mail'}) - return res - - def _track_subtype(self, init_values): - self.ensure_one() - if 'umbrella_id' in init_values and self.umbrella_id: - return 'mail.track_subtype_umbrella' - return super(MailTestFull, self)._track_subtype(init_values) - - -class MailTestAlias(models.Model): - """ This model can be used in tests when umbrella records like projects - or teams are required. """ - _description = 'Alias Chatter Model' - _name = 'mail.test' - _mail_post_access = 'read' - _inherit = ['mail.thread', 'mail.alias.mixin'] - - name = fields.Char() - description = fields.Text() - alias_id = fields.Many2one( - 'mail.alias', 'Alias', - delegate=True) - - def get_alias_model_name(self, vals): - return vals.get('alias_model', 'mail.test') - - def get_alias_values(self): - self.ensure_one() - res = super(MailTestAlias, self).get_alias_values() - res['alias_force_thread_id'] = self.id - res['alias_parent_thread_id'] = self.id - return res diff --git a/addons/mail/tests/test_discuss.py b/addons/mail/tests/test_discuss.py deleted file mode 100644 index ea155bf3232..00000000000 --- a/addons/mail/tests/test_discuss.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo.addons.mail.tests.common import BaseFunctionalTest, TestRecipients, MockEmails - - -class TestChatterTweaks(BaseFunctionalTest, TestRecipients): - - 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_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')) - - 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) - - -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'}) - - 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_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]) - - 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_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 - msg.toggle_message_starred() - self.assertTrue(msg.starred) - - # Employee set as starred - msg_emp.toggle_message_starred() - self.assertTrue(msg_emp.starred) - - # Do: Admin unstars msg - msg.toggle_message_starred() - self.assertFalse(msg.starred) - self.assertTrue(msg_emp.starred) - - -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_invite.py b/addons/mail/tests/test_invite.py deleted file mode 100644 index bb50b3f1dc9..00000000000 --- a/addons/mail/tests/test_invite.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo.addons.mail.tests import common -from odoo.tools import mute_logger - - -class TestInvite(common.BaseFunctionalTest, common.MockEmails): - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_invite_email(self): - test_partner = self.env['res.partner'].with_context(self._quick_create_ctx).create({ - 'name': 'Valid Lelitre', - 'email': 'valid.lelitre@agrolait.com'}) - - mail_invite = self.env['mail.wizard.invite'].with_context({ - 'default_res_model': 'mail.test.simple', - 'default_res_id': self.test_record.id - }).sudo(self.user_employee.id).create({ - 'partner_ids': [(4, test_partner.id), (4, self.user_admin.partner_id.id)], - 'send_mail': True}) - mail_invite.add_followers() - - # check added followers and that emails were sent - self.assertEqual(self.test_record.message_partner_ids, - test_partner | self.user_admin.partner_id) - self.assertEqual(self.test_record.message_follower_ids.mapped('channel_id'), - self.env['mail.channel']) - self.assertEqual(len(self._mails), 2) diff --git a/addons/mail/tests/test_ir_actions.py b/addons/mail/tests/test_ir_actions.py deleted file mode 100644 index 543c27d4a21..00000000000 --- a/addons/mail/tests/test_ir_actions.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo.addons.base.tests.test_ir_actions import TestServerActionsBase - - -class TestServerActionsEmail(TestServerActionsBase): - - def test_action_email(self): - email_template = self.env['mail.template'].create({ - 'name': 'TestTemplate', - 'email_from': 'myself@example.com', - 'email_to': 'brigitte@example.com', - 'partner_to': '%s' % self.test_partner.id, - 'model_id': self.res_partner_model.id, - 'subject': 'About ${object.name}', - 'body_html': '<p>Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}</p>', - }) - self.action.write({'state': 'email', 'template_id': email_template.id}) - self.action.with_context(self.context).run() - # check an email is waiting for sending - mail = self.env['mail.mail'].search([('subject', '=', 'About TestingPartner')]) - self.assertEqual(len(mail), 1) - # check email content - self.assertEqual(mail.body, '<p>Dear TestingPartner, your parent is False</p>') - - def test_action_followers(self): - self.test_partner.message_unsubscribe(self.test_partner.message_partner_ids.ids) - self.action.write({ - 'state': 'followers', - 'partner_ids': [(4, self.env.ref('base.partner_root').id), (4, self.env.ref('base.partner_demo').id)], - 'channel_ids': [(4, self.env.ref('mail.channel_all_employees').id)] - }) - self.action.with_context(self.context).run() - self.assertEqual(self.test_partner.message_partner_ids, self.env.ref('base.partner_root') | self.env.ref('base.partner_demo')) - self.assertEqual(self.test_partner.message_channel_ids, self.env.ref('mail.channel_all_employees')) diff --git a/addons/mail/tests/test_mail_activity.py b/addons/mail/tests/test_mail_activity.py deleted file mode 100644 index 637bd05c021..00000000000 --- a/addons/mail/tests/test_mail_activity.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from datetime import date -from dateutil.relativedelta import relativedelta - -from odoo import exceptions -from odoo.addons.mail.tests.common import BaseFunctionalTest -from odoo.tools import mute_logger - - -class TestMailActivity(BaseFunctionalTest): - - @classmethod - def setUpClass(cls): - super(TestMailActivity, cls).setUpClass() - cls.test_record = cls.env['mail.test.activity'].create({'name': 'Test'}) - - def test_activity_flow_employee(self): - with self.sudoAs('ernest'): - test_record = self.env['mail.test.activity'].browse(self.test_record.id) - self.assertEqual(test_record.activity_ids, self.env['mail.activity']) - - # employee record an activity and check the deadline - self.env['mail.activity'].create({ - 'summary': 'Test Activity', - 'date_deadline': date.today() + relativedelta(days=1), - 'activity_type_id': self.env.ref('mail.mail_activity_data_email').id, - 'res_model_id': self.env['ir.model']._get(test_record._name).id, - 'res_id': test_record.id, - }) - self.assertEqual(test_record.activity_summary, 'Test Activity') - self.assertEqual(test_record.activity_state, 'planned') - - test_record.activity_ids.write({'date_deadline': date.today() - relativedelta(days=1)}) - test_record.invalidate_cache() # TDE note: should not have to do it I think - self.assertEqual(test_record.activity_state, 'overdue') - - test_record.activity_ids.write({'date_deadline': date.today()}) - test_record.invalidate_cache() # TDE note: should not have to do it I think - self.assertEqual(test_record.activity_state, 'today') - - # activity is done - test_record.activity_ids.action_feedback(feedback='So much feedback') - self.assertEqual(test_record.activity_ids, self.env['mail.activity']) - self.assertEqual(test_record.message_ids[0].subtype_id, self.env.ref('mail.mt_activities')) - - def test_activity_flow_portal(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.sudoAs('chell'): - test_record = self.env['mail.test.activity'].browse(self.test_record.id) - # test_record.name - # test_record.read() - with self.assertRaises(exceptions.AccessError): - self.env['mail.activity'].create({ - 'summary': 'Test Activity', - 'activity_type_id': self.env.ref('mail.mail_activity_data_email').id, - 'res_model_id': self.env['ir.model']._get(test_record._name).id, - 'res_id': test_record.id, - }) - # self.assertEqual(test_record.activity_ids, self.env['mail.activity']) diff --git a/addons/mail/tests/test_mail_channel.py b/addons/mail/tests/test_mail_channel.py deleted file mode 100644 index e06b10eeaa8..00000000000 --- a/addons/mail/tests/test_mail_channel.py +++ /dev/null @@ -1,197 +0,0 @@ -# -*- coding: utf-8 -*- - -from email.utils import formataddr - -from odoo.addons.mail.tests import common -from odoo.exceptions import AccessError, except_orm -from odoo.tools import mute_logger - - -class TestChannelAccessRights(common.BaseFunctionalTest, common.MockEmails): - - @classmethod - def setUpClass(cls): - super(TestChannelAccessRights, cls).setUpClass() - Channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx) - - Users = cls.env['res.users'].with_context(cls._quick_create_user_ctx) - cls.user_public = Users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [cls.env.ref('base.group_public').id])]}) - cls.user_portal = Users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])]}) - - # Pigs: base group for tests - cls.group_pigs = Channel.create({ - 'name': 'Pigs', - 'public': 'groups', - 'group_public_id': cls.env.ref('base.group_user').id}) - # Jobs: public group - cls.group_public = Channel.create({ - 'name': 'Jobs', - 'description': 'NotFalse', - 'public': 'public'}) - # Private: private group - cls.group_private = Channel.create({ - 'name': 'Private', - 'public': 'private'}) - - @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_access_rights_public(self): - # Read public group -> ok - self.group_public.sudo(self.user_public).read() - - # Read Pigs -> ko, restricted to employees - # TODO: Change the except_orm to Warning ( Because here it's call check_access_rule - # which still generate exception in except_orm.So we need to change all - # except_orm to warning in mail module.) - with self.assertRaises(except_orm): - self.group_pigs.sudo(self.user_public).read() - - # Read a private group when being a member: ok - self.group_private.write({'channel_partner_ids': [(4, self.user_public.partner_id.id)]}) - self.group_private.sudo(self.user_public).read() - - # Create group: ko, no access rights - with self.assertRaises(AccessError): - self.env['mail.channel'].sudo(self.user_public).create({'name': 'Test'}) - - # Update group: ko, no access rights - with self.assertRaises(AccessError): - self.group_public.sudo(self.user_public).write({'name': 'Broutouschnouk'}) - - # Unlink group: ko, no access rights - with self.assertRaises(AccessError): - self.group_public.sudo(self.user_public).unlink() - - @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models', 'odoo.models.unlink') - def test_access_rights_groups(self): - # Employee read employee-based group: ok - # TODO Change the except_orm to Warning - self.group_pigs.sudo(self.user_employee).read() - - # Employee can create a group - self.env['mail.channel'].sudo(self.user_employee).create({'name': 'Test'}) - - # Employee update employee-based group: ok - self.group_pigs.sudo(self.user_employee).write({'name': 'modified'}) - - # Employee unlink employee-based group: ok - self.group_pigs.sudo(self.user_employee).unlink() - - # Employee cannot read a private group - with self.assertRaises(except_orm): - self.group_private.sudo(self.user_employee).read() - - # Employee cannot write on private - with self.assertRaises(AccessError): - self.group_private.sudo(self.user_employee).write({'name': 're-modified'}) - - @mute_logger('odoo.addons.base.ir.ir_model', 'odoo.models') - def test_access_rights_followers_ko(self): - with self.assertRaises(AccessError): - self.group_private.sudo(self.user_portal).name - - def test_access_rights_followers_portal(self): - # Do: Chell is added into Pigs members and browse it -> ok for messages, ko for partners (no read permission) - self.group_private.write({'channel_partner_ids': [(4, self.user_portal.partner_id.id)]}) - chell_pigs = self.group_private.sudo(self.user_portal) - trigger_read = chell_pigs.name - for message in chell_pigs.message_ids: - trigger_read = message.subject - for partner in chell_pigs.message_partner_ids: - if partner.id == self.user_portal.partner_id.id: - # Chell can read her own partner record - continue - # TODO Change the except_orm to Warning - with self.assertRaises(except_orm): - trigger_read = partner.name - - -class TestChannelFeatures(common.BaseFunctionalTest, common.MockEmails): - - @classmethod - def setUpClass(cls): - super(TestChannelFeatures, cls).setUpClass() - cls.test_channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx).create({ - 'name': 'Test', - 'description': 'Description', - 'alias_name': 'test', - 'public': 'public', - }) - cls.test_partner = cls.env['res.partner'].with_context(cls._quick_create_ctx).create({ - 'name': 'Test Partner', - 'email': 'test@example.com', - }) - - def _join_channel(self, channel, partners): - for partner in partners: - channel.write({'channel_last_seen_partner_ids': [(0, 0, {'partner_id': partner.id})]}) - channel.invalidate_cache() - - def _leave_channel(self, channel, partners): - for partner in partners: - channel._action_unfollow(partner) - - def test_channel_listeners(self): - self.assertEqual(self.test_channel.message_channel_ids, self.test_channel) - self.assertEqual(self.test_channel.message_partner_ids, self.env['res.partner']) - self.assertEqual(self.test_channel.channel_partner_ids, self.env['res.partner']) - - self._join_channel(self.test_channel, self.test_partner) - self.assertEqual(self.test_channel.message_channel_ids, self.test_channel) - self.assertEqual(self.test_channel.message_partner_ids, self.env['res.partner']) - self.assertEqual(self.test_channel.channel_partner_ids, self.test_partner) - - self._leave_channel(self.test_channel, self.test_partner) - self.assertEqual(self.test_channel.message_channel_ids, self.test_channel) - self.assertEqual(self.test_channel.message_partner_ids, self.env['res.partner']) - self.assertEqual(self.test_channel.channel_partner_ids, self.env['res.partner']) - - def test_channel_post_nofollow(self): - self.test_channel.message_post(body='Test', message_type='comment', subtype='mt_comment') - self.assertEqual(self.test_channel.message_channel_ids, self.test_channel) - self.assertEqual(self.test_channel.message_partner_ids, self.env['res.partner']) - - @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - def test_channel_mailing_list_recipients(self): - """ Posting a message on a mailing list should send one email to all recipients """ - self.env['ir.config_parameter'].set_param('mail.catchall.domain', 'schlouby.fr') - self.test_channel.write({'email_send': True}) - self._join_channel(self.test_channel, self.user_employee.partner_id | self.test_partner) - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') - - self.assertEqual(len(self._mails), 1) - for email in self._mails: - self.assertEqual( - set(email['email_to']), - set([formataddr((self.user_employee.name, self.user_employee.email)), formataddr((self.test_partner.name, self.test_partner.email))])) - - @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - def test_channel_chat_recipients(self): - """ Posting a message on a chat should not send emails """ - self.env['ir.config_parameter'].set_param('mail.catchall.domain', 'schlouby.fr') - self.test_channel.write({'email_send': False}) - self._join_channel(self.test_channel, self.user_employee.partner_id | self.test_partner) - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') - - self.assertEqual(len(self._mails), 0) - - @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') - def test_channel_classic_recipients(self): - """ Posting a message on a classic channel should work like classic post """ - self.test_channel.write({'alias_name': False}) - self.test_channel.message_subscribe([self.user_employee.partner_id.id, self.test_partner.id]) - self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment') - - sent_emails = self._mails - self.assertEqual(len(sent_emails), 2) - for email in sent_emails: - self.assertIn( - email['email_to'][0], - [formataddr((self.user_employee.name, self.user_employee.email)), formataddr((self.test_partner.name, self.test_partner.email))]) diff --git a/addons/mail/tests/test_mail_followers.py b/addons/mail/tests/test_mail_followers.py deleted file mode 100644 index 887f9140c2b..00000000000 --- a/addons/mail/tests/test_mail_followers.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from psycopg2 import IntegrityError - -from odoo.addons.mail.tests import common -from odoo.tools.misc import mute_logger - - -class BaseFollowersTest(common.BaseFunctionalTest): - - @classmethod - def setUpClass(cls): - super(BaseFollowersTest, cls).setUpClass() - Subtype = cls.env['mail.message.subtype'] - cls.mt_mg_def = Subtype.create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test.simple'}) - cls.mt_cl_def = Subtype.create({'name': 'mt_cl_def', 'default': True, 'res_model': 'mail.test'}) - cls.mt_al_def = Subtype.create({'name': 'mt_al_def', 'default': True, 'res_model': False}) - cls.mt_mg_nodef = Subtype.create({'name': 'mt_mg_nodef', 'default': False, 'res_model': 'mail.test.simple'}) - cls.mt_al_nodef = Subtype.create({'name': 'mt_al_nodef', 'default': False, 'res_model': False}) - cls.mt_mg_def_int = cls.env['mail.message.subtype'].create({'name': 'mt_mg_def', 'default': True, 'res_model': 'mail.test.simple', 'internal': True}) - cls.default_group_subtypes = Subtype.search([('default', '=', True), '|', ('res_model', '=', 'mail.test.simple'), ('res_model', '=', False)]) - cls.default_group_subtypes_portal = Subtype.search([('internal', '=', False), ('default', '=', True), '|', ('res_model', '=', 'mail.test.simple'), ('res_model', '=', False)]) - - def test_field_message_is_follower(self): - test_record = self.test_record.sudo(self.user_employee) - followed_before = test_record.search([('message_is_follower', '=', True)]) - self.assertFalse(test_record.message_is_follower) - test_record.message_subscribe_users(user_ids=[self.user_employee.id]) - followed_after = test_record.search([('message_is_follower', '=', True)]) - self.assertTrue(test_record.message_is_follower) - self.assertEqual(followed_before | test_record, followed_after) - - def test_field_followers(self): - test_record = self.test_record.sudo(self.user_employee) - test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id, self.user_admin.partner_id.id], channel_ids=[self.channel_listen.id]) - followers = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test.simple'), - ('res_id', '=', test_record.id)]) - self.assertEqual(followers, test_record.message_follower_ids) - self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) - self.assertEqual(test_record.message_channel_ids, self.channel_listen) - - def test_followers_subtypes_default(self): - test_record = self.test_record.sudo(self.user_employee) - test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id]) - self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test.simple'), - ('res_id', '=', test_record.id), - ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(follower, test_record.message_follower_ids) - self.assertEqual(follower.subtype_ids, self.default_group_subtypes) - - def test_followers_subtypes_default_internal(self): - user_portal = 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])] - }) - - test_record = self.test_record.sudo(self.user_employee) - test_record.message_subscribe(partner_ids=[user_portal.partner_id.id]) - self.assertEqual(test_record.message_partner_ids, user_portal.partner_id) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test.simple'), - ('res_id', '=', test_record.id), - ('partner_id', '=', user_portal.partner_id.id)]) - self.assertEqual(follower.subtype_ids, self.default_group_subtypes_portal) - - def test_followers_subtypes_specified(self): - test_record = self.test_record.sudo(self.user_employee) - test_record.message_subscribe(partner_ids=[self.user_employee.partner_id.id], subtype_ids=[self.mt_mg_nodef.id]) - self.assertEqual(test_record.message_partner_ids, self.user_employee.partner_id) - follower = self.env['mail.followers'].search([ - ('res_model', '=', 'mail.test.simple'), - ('res_id', '=', test_record.id), - ('partner_id', '=', self.user_employee.partner_id.id)]) - self.assertEqual(follower, test_record.message_follower_ids) - self.assertEqual(follower.subtype_ids, self.mt_mg_nodef) - - def test_followers_multiple_subscription(self): - test_record = self.test_record.sudo(self.user_employee) - - test_record.message_subscribe(partner_ids=[self.user_admin.partner_id.id], subtype_ids=[self.mt_mg_nodef.id]) - self.assertEqual(test_record.message_partner_ids, self.user_admin.partner_id) - self.assertEqual(test_record.message_channel_ids, self.env['mail.channel']) - self.assertEqual(test_record.message_follower_ids.subtype_ids, self.mt_mg_nodef) - - test_record.message_subscribe(partner_ids=[self.user_admin.partner_id.id], subtype_ids=[self.mt_mg_nodef.id, self.mt_al_nodef.id]) - self.assertEqual(test_record.message_partner_ids, self.user_admin.partner_id) - self.assertEqual(test_record.message_channel_ids, self.env['mail.channel']) - self.assertEqual(test_record.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_admin.partner_id).subtype_ids, self.mt_mg_nodef | self.mt_al_nodef) - - def test_followers_no_DID(self): - """Test that a follower cannot suffer from dissociative identity disorder. - It cannot be both a partner and a channel. - """ - with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): - self.env['mail.followers'].create({ - 'res_model': self.test_record._name, - 'res_id': self.test_record.id, - 'partner_id': self.user_employee.partner_id.id, - 'channel_id': self.channel_listen.id, - }) - - -class AdvancedFollowersTest(common.BaseFunctionalTest): - @classmethod - def setUpClass(cls): - super(AdvancedFollowersTest, cls).setUpClass() - - cls.user_portal = cls.env['res.users'].with_context(cls._quick_create_user_ctx).create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])], - }) - - cls.test_track = cls.env['mail.test.track'].sudo(cls.user_employee).create({ - 'name': 'Test', - }) - - Subtype = cls.env['mail.message.subtype'] - cls.sub_nodef = Subtype.create({'name': 'Sub NoDefault', 'default': False, 'res_model': 'mail.test'}) - cls.sub_umb1 = Subtype.create({'name': 'Sub Umbrella1', 'default': False, 'res_model': 'mail.test.track'}) - cls.sub_umb2 = Subtype.create({'name': 'Sub Umbrella2', 'default': False, 'res_model': 'mail.test.track'}) - cls.umb_def = Subtype.create({'name': 'Umbrella Default', 'default': True, 'res_model': 'mail.test'}) - # create subtypes for auto subscription from umbrella to sub records - cls.umb_sub_def = Subtype.create({ - 'name': 'Umbrella Sub1', 'default': True, 'res_model': 'mail.test', - 'parent_id': cls.sub_umb1.id, 'relation_field': 'umbrella_id'}) - cls.umb_sub_nodef = Subtype.create({ - 'name': 'Umbrella Sub2', 'default': False, 'res_model': 'mail.test', - 'parent_id': cls.sub_umb2.id, 'relation_field': 'umbrella_id'}) - - def test_auto_subscribe_create(self): - """ Creator of records are automatically added as followers """ - self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id) - - def test_auto_subscribe_post(self): - """ People posting a message are automatically added as followers """ - self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='comment') - self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) - - def test_auto_subscribe_post_email(self): - """ People posting an email are automatically added as followers """ - self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='email') - self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id | self.user_admin.partner_id) - - def test_auto_subscribe_not_on_notification(self): - """ People posting an automatic notification are not subscribed """ - self.test_track.sudo(self.user_admin).message_post(body='Coucou hibou', message_type='notification') - self.assertEqual(self.test_track.message_partner_ids, self.user_employee.partner_id) - - def test_auto_subscribe_responsible(self): - """ Responsibles are tracked and added as followers """ - sub = self.env['mail.test.track'].sudo(self.user_employee).create({ - 'name': 'Test', - 'user_id': self.user_admin.id, - }) - - self.assertEqual(sub.message_partner_ids, (self.user_employee.partner_id | self.user_admin.partner_id)) - - def test_auto_subscribe_defaults(self): - """ Test auto subscription based on an umbrella record. This mimics - the behavior of addons like project and task where subscribing to - some project's subtypes automatically subscribe the follower to its tasks. - - Functional rules applied here - - * subscribing to an umbrella subtype with parent_id / relation_field set - automatically create subscription with matching subtypes - * subscribing to a sub-record as creator applies default subtype values - * portal user should not have access to internal subtypes - """ - umbrella = self.env['mail.test'].with_context(self._quick_create_ctx).create({ - 'name': 'Project-Like', - }) - - umbrella.message_subscribe(partner_ids=[self.user_portal.partner_id.id]) - self.assertEqual(umbrella.message_partner_ids, self.user_portal.partner_id) - - sub1 = self.env['mail.test.track'].sudo(self.user_employee).create({ - 'name': 'Task-Like Test', - 'umbrella_id': umbrella.id, - }) - - all_defaults = self.env['mail.message.subtype'].search([('default', '=', True), '|', ('res_model', '=', 'mail.test.full'), ('res_model', '=', False)]) - external_defaults = all_defaults.filtered(lambda subtype: not subtype.internal) - - self.assertEqual(sub1.message_partner_ids, self.user_portal.partner_id | self.user_employee.partner_id) - self.assertEqual( - sub1.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_portal.partner_id).subtype_ids, - external_defaults | self.sub_umb1) - self.assertEqual( - sub1.message_follower_ids.filtered(lambda fol: fol.partner_id == self.user_employee.partner_id).subtype_ids, - all_defaults) diff --git a/addons/mail/tests/test_mail_gateway.py b/addons/mail/tests/test_mail_gateway.py deleted file mode 100644 index 575972d4adf..00000000000 --- a/addons/mail/tests/test_mail_gateway.py +++ /dev/null @@ -1,512 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -import socket - -from email.utils import formataddr - -from odoo.addons.mail.tests.data.test_mail_data import MAIL_TEMPLATE, MAIL_TEMPLATE_PLAINTEXT, MAIL_MULTIPART_MIXED, MAIL_MULTIPART_MIXED_TWO, MAIL_MULTIPART_IMAGE -from odoo.addons.mail.tests.common import BaseFunctionalTest, MockEmails -from odoo.tools import mute_logger - - -class TestEmailParsing(BaseFunctionalTest, MockEmails): - - @mute_logger('odoo.addons.mail.models.mail_thread') - def test_message_parse(self): - pass - - def test_message_parse_body(self): - # test pure plaintext - plaintext = self.format(MAIL_TEMPLATE_PLAINTEXT, email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>') - res = self.env['mail.thread'].message_parse(plaintext) - self.assertIn('Please call me as soon as possible this afternoon!', res['body']) - - # test multipart / text and html -> html has priority - multipart = self.format(MAIL_TEMPLATE, email_from='Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>') - res = self.env['mail.thread'].message_parse(multipart) - self.assertIn('<p>Please call me as soon as possible this afternoon!</p>', res['body']) - - # test multipart / mixed - res = self.env['mail.thread'].message_parse(MAIL_MULTIPART_MIXED) - self.assertNotIn( - 'Should create a multipart/mixed: from gmail, *bold*, with attachment', res['body'], - 'message_parse: text version should not be in body after parsing multipart/mixed') - self.assertIn( - '<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>', res['body'], - 'message_parse: html version should be in body after parsing multipart/mixed') - - res = self.env['mail.thread'].message_parse(MAIL_MULTIPART_MIXED_TWO) - self.assertNotIn('First and second part', res['body'], - 'message_parse: text version should not be in body after parsing multipart/mixed') - self.assertIn('First part', res['body'], - 'message_parse: first part of the html version should be in body after parsing multipart/mixed') - self.assertIn('Second part', res['body'], - 'message_parse: second part of the html version should be in body after parsing multipart/mixed') - - -class TestMailgateway(BaseFunctionalTest, MockEmails): - - @classmethod - def setUpClass(cls): - super(TestMailgateway, cls).setUpClass() - mail_test_simple_model = cls.env['ir.model']._get('mail.test.simple') - - cls.partner_1 = cls.env['res.partner'].with_context(cls._quick_create_ctx).create({ - 'name': 'Valid Lelitre', - 'email': 'valid.lelitre@agrolait.com', - }) - # groups@.. will cause the creation of new mail.test.simple - cls.alias = cls.env['mail.alias'].create({ - 'alias_name': 'groups', - 'alias_user_id': False, - 'alias_model_id': mail_test_simple_model.id, - 'alias_contact': 'everyone'}) - - # Set a first message on public group to test update and hierarchy - cls.fake_email = cls.env['mail.message'].create({ - 'model': 'mail.test.simple', - 'res_id': cls.test_record.id, - 'subject': 'Public Discussion', - 'message_type': 'email', - 'author_id': cls.partner_1.id, - 'message_id': '<123456-openerp-%s-mail.test.simple@%s>' % (cls.test_record.id, socket.gethostname()), - }) - - @mute_logger('odoo.addons.mail.models.mail_thread') - def test_message_process_cid(self): - record = self.format_and_process(MAIL_MULTIPART_IMAGE, to='groups@example.com') - message = record.message_ids[0] - for attachment in message.attachment_ids: - self.assertIn('/web/image/%s' % attachment.id, message.body) - - def test_message_process_followers(self): - pass - # TODO : the author of a message post should be added as follower - # currently it is not the case as otherwise Administrator would be follower of a lot of stuff - # this is a bug with mail_create_nosubscribe -> should be changed in master - # self.assertEqual(record.message_partner_ids, self.partner_1, - # 'message_process: recognized email -> added as follower') - - # TODO : the author of a message post on mail.test should not be added as follower - # Test: author (and not recipient) added as follower - # self.assertEqual(self.test_public.message_partner_ids, self.partner_1 | self.partner_2, - # 'message_process: after reply, group should have 2 followers') - # self.assertEqual(self.test_public.message_channel_ids, self.env['mail.test'], - # 'message_process: after reply, group should have 2 followers (0 channels)') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_alias_basic(self): - """ Test details of created message going through mailgateway """ - record = self.format_and_process(MAIL_TEMPLATE, subject='Specific') - - # Test: one group created by mailgateway administrator as user_id is not set - self.assertEqual(len(record), 1, 'message_process: a new mail.test should have been created') - res = record.get_metadata()[0].get('create_uid') or [None] - self.assertEqual(res[0], self.env.uid) - - # Test: one message that is the incoming email - self.assertEqual(len(record.message_ids), 1) - msg = record.message_ids[0] - self.assertEqual(msg.subject, 'Specific') - self.assertIn('Please call me as soon as possible this afternoon!', msg.body) - self.assertEqual(msg.message_type, 'email') - self.assertEqual(msg.subtype_id, self.env.ref('mail.mt_comment')) - - # -------------------------------------------------- - # Author recognition - # -------------------------------------------------- - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_email_email_from(self): - """ Incoming email: not recognized author: email_from, no author_id, no followers """ - email_from = 'Sylvie Lelitre <test.sylvie.lelitre@agrolait.com>' - - record = self.format_and_process(MAIL_TEMPLATE, email_from=email_from) - self.assertFalse(record.message_ids[0].author_id, 'message_process: unrecognized email -> no author_id') - self.assertEqual(record.message_ids[0].email_from, email_from) - self.assertEqual(len(record.message_partner_ids), 0, - 'message_process: newly create group should not have any follower') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_email_author(self): - """ Incoming email: recognized author: email_from, author_id, added as follower """ - record = self.format_and_process(MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email))) - - self.assertEqual(record.message_ids[0].author_id, self.partner_1, - 'message_process: recognized email -> author_id') - self.assertEqual(record.message_ids[0].email_from, formataddr((self.partner_1.name, self.partner_1.email))) - self.assertEqual(len(self._mails), 0, 'No notification / bounce should be sent') - - # -------------------------------------------------- - # Alias configuration - # -------------------------------------------------- - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_alias_user_id(self): - """ Test alias ownership """ - self.alias.write({'alias_user_id': self.user_employee.id}) - - record = self.format_and_process(MAIL_TEMPLATE) - self.assertEqual(len(record), 1) - res = record.get_metadata()[0].get('create_uid') or [None] - self.assertEqual(res[0], self.user_employee.id) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_alias_everyone(self): - """ Incoming email: everyone: new record + message_new """ - self.alias.write({'alias_contact': 'everyone'}) - - record = self.format_and_process(MAIL_TEMPLATE, subject='Specific') - self.assertEqual(len(record), 1) - self.assertEqual(len(record.message_ids), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') - def test_message_process_alias_partners_bounce(self): - """ Incoming email from an unknown partner on a Partners only alias -> bounce + test bounce email """ - self.env['ir.config_parameter'].set_param('mail.bounce.alias', 'bounce.test') - self.env['ir.config_parameter'].set_param('mail.catchall.domain', 'test.com') - self.alias.write({'alias_contact': 'partners'}) - - # Test: no group created, email bounced - record = self.format_and_process(MAIL_TEMPLATE, subject='Should Bounce') - self.assertTrue(len(record) == 0) - self.assertEqual(len(self._mails), 1, - 'message_process: incoming email on Partners alias should send a bounce email') - # Test bounce email - self.assertEqual(self._mails[0].get('subject'), 'Re: Should Bounce') - self.assertEqual(self._mails[0].get('email_to')[0], 'whatever-2a840@postmaster.twitter.com') - self.assertEqual(self._mails[0].get('email_from'), formataddr(('MAILER-DAEMON', 'bounce.test@test.com'))) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') - def test_message_process_alias_followers_bounce(self): - """ Incoming email from unknown partner / not follower partner on a Followers only alias -> bounce """ - self.alias.write({ - 'alias_contact': 'followers', - 'alias_parent_model_id': self.env['ir.model']._get('mail.test.simple').id, - 'alias_parent_thread_id': self.test_record.id, - }) - - # Test: unknown on followers alias -> bounce - record = self.format_and_process(MAIL_TEMPLATE, to='groups@example.com, other@gmail.com') - self.assertEqual(len(record), 0, 'message_process: should have bounced') - self.assertEqual(len(self._mails), 1, - 'message_process: incoming email on Followers alias should send a bounce email') - - # Test: partner on followers alias -> bounce - self._init_mock_build_email() - record = self.format_and_process(MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email))) - self.assertTrue(len(record) == 0, 'message_process: should have bounced') - self.assertEqual(len(self._mails), 1, - 'message_process: incoming email on Followers alias should send a bounce email') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_alias_partner(self): - """ Incoming email from a known partner on a Partners alias -> ok (+ test on alias.user_id) """ - self.alias.write({'alias_contact': 'partners'}) - record = self.format_and_process(MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email))) - - # Test: one group created by alias user - self.assertEqual(len(record), 1) - self.assertEqual(len(record.message_ids), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_alias_followers(self): - """ Incoming email from a parent document follower on a Followers only alias -> ok """ - self.alias.write({ - 'alias_contact': 'followers', - 'alias_parent_model_id': self.env['ir.model']._get('mail.test.simple').id, - 'alias_parent_thread_id': self.test_record.id, - }) - self.test_record.message_subscribe(partner_ids=[self.partner_1.id]) - record = self.format_and_process(MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email))) - - # Test: one group created by Raoul (or Sylvie maybe, if we implement it) - self.assertEqual(len(record), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') - def test_message_process_alias_update(self): - """ Incoming email update discussion + notification email """ - self.alias.write({'alias_force_thread_id': self.test_record.id}) - - self.test_record.message_subscribe(partner_ids=[self.partner_1.id]) - record = self.format_and_process( - MAIL_TEMPLATE, email_from='valid.other@gmail.com', - msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>', - to='groups@example.com>', subject='Re: cats') - - # Test: no new group + new message - self.assertEqual(len(record), 0, 'message_process: alias update should not create new records') - self.assertEqual(len(self.test_record.message_ids), 2) - # Test: sent emails: 1 (Sylvie copy of the incoming email) - self.assertEqual(len(self._mails), 1, - 'message_process: one email should have been generated') - self.assertEqual(formataddr((self.partner_1.name, self.partner_1.email)), self._mails[0].get('email_to')[0], - 'message_process: email should be sent to Sylvie') - - # -------------------------------------------------- - # Thread formation - # -------------------------------------------------- - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_in_reply_to(self): - """ Incoming email using in-rely-to should go into the right destination even with a wrong destination """ - self.format_and_process( - MAIL_TEMPLATE, email_from='valid.other@gmail.com', - msg_id='<1198923581.41972151344608186800.JavaMail.diff1@agrolait.com>', - to='erroneous@example.com>', subject='Re: news', - extra='In-Reply-To:\r\n\t%s\n' % self.fake_email.message_id) - - self.assertEqual(len(self.test_record.message_ids), 2, 'message_process: group should contain one new message') - self.assertEqual(len(self.fake_email.child_ids), 1, 'message_process: new message should be children of the existing one') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_references(self): - """ Incoming email using references should go into the right destination even with a wrong destination """ - init_msg_count = len(self.test_record.message_ids) - self.format_and_process( - MAIL_TEMPLATE, to='erroneous@example.com', - extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id, - msg_id='<1198923581.41972151344608186800.JavaMail.4@agrolait.com>') - - self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1) - self.assertEqual(len(self.fake_email.child_ids), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread') - def test_message_process_references_external(self): - """ Incoming email being a reply to an external email processed by odoo should update thread accordingly """ - new_message_id = '<ThisIsTooMuchFake.MonsterEmail.789@agrolait.com>' - self.fake_email.write({ - 'message_id': new_message_id - }) - init_msg_count = len(self.test_record.message_ids) - self.format_and_process( - MAIL_TEMPLATE, to='erroneous@example.com', - extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id, - msg_id='<1198923581.41972151344608186800.JavaMail.4@agrolait.com>') - - self.assertEqual(len(self.test_record.message_ids), init_msg_count + 1) - self.assertEqual(len(self.fake_email.child_ids), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread') - def test_message_process_references_forward(self): - """ Incoming email using references but with alias forward should not go into references destination """ - new_alias_2 = self.env['mail.alias'].create({ - 'alias_name': 'test', - 'alias_user_id': False, - 'alias_model_id': self.env['ir.model']._get('mail.test').id, - 'alias_contact': 'everyone', - }) - init_msg_count = len(self.test_record.message_ids) - res_test = self.format_and_process( - MAIL_TEMPLATE, to='test@example.com', - subject='My Dear Forward', - extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id, - msg_id='<1198923581.41972151344608186800.JavaMail.4@agrolait.com>', - target_model='mail.test') - - self.assertEqual(len(self.test_record.message_ids), init_msg_count) - self.assertEqual(len(self.fake_email.child_ids), 0) - self.assertEqual(res_test.name, 'My Dear Forward') - self.assertEqual(len(res_test.message_ids), 1) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_references_forward_cc(self): - """ Incoming email using references but with alias forward should not go into references destination """ - self.format_and_process( - MAIL_TEMPLATE, to='erroneous@example.com', cc='test@example.com', - subject='My Dear Forward', - extra='References: <2233@a.com>\r\n\t<3edss_dsa@b.com> %s' % self.fake_email.message_id, - msg_id='<1198923581.41972151344608186800.JavaMail.4@agrolait.com>', - target_model='mail.test.simple') - - self.assertEqual(len(self.test_record.message_ids), 2, 'message_process: group should contain one new message') - self.assertEqual(len(self.fake_email.child_ids), 1, 'message_process: new message should be children of the existing one') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_model_res_id(self): - """ Incoming email with ref holding model / res_id but that does not match any message in the thread: must raise since OpenERP saas-3 """ - self.assertRaises(ValueError, - self.format_and_process, MAIL_TEMPLATE, - email_from=formataddr((self.partner_1.name, self.partner_1.email)), - to='noone@example.com', subject='spam', - extra='In-Reply-To: <12321321-openerp-%d-mail.test.simple@%s>' % (self.test_record.id, socket.gethostname()), - msg_id='<1198923581.41972151344608186802.JavaMail.diff1@agrolait.com>') - - # when 6.1 messages are present, compat mode is available - # Odoo 10 update: compat mode has been removed and should not work anymore - self.fake_email.write({'message_id': False}) - # Do: compat mode accepts partial-matching emails - self.assertRaises( - ValueError, - self.format_and_process, - MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email)), - msg_id='<1.2.JavaMail.new@agrolait.com>', - to='noone@example.com>', subject='spam', - extra='In-Reply-To: <12321321-openerp-%d-mail.test.simple@%s>' % (self.test_record.id, socket.gethostname())) - - # 3''. 6.1 compat mode should not work if hostname does not match! - # Odoo 10 update: compat mode has been removed and should not work anymore and does not depend from hostname - self.assertRaises(ValueError, - self.format_and_process, - MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email)), - msg_id='<1.3.JavaMail.new@agrolait.com>', - to='noone@example.com>', subject='spam', - extra='In-Reply-To: <12321321-openerp-%d-mail.test@neighbor.com>' % self.test_record.id) - - # Test created messages - self.assertEqual(len(self.test_record.message_ids), 1) - self.assertEqual(len(self.test_record.message_ids[0].child_ids), 0) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_duplicate(self): - """ Duplicate emails (same message_id) are not processed """ - self.alias.write({'alias_force_thread_id': self.test_record.id,}) - - # Post a base message - record = self.format_and_process( - MAIL_TEMPLATE, email_from='valid.other@gmail.com', subject='Re: super cats', - msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>') - - # Do: due to some issue, same email goes back into the mailgateway - record = self.format_and_process( - MAIL_TEMPLATE, email_from='other4@gmail.com', subject='Re: news', - msg_id='<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>', - extra='In-Reply-To: <1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>\n') - - # Test: no group 'Re: news' created, still only 1 Frogs group - self.assertEqual(len(record), 0) - - # Test: no new message - self.assertEqual(len(self.test_record.message_ids), 2, 'message_process: message with already existing message_id should not have been duplicated') - # Test: message_id is still unique - no_of_msg = self.env['mail.message'].search_count([('message_id', 'ilike', '<1198923581.41972151344608186799.JavaMail.diff1@agrolait.com>')]) - self.assertEqual(no_of_msg, 1, - 'message_process: message with already existing message_id should not have been duplicated') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_partner_find(self): - """ Finding the partner based on email, based on partner / user / follower """ - self.alias.write({'alias_force_thread_id': self.test_record.id}) - from_1 = self.env['res.partner'].create({'name': 'Brice Denisse', 'email': 'from.test@example.com'}) - - self.format_and_process(MAIL_TEMPLATE, msg_id='<1>', email_from='Brice Denisse <from.test@example.com>') - self.assertEqual(self.test_record.message_ids[0].author_id, from_1) - self.test_record.message_unsubscribe([from_1.id]) - - from_2 = self.env['res.users'].with_context(self._quick_create_user_ctx).create({'name': 'Brice Denisse', 'login': 'B', 'email': 'from.test@example.com'}) - - self.format_and_process(MAIL_TEMPLATE, msg_id='<2>', email_from='Brice Denisse <from.test@example.com>') - self.assertEqual(self.test_record.message_ids[0].author_id, from_2.partner_id) - self.test_record.message_unsubscribe([from_2.partner_id.id]) - - from_3 = self.env['res.partner'].create({'name': 'Brice Denisse', 'email': 'from.test@example.com'}) - self.test_record.message_subscribe([from_3.id]) - - self.format_and_process(MAIL_TEMPLATE, msg_id='<3>', email_from='Brice Denisse <from.test@example.com>') - self.assertEqual(self.test_record.message_ids[0].author_id, from_3) - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_crash_wrong_model(self): - """ Incoming email with model that does not accepts incoming emails must raise """ - self.assertRaises(ValueError, - self.format_and_process, - MAIL_TEMPLATE, - to='noone@example.com', subject='spam', extra='', model='res.country', - msg_id='<1198923581.41972151344608186760.JavaMail.new4@agrolait.com>') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_crash_no_data(self): - """ Incoming email without model and without alias must raise """ - self.assertRaises(ValueError, - self.format_and_process, - MAIL_TEMPLATE, - to='noone@example.com', subject='spam', extra='', - msg_id='<1198923581.41972151344608186760.JavaMail.new5@agrolait.com>') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_fallback(self): - """ Incoming email with model that accepting incoming emails as fallback """ - record = self.format_and_process( - MAIL_TEMPLATE, to='noone@example.com', subject='Spammy', extra='', model='mail.test.simple', - msg_id='<1198923581.41972151344608186760.JavaMail.new6@agrolait.com>') - self.assertEqual(len(record), 1) - self.assertEqual(record._name, 'mail.test.simple') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') - def test_message_process_plain_text(self): - """ Incoming email in plaintext should be stored as html """ - record = self.format_and_process( - MAIL_TEMPLATE_PLAINTEXT, to='groups@example.com', subject='Frogs Return', extra='', - msg_id='<deadcafe.1337@smtp.agrolait.com>') - self.assertEqual(len(record), 1, 'message_process: a new mail.test should have been created') - msg = record.message_ids[0] - # signature recognition -> Sylvie should be in a span - self.assertIn('<pre>\nPlease call me as soon as possible this afternoon!\n<span data-o-mail-quote="1">\n--\nSylvie\n</span></pre>', msg.body, - 'message_process: plaintext incoming email incorrectly parsed') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models', 'odoo.addons.mail.models.mail_mail') - def test_private_discussion(self): - """ Testing private discussion between partners. """ - msg1_pids = [self.env.user.partner_id.id, self.partner_1.id] - - # Do: Raoul writes to Bert and Administrator, with a thread_model in context that should not be taken into account - msg1 = self.env['mail.thread'].with_context({ - 'thread_model': 'mail.test' - }).sudo(self.user_employee).message_post(partner_ids=msg1_pids, subtype='mail.mt_comment') - - # Test: message recipients - msg = self.env['mail.message'].browse(msg1.id) - self.assertEqual(msg.partner_ids, self.env.user.partner_id | self.partner_1, - 'message_post: private discussion: incorrect recipients') - self.assertEqual(msg.model, False, - 'message_post: private discussion: context key "thread_model" not correctly ignored when having no res_id') - # Test: message-id - 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) - self.format_and_process( - MAIL_TEMPLATE, to='not_important@mydomain.com', email_from='valid.lelitre@agrolait.com', - extra='In-Reply-To: %s' % msg.message_id, msg_id='<test30.JavaMail.0@agrolait.com>') - - # Test: last mail_message created - msg2 = self.env['mail.message'].search([], limit=1) - # Test: message recipients - self.assertEqual(msg2.author_id, self.partner_1, - 'message_post: private discussion: wrong author through mailgateway based on email') - self.assertEqual(msg2.partner_ids, self.user_employee.partner_id | self.env.user.partner_id, - 'message_post: private discussion: incorrect recipients when replying') - - # Do: Bert replies through chatter (is a customer) - msg3 = self.env['mail.thread'].message_post(author_id=self.partner_1.id, parent_id=msg1.id, subtype='mail.mt_comment') - - # Test: message recipients - msg = self.env['mail.message'].browse(msg3.id) - self.assertEqual(msg.partner_ids, self.user_employee.partner_id | self.env.user.partner_id, - 'message_post: private discussion: incorrect recipients when replying') - self.assertEqual(msg.needaction_partner_ids, self.user_employee.partner_id | self.env.user.partner_id, - 'message_post: private discussion: incorrect notified recipients when replying') - - @mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models', 'odoo.addons.mail.models.mail_mail') - def test_forward_parent_id(self): - msg = self.test_record.sudo(self.user_employee).message_post(no_auto_thread=True, subtype='mail.mt_comment') - self.assertNotIn(msg.model, msg.message_id) - self.assertNotIn('-%d-' % msg.res_id, msg.message_id) - self.assertIn('reply_to', msg.message_id) - - # forward it to a new thread AND an existing thread - fw_msg_id = '<THIS.IS.A.FW.MESSAGE.1@bert.fr>' - fw_message = MAIL_TEMPLATE.format(to='groups@example.com', - cc='', - subject='FW: Re: 1', - email_from='b.t@example.com', - extra='In-Reply-To: %s' % msg.message_id, - msg_id=fw_msg_id) - self.env['mail.thread'].message_process(None, fw_message) - msg_fw = self.env['mail.message'].search([('message_id', '=', fw_msg_id)]) - self.assertEqual(len(msg_fw), 1) - new_record = self.env['mail.test.simple'].search([('name', "=", msg_fw.subject)]) - self.assertEqual(len(new_record), 1) - self.assertEqual(msg_fw.model, 'mail.test.simple') - self.assertFalse(msg_fw.parent_id) - self.assertTrue(msg_fw.res_id == new_record.id) diff --git a/addons/mail/tests/test_mail_mail.py b/addons/mail/tests/test_mail_mail.py deleted file mode 100644 index 862178c0c7c..00000000000 --- a/addons/mail/tests/test_mail_mail.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -import itertools - -from odoo.addons.mail.tests import common as mail_common -from odoo.tests import common -from odoo.tools import mute_logger - - -class TestMail(common.SavepointCase, mail_common.MockEmails): - - @classmethod - def setUpClass(cls): - super(TestMail, cls).setUpClass() - - cls.user_employee = cls.env['res.users'].with_context({ - 'no_reset_password': True, - 'mail_create_nolog': True, - 'mail_create_nosubscribe': True, - 'mail_notrack': True, - }).create({ - 'name': 'Ernest Employee', - 'login': 'ernest', - 'email': 'e.e@example.com', - 'signature': '--\nErnest', - 'notification_type': 'email', - 'groups_id': [(6, 0, [cls.env.ref('base.group_user').id])] - }) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_mail_message_notify_from_mail_mail(self): - # Due ot post-commit hooks, store send emails in every step - self.email_to_list = [] - mail = self.env['mail.mail'].create({ - 'body_html': '<p>Test</p>', - 'email_to': 'test@example.com', - 'partner_ids': [(4, self.user_employee.partner_id.id)] - }) - self.email_to_list.extend(itertools.chain.from_iterable(sent_email['email_to'] for sent_email in self._mails if sent_email.get('email_to'))) - self.assertNotIn(u'Ernest Employee <e.e@example.com>', self.email_to_list) - mail.send() - self.email_to_list.extend(itertools.chain.from_iterable(sent_email['email_to'] for sent_email in self._mails if sent_email.get('email_to'))) - self.assertNotIn(u'Ernest Employee <e.e@example.com>', self.email_to_list) - self.assertIn(u'test@example.com', self.email_to_list) diff --git a/addons/mail/tests/test_mail_message.py b/addons/mail/tests/test_mail_message.py deleted file mode 100644 index 779b8d4f526..00000000000 --- a/addons/mail/tests/test_mail_message.py +++ /dev/null @@ -1,276 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -import base64 - -from odoo.addons.mail.tests import common -from odoo.exceptions import AccessError, except_orm -from odoo.tools import mute_logger - - -class TestMessageValues(common.BaseFunctionalTest, common.MockEmails): - - @classmethod - def setUpClass(cls): - super(TestMessageValues, cls).setUpClass() - - cls.alias_record = cls.env['mail.test'].with_context(cls._quick_create_ctx).create({ - 'name': 'Pigs', - 'alias_name': 'pigs', - 'alias_contact': 'followers', - }) - - cls.Message = cls.env['mail.message'].sudo(cls.user_employee) - - def test_mail_message_values_basic(self): - self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink() - - msg = self.Message.create({ - 'reply_to': 'test.reply@example.com', - 'email_from': 'test.from@example.com', - }) - self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one') - self.assertEqual(msg.reply_to, 'test.reply@example.com') - self.assertEqual(msg.email_from, 'test.from@example.com') - - def test_mail_message_values_default(self): - self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink() - - msg = self.Message.create({}) - self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one') - self.assertEqual(msg.reply_to, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - @mute_logger('odoo.models.unlink') - def test_mail_message_values_alias(self): - alias_domain = 'example.com' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain) - self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.alias')]).unlink() - - msg = self.Message.create({}) - self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one') - self.assertEqual(msg.reply_to, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - def test_mail_message_values_alias_catchall(self): - alias_domain = 'example.com' - alias_catchall = 'pokemon' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain) - self.env['ir.config_parameter'].set_param('mail.catchall.alias', alias_catchall) - - msg = self.Message.create({}) - self.assertIn('-private', msg.message_id, 'mail_message: message_id for a void message should be a "private" one') - self.assertEqual(msg.reply_to, '%s <%s@%s>' % (self.env.user.company_id.name, alias_catchall, alias_domain)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - def test_mail_message_values_document_no_alias(self): - self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.domain')]).unlink() - - msg = self.Message.create({ - 'model': 'mail.test', - 'res_id': self.alias_record.id - }) - self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id) - self.assertEqual(msg.reply_to, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - @mute_logger('odoo.models.unlink') - def test_mail_message_values_document_alias(self): - alias_domain = 'example.com' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain) - self.env['ir.config_parameter'].search([('key', '=', 'mail.catchall.alias')]).unlink() - - msg = self.Message.create({ - 'model': 'mail.test', - 'res_id': self.alias_record.id - }) - self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id) - self.assertEqual(msg.reply_to, '%s %s <%s@%s>' % (self.env.user.company_id.name, self.alias_record.name, self.alias_record.alias_name, alias_domain)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - def test_mail_message_values_document_alias_catchall(self): - alias_domain = 'example.com' - alias_catchall = 'pokemon' - self.env['ir.config_parameter'].set_param('mail.catchall.domain', alias_domain) - self.env['ir.config_parameter'].set_param('mail.catchall.alias', alias_catchall) - - msg = self.Message.create({ - 'model': 'mail.test', - 'res_id': self.alias_record.id - }) - self.assertIn('-openerp-%d-mail.test' % self.alias_record.id, msg.message_id) - self.assertEqual(msg.reply_to, '%s %s <%s@%s>' % (self.env.user.company_id.name, self.alias_record.name, self.alias_record.alias_name, alias_domain)) - self.assertEqual(msg.email_from, '%s <%s>' % (self.user_employee.name, self.user_employee.email)) - - def test_mail_message_values_no_auto_thread(self): - msg = self.Message.create({ - 'model': 'mail.test', - 'res_id': self.alias_record.id, - 'no_auto_thread': True, - }) - self.assertIn('reply_to', msg.message_id) - self.assertNotIn('mail.test', msg.message_id) - self.assertNotIn('-%d-' % self.alias_record.id, msg.message_id) - - -class TestMessageAccess(common.BaseFunctionalTest, common.MockEmails): - - @classmethod - def setUpClass(cls): - super(TestMessageAccess, cls).setUpClass() - - Users = cls.env['res.users'].with_context(cls._quick_create_user_ctx) - cls.user_public = Users.create({ - 'name': 'Bert Tartignole', - 'login': 'bert', - 'email': 'b.t@example.com', - 'groups_id': [(6, 0, [cls.env.ref('base.group_public').id])]}) - cls.user_portal = Users.create({ - 'name': 'Chell Gladys', - 'login': 'chell', - 'email': 'chell@gladys.portal', - 'groups_id': [(6, 0, [cls.env.ref('base.group_portal').id])]}) - - Channel = cls.env['mail.channel'].with_context(cls._quick_create_ctx) - # Pigs: base group for tests - cls.group_pigs = Channel.create({ - 'name': 'Pigs', - 'public': 'groups', - 'group_public_id': cls.env.ref('base.group_user').id}) - # Jobs: public group - cls.group_public = Channel.create({ - 'name': 'Jobs', - 'description': 'NotFalse', - 'public': 'public'}) - # Private: private gtroup - cls.group_private = Channel.create({ - 'name': 'Private', - 'public': 'private'}) - cls.message = cls.env['mail.message'].create({ - 'body': 'My Body', - 'model': 'mail.channel', - 'res_id': cls.group_private.id, - }) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_mail_message_access_search(self): - # Data: various author_ids, partner_ids, documents - msg1 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A', 'subtype_id': self.ref('mail.mt_comment')}) - msg2 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A+B', 'subtype_id': self.ref('mail.mt_comment'), - 'partner_ids': [(6, 0, [self.user_public.partner_id.id])]}) - msg3 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A Pigs', 'subtype_id': False, - 'model': 'mail.channel', 'res_id': self.group_pigs.id}) - msg4 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A+P Pigs', 'subtype_id': self.ref('mail.mt_comment'), - 'model': 'mail.channel', 'res_id': self.group_pigs.id, - 'partner_ids': [(6, 0, [self.user_public.partner_id.id])]}) - msg5 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A+E Pigs', 'subtype_id': self.ref('mail.mt_comment'), - 'model': 'mail.channel', 'res_id': self.group_pigs.id, - 'partner_ids': [(6, 0, [self.user_employee.partner_id.id])]}) - msg6 = self.env['mail.message'].create({ - 'subject': '_Test', 'body': 'A Birds', 'subtype_id': self.ref('mail.mt_comment'), - 'model': 'mail.channel', 'res_id': self.group_private.id}) - msg7 = self.env['mail.message'].sudo(self.user_employee).create({ - 'subject': '_Test', 'body': 'B', 'subtype_id': self.ref('mail.mt_comment')}) - msg8 = self.env['mail.message'].sudo(self.user_employee).create({ - 'subject': '_Test', 'body': 'B+E', 'subtype_id': self.ref('mail.mt_comment'), - 'partner_ids': [(6, 0, [self.user_employee.partner_id.id])]}) - - # Test: Public: 2 messages (recipient) - messages = self.env['mail.message'].sudo(self.user_public).search([('subject', 'like', '_Test')]) - self.assertEqual(messages, msg2 | msg4) - - # Test: Employee: 3 messages on Pigs Raoul can read (employee can read group with default values) - messages = self.env['mail.message'].sudo(self.user_employee).search([('subject', 'like', '_Test'), ('body', 'ilike', 'A')]) - self.assertEqual(messages, msg3 | msg4 | msg5) - - # Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group) + 2 messages as author - messages = self.env['mail.message'].sudo(self.user_employee).search([('subject', 'like', '_Test')]) - self.assertEqual(messages, msg3 | msg4 | msg5 | msg7 | msg8) - - # Test: Admin: all messages - messages = self.env['mail.message'].search([('subject', 'like', '_Test')]) - self.assertEqual(messages, msg1 | msg2 | msg3 | msg4 | msg5 | msg6 | msg7 | msg8) - - # Test: Portal: 0 (no access to groups, not recipient) - messages = self.env['mail.message'].sudo(self.user_portal).search([('subject', 'like', '_Test')]) - self.assertFalse(messages) - - # Test: Portal: 2 messages (public group with a subtype) - self.group_pigs.write({'public': 'public'}) - messages = self.env['mail.message'].sudo(self.user_portal).search([('subject', 'like', '_Test')]) - self.assertEqual(messages, msg4 | msg5) - - @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_mail_message_access_read_crash(self): - # TODO: Change the except_orm to Warning ( Because here it's call check_access_rule - # which still generate exception in except_orm.So we need to change all - # except_orm to warning in mail module.) - with self.assertRaises(except_orm): - self.message.sudo(self.user_employee).read() - - @mute_logger('odoo.models') - def test_mail_message_access_read_crash_portal(self): - with self.assertRaises(except_orm): - self.message.sudo(self.user_portal).read(['body', 'message_type', 'subtype_id']) - - def test_mail_message_access_read_ok_portal(self): - self.message.write({'subtype_id': self.ref('mail.mt_comment'), 'res_id': self.group_public.id}) - self.message.sudo(self.user_portal).read(['body', 'message_type', 'subtype_id']) - - def test_mail_message_access_read_notification(self): - attachment = self.env['ir.attachment'].create({ - 'datas': base64.b64encode(b'My attachment'), - 'name': 'doc.txt', - 'datas_fname': 'doc.txt'}) - # attach the attachment to the message - self.message.write({'attachment_ids': [(4, attachment.id)]}) - self.message.write({'partner_ids': [(4, self.user_employee.partner_id.id)]}) - self.message.sudo(self.user_employee).read() - # Test: Bert has access to attachment, ok because he can read message - attachment.sudo(self.user_employee).read(['name', 'datas']) - - def test_mail_message_access_read_author(self): - self.message.write({'author_id': self.user_employee.partner_id.id}) - self.message.sudo(self.user_employee).read() - - def test_mail_message_access_read_doc(self): - self.message.write({'model': 'mail.channel', 'res_id': self.group_public.id}) - # Test: Bert reads the message, ok because linked to a doc he is allowed to read - self.message.sudo(self.user_employee).read() - - @mute_logger('odoo.addons.base.models.ir_model') - def test_mail_message_access_create_crash_public(self): - # Do: Bert creates a message on Pigs -> ko, no creation rights - with self.assertRaises(AccessError): - self.env['mail.message'].sudo(self.user_public).create({'model': 'mail.channel', 'res_id': self.group_pigs.id, 'body': 'Test'}) - - # Do: Bert create a message on Jobs -> ko, no creation rights - with self.assertRaises(AccessError): - self.env['mail.message'].sudo(self.user_public).create({'model': 'mail.channel', 'res_id': self.group_public.id, 'body': 'Test'}) - - @mute_logger('odoo.models') - def test_mail_message_access_create_crash(self): - # Do: Bert create a private message -> ko, no creation rights - with self.assertRaises(except_orm): - self.env['mail.message'].sudo(self.user_employee).create({'model': 'mail.channel', 'res_id': self.group_private.id, 'body': 'Test'}) - - @mute_logger('odoo.models') - def test_mail_message_access_create_doc(self): - # TODO Change the except_orm to Warning - Message = self.env['mail.message'].sudo(self.user_employee) - # Do: Raoul creates a message on Jobs -> ok, write access to the related document - Message.create({'model': 'mail.channel', 'res_id': self.group_public.id, 'body': 'Test'}) - # Do: Raoul creates a message on Priv -> ko, no write access to the related document - with self.assertRaises(except_orm): - Message.create({'model': 'mail.channel', 'res_id': self.group_private.id, 'body': 'Test'}) - - def test_mail_message_access_create_private(self): - self.env['mail.message'].sudo(self.user_employee).create({'body': 'Test'}) - - def test_mail_message_access_create_reply(self): - self.message.write({'partner_ids': [(4, self.user_employee.partner_id.id)]}) - self.env['mail.message'].sudo(self.user_employee).create({'model': 'mail.channel', 'res_id': self.group_private.id, 'body': 'Test', 'parent_id': self.message.id}) diff --git a/addons/mail/tests/test_mail_template.py b/addons/mail/tests/test_mail_template.py deleted file mode 100644 index 5705ac3ad4e..00000000000 --- a/addons/mail/tests/test_mail_template.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -import base64 -from datetime import datetime, timedelta - -from odoo.addons.mail.tests.common import BaseFunctionalTest, MockEmails, TestRecipients -from odoo.tools import mute_logger, DEFAULT_SERVER_DATETIME_FORMAT - - -class TestMailTemplate(BaseFunctionalTest, MockEmails, TestRecipients): - - def setUp(self): - super(TestMailTemplate, self).setUp() - - self.user_employee.write({ - 'groups_id': [(4, self.env.ref('base.group_partner_manager').id)], - }) - - self._attachments = [{ - 'name': '_Test_First', - 'datas_fname': 'first.txt', - 'datas': base64.b64encode(b'My first attachment'), - 'res_model': 'res.partner', - 'res_id': self.user_admin.partner_id.id - }, { - 'name': '_Test_Second', - 'datas_fname': 'second.txt', - 'datas': base64.b64encode(b'My second attachment'), - 'res_model': 'res.partner', - 'res_id': self.user_admin.partner_id.id - }] - - self.email_1 = 'test1@example.com' - self.email_2 = 'test2@example.com' - self.email_3 = self.partner_1.email - self.email_template = self.env['mail.template'].create({ - 'model_id': self.env['ir.model']._get('mail.test.simple').id, - 'name': 'Pigs Template', - 'subject': '${object.name}', - 'body_html': '${object.email_from}', - 'user_signature': False, - 'attachment_ids': [(0, 0, self._attachments[0]), (0, 0, self._attachments[1])], - 'partner_to': '%s,%s' % (self.partner_2.id, self.user_admin.partner_id.id), - 'email_to': '%s, %s' % (self.email_1, self.email_2), - 'email_cc': '%s' % self.email_3}) - - # admin should receive emails - self.user_admin.write({'notification_type': 'email'}) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_composer_w_template(self): - composer = self.env['mail.compose.message'].sudo(self.user_employee).with_context({ - 'default_composition_mode': 'comment', - 'default_model': 'mail.test.simple', - 'default_res_id': self.test_record.id, - 'default_template_id': self.email_template.id, - }).create({'subject': 'Forget me subject', 'body': 'Dummy body'}) - - # perform onchange and send emails - values = composer.onchange_template_id(self.email_template.id, 'comment', self.test_record._name, self.test_record.id)['value'] - composer.write(values) - composer.send_mail() - - new_partners = self.env['res.partner'].search([('email', 'in', [self.email_1, self.email_2])]) - self.assertEmails( - self.user_employee.partner_id, - [[self.partner_1], [self.partner_2], [new_partners[0]], [new_partners[1]], [self.partner_admin]], - subject=self.test_record.name, - body_content=self.test_record.email_from, - attachments=[('first.txt', b'My first attachment', 'text/plain'), ('second.txt', b'My second attachment', 'text/plain')]) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_post_post_w_template(self): - self.test_record.sudo(self.user_employee).message_post_with_template(self.email_template.id, composition_mode='comment') - - new_partners = self.env['res.partner'].search([('email', 'in', [self.email_1, self.email_2])]) - self.assertEmails( - self.user_employee.partner_id, - [[self.partner_1], [self.partner_2], [new_partners[0]], [new_partners[1]], [self.partner_admin]], - subject=self.test_record.name, - body_content=self.test_record.email_from, - attachments=[('first.txt', b'My first attachment', 'text/plain'), ('second.txt', b'My second attachment', 'text/plain')]) - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_composer_w_template_mass_mailing(self): - test_record_2 = self.env['mail.test.simple'].with_context(self._quick_create_ctx).create({'name': 'Test2', 'email_from': 'laurie.poiret@example.com'}) - - composer = self.env['mail.compose.message'].sudo(self.user_employee).with_context({ - 'default_composition_mode': 'mass_mail', - # 'default_notify': True, - 'default_notify': False, - 'default_model': 'mail.test.simple', - 'default_res_id': self.test_record.id, - 'default_template_id': self.email_template.id, - 'active_ids': [self.test_record.id, test_record_2.id] - }).create({}) - values = composer.onchange_template_id(self.email_template.id, 'mass_mail', 'mail.test.simple', self.test_record.id)['value'] - composer.write(values) - composer.send_mail() - - new_partners = self.env['res.partner'].search([('email', 'in', [self.email_1, self.email_2])]) - # hack to use assertEmails - self._mails_record1 = [dict(mail) for mail in self._mails if '%s-%s' % (self.test_record.id, self.test_record._name) in mail['message_id']] - self._mails_record2 = [dict(mail) for mail in self._mails if '%s-%s' % (test_record_2.id, test_record_2._name) in mail['message_id']] - - self._mails = self._mails_record1 - self.assertEmails( - self.user_employee.partner_id, - [[self.partner_1], [self.partner_2], [new_partners[0]], [new_partners[1]], [self.partner_admin]], - subject=self.test_record.name, - body_content=self.test_record.email_from, - attachments=[('first.txt', b'My first attachment', 'text/plain'), ('second.txt', b'My second attachment', 'text/plain')]) - - self._mails = self._mails_record2 - self.assertEmails( - self.user_employee.partner_id, - [[self.partner_1], [self.partner_2], [new_partners[0]], [new_partners[1]], [self.partner_admin]], - subject=test_record_2.name, - body_content=test_record_2.email_from, - attachments=[('first.txt', b'My first attachment', 'text/plain'), ('second.txt', b'My second attachment', 'text/plain')]) - - message_1 = self.test_record.message_ids[0] - message_2 = test_record_2.message_ids[0] - - # messages effectively posted - self.assertEqual(message_1.subject, self.test_record.name) - self.assertEqual(message_2.subject, test_record_2.name) - self.assertIn(self.test_record.email_from, message_1.body) - self.assertIn(test_record_2.email_from, message_2.body) - - def test_composer_template_save(self): - self.env['mail.compose.message'].with_context({ - 'default_composition_mode': 'comment', - 'default_model': 'mail.test.simple', - 'default_res_id': self.test_record.id, - }).create({ - 'subject': 'Forget me subject', - 'body': '<p>Dummy body</p>' - }).save_as_template() - # Test: email_template subject, body_html, model - last_template = self.env['mail.template'].search([('model', '=', 'mail.test.simple'), ('subject', '=', 'Forget me subject')], limit=1) - self.assertEqual(last_template.body_html, '<p>Dummy body</p>', 'email_template incorrect body_html') - - @mute_logger('odoo.addons.mail.models.mail_mail') - def test_template_send_email(self): - mail_id = self.email_template.send_mail(self.test_record.id) - mail = self.env['mail.mail'].browse(mail_id) - self.assertEqual(mail.subject, self.test_record.name) - self.assertEqual(mail.email_to, self.email_template.email_to) - self.assertEqual(mail.email_cc, self.email_template.email_cc) - self.assertEqual(mail.recipient_ids, self.partner_2 | self.user_admin.partner_id) - - def test_template_add_context_action(self): - self.email_template.create_action() - - # check template act_window has been updated - self.assertTrue(bool(self.email_template.ref_ir_act_window)) - - # check those records - action = self.email_template.ref_ir_act_window - self.assertEqual(action.name, 'Send Mail (%s)' % self.email_template.name) - self.assertEqual(action.binding_model_id.model, 'mail.test.simple') - - # def test_template_scheduled_date(self): - # from unittest.mock import patch - - # self.email_template_in_2_days = self.email_template.copy() - - # with patch('odoo.addons.mail.tests.test_mail_template.datetime', wraps=datetime) as mock_datetime: - # mock_datetime.now.return_value = datetime(2017, 11, 15, 11, 30, 28) - # mock_datetime.side_effect = lambda *args, **kw: datetime(*args, **kw) - - # self.email_template_in_2_days.write({ - # 'scheduled_date': "${(datetime.datetime.now() + relativedelta(days=2)).strftime('%s')}" % DEFAULT_SERVER_DATETIME_FORMAT, - # }) - - # mail_now_id = self.email_template.send_mail(self.test_record.id) - # mail_in_2_days_id = self.email_template_in_2_days.send_mail(self.test_record.id) - - # mail_now = self.env['mail.mail'].browse(mail_now_id) - # mail_in_2_days = self.env['mail.mail'].browse(mail_in_2_days_id) - - # # mail preparation - # self.assertEqual(mail_now.exists() | mail_in_2_days.exists(), mail_now | mail_in_2_days) - # self.assertEqual(bool(mail_now.scheduled_date), False) - # self.assertEqual(mail_now.state, 'outgoing') - # self.assertEqual(mail_in_2_days.state, 'outgoing') - # scheduled_date = datetime.strptime(mail_in_2_days.scheduled_date, DEFAULT_SERVER_DATETIME_FORMAT) - # date_in_2_days = datetime.now() + timedelta(days = 2) - # self.assertEqual(scheduled_date, date_in_2_days) - # # self.assertEqual(scheduled_date.month, date_in_2_days.month) - # # self.assertEqual(scheduled_date.year, date_in_2_days.year) - - # # Launch the scheduler on the first mail, it should be reported in self.mails - # # and the mail_mail is now deleted - # self.env['mail.mail'].process_email_queue() - # self.assertEqual(mail_now.exists() | mail_in_2_days.exists(), mail_in_2_days) - - # # Launch the scheduler on the first mail, it's still in 'outgoing' state - # self.env['mail.mail'].process_email_queue(ids=[mail_in_2_days.id]) - # self.assertEqual(mail_in_2_days.state, 'outgoing') - # self.assertEqual(mail_now.exists() | mail_in_2_days.exists(), mail_in_2_days) diff --git a/addons/mail/tests/test_message_compose.py b/addons/mail/tests/test_message_compose.py deleted file mode 100644 index 043f458e33f..00000000000 --- a/addons/mail/tests/test_message_compose.py +++ /dev/null @@ -1,355 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -import base64 - -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(BaseFunctionalTest, MockEmails, TestRecipients): - - def setUp(self): - super(TestMessagePost, 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_post_notifications(self): - _body, _body_alt, _subject = '<p>Test Body</p>', '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') - ] - _attach_1 = self.env['ir.attachment'].sudo(self.user_employee).create({ - 'name': 'Attach1', 'datas_fname': 'Attach1', - 'datas': 'bWlncmF0aW9uIHRlc3Q=', - 'res_model': 'mail.compose.message', 'res_id': 0}) - _attach_2 = self.env['ir.attachment'].sudo(self.user_employee).create({ - 'name': 'Attach2', 'datas_fname': 'Attach2', - 'datas': 'bWlncmF0aW9uIHRlc3Q=', - 'res_model': 'mail.compose.message', 'res_id': 0}) - - 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, - ) - - # 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') - - # 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): - parent_msg = self.test_record.sudo(self.user_employee).message_post( - body='<p>Test</p>', 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_record.sudo(self.user_employee).message_post( - body='<p>Test Answer</p>', - 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.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='<p>Test Answer Bis</p>', - 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.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='<p>Test</p>', 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='<p>Test</p>', 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_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.format_and_process( - MAIL_TEMPLATE_PLAINTEXT, - email_from=self.user_admin.email, - 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_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_composer_comment(self): - composer = self.env['mail.compose.message'].with_context({ - 'default_composition_mode': 'comment', - 'default_model': self.test_record._name, - 'default_res_id': self.test_record.id, - }).sudo(self.user_employee).create({ - 'body': '<p>Test Body</p>', - 'partner_ids': [(4, self.partner_1.id), (4, self.partner_2.id)] - }) - composer.send_mail() - - message = self.test_record.message_ids[0] - self.assertEqual(message.body, '<p>Test Body</p>') - 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_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': '<p>Mega</p>', - }).send_mail() - - message = self.test_record.message_ids[0] - self.assertEqual(message.body, '<p>Mega</p>') - 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': self.test_record._name, - 'default_res_id': False, - 'active_ids': [self.test_record.id, test_record_2.id] - }).sudo(self.user_employee).create({ - 'subject': 'Testing ${object.name}', - 'body': '<p>${object.name}</p>', - 'partner_ids': [(4, self.partner_1.id), (4, self.partner_2.id)] - }) - composer.with_context({ - 'default_res_id': -1, - 'active_ids': [self.test_record.id, test_record_2.id] - }).send_mail() - - # check mail_mail - mails = self.env['mail.mail'].search([('subject', 'ilike', 'Testing')]) - for mail in mails: - 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_record - message1 = self.test_record.message_ids[0] - self.assertEqual(message1.subject, 'Testing %s' % self.test_record.name) - self.assertEqual(message1.body, '<p>%s</p>' % self.test_record.name) - - # 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, '<p>%s</p>' % test_record_2.name) - - @mute_logger('odoo.addons.mail.models.mail_mail') - 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': self.test_record._name, - 'default_use_active_domain': True, - '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.name}', - }).send_mail() - - 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': self.test_record._name, - 'default_use_active_domain': False, - '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.name}', - }).send_mail() - - 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': '<p>Body text</p>', - 'partner_ids': []}).send_mail() - - self.assertEqual(self.test_record.message_ids[0].body, '<p>Body text</p>') - 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': '<p>Body text 2</p>'}).send_mail() - - self.assertEqual(self.test_record.message_ids[0].body, '<p>Body text 2</p>') - self.assertEqual(self.test_record.message_ids[0].author_id, portal_user.partner_id) diff --git a/addons/mail/tests/test_message_track.py b/addons/mail/tests/test_message_track.py deleted file mode 100644 index abb7bdf0fae..00000000000 --- a/addons/mail/tests/test_message_track.py +++ /dev/null @@ -1,137 +0,0 @@ -# -*- coding: utf-8 -*- - -from email.utils import formataddr - -from odoo.addons.mail.tests import common - - -class TestTracking(common.BaseFunctionalTest, common.MockEmails): - - def assertTracking(self, message, data): - tracking_values = message.sudo().tracking_value_ids - for field_name, value_type, old_value, new_value in data: - tracking = tracking_values.filtered(lambda track: track.field == field_name) - self.assertEqual(len(tracking), 1) - if value_type in ('char', 'integer'): - self.assertEqual(tracking.old_value_char, old_value) - self.assertEqual(tracking.new_value_char, new_value) - elif value_type in ('many2one'): - self.assertEqual(tracking.old_value_integer, old_value and old_value.id or False) - self.assertEqual(tracking.new_value_integer, new_value and new_value.id or False) - self.assertEqual(tracking.old_value_char, old_value and old_value.name_get()[0][1] or '') - self.assertEqual(tracking.new_value_char, new_value and new_value.name_get()[0][1] or '') - else: - self.assertEqual(1, 0) - - def setUp(self): - super(TestTracking, self).setUp() - - self.track_subtype_umbrella = self.env['mail.message.subtype'].create({ - 'name': 'Umbrella', - 'description': 'Umbrella Changed', - }) - self.env['ir.model.data'].create({ - 'name': 'track_subtype_umbrella', - 'model': 'mail.message.subtype', - 'module': 'mail', - 'res_id': self.track_subtype_umbrella.id - }) - - record = self.env['mail.test.full'].sudo(self.user_employee).with_context(self._quick_create_ctx).create({ - 'name': 'Test', - }) - self.record = record.with_context(mail_notrack=False) - - def test_message_track_no_tracking(self): - """ Update a set of non tracked fields -> no message, no tracking """ - self.record.write({ - 'name': 'Tracking or not', - 'count': 32, - }) - self.assertEqual(self.record.message_ids, self.env['mail.message']) - - def test_message_track_no_subtype(self): - """ Update some tracked fields not linked to some subtype -> message with onchange + always tracked values """ - customer = self.env['res.partner'].create({'name': 'Customer', 'email': 'cust@example.com'}) - self.record.write({ - 'name': 'Test2', - 'customer_id': customer.id, - }) - - # one new message containing tracking; without subtype linked to tracking, a note is generated - self.assertEqual(len(self.record.message_ids), 1) - self.assertEqual(self.record.message_ids.subtype_id, self.env.ref('mail.mt_note')) - - # no specific recipients except those following notes, no email - self.assertEqual(self.record.message_ids.partner_ids, self.env['res.partner']) - self.assertEqual(self.record.message_ids.needaction_partner_ids, self.env['res.partner']) - self.assertEqual(self._mails, []) - - # verify tracked value - self.assertTracking( - self.record.message_ids, - [('email_from', 'char', False, False), # always tracked field - ('customer_id', 'many2one', False, customer) # onchange tracked field - ]) - - def test_message_track_subtype(self): - """ Update some tracked fields linked to some subtype -> message with onchange + always tracked values """ - self.record.message_subscribe( - partner_ids=[self.user_admin.partner_id.id], - subtype_ids=[self.track_subtype_umbrella.id] - ) - - umbrella = self.env['mail.test'].create({'name': 'Umbrella'}) - self.record.write({ - 'name': 'Test2', - 'email_from': 'noone@example.com', - 'umbrella_id': umbrella.id, - }) - # one new message containing tracking; subtype linked to tracking - self.assertEqual(len(self.record.message_ids), 1) - self.assertEqual(self.record.message_ids.subtype_id, self.track_subtype_umbrella) - - # no specific recipients except those following umbrella - self.assertEqual(self.record.message_ids.partner_ids, self.env['res.partner']) - self.assertEqual(self.record.message_ids.needaction_partner_ids, self.user_admin.partner_id) - - # verify tracked value - self.assertTracking( - self.record.message_ids, - [('email_from', 'char', False, 'noone@example.com'), # always tracked field - ('umbrella_id', 'many2one', False, umbrella) # onchange tracked field - ]) - - def test_message_track_template(self): - """ Update some tracked fields linked to some template -> message with onchange + always tracked values """ - mail_template = self.env['mail.template'].create({ - 'model_id': self.env.ref('mail.model_mail_test_full').id, - 'body_html': '<p>Hello ${object.name}</p>', - 'subject': 'Test Template', - 'partner_to': '${object.customer_id.id | safe}', - }) - self.record.write({'mail_template': mail_template.id}) - self.assertEqual(self.record.message_ids, self.env['mail.message']) - - self.record.write({ - 'name': 'Test2', - 'customer_id': self.user_admin.partner_id.id, - }) - - self.assertEqual(len(self.record.message_ids), 2, 'should have 2 new messages: one for tracking, one for template') - - # one new message containing the template linked to tracking - self.assertEqual(self.record.message_ids[0].subject, 'Test Template') - self.assertEqual(self.record.message_ids[0].body, '<p>Hello Test2</p>') - - # one email send due to template - self.assertEqual(len(self._mails), 1) - self.assertEqual(set(self._mails[0]['email_to']), set([formataddr((self.user_admin.name, self.user_admin.email))])) - self.assertHtmlEqual(self._mails[0]['body'], '<p>Hello Test2</p>') - - # one new message containing tracking; without subtype linked to tracking - self.assertEqual(self.record.message_ids[1].subtype_id, self.env.ref('mail.mt_note')) - self.assertTracking( - self.record.message_ids[1], - [('customer_id', 'many2one', False, self.user_admin.partner_id) # onchange tracked field - ]) diff --git a/addons/mail/tests/test_update_notification.py b/addons/mail/tests/test_update_notification.py deleted file mode 100644 index 7621e4056a1..00000000000 --- a/addons/mail/tests/test_update_notification.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo.tests.common import TransactionCase - - -class TestUpdateNotification(TransactionCase): - def test_user_count(self): - ping_msg = self.env['publisher_warranty.contract'].with_context(active_test=False)._get_message() - user_count = self.env['res.users'].search_count([('active', '=', True)]) - self.assertEqual(ping_msg.get('nbr_users'), user_count, 'Update Notification: Users count is badly computed in ping message') - share_user_count = self.env['res.users'].search_count([('active', '=', True), ('share', '=', True)]) - self.assertEqual(ping_msg.get('nbr_share_users'), share_user_count, 'Update Notification: Portal Users count is badly computed in ping message') |
