Source code for notifications.tests.common_functions

import logging

from post_office.models import Email

from tests.test_manager import CobaltTestManagerIntegration

logger = logging.getLogger("cobalt")


[docs] def check_email_sent( manager: CobaltTestManagerIntegration = None, test_name: str = "", test_description: str = "", email_to: str = None, subject_search: str = None, body_search: str = None, email_count: int = 20, debug: bool = False, save_results: bool = True, ): """ Check if an email has been sent. This isn't the greatest test going around. Email addresses get changed by the playpen checks and you can also find older emails that match by accident. Emails really need to be manually tested as you need to look at the presentation as well as the content, but this is better than nothing. NOTE: This is used by both integration tests and smoke tests Search parameters will combine, e.g. if you provide email_to and subject_search then both need to match for this to succeed. Args: manager: standard manager object (only needed if save_results=True) test_name: Name for this test to appear in report (only needed if save_results=True) test_description: Description for this test (only needed if save_results=True) subject_search: string to search for in the email subject body_search: string to search for in the email body email_to: first name of person sent the email. Assumes using normal templates for this. email_count: how many recent emails to look through debug: print diagnostics save_results: flag to save results (for integration tests) or not (for smoke tests) """ try: last_email = Email.objects.order_by("-pk")[0].pk except (AttributeError, IndexError): error_message = "Email Check: No emails found at all - emails are empty" if debug: logger.critical(error_message) if save_results: manager.save_results( status=False, output=error_message, test_name=test_name, test_description=test_description, ) return False, error_message # We can't use the ORM to filter emails, we need to call Django Post Office functions emails = Email.objects.filter(id__gt=last_email - email_count) ok, output = _check_email_sent_tests( email_count, email_to, emails, subject_search, body_search, debug, ) output += f" Result was '{ok}'" if save_results: manager.save_results( status=ok, output=output, test_name=test_name, test_description=test_description, ) return ok, output
def _check_email_sent_tests_list_emails(debug, emails): """sub of _check_email_sent_tests. Lists emails if debug is set""" if debug: mail_count = Email.objects.count() logger.debug(f"There are {mail_count} emails. Email list follows") for email in emails: logger.debug( # f"To: {email.context['name']} Subject: {email.context['title']}" f"{email} - Check later. Cannot get context" ) def _check_email_sent_tests_handle_email_to(output, email_to, emails, debug): """sub of _check_email_sent_tests""" if debug: logger.debug(f"Checking {emails.count()} emails.") ok = False output += f"Looking for to={email_to}. " for email in emails: try: if email.context["name"] == email_to: ok = True _debug_mail_print(email, debug, "email_to", email_to) else: emails = emails.exclude(pk=email.id) except TypeError: if debug: logger.debug( "Email Check: TypeError exception in checking email_to. email.context['name'] not found." ) # Remove email if no match if not ok: emails = emails = emails.exclude(pk=email.id) if debug: logger.debug( f"Finished handle_email_to. There are now {emails.count()} emails." ) return ok, output, emails def _check_email_sent_tests_handle_subject(output, subject_search, debug, emails): """sub of _check_email_sent_tests to handle subject searches""" if debug: logger.debug(f"Checking {emails.count()} emails.") ok = False output += f"looking for '{subject_search}' in subject. " for email in emails: try: if email.context["subject"].find(subject_search) >= 0: ok = True _debug_mail_print(email, debug, "subject", subject_search) except TypeError: if debug: print( "Email Check: TypeError exception in checking subject_search. email.context['name'] not found." ) # Remove email if no match if not ok: emails = emails.exclude(pk=email.id) if debug: logger.debug( f"Finished handle_email_to. There are now {emails.count()} emails." ) return ok, output, emails def _check_email_sent_tests_handle_body(output, body_search, debug, emails): """sub of _check_email_sent_tests to handle searching the email body""" if debug: logger.debug(f"Checking {emails.count()} emails.") ok = False output += f"body contains '{body_search}' " for email in emails: try: if email.context["email_body"].find(body_search) >= 0: ok = True _debug_mail_print(email, debug, "body", "body too long for debug") except TypeError: if debug: logger.debug( "Email Check: TypeError exception in checking body_search. email.context['name'] not found." ) # Remove email if no match if not ok: emails = emails.exclude(pk=email.id) if debug: logger.debug(f"Finished handle_body. There are now {emails.count()} emails.") return ok, output, emails def _check_email_sent_tests( email_count, email_to, emails, subject_search, body_search, debug=False ): """Sub step of check_email_sent. Does the actual checking.""" ok = False if not emails: return False, "No emails found at all. Could not search." _check_email_sent_tests_list_emails(debug, emails) # Output string has a story to tell output = f"Looked through last {email_count} emails for an email matching search criteria. " if email_to: ok, output, emails = _check_email_sent_tests_handle_email_to( output, email_to, emails, debug ) if not ok: output += "Failed on email_to." if debug: logger.debug( "Email Check: Failed to match any emails in email_to check" ) return ok, output if subject_search: ok, output, emails = _check_email_sent_tests_handle_subject( output, subject_search, debug, emails ) if not ok: output += "Failed on subject_search." if debug: logger.debug( "Email Check: Failed to match any emails in subject_search check" ) return ok, output if body_search: ok, output, emails = _check_email_sent_tests_handle_body( output, body_search, debug, emails ) if not ok: output += "Failed on body_search." if debug: logger.debug( "Email Check: Failed to match any emails in body_search check" ) return ok, output output += f"Matched on {emails.count()} emails. Emails were {emails}" return ok, output def _debug_mail_print(email, debug, check, search_str): """helper to print debug info for email searches""" if not debug: return logger.debug( f"debug: {check}: looked for '{search_str}'. Match: id: {email.id} to: {email.context['name']} subject: {email.context['subject']}" )