summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2019-10-21 12:51:32 +0000
committerThibault Delavallée <tde@odoo.com>2020-11-26 08:45:55 +0000
commitdef98d2375a8a906092293f0aa1ce03bf948d2d3 (patch)
tree2136ce434aa8ba5912f8bf3dd39bea8c71dd2909
parent8c0e92cdcdf98daa3c841af97e0bd2e4b015a1b9 (diff)
[IMP] test_mail: add new mail composer tests for its internals
Purpose is to have some low level tests for composer itself allowing to ensure its behavior. We add tests notably about default values computation in mass mailing mode as well as template_id change and values synchronization in composer model. In a near future composer will probably be improved (use computed fields, rewrite part of its logic to improve performances). Having tests done before those tasks ensure we notice every change that might happen. Task ID-2390314 PR odoo/odoo#62061
-rw-r--r--addons/test_mail/data/template_data.xml12
-rw-r--r--addons/test_mail/tests/__init__.py1
-rw-r--r--addons/test_mail/tests/common.py23
-rw-r--r--addons/test_mail/tests/test_mail_composer.py317
-rw-r--r--addons/test_mail/tests/test_message_composer.py4
-rw-r--r--addons/test_mail_full/tests/common.py19
6 files changed, 359 insertions, 17 deletions
diff --git a/addons/test_mail/data/template_data.xml b/addons/test_mail/data/template_data.xml
index 4716060d444..d7a9248f449 100644
--- a/addons/test_mail/data/template_data.xml
+++ b/addons/test_mail/data/template_data.xml
@@ -21,4 +21,16 @@
<template id="mail_test_ticket_tracking_view">
<p><span t-esc="object.name"/> datetime has been updated to <span t-esc="object.datetime"/></p>
</template>
+
+ <template id="mail_test_ticket_test_template">
+ <t t-call="web.html_container">
+ <t t-set="o" t-value="res_company"/>
+ <t t-call="web.external_layout">
+ <div class="page">
+ <p>This is a sample of an external report.</p>
+ </div>
+ </t>
+ </t>
+ </template>
+
</odoo>
diff --git a/addons/test_mail/tests/__init__.py b/addons/test_mail/tests/__init__.py
index 02ebd701f5c..e328b555861 100644
--- a/addons/test_mail/tests/__init__.py
+++ b/addons/test_mail/tests/__init__.py
@@ -3,6 +3,7 @@
from . import test_invite
from . import test_ir_actions
from . import test_mail_activity
+from . import test_mail_composer
from . import test_mail_followers
from . import test_mail_message
from . import test_mail_mail
diff --git a/addons/test_mail/tests/common.py b/addons/test_mail/tests/common.py
index b62b1a444aa..c556a988367 100644
--- a/addons/test_mail/tests/common.py
+++ b/addons/test_mail/tests/common.py
@@ -12,6 +12,29 @@ class TestMailCommon(MailCommon):
def _create_channel_listener(cls):
cls.channel_listen = cls.env['mail.channel'].with_context(cls._test_context).create({'name': 'Listener'})
+ @classmethod
+ def _create_records_for_batch(cls, model, count):
+ # TDE note: to be cleaned in master
+ records = cls.env[model]
+ partners = cls.env['res.partner']
+ country_id = cls.env.ref('base.be').id
+
+ partners = cls.env['res.partner'].with_context(**cls._test_context).create([{
+ 'name': 'Partner_%s' % (x),
+ 'email': '_test_partner_%s@example.com' % (x),
+ 'country_id': country_id,
+ 'mobile': '047500%02d%02d' % (x, x)
+ } for x in range(count)])
+
+ records = cls.env[model].with_context(**cls._test_context).create([{
+ 'name': 'Test_%s' % (x),
+ 'customer_id': partners[x].id,
+ } for x in range(count)])
+
+ cls.records = cls._reset_mail_context(records)
+ cls.partners = partners
+ return cls.records, cls.partners
+
class TestMailMultiCompanyCommon(MailCommon):
diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py
new file mode 100644
index 00000000000..beed5150276
--- /dev/null
+++ b/addons/test_mail/tests/test_mail_composer.py
@@ -0,0 +1,317 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import base64
+
+from odoo.addons.mail.tests.common import mail_new_test_user
+from odoo.addons.test_mail.tests.common import TestMailCommon, TestRecipients
+from odoo.tests import tagged
+from odoo.tests.common import users, Form
+from odoo.tools import mute_logger
+
+@tagged('mail_composer')
+class TestMailComposer(TestMailCommon, TestRecipients):
+ """ Test Composer internals """
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestMailComposer, cls).setUpClass()
+ cls._init_mail_gateway()
+
+ cls.user_employee_2 = mail_new_test_user(
+ cls.env, login='employee2', groups='base.group_user',
+ notification_type='inbox', email='eglantine@example.com',
+ name='Eglantine Employee', signature='--\nEglantine')
+ cls.partner_employee_2 = cls.user_employee_2.partner_id
+
+ cls.test_record = cls.env['mail.test.ticket'].with_context(cls._test_context).create({
+ 'name': 'TestRecord',
+ 'customer_id': cls.partner_1.id,
+ 'user_id': cls.user_employee_2.id,
+ })
+ cls.test_records, cls.test_partners = cls._create_records_for_batch('mail.test.ticket', 2)
+
+ cls.test_report = cls.env['ir.actions.report'].create({
+ 'name': 'Test Report on mail test ticket',
+ 'model': 'mail.test.ticket',
+ 'report_type': 'qweb-pdf',
+ 'report_name': 'test_mail.mail_test_ticket_test_template',
+ })
+
+ cls.test_from = '"John Doe" <john@example.com>'
+
+ cls.mail_server = cls.env['ir.mail_server'].create({
+ 'name': 'Dummy Test Server',
+ 'smtp_host': 'smtp.pizza.moc',
+ 'smtp_port': 17,
+ 'smtp_encryption': 'ssl',
+ 'sequence': 666,
+ })
+
+ cls.template = cls.env['mail.template'].create({
+ 'name': 'TestTemplate',
+ 'subject': 'TemplateSubject ${object.name}',
+ 'body_html': '<p>TemplateBody ${object.name}</p>',
+ 'partner_to': '${object.customer_id.id if object.customer_id else ""}',
+ 'email_to': '${(object.email_from if not object.customer_id else "") | safe}',
+ 'email_from': '${object.user_id.email_formatted | safe}',
+ 'model_id': cls.env['ir.model']._get('mail.test.ticket').id,
+ 'mail_server_id': cls.mail_server.id,
+ })
+
+ def _generate_attachments_data(self, count):
+ return [{
+ 'name': '%02d.txt' % x,
+ 'datas': base64.b64encode(b'Att%02d' % x),
+ } for x in range(count)]
+
+ def _get_web_context(self, records, add_web=True, **values):
+ """ Helper to generate composer context. Will make tests a bit less
+ verbose.
+
+ :param add_web: add web context, generally making noise especially in
+ mass mail mode (active_id/ids both present in context)
+ """
+ base_context = {
+ 'default_model': records._name,
+ }
+ if len(records) == 1:
+ base_context['default_composition_mode'] = 'comment'
+ base_context['default_res_id'] = records.id
+ else:
+ base_context['default_composition_mode'] = 'mass_mail'
+ base_context['active_ids'] = records.ids
+ if add_web:
+ base_context['active_model'] = records._name
+ base_context['active_id'] = records[0].id
+ if values:
+ base_context.update(**values)
+ return base_context
+
+
+@tagged('mail_composer')
+class TestComposerForm(TestMailComposer):
+
+ @users('employee')
+ def test_mail_composer_comment(self):
+ composer_form = Form(self.env['mail.compose.message'].with_context(self._get_web_context(self.test_record, add_web=True)))
+ self.assertEqual(
+ composer_form.subject, 'Re: %s' % self.test_record.name,
+ 'MailComposer: comment mode should have default subject Re: record_name')
+ # record name not displayed currently in view
+ # self.assertEqual(composer_form.record_name, self.test_record.name, 'MailComposer: comment mode should compute record name')
+ self.assertFalse(composer_form.no_auto_thread)
+ self.assertEqual(composer_form.composition_mode, 'comment')
+ self.assertEqual(composer_form.model, self.test_records._name)
+
+ @users('employee')
+ def test_mail_composer_mass(self):
+ composer_form = Form(self.env['mail.compose.message'].with_context(self._get_web_context(self.test_records, add_web=True)))
+ # TDE FIXME: currently failing
+ # self.assertFalse(composer_form.subject, 'MailComposer: mass mode should have void default subject if no template')
+ # record name not displayed currently in view
+ # self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name')
+ self.assertFalse(composer_form.no_auto_thread)
+ self.assertEqual(composer_form.composition_mode, 'mass_mail')
+ self.assertEqual(composer_form.model, self.test_records._name)
+
+ @users('employee')
+ def test_mail_composer_mass_wtpl(self):
+ ctx = self._get_web_context(self.test_records, add_web=True, default_template_id=self.template.id)
+ composer_form = Form(self.env['mail.compose.message'].with_context(ctx))
+ self.assertEqual(composer_form.subject, self.template.subject,
+ 'MailComposer: mass mode should have template raw subject if template')
+ self.assertEqual(composer_form.body, self.template.body_html,
+ 'MailComposer: mass mode should have template raw body if template')
+ # record name not displayed currently in view
+ # self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name')
+ self.assertFalse(composer_form.no_auto_thread)
+ self.assertEqual(composer_form.composition_mode, 'mass_mail')
+ self.assertEqual(composer_form.model, self.test_records._name)
+
+
+@tagged('mail_composer')
+class TestComposerInternals(TestMailComposer):
+
+ @users('employee')
+ @mute_logger('odoo.addons.mail.models.mail_mail')
+ def test_mail_composer_attachments_comment(self):
+ """ Test attachments management in comment mode. """
+ attachment_data = self._generate_attachments_data(3)
+ self.template.write({
+ 'attachment_ids': [(0, 0, a) for a in attachment_data],
+ 'report_template': self.test_report.id,
+ })
+ attachs = self.env['ir.attachment'].search([('name', 'in', [a['name'] for a in attachment_data])])
+ self.assertEqual(len(attachs), 3)
+
+ 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,
+ 'default_template_id': self.template.id,
+ }).create({
+ 'body': '<p>Test Body</p>',
+ })
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+
+ # values coming from template
+ self.assertEqual(len(composer.attachment_ids), 4)
+ for attach in attachs:
+ self.assertIn(attach, composer.attachment_ids)
+ generated = composer.attachment_ids - attachs
+ self.assertEqual(len(generated), 1, 'MailComposer: should have 1 additional attachment for report')
+ self.assertEqual(generated.res_model, 'mail.compose.message')
+ self.assertEqual(generated.res_id, 0)
+
+ @users('employee')
+ @mute_logger('odoo.addons.mail.models.mail_mail')
+ def test_mail_composer_author(self):
+ """ Test author_id / email_from synchronization, in both comment and mass mail
+ modes. """
+ for composition_mode in ['comment', 'mass_mail']:
+ if composition_mode == 'comment':
+ ctx = self._get_web_context(self.test_record, add_web=False)
+ else:
+ ctx = self._get_web_context(self.test_records, add_web=False)
+ composer = self.env['mail.compose.message'].with_context(ctx).create({
+ 'body': '<p>Test Body</p>',
+ })
+
+ # default values are current user
+ self.assertEqual(composer.author_id, self.env.user.partner_id)
+ self.assertEqual(composer.email_from, self.env.user.email_formatted)
+
+ # author values reset email (FIXME: currently not synchronized)
+ composer.write({'author_id': self.partner_1})
+ self.assertEqual(composer.author_id, self.partner_1)
+ self.assertEqual(composer.email_from, self.env.user.email_formatted)
+ # self.assertEqual(composer.email_from, self.partner_1.email_formatted)
+
+ # changing template should update its email_from
+ composer.write({'template_id': self.template.id, 'author_id': self.env.user.partner_id})
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+ self.assertEqual(composer.author_id, self.env.user.partner_id,
+ 'MailComposer: should take value given by user')
+ if composition_mode == 'comment':
+ self.assertEqual(composer.email_from, self.test_record.user_id.email_formatted,
+ 'MailComposer: should take email_from rendered from template')
+ else:
+ self.assertEqual(composer.email_from, self.template.email_from,
+ 'MailComposer: should take email_from raw from template')
+
+ # manual values are kept over template values
+ composer.write({'email_from': self.test_from})
+ self.assertEqual(composer.author_id, self.env.user.partner_id)
+ self.assertEqual(composer.email_from, self.test_from)
+
+ @users('employee')
+ def test_mail_composer_content_comment(self):
+ """ Test content management (subject, body, server) in comment mode.
+ Template update is also tested. """
+ for composition_mode in ['comment', 'mass_mail']:
+ if composition_mode == 'comment':
+ ctx = self._get_web_context(self.test_record, add_web=False)
+ else:
+ ctx = self._get_web_context(self.test_records, add_web=False)
+
+ # 1. check without template + template update
+ composer = self.env['mail.compose.message'].with_context(ctx).create({
+ 'subject': 'My amazing subject',
+ 'body': '<p>Test Body</p>',
+ })
+
+ # creation values are taken
+ self.assertEqual(composer.subject, 'My amazing subject')
+ self.assertEqual(composer.body, '<p>Test Body</p>')
+ self.assertEqual(composer.mail_server_id.id, False)
+
+ # changing template should update its content
+ composer.write({'template_id': self.template.id})
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+
+ # values come from template
+ if composition_mode == 'comment':
+ self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name)
+ self.assertEqual(composer.body, '<p>TemplateBody %s</p>' % self.test_record.name)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+ else:
+ self.assertEqual(composer.subject, self.template.subject)
+ self.assertEqual(composer.body, self.template.body_html)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+
+ # manual values is kept over template
+ composer.write({'subject': 'Back to my amazing subject'})
+ self.assertEqual(composer.subject, 'Back to my amazing subject')
+
+ # reset template should reset values
+ composer.write({'template_id': False})
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+
+ # values are reset
+ if composition_mode == 'comment':
+ self.assertEqual(composer.subject, 'Re: %s' % self.test_record.name)
+ self.assertEqual(composer.body, '')
+ # TDE FIXME: server id is kept, not sure why
+ # self.assertFalse(composer.mail_server_id.id)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+ else:
+ # values are reset TDE FIXME: strange for subject
+ self.assertEqual(composer.subject, 'Back to my amazing subject')
+ self.assertEqual(composer.body, '')
+ # TDE FIXME: server id is kept, not sure why
+ # self.assertFalse(composer.mail_server_id.id)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+
+ # 2. check with default
+ ctx['default_template_id'] = self.template.id
+ composer = self.env['mail.compose.message'].with_context(ctx).create({
+ 'template_id': self.template.id,
+ })
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+
+ # values come from template
+ if composition_mode == 'comment':
+ self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name)
+ self.assertEqual(composer.body, '<p>TemplateBody %s</p>' % self.test_record.name)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+ else:
+ self.assertEqual(composer.subject, self.template.subject)
+ self.assertEqual(composer.body, self.template.body_html)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+
+ # 3. check at create
+ ctx.pop('default_template_id')
+ composer = self.env['mail.compose.message'].with_context(ctx).create({
+ 'template_id': self.template.id,
+ })
+ # currently onchange necessary
+ composer.onchange_template_id_wrapper()
+
+ # values come from template
+ if composition_mode == 'comment':
+ self.assertEqual(composer.subject, 'TemplateSubject %s' % self.test_record.name)
+ self.assertEqual(composer.body, '<p>TemplateBody %s</p>' % self.test_record.name)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+ else:
+ self.assertEqual(composer.subject, self.template.subject)
+ self.assertEqual(composer.body, self.template.body_html)
+ self.assertEqual(composer.mail_server_id, self.template.mail_server_id)
+
+ # 4. template + user input
+ ctx['default_template_id'] = self.template.id
+ composer = self.env['mail.compose.message'].with_context(ctx).create({
+ 'subject': 'My amazing subject',
+ 'body': '<p>Test Body</p>',
+ 'mail_server_id': False,
+ })
+
+ # creation values are taken
+ self.assertEqual(composer.subject, 'My amazing subject')
+ self.assertEqual(composer.body, '<p>Test Body</p>')
+ self.assertEqual(composer.mail_server_id.id, False)
diff --git a/addons/test_mail/tests/test_message_composer.py b/addons/test_mail/tests/test_message_composer.py
index a93432a1575..ea6aa91803f 100644
--- a/addons/test_mail/tests/test_message_composer.py
+++ b/addons/test_mail/tests/test_message_composer.py
@@ -7,10 +7,13 @@ from unittest.mock import patch
from odoo.addons.test_mail.tests.common import TestMailCommon, TestRecipients
from odoo.addons.test_mail.models.test_mail_models import MailTestSimple
+from odoo.tests import tagged
from odoo.tools import mute_logger
+@tagged('mail_composer')
class TestComposer(TestMailCommon, TestRecipients):
+ """ Test Composer integration and results """
@classmethod
def setUpClass(cls):
@@ -153,6 +156,7 @@ class TestComposer(TestMailCommon, TestRecipients):
self.assertEqual(self.test_record.message_ids[0].author_id, portal_user.partner_id)
+@tagged('mail_composer')
class TestComposerWTpl(TestMailCommon, TestRecipients):
@classmethod
diff --git a/addons/test_mail_full/tests/common.py b/addons/test_mail_full/tests/common.py
index 10b2528b5ce..579ff6cb7ca 100644
--- a/addons/test_mail_full/tests/common.py
+++ b/addons/test_mail_full/tests/common.py
@@ -9,23 +9,8 @@ from odoo.addons.test_mass_mailing.tests.common import TestMassMailCommon
class TestMailFullCommon(TestMassMailCommon, MassSMSCommon):
@classmethod
- def _create_records_for_batch(cls, model, count):
- records = cls.env[model]
- partners = cls.env['res.partner']
- country_id = cls.env.ref('base.be').id,
- for x in range(count):
- partners += cls.env['res.partner'].with_context(**cls._test_context).create({
- 'name': 'Partner_%s' % (x),
- 'email': '_test_partner_%s@example.com' % (x),
- 'country_id': country_id,
- 'mobile': '047500%02d%02d' % (x, x)
- })
- records += cls.env[model].with_context(**cls._test_context).create({
- 'name': 'Test_%s' % (x),
- 'customer_id': partners[x].id,
- })
- cls.records = cls._reset_mail_context(records)
- cls.partners = partners
+ def setUpClass(cls):
+ super(TestMailFullCommon, cls).setUpClass()
class TestRecipients(TestRecipients):