[FIX] web, tools: static inheritance supports replace in debug mode

Have a parent template
Have a child, in extension inherit mode of the parent
The child has a xpath like
`<xpath expr="." position="replace" />`

Before this commit, there was a crash.
That was because the Comment
(which indicates which templates modified the parent)
was taken as the replacer node
instead of the actual content of the xpath

After this commit, there is no crash, and it works as expected

closes odoo/odoo#39453

X-original-commit: 02d790e1d21b78395e489f57bf30c82f728cbee6
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
Lucas Perais (lpe)
2019-10-28 14:15:53 +00:00
committed by fw-bot
parent eccfdd5512
commit bbbfca2d97
2 changed files with 281 additions and 1 deletions
+267
View File
@@ -450,3 +450,270 @@ class TestStaticInheritance(BaseCase):
after = datetime.now()
self.assertLessEqual(after - before, timedelta(milliseconds=1000))
def test_replace_in_debug_mode(self):
"""
Replacing a template's meta definition in place doesn't keep the original attrs of the template
"""
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="extension">
<xpath expr="." position="replace">
<div overriden-attr="overriden">And I grew strong</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form overriden-attr="overriden">
<!-- Modified by template_1_2 from module_1 -->And I grew strong
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_replace_in_debug_mode2(self):
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="extension">
<xpath expr="." position="replace">
<div>
And I grew strong
<p>And I learned how to get along</p>
And so you're back
</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form>
<!-- Modified by template_1_2 from module_1 -->And I grew strong
<p>And I learned how to get along</p>
And so you're back
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_replace_in_debug_mode3(self):
"""Text outside of a div which will replace a whole template
becomes outside of the template
This doesn't mean anything in terms of the business of template inheritance
But it is in the XPATH specs"""
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="extension">
<xpath expr="." position="replace">
<div>
And I grew strong
<p>And I learned how to get along</p>
</div>
And so you're back
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form>
<!-- Modified by template_1_2 from module_1 -->
And I grew strong
<p>And I learned how to get along</p>
</form>
And so you're back
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_replace_root_node_tag(self):
"""
Root node is not targeted by //NODE_TAG in xpath
"""
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
<form>Inner Form</form>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="extension">
<xpath expr="//form" position="replace">
<div>
Form replacer
</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
<!-- Modified by template_1_2 from module_1 -->
<div>Form replacer</div>
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_replace_root_node_tag_in_primary(self):
"""
Root node is not targeted by //NODE_TAG in xpath
"""
self.maxDiff = None
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
<form>Inner Form</form>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="primary">
<xpath expr="//form" position="replace">
<div>Form replacer</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
<form>Inner Form</form>
</form>
<form t-name="template_1_2" random-attr="gloria" t-inherit="template_1_1">
<div>At first I was afraid</div>
<div>Form replacer</div>
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_inherit_primary_replace_debug(self):
"""
The inheriting template has got both its own defining attrs
and new ones if one is to replace its defining root node
"""
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="primary">
<xpath expr="." position="replace">
<div overriden-attr="overriden">
And I grew strong
<p>And I learned how to get along</p>
</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=True)
expected = b"""
<templates>
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<form overriden-attr="overriden" t-name="template_1_2" t-inherit="template_1_1">
And I grew strong
<p>And I learned how to get along</p>
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
def test_replace_in_nodebug_mode1(self):
"""Comments already in the arch are ignored"""
self.modules = [
('module_1_file_1', None, 'module_1'),
]
self.template_files = {
'module_1_file_1': b"""
<templates id="template" xml:space="preserve">
<form t-name="template_1_1" random-attr="gloria">
<div>At first I was afraid</div>
</form>
<t t-name="template_1_2" t-inherit="template_1_1" t-inherit-mode="extension">
<xpath expr="." position="replace">
<div>
<!-- Random Comment -->
And I grew strong
<p>And I learned how to get along</p>
And so you're back
</div>
</xpath>
</t>
</templates>
""",
}
contents = HomeStaticTemplateHelpers.get_qweb_templates(addons=self._get_module_names(), debug=False)
expected = b"""
<templates>
<form>
And I grew strong
<p>And I learned how to get along</p>
And so you're back
</form>
</templates>
"""
self.assertXMLEqual(contents, expected)
+14 -1
View File
@@ -129,7 +129,20 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
loc.text = ''
loc.append(copy.deepcopy(node))
if node.getparent() is None:
source = copy.deepcopy(spec[0])
spec_content = None
comment = None
for content in spec:
if content.tag is not etree.Comment:
spec_content = content
break
else:
comment = content
source = copy.deepcopy(spec_content)
if comment is not None:
text = source.text
source.text = None
comment.tail = text
source.insert(0, comment)
else:
replaced_node_tag = None
for child in spec: