diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web_editor/tests | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web_editor/tests')
| -rw-r--r-- | addons/web_editor/tests/__init__.py | 5 | ||||
| -rw-r--r-- | addons/web_editor/tests/test_converter.py | 223 | ||||
| -rw-r--r-- | addons/web_editor/tests/test_views.py | 64 |
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'], + ) |
