[FIX] mail_debrand: tolerate binary inputs, solve etree FutureWarning

This commit is contained in:
Daniel Reis 2021-03-15 18:44:13 +00:00 committed by AlvaroTForgeFlow
parent d3de34627b
commit 7f6b13b660
2 changed files with 17 additions and 3 deletions

View File

@ -15,17 +15,20 @@ class MailRenderMixin(models.AbstractModel):
def remove_href_odoo(self, value, remove_parent=True, remove_before=False): def remove_href_odoo(self, value, remove_parent=True, remove_before=False):
if len(value) < 20: if len(value) < 20:
return value return value
# value can be bytes type; ensure we get a proper string
if type(value) is bytes:
value = value.decode()
has_odoo_link = re.search(r"<a\s(.*)odoo\.com", value, flags=re.IGNORECASE) has_odoo_link = re.search(r"<a\s(.*)odoo\.com", value, flags=re.IGNORECASE)
if has_odoo_link: if has_odoo_link:
tree = etree.HTML( tree = etree.HTML(
value value
) # html with brlken links tree = etree.fromstring(value) just xml ) # html with broken links tree = etree.fromstring(value) just xml
odoo_achors = tree.xpath('//a[contains(@href,"odoo.com")]') odoo_achors = tree.xpath('//a[contains(@href,"odoo.com")]')
for elem in odoo_achors: for elem in odoo_achors:
parent = elem.getparent() parent = elem.getparent()
previous = elem.getprevious() previous = elem.getprevious()
if remove_before and not remove_parent and previous: if remove_before and not remove_parent and len(previous):
# remove 'using' that is before <a and after </span> # remove 'using' that is before <a and after </span>
bytes_text = etree.tostring( bytes_text = etree.tostring(
previous, pretty_print=True, method="html" previous, pretty_print=True, method="html"
@ -33,7 +36,7 @@ class MailRenderMixin(models.AbstractModel):
only_what_is_in_tags = bytes_text[: bytes_text.rfind(b">") + 1] only_what_is_in_tags = bytes_text[: bytes_text.rfind(b">") + 1]
data_formatted = html.fromstring(only_what_is_in_tags) data_formatted = html.fromstring(only_what_is_in_tags)
parent.replace(previous, data_formatted) parent.replace(previous, data_formatted)
if len(parent.getparent()) and remove_parent: if remove_parent and len(parent.getparent()):
# anchor <a href odoo has a parent powered by that must be removed # anchor <a href odoo has a parent powered by that must be removed
parent.getparent().remove(parent) parent.getparent().remove(parent)
else: else:

View File

@ -13,6 +13,17 @@ class TestMailDebrand(common.TransactionCase):
self.default_template = self.env.ref("mail.message_notification_email") self.default_template = self.env.ref("mail.message_notification_email")
self.paynow_template = self.env.ref("mail.mail_notification_paynow") self.paynow_template = self.env.ref("mail.mail_notification_paynow")
def test_debrand_binary_value(self):
"""
Regression test: ensure binary input is gracefully handled
"""
try:
self.env["mail.template"].remove_href_odoo(
b"Binary value with more than 20 characters"
)
except TypeError:
self.fail("Debranding binary string raised TypeError")
def test_default_debrand(self): def test_default_debrand(self):
self.assertIn("using", self.default_template.arch) self.assertIn("using", self.default_template.arch)
res = self.env["mail.template"]._render_template( res = self.env["mail.template"]._render_template(