summaryrefslogtreecommitdiff
path: root/addons/mail
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2020-11-18 15:38:45 +0000
committerThibault Delavallée <tde@odoo.com>2021-04-08 15:06:28 +0000
commit070bec2f3a7a50c6fc8f104cf92a9416ebc001b8 (patch)
treecffc9ad409b32a6d72fff32ce2f2a232a9472deb /addons/mail
parentc75e8619663efc4d97ab13fb35f815104239dd36 (diff)
[IMP] mail: add tests and docstrings for rendering mixin tools (jinja / qweb)
PURPOSE Add some tests for ``mail.render.mixin`` in order to assert its base behavior. SPECIFICATIONS Add tests for * jinja rendering tools; * QWeb rendering tools; * translation support; Also add tests for jinja markers: block, variable and line statement markers should be tested. Also improve docstrings of tool methods. Add notably explanation of parameters and better explain methods purpose. LINKS Task ID-2500615 Prepares Task ID-2484296 (improve markers use in Jinja) Prepares Task ID-27033 (support QWeb in templates) COM PR odoo/odoo#68874
Diffstat (limited to 'addons/mail')
-rw-r--r--addons/mail/models/mail_render_mixin.py43
-rw-r--r--addons/mail/tests/__init__.py1
-rw-r--r--addons/mail/tests/test_mail_render.py191
3 files changed, 224 insertions, 11 deletions
diff --git a/addons/mail/models/mail_render_mixin.py b/addons/mail/models/mail_render_mixin.py
index 0539716fe38..4804ee78166 100644
--- a/addons/mail/models/mail_render_mixin.py
+++ b/addons/mail/models/mail_render_mixin.py
@@ -252,6 +252,19 @@ class MailRenderMixin(models.AbstractModel):
@api.model
def _render_template_qweb(self, template_src, model, res_ids, add_context=None):
+ """ Render a QWeb template.
+
+ :param str template_src: source QWeb template. It should be a string
+ XmlID allowing to fetch an ir.ui.view;
+ :param str model: see ``MailRenderMixin._render_field)``;
+ :param list res_ids: see ``MailRenderMixin._render_field)``;
+
+ :param dict add_context: additional context to give to renderer. It
+ allows to add values to base rendering context generated by
+ ``MailRenderMixin._render_qweb_eval_context()``;
+
+ :return dict: {res_id: string of rendered template based on record}
+ """
view = self.env.ref(template_src, raise_if_not_found=False) or self.env['ir.ui.view']
results = dict.fromkeys(res_ids, u"")
if not view:
@@ -363,15 +376,14 @@ class MailRenderMixin(models.AbstractModel):
@api.model
def _render_template(self, template_src, model, res_ids, engine='jinja', add_context=None, post_process=False):
""" Render the given string on records designed by model / res_ids using
- the given rendering engine. Currently only jinja is supported.
+ the given rendering engine. Currently only jinja or qweb are supported.
:param str template_src: template text to render (jinja) or xml id of view (qweb)
this could be cleaned but hey, we are in a rush
:param str model: model name of records on which we want to perform rendering
:param list res_ids: list of ids of records (all belonging to same model)
:param string engine: jinja
- :param post_process: perform rendered str / html post processing (see
- ``_render_template_postprocess``)
+ :param post_process: see ``MailRenderMixin._render_field``;
:return dict: {res_id: string of rendered template based on record}
"""
@@ -430,16 +442,25 @@ class MailRenderMixin(models.AbstractModel):
for lang, lang_res_ids in lang_to_res_ids.items()
)
- def _render_field(self, field, res_ids, compute_lang=False, set_lang=False, post_process=False):
- """ Given some record ids, render a given field of template rendered on
- all records.
+ def _render_field(self, field, res_ids,
+ compute_lang=False, set_lang=False,
+ post_process=False):
+ """ Given some record ids, render a template located on field on all
+ records. ``field`` should be a field of self (i.e. ``body_html`` on
+ ``mail.template``). res_ids are record IDs linked to ``model`` field
+ on self.
:param list res_ids: list of ids of records (all belonging to same model
- defined by self.model)
- :param compute_lang: compute rendering language based on template.lang
- :param set_lang: force language
- :param post_process: perform rendered str / html post processing (see
- ``_render_template_postprocess``)
+ defined by ``self.model``)
+
+ :param boolean compute_lang: compute language to render on translated
+ version of the template instead of default (probably english) one.
+ Language will be computed based on ``self.lang``;
+ :param string set_lang: force language for rendering. It should be a
+ valid lang code matching an activate res.lang. Checked only if
+ ``compute_lang`` is False;
+ :param boolean post_process: perform a post processing on rendered result
+ (notably html links management). See``_render_template_postprocess``);
:return dict: {res_id: string of rendered template based on record}
"""
diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py
index 4a5e1461878..7287046d6cc 100644
--- a/addons/mail/tests/__init__.py
+++ b/addons/mail/tests/__init__.py
@@ -2,5 +2,6 @@
from . import common
from . import test_mail_full_composer
+from . import test_mail_render
from . import test_res_partner
from . import test_update_notification
diff --git a/addons/mail/tests/test_mail_render.py b/addons/mail/tests/test_mail_render.py
new file mode 100644
index 00000000000..2f14cbca97e
--- /dev/null
+++ b/addons/mail/tests/test_mail_render.py
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.mail.tests import common
+from odoo.tests import tagged, users
+
+
+@tagged('mail_render')
+class TestMailRender(common.MailCommon):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestMailRender, cls).setUpClass()
+
+ # activate multi language support
+ cls.env['res.lang']._activate_lang('fr_FR')
+ cls.user_admin.write({'lang': 'en_US'})
+
+ # test records
+ cls.render_object = cls.env['res.partner'].create({
+ 'name': 'TestRecord',
+ 'lang': 'en_US',
+ })
+ cls.render_object_fr = cls.env['res.partner'].create({
+ 'name': 'Element de Test',
+ 'lang': 'fr_FR',
+ })
+
+ # some jinja templates
+ cls.base_jinja_bits = [
+ '<p>Hello</p>',
+ '<p>Hello ${object.name}</p>',
+ """<p>
+% set english = object.lang == 'en_US'
+% if english
+ <span>English Speaker</span>
+% else
+ <span>Other Speaker</span>
+% endif
+</p>"""
+ ]
+ cls.base_jinja_bits_fr = [
+ '<p>Bonjour</p>',
+ '<p>Bonjour ${object.name}</p>',
+ """<p>
+% set english = object.lang == 'en_US'
+% if english
+ <span>Narrateur Anglais</span>
+% else
+ <span>Autre Narrateur</span>
+% endif
+</p>"""
+ ]
+
+ # some qweb templates and their xml ids
+ cls.base_qweb_templates = cls.env['ir.ui.view'].create([
+ {'name': 'TestRender', 'type': 'qweb',
+ 'arch': '<p>Hello</p>',
+ },
+ {'name': 'TestRender2', 'type': 'qweb',
+ 'arch': '<p>Hello <t t-esc="object.name"/></p>',
+ },
+ {'name': 'TestRender3', 'type': 'qweb',
+ 'arch': """<p>
+ <span t-if="object.lang == 'en_US'">English Speaker</span>
+ <span t-else="">Other Speaker</span>
+</p>""",
+ },
+ ])
+ cls.base_qweb_templates_data = cls.env['ir.model.data'].create([
+ {'name': template.name, 'module': 'mail',
+ 'model': template._name, 'res_id': template.id,
+ } for template in cls.base_qweb_templates
+ ])
+ cls.base_qweb_templates_xmlids = [
+ model_data.complete_name
+ for model_data in cls.base_qweb_templates_data
+ ]
+
+ # render result
+ cls.base_rendered = [
+ '<p>Hello</p>',
+ '<p>Hello %s</p>' % cls.render_object.name,
+ """<p>
+ <span>English Speaker</span>
+</p>"""
+ ]
+ cls.base_rendered_fr = [
+ '<p>Bonjour</p>',
+ '<p>Bonjour %s</p>' % cls.render_object_fr.name,
+ """<p>
+ <span>Autre Narrateur</span>
+</p>"""
+ ]
+
+ # link to mail template
+ cls.test_template_jinja = cls.env['mail.template'].create({
+ 'name': 'Test Template',
+ 'subject': cls.base_jinja_bits[0],
+ 'body_html': cls.base_jinja_bits[1],
+ 'model_id': cls.env['ir.model']._get('res.partner').id,
+ 'lang': '${object.lang}'
+ })
+
+ # some translations
+ cls.env['ir.translation'].create({
+ 'type': 'model',
+ 'name': 'mail.template,subject',
+ 'lang': 'fr_FR',
+ 'res_id': cls.test_template_jinja.id,
+ 'src': cls.test_template_jinja.subject,
+ 'value': cls.base_jinja_bits_fr[0],
+ })
+ cls.env['ir.translation'].create({
+ 'type': 'model',
+ 'name': 'mail.template,body_html',
+ 'lang': 'fr_FR',
+ 'res_id': cls.test_template_jinja.id,
+ 'src': cls.test_template_jinja.body_html,
+ 'value': cls.base_jinja_bits_fr[1],
+ })
+ cls.env['ir.model.data'].create({
+ 'name': 'test_template_xmlid',
+ 'module': 'mail',
+ 'model': cls.test_template_jinja._name,
+ 'res_id': cls.test_template_jinja.id,
+ })
+
+ @users('employee')
+ def test_render_jinja(self):
+ source = """<p>
+% set line_statement_variable = 3
+<span>We have ${line_statement_variable} cookies in stock</span>
+<span>We have <% set block_variable = 4 %>${block_variable} cookies in stock</span>
+</p>"""
+ partner = self.env['res.partner'].browse(self.render_object.ids)
+ result = self.env['mail.render.mixin']._render_template(
+ source,
+ partner._name,
+ partner.ids,
+ engine='jinja',
+ )[partner.id]
+ self.assertEqual(result, """<p>
+<span>We have 3 cookies in stock</span>
+<span>We have 4 cookies in stock</span>
+</p>""")
+
+ @users('employee')
+ def test_render_mail_template_jinja(self):
+ template = self.env['mail.template'].browse(self.test_template_jinja.ids)
+ partner = self.env['res.partner'].browse(self.render_object.ids)
+ for fname, expected in zip(['subject', 'body_html'], self.base_rendered):
+ rendered = template._render_field(
+ fname,
+ partner.ids,
+ compute_lang=True
+ )[partner.id]
+ self.assertEqual(rendered, expected)
+
+ partner = self.env['res.partner'].browse(self.render_object_fr.ids)
+ for fname, expected in zip(['subject', 'body_html'], self.base_rendered_fr):
+ rendered = template._render_field(
+ fname,
+ partner.ids,
+ compute_lang=True
+ )[partner.id]
+ self.assertEqual(rendered, expected)
+
+ @users('employee')
+ def test_render_template_jinja(self):
+ partner = self.env['res.partner'].browse(self.render_object.ids)
+ for source, expected in zip(self.base_jinja_bits, self.base_rendered):
+ rendered = self.env['mail.render.mixin']._render_template(
+ source,
+ partner._name,
+ partner.ids,
+ engine='jinja',
+ )[partner.id]
+ self.assertEqual(rendered, expected)
+
+ @users('employee')
+ def test_render_template_qweb(self):
+ partner = self.env['res.partner'].browse(self.render_object.ids)
+ for source, expected in zip(self.base_qweb_templates_xmlids, self.base_rendered):
+ rendered = self.env['mail.render.mixin']._render_template(
+ source,
+ partner._name,
+ partner.ids,
+ engine='qweb',
+ )[partner.id].decode()
+ self.assertEqual(rendered, expected)