diff --git a/manage_breast_screening/notifications/services/nhs_mail.py b/manage_breast_screening/notifications/services/nhs_mail.py index 289a8b087..ce948b300 100644 --- a/manage_breast_screening/notifications/services/nhs_mail.py +++ b/manage_breast_screening/notifications/services/nhs_mail.py @@ -6,6 +6,8 @@ from logging import getLogger from smtplib import SMTP +from django.template.loader import render_to_string + logger = getLogger(__name__) SMTP_SERVER = "smtp.office365.com" @@ -55,7 +57,7 @@ def send_report_email( def _get_email_content(self, attachment_data, attachment_filename, report_type): todays_date = datetime.today().strftime("%d-%m-%Y") content = ( - self.failure_report_content(todays_date) + self.invites_not_sent_content(todays_date) if report_type == "invites_not_sent" else self.aggregate_report_content(todays_date) ) @@ -76,19 +78,17 @@ def _get_email_content(self, attachment_data, attachment_filename, report_type): return message - def failure_report_content(self, date) -> dict[str, str]: + def invites_not_sent_content(self, date) -> dict[str, str]: return { - "subject": self._failure_report_subject_text(date), - "body": self._failure_report_body_text(), + "subject": self._invites_not_sent_subject_text(date), + "body": self._invites_not_sent_body_text(), } - def _failure_report_subject_text(self, date) -> str: + def _invites_not_sent_subject_text(self, date) -> str: return f"Breast screening digital comms invites not sent report – {date} – Birmingham (MCR)" - def _failure_report_body_text(self) -> str: - return f"""Hello \n - Please find invites not sent report attached. \n - For any questions please email {self._sender_email}""" + def _invites_not_sent_body_text(self) -> str: + return render_to_string("report_emails/invites_not_sent.html") def aggregate_report_content(self, date) -> dict[str, str]: return { @@ -100,6 +100,4 @@ def _aggregate_report_subject_text(self, date) -> str: return f"Breast screening digital comms daily aggregate report – {date} – Birmingham (MCR)" def _aggregate_report_body_text(self) -> str: - return f"""Hello \n - Please find daily aggregate report attached. \n - For any questions please email {self._sender_email}""" + return render_to_string("report_emails/aggregate.html") diff --git a/manage_breast_screening/notifications/templates/report_emails/aggregate.html b/manage_breast_screening/notifications/templates/report_emails/aggregate.html new file mode 100644 index 000000000..a86912a86 --- /dev/null +++ b/manage_breast_screening/notifications/templates/report_emails/aggregate.html @@ -0,0 +1,11 @@ + +
+Hello.
++ Attached to the email is the daily report for breast screening digital + comms. For more information on the data in the report, please check the + guidance here. +
+Thank you.
+ + diff --git a/manage_breast_screening/notifications/templates/report_emails/invites_not_sent.html b/manage_breast_screening/notifications/templates/report_emails/invites_not_sent.html new file mode 100644 index 000000000..b1c0a3b9a --- /dev/null +++ b/manage_breast_screening/notifications/templates/report_emails/invites_not_sent.html @@ -0,0 +1,12 @@ + + +Hello.
++ It's important that you take action when you receive this email.This is a + list of clients who we haven't been able to invite to their breast + screening appointment. +
+Please contact them using your standard operating procedure
+Thank you.
+ + diff --git a/manage_breast_screening/notifications/tests/services/test_nhs_mail.py b/manage_breast_screening/notifications/tests/services/test_nhs_mail.py index bc396d514..d11671783 100644 --- a/manage_breast_screening/notifications/tests/services/test_nhs_mail.py +++ b/manage_breast_screening/notifications/tests/services/test_nhs_mail.py @@ -1,8 +1,7 @@ -import base64 import email import smtplib from datetime import datetime -from email.header import decode_header +from email.header import decode_header, make_header from unittest.mock import ANY, MagicMock, patch import pytest @@ -54,22 +53,29 @@ def test_sends_a_failure_report_email(self, mock_smtp_server, csv_data): mock_smtp_server.sendmail.assert_called_once_with( "sender@nhsmail.net", ["recipient@nhsmail.net"], ANY ) + email_content = mock_smtp_server.sendmail.call_args[0][2] + mime_message = email.message_from_string(email_content) - decoded_email = email.message_from_string(email_content) - decoded_subject_line = decode_header(decoded_email["Subject"])[0][0].decode( - "utf-8" - ) + decoded_subject_line = str(make_header(decode_header(mime_message["Subject"]))) assert ( "Breast screening digital comms invites not sent report – 11-10-2025 – Birmingham (MCR)" in decoded_subject_line ) - assert "Please find invites not sent report attached." in email_content + assert ( + "It's important that you take action when you receive this email" + in email_content + ) + assert "filename.csv" in email_content - decoded_attachment_data = base64.b64encode(csv_data.encode("utf-8")).decode( - "utf-8" + decoded_attachment_data = ( + mime_message.get_payload()[1] # type: ignore + .get_payload( # type: ignore + None, True + ) + .decode("utf-8") # type: ignore ) - assert decoded_attachment_data in email_content + assert csv_data in decoded_attachment_data def test_sends_an_aggregate_report_email(self, mock_smtp_server, csv_data): subject = NhsMail() @@ -80,23 +86,27 @@ def test_sends_an_aggregate_report_email(self, mock_smtp_server, csv_data): "sender@nhsmail.net", ["recipient@nhsmail.net"], ANY ) email_content = mock_smtp_server.sendmail.call_args[0][2] + mime_message = email.message_from_string(email_content) - decoded_email = email.message_from_string(email_content) - decoded_subject_line = decode_header(decoded_email["Subject"])[0][0].decode( - "utf-8" - ) + decoded_subject_line = str(make_header(decode_header(mime_message["Subject"]))) assert ( "Breast screening digital comms daily aggregate report – 11-10-2025 – Birmingham (MCR)" in decoded_subject_line ) - assert "Please find invites not sent report attached." not in email_content - assert "Please find daily aggregate report attached." in email_content + assert ( + "Attached to the email is the daily report for breast screening digital" + in email_content + ) assert "filename.csv" in email_content - decoded_attachment_data = base64.b64encode(csv_data.encode("utf-8")).decode( - "utf-8" + decoded_attachment_data = ( + mime_message.get_payload()[1] # type: ignore + .get_payload( # type: ignore + None, True + ) + .decode("utf-8") # type: ignore ) - assert decoded_attachment_data in email_content + assert csv_data in decoded_attachment_data def test_raises_exception_if_email_fails(self, mock_smtp_server, csv_data): mock_smtp_server.sendmail.side_effect = smtplib.SMTPException