summaryrefslogtreecommitdiff
path: root/addons/web_editor/tests
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web_editor/tests
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web_editor/tests')
-rw-r--r--addons/web_editor/tests/__init__.py5
-rw-r--r--addons/web_editor/tests/test_converter.py223
-rw-r--r--addons/web_editor/tests/test_views.py64
3 files changed, 292 insertions, 0 deletions
diff --git a/addons/web_editor/tests/__init__.py b/addons/web_editor/tests/__init__.py
new file mode 100644
index 00000000..d399772d
--- /dev/null
+++ b/addons/web_editor/tests/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_converter
+from . import test_views
diff --git a/addons/web_editor/tests/test_converter.py b/addons/web_editor/tests/test_converter.py
new file mode 100644
index 00000000..3d9259ba
--- /dev/null
+++ b/addons/web_editor/tests/test_converter.py
@@ -0,0 +1,223 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import textwrap
+
+from lxml import etree, html
+from lxml.builder import E
+
+from odoo.tests import common
+from odoo.tests.common import BaseCase
+from odoo.addons.web_editor.models.ir_qweb import html_to_text
+
+
+class TestHTMLToText(BaseCase):
+ def test_rawstring(self):
+ self.assertEqual(
+ "foobar",
+ html_to_text(E.div("foobar")))
+
+ def test_br(self):
+ self.assertEqual(
+ "foo\nbar",
+ html_to_text(E.div("foo", E.br(), "bar")))
+
+ self.assertEqual(
+ "foo\n\nbar\nbaz",
+ html_to_text(E.div(
+ "foo", E.br(), E.br(),
+ "bar", E.br(),
+ "baz")))
+
+ def test_p(self):
+ self.assertEqual(
+ "foo\n\nbar\n\nbaz",
+ html_to_text(E.div(
+ "foo",
+ E.p("bar"),
+ "baz")))
+
+ self.assertEqual(
+ "foo",
+ html_to_text(E.div(E.p("foo"))))
+
+ self.assertEqual(
+ "foo\n\nbar",
+ html_to_text(E.div("foo", E.p("bar"))))
+ self.assertEqual(
+ "foo\n\nbar",
+ html_to_text(E.div(E.p("foo"), "bar")))
+
+ self.assertEqual(
+ "foo\n\nbar\n\nbaz",
+ html_to_text(E.div(
+ E.p("foo"),
+ E.p("bar"),
+ E.p("baz"),
+ )))
+
+ def test_div(self):
+ self.assertEqual(
+ "foo\nbar\nbaz",
+ html_to_text(E.div(
+ "foo",
+ E.div("bar"),
+ "baz"
+ )))
+
+ self.assertEqual(
+ "foo",
+ html_to_text(E.div(E.div("foo"))))
+
+ self.assertEqual(
+ "foo\nbar",
+ html_to_text(E.div("foo", E.div("bar"))))
+ self.assertEqual(
+ "foo\nbar",
+ html_to_text(E.div(E.div("foo"), "bar")))
+
+ self.assertEqual(
+ "foo\nbar\nbaz",
+ html_to_text(E.div(
+ "foo",
+ E.div("bar"),
+ E.div("baz")
+ )))
+
+ def test_other_block(self):
+ self.assertEqual(
+ "foo\nbar\nbaz",
+ html_to_text(E.div(
+ "foo",
+ E.section("bar"),
+ "baz"
+ )))
+
+ def test_inline(self):
+ self.assertEqual(
+ "foobarbaz",
+ html_to_text(E.div("foo", E.span("bar"), "baz")))
+
+ def test_whitespace(self):
+ self.assertEqual(
+ "foo bar\nbaz",
+ html_to_text(E.div(
+ "foo\nbar",
+ E.br(),
+ "baz")
+ ))
+
+ self.assertEqual(
+ "foo bar\nbaz",
+ html_to_text(E.div(
+ E.div(E.span("foo"), " bar"),
+ "baz")))
+
+
+class TestConvertBack(common.TransactionCase):
+ def setUp(self):
+ super(TestConvertBack, self).setUp()
+ self.env = self.env(context={'inherit_branding': True})
+
+ def field_rountrip_result(self, field, value, expected):
+ model = 'web_editor.converter.test'
+ record = self.env[model].create({field: value})
+
+ t = etree.Element('t')
+ e = etree.Element('span')
+ t.append(e)
+ field_value = 'record.%s' % field
+ e.set('t-field', field_value)
+
+ rendered = self.env['ir.qweb']._render(t, {'record': record})
+
+ element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8'))
+ model = 'ir.qweb.field.' + element.get('data-oe-type', '')
+ converter = self.env[model] if model in self.env else self.env['ir.qweb.field']
+ value_back = converter.from_html(model, record._fields[field], element)
+
+ if isinstance(expected, bytes):
+ expected = expected.decode('utf-8')
+ self.assertEqual(value_back, expected)
+
+ def field_roundtrip(self, field, value):
+ self.field_rountrip_result(field, value, value)
+
+ def test_integer(self):
+ self.field_roundtrip('integer', 42)
+
+ def test_float(self):
+ self.field_roundtrip('float', 42.567890)
+ self.field_roundtrip('float', 324542.567890)
+
+ def test_numeric(self):
+ self.field_roundtrip('numeric', 42.77)
+
+ def test_char(self):
+ self.field_roundtrip('char', "foo bar")
+ self.field_roundtrip('char', "ⒸⓄⓇⒼⒺ")
+
+ def test_selection_str(self):
+ self.field_roundtrip('selection_str', 'B')
+
+ def test_text(self):
+ self.field_roundtrip('text', textwrap.dedent("""\
+ You must obey the dance commander
+ Givin' out the order for fun
+ You must obey the dance commander
+ You know that he's the only one
+ Who gives the orders here,
+ Alright
+ Who gives the orders here,
+ Alright
+
+ It would be awesome
+ If we could dance-a
+ It would be awesome, yeah
+ Let's take the chance-a
+ It would be awesome, yeah
+ Let's start the show
+ Because you never know
+ You never know
+ You never know until you go"""))
+
+ def test_m2o(self):
+ """ the M2O field conversion (from html) is markedly different from
+ others as it directly writes into the m2o and returns nothing at all.
+ """
+ field = 'many2one'
+
+ subrec1 = self.env['web_editor.converter.test.sub'].create({'name': "Foo"})
+ subrec2 = self.env['web_editor.converter.test.sub'].create({'name': "Bar"})
+ record = self.env['web_editor.converter.test'].create({field: subrec1.id})
+
+ t = etree.Element('t')
+ e = etree.Element('span')
+ t.append(e)
+ field_value = 'record.%s' % field
+ e.set('t-field', field_value)
+
+ rendered = self.env['ir.qweb']._render(t, {'record': record})
+ element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8'))
+
+ # emulate edition
+ element.set('data-oe-many2one-id', str(subrec2.id))
+ element.text = "New content"
+
+ model = 'ir.qweb.field.' + element.get('data-oe-type')
+ converter = self.env[model] if model in self.env else self.env['ir.qweb.field']
+ value_back = converter.from_html('web_editor.converter.test', record._fields[field], element)
+
+ self.assertIsNone(
+ value_back, "the m2o converter should return None to avoid spurious"
+ " or useless writes on the parent record")
+ self.assertEqual(
+ subrec1.name,
+ "Foo",
+ "element edition can't change directly the m2o record"
+ )
+ self.assertEqual(
+ record.many2one.name,
+ "Bar",
+ "element edition should have been change the m2o id"
+ )
diff --git a/addons/web_editor/tests/test_views.py b/addons/web_editor/tests/test_views.py
new file mode 100644
index 00000000..322e2a78
--- /dev/null
+++ b/addons/web_editor/tests/test_views.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.tests import TransactionCase
+
+
+class TestViews(TransactionCase):
+
+ def setUp(self):
+ super().setUp()
+ View = self.env['ir.ui.view']
+ self.first_view = View.create({
+ 'name': 'Test View 1',
+ 'type': 'qweb',
+ 'arch': '<div>Hello World</div>',
+ 'key': 'web_editor.test_first_view',
+ })
+ self.second_view = View.create({
+ 'name': 'Test View 2',
+ 'type': 'qweb',
+ 'arch': '<div><t t-call="web_editor.test_first_view"/></div>',
+ 'key': 'web_editor.test_second_view',
+ })
+
+ def test_infinite_inherit_loop(self):
+ # Creates an infinite loop: A t-call B and A inherit from B
+ View = self.env['ir.ui.view']
+
+ self.second_view.write({
+ 'inherit_id': self.first_view.id,
+ })
+ # Test for RecursionError: maximum recursion depth exceeded in this function
+ View._views_get(self.first_view)
+
+ def test_oe_structure_as_inherited_view(self):
+ View = self.env['ir.ui.view']
+
+ base = View.create({
+ 'name': 'Test View oe_structure',
+ 'type': 'qweb',
+ 'arch': """<xpath expr='//t[@t-call="web_editor.test_first_view"]' position='after'>
+ <div class="oe_structure" id='oe_structure_test_view_oe_structure'/>
+ </xpath>""",
+ 'key': 'web_editor.oe_structure_view',
+ 'inherit_id': self.second_view.id
+ })
+
+ # check view mode
+ self.assertEqual(base.mode, 'extension')
+
+ # update content of the oe_structure
+ value = '''<div class="oe_structure" id="oe_structure_test_view_oe_structure" data-oe-id="%s"
+ data-oe-xpath="/div" data-oe-model="ir.ui.view" data-oe-field="arch">
+ <p>Hello World!</p>
+ </div>''' % base.id
+
+ base.save(value=value, xpath='/xpath/div')
+
+ self.assertEqual(len(base.inherit_children_ids), 1)
+ self.assertEqual(base.inherit_children_ids.mode, 'extension')
+ self.assertIn(
+ '<p>Hello World!</p>',
+ base.inherit_children_ids.read_combined(['arch'])['arch'],
+ )