From 8c93bda1ba187f32430fc8cfbdcca4c028ac295f Mon Sep 17 00:00:00 2001 From: willeM_ Van Onsem <3482343+KommuSoft@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:23:07 +0100 Subject: [PATCH] Move logic to render HTML and text content to dedicated methods, fixing #21. (#22) * Move logic to render HTML and text content to dedicated methods, fixing #21. * `_generate_html_content()` and `_generate_text_content()` to protected methods. * added tests fo `_generate_html_content()` and `_generate_text_content()`. * linting --------- Co-authored-by: Willem Van Onsem --- django_pony_express/services/base.py | 25 ++++++++----- tests/services/base/test_base_mail_service.py | 37 +++++++++++++++++++ 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/django_pony_express/services/base.py b/django_pony_express/services/base.py index 410fdcb..3df985f 100644 --- a/django_pony_express/services/base.py +++ b/django_pony_express/services/base.py @@ -230,6 +230,19 @@ def _add_attachments(self, msg: EmailMultiAlternatives): return msg + def _generate_html_content(self, mail_attributes: dict) -> str: + return render_to_string(self.template_name, mail_attributes) + + def _generate_text_content(self, mail_attributes: dict, html_content: str) -> str: + # Render TXT body part if a template is explicitly set, otherwise convert HTML template to plain text + if not self.template_txt_name: + h = html2text.HTML2Text() + # Set body width to "infinite" to avoid weird line breaks + h.body_width = 0 + return h.handle(html_content) + else: + return render_to_string(self.template_txt_name, mail_attributes) + def _build_mail_object(self) -> EmailMultiAlternatives: """ This method creates a mail object. It collects the required variables, sets the subject and makes sure that @@ -245,16 +258,8 @@ def _build_mail_object(self) -> EmailMultiAlternatives: mail_attributes = self.get_context_data() # Render HTML body content - html_content = render_to_string(self.template_name, mail_attributes) - - # Render TXT body part if a template is explicitly set, otherwise convert HTML template to plain text - if not self.template_txt_name: - h = html2text.HTML2Text() - # Set body width to "infinite" to avoid weird line breaks - h.body_width = 0 - text_content = h.handle(html_content) - else: - text_content = render_to_string(self.template_txt_name, mail_attributes) + html_content = self._generate_html_content(mail_attributes) + text_content = self._generate_text_content(mail_attributes, html_content) # Build mail object msg = EmailMultiAlternatives( diff --git a/tests/services/base/test_base_mail_service.py b/tests/services/base/test_base_mail_service.py index 01d279e..0c27a74 100644 --- a/tests/services/base/test_base_mail_service.py +++ b/tests/services/base/test_base_mail_service.py @@ -406,3 +406,40 @@ def test_process_with_error(self): def test_process_is_valid_invalid(self, *args): factory = BaseEmailService() self.assertEqual(factory.process(), 0) + + def test_html_templates_rendering(self): + my_var = "Lorem ipsum dolor!" + service = BaseEmailService() + service.template_name = "testapp/test_email.html" + msg_html = service._generate_html_content({"my_var": my_var}) + + # Assertions + self.assertIsInstance(msg_html, str) + + self.assertIn("Lorem ipsum dolor", msg_html) + self.assertNotIn("I am a different content", msg_html) + + def test_text_templates_rendering(self): + my_var = "Lorem ipsum dolor!" + service = BaseEmailService() + service.template_txt_name = "testapp/test_email.txt" + msg_html = service._generate_text_content({"my_var": my_var}, "") + + # Assertions + self.assertIsInstance(msg_html, str) + + self.assertIn("Lorem ipsum dolor", msg_html) + self.assertIn("I am a different content", msg_html) + self.assertNotIn("Current date test", msg_html) + + def test_text_templates_rendering_fallback(self): + my_var = "Lorem ipsum dolor!" + service = BaseEmailService() + msg_html = service._generate_text_content({"my_var": my_var}, "Lorem ipsum dolor") + + # Assertions + self.assertIsInstance(msg_html, str) + + self.assertIn("Lorem ipsum dolor", msg_html) + self.assertNotIn("I am a different content", msg_html) + self.assertNotIn("Current date test", msg_html)