def test_format_test_address_valid(self) -> None: """Given a valid test_address and recipient_address, it returns the test address with the recipient email address name appended.""" expected = "*****@*****.**" actual = utils.format_test_address("*****@*****.**", "*****@*****.**") self.assertEqual(expected, actual)
def start(state_code: str, report_type: str, test_address: Optional[str] = None) -> str: """Begins data retrieval for a new batch of email reports. Start with collection of data from the calculation pipelines. If a test_address is provided, it overrides the recipient's email_address with a formatted test_address and uses the formatted test_address to save the generated emails. Args: state_code: The state for which to generate reports report_type: The type of report to send test_address: Optional email address for which to generate all emails Returns: The batch id for the newly started batch """ batch_id = utils.generate_batch_id() logging.info("New batch started for %s and %s. Batch id = %s", state_code, report_type, batch_id) recipient_data = retrieve_data(state_code, report_type, batch_id) for recipient in recipient_data: if test_address: recipient_email_address = recipient[utils.KEY_EMAIL_ADDRESS] formatted_test_address = utils.format_test_address( test_address, recipient_email_address) # Override the recipient's address with the test address recipient[utils.KEY_EMAIL_ADDRESS] = formatted_test_address logging.info("Generating email for [%s] with test address: %s", recipient_email_address, formatted_test_address) recipient[utils.KEY_BATCH_ID] = batch_id report_context = get_report_context(state_code, report_type, recipient) email_generation.generate(report_context) return batch_id
def test_format_test_address_invalid_recipient(self) -> None: """Given an invalid recipient address, it raises a ValueError.""" with self.assertRaises(ValueError): utils.format_test_address("*****@*****.**", "invalid recipient address")
def test_format_test_address_invalid(self) -> None: """Given an invalid test address, it raises a ValueError.""" with self.assertRaises(ValueError): utils.format_test_address("random string", "*****@*****.**")
def start( state_code: str, report_type: str, batch_id: Optional[str] = None, test_address: Optional[str] = None, region_code: Optional[str] = None, email_allowlist: Optional[List[str]] = None, message_body: Optional[str] = None, ) -> Tuple[int, int]: """Begins data retrieval for a new batch of email reports. Start with collection of data from the calculation pipelines. If a test_address is provided, it overrides the recipient's email_address with a formatted test_address and uses the formatted test_address to save the generated emails. Args: state_code: The state for which to generate reports report_type: The type of report to send batch_id: The batch id to save the newly started batch to test_address: Optional email address for which to generate all emails region_code: Optional region code which specifies the sub-region of the state in which to generate reports. If empty, this generates reports for all regions. email_allowlist: Optional list of email_addresses to generate for; all other recipients are skipped recipient_emails: Optional list of email_addresses to generate for; all other recipients are skipped message_body: Optional override for the message body in the email. Returns: Tuple containing: - Number of failed email generations - Number of successful email generations """ if batch_id is None: batch_id = utils.generate_batch_id() logging.info( "New batch started for %s (region: %s) and %s. Batch id = %s", state_code, region_code, report_type, batch_id, ) recipients: List[Recipient] = retrieve_data(state_code, report_type, batch_id) recipients = filter_recipients(recipients, region_code, email_allowlist) if test_address: logging.info("Overriding batch emails with test address: %s", test_address) recipients = [ recipient.create_derived_recipient( { "email_address": utils.format_test_address( test_address, recipient.email_address ), } ) for recipient in recipients ] if message_body is not None: logging.info( "Overriding default message body in batch emails (batch id = %s)", batch_id ) recipients = [ recipient.create_derived_recipient({"message_body": message_body}) for recipient in recipients ] failure_count = 0 success_count = 0 for recipient in recipients: try: report_context = get_report_context(state_code, report_type, recipient) email_generation.generate(report_context) except Exception as e: failure_count += 1 logging.error("Failed to generate report email for %s %s", recipient, e) else: success_count += 1 return failure_count, success_count
def start( state_code: StateCode, report_type: ReportType, batch_id: Optional[str] = None, test_address: Optional[str] = None, region_code: Optional[str] = None, email_allowlist: Optional[List[str]] = None, message_body_override: Optional[str] = None, ) -> MultiRequestResult[str, str]: """Begins data retrieval for a new batch of email reports. Start with collection of data from the calculation pipelines. If a test_address is provided, it overrides the recipient's email_address with a formatted test_address and uses the formatted test_address to save the generated emails. Args: state_code: The state for which to generate reports report_type: The type of report to send batch_id: The batch id to save the newly started batch to test_address: Optional email address for which to generate all emails region_code: Optional region code which specifies the sub-region of the state in which to generate reports. If empty, this generates reports for all regions. email_allowlist: Optional list of email_addresses to generate for; all other recipients are skipped recipient_emails: Optional list of email_addresses to generate for; all other recipients are skipped message_body_override: Optional override for the message body in the email. Returns: A MultiRequestResult containing the email addresses for which reports were successfully generated for and failed to generate for """ if batch_id is None: batch_id = utils.generate_batch_id() logging.info( "New batch started for %s (region: %s) and %s. Batch id = %s", state_code, region_code, report_type, batch_id, ) recipients: List[Recipient] = retrieve_data(state_code, report_type, batch_id) recipients = filter_recipients(recipients, region_code, email_allowlist) if test_address: logging.info("Overriding batch emails with test address: %s", test_address) recipients = [ recipient.create_derived_recipient( { "email_address": utils.format_test_address( test_address, recipient.email_address ), } ) for recipient in recipients ] if message_body_override is not None: logging.info( "Overriding default message body in batch emails (batch id = %s)", batch_id ) recipients = [ recipient.create_derived_recipient( {"message_body_override": message_body_override} ) for recipient in recipients ] failed_email_addresses: List[str] = [] succeeded_email_addresses: List[str] = [] # Currently this is only used to pass review month & year, but when we need to add # more, the way that we do this should likely be changed/refactored. metadata: Dict[str, str] = {} for recipient in recipients: try: report_context = get_report_context(state_code, report_type, recipient) email_generation.generate(report_context) except Exception as e: failed_email_addresses.append(recipient.email_address) logging.error("Failed to generate report email for %s %s", recipient, e) else: succeeded_email_addresses.append(recipient.email_address) if report_type == ReportType.POMonthlyReport and len(metadata) == 0: metadata["review_year"] = recipient.data["review_year"] metadata["review_month"] = recipient.data["review_month"] _write_batch_metadata( batch_id=batch_id, state_code=state_code, report_type=report_type, **metadata, ) return MultiRequestResult( successes=succeeded_email_addresses, failures=failed_email_addresses )