def send_verification_email( strategy, backend, code, partial_token ): # pylint: disable=unused-argument """ Sends a verification email for python-social-auth Args: strategy (social_django.strategy.DjangoStrategy): the strategy used to authenticate backend (social_core.backends.base.BaseAuth): the backend being used to authenticate code (social_django.models.Code): the confirmation code used to confirm the email address partial_token (str): token used to resume a halted pipeline """ url = "{}?verification_code={}&partial_token={}".format( strategy.build_absolute_uri(reverse("register-confirm")), quote_plus(code.code), quote_plus(partial_token), ) api.send_messages( list( api.messages_for_recipients( [ ( code.email, api.context_for_user(extra_context={"confirmation_url": url}), ) ], VERIFICATION_TEMPLATE_NAME, ) ) )
def test_messages_for_recipients(): """Tests that messages_for_recipients works as expected""" users = UserFactory.create_batch(5) messages = list( messages_for_recipients( [ ( recipient, context_for_user( user=user, extra_context={"url": "https://example.com"} ), ) for recipient, user in safe_format_recipients(users) ], "sample", ) ) assert len(messages) == len(users) for user, msg in zip(users, messages): assert user.email in str(msg.to[0]) assert msg.subject == "Welcome {}".format(user.name)
def test_send_message_failure(mocker): """Tests that send_messages logs all exceptions""" sendmail = mocker.patch("mail.api.AnymailMessage.send", side_effect=ConnectionError) patched_logger = mocker.patch("mail.api.log") users = UserFactory.create_batch(2) messages = list( messages_for_recipients( [ ( recipient, context_for_user( user=user, extra_context={"url": "https://example.com"} ), ) for recipient, user in safe_format_recipients(users) ], "sample", ) ) send_messages(messages) assert sendmail.call_count == len(users) assert patched_logger.exception.call_count == len(users)
def send_verification_email(strategy, backend, code, partial_token): # pylint: disable=unused-argument """ Sends a verification email for python-social-auth Args: strategy (social_django.strategy.DjangoStrategy): the strategy used to authenticate backend (social_core.backends.base.BaseAuth): the backend being used to authenticate code (social_django.models.Code): the confirmation code used to confirm the email address partial_token (str): token used to resume a halted pipeline """ url = "{}?verification_code={}&partial_token={}".format( strategy.build_absolute_uri(reverse("register-confirm")), quote_plus(code.code), quote_plus(partial_token), ) affiliate_code = get_affiliate_code_from_request(strategy.request) if affiliate_code is not None: url = f"{url}&{AFFILIATE_QS_PARAM}={affiliate_code}" api.send_message( api.message_for_recipient( code.email, api.context_for_user(extra_context={"confirmation_url": url}), EMAIL_VERIFICATION, ))
def send_b2b_receipt_email(order): """ Send an email summarizing the enrollment codes purchased by a user Args: order (b2b_ecommerce.models.B2BOrder): An order """ from ecommerce.api import get_readable_id course_run_or_program = order.product_version.product.content_object title = course_run_or_program.title if ( isinstance(course_run_or_program, CourseRun) and course_run_or_program.start_date is not None and course_run_or_program.end_date is not None ): run = course_run_or_program date_range = f"{run.start_date.strftime(EMAIL_DATE_FORMAT)} - {run.end_date.strftime(EMAIL_DATE_FORMAT)}" else: date_range = "" download_url = ( f'{urljoin(settings.SITE_BASE_URL, reverse("bulk-enrollment-code-receipt"))}?' f'{urlencode({"hash": str(order.unique_id)})}' ) try: api.send_message( api.message_for_recipient( order.email, api.context_for_user( user=None, extra_context={ "purchase_date": order.updated_on.strftime(EMAIL_DATE_FORMAT), "total_price": format_price(order.total_price), "item_price": format_price(order.per_item_price), "discount": format_price(order.discount) if order.discount is not None else None, "contract_number": order.contract_number, "num_seats": str(order.num_seats), "readable_id": get_readable_id( order.product_version.product.content_object ), "run_date_range": date_range, "title": title, "download_url": download_url, "email": order.email, "order_reference_id": order.reference_number, "receipt_data": get_b2b_receipt_data(order), }, ), EMAIL_B2B_RECEIPT, ) ) except: # pylint: disable=bare-except log.exception("Error sending receipt email")
def test_context_for_user(settings, test_user, extra_context): """Tests that context_for_user returns the expected values""" user_ctx = {"user": test_user} if test_user else {} assert context_for_user(user=test_user, extra_context=extra_context) == { "base_url": settings.SITE_BASE_URL, "site_name": settings.SITE_NAME, **(extra_context or {}), **user_ctx, }
def test_context_for_user(settings, test_user, extra_context): """Tests that context_for_user returns the expected values""" user_ctx = ({ "user": test_user, "anon_token": any_instance_of(str) } if test_user else {}) assert context_for_user(user=test_user, extra_context=extra_context) == { "base_url": settings.SITE_BASE_URL, "site_name": get_default_site().title, **(extra_context or {}), **user_ctx, }
def test_render_email_templates(user): """Test render_email_templates""" user.profile.name = "Jane Smith" context = context_for_user(user=user, extra_context={"url": "http://example.com"}) subject, text_body, html_body = render_email_templates("sample", context) assert subject == "Welcome Jane Smith" assert text_body == "html link (http://example.com)" assert html_body == ('<style type="text/css">\n' "a {\n" " color: red;\n" "}\n" "</style>\n" '<a href="http://example.com">html link</a>\n')
def send_notification(self, email_notification): """ Sends the notification to the user Args: email_notification (EmailNotification): the notification to be sent """ messages = None user = email_notification.user with utils.mark_as_sent_or_canceled(email_notification) as will_send: # check against programmer error if user != self.user: raise Exception( "Notification user doesn't match settings user") # if we're trying to send an email, but the preference is never, we should just cancel it if self.notification_settings.is_triggered_never: raise CancelNotificationError() if not will_send: return last_notification = self._get_most_recent_notification( before=email_notification) data = self._get_notification_data(email_notification, last_notification) # generate the message (there's only 1) messages = list( api.messages_for_recipients( [(recipient, api.context_for_user(user=user, extra_context=data)) for recipient, user in api.safe_format_recipients([user]) ], self._template_name, )) if not messages: raise CancelNotificationError() # we don't want an error sending to cause a resend, because it could cause us to actually send it twice if messages: # if we got this far and have messages, send them api.send_messages(messages)
def test_send_message(mailoutbox): """Tests that send_messages works as expected""" users = UserFactory.create_batch(5) messages = list( messages_for_recipients( [( recipient, context_for_user(user=user, extra_context={"url": "https://example.com"}), ) for recipient, user in safe_format_recipients(users)], "sample", )) send_messages(messages) for message in mailoutbox: assert message in messages
def send_course_run_unenrollment_email(enrollment): """ Notify the user of successful unenrollment for a course run Args: enrollment (CourseRunEnrollment): the enrollment for which to send the email """ try: user = enrollment.user api.send_message( api.message_for_recipient( user.email, api.context_for_user( user=user, extra_context={"enrollment": enrollment} ), EMAIL_COURSE_RUN_UNENROLLMENT, ) ) except Exception as exp: # pylint: disable=broad-except log.exception("Error sending unenrollment success email: %s", exp)
def send_invitation_email(channel_invitation_id): """ Sends a channel invitation Args: channel_invitation_id (int): the id of the ChannelInvitation """ invite = ChannelInvitation.objects.get(id=channel_invitation_id) signup_url = urljoin(settings.SITE_BASE_URL, reverse("signup")) mail_api.send_messages( list( mail_api.messages_for_recipients( [( invite.email, mail_api.context_for_user(extra_context={ "invite": invite, "signup_url": signup_url }), )], "invite", )))
def send_verify_email_change_email(request, change_request): """ Sends a verification email for a user email change Args: request (django.http.Request): the http request we're sending this email for change_request (ChangeEmailRequest): the change request to send the confirmation for """ url = "{}?verification_code={}".format( request.build_absolute_uri(reverse("account-confirm-email-change")), quote_plus(change_request.code), ) api.send_messages( list( api.messages_for_recipients( [( change_request.new_email, api.context_for_user( extra_context={"confirmation_url": url}), )], EMAIL_CHANGE_EMAIL, )))
def send_ecommerce_order_receipt(order, cyber_source_provided_email=None): """ Send emails receipt summarizing the user purchase detail. Args: cyber_source_provided_email: Include the email address if user provide though CyberSource payment process. order: An order. """ from ecommerce.serializers import OrderReceiptSerializer data = OrderReceiptSerializer(instance=order).data purchaser = data.get("purchaser") coupon = data.get("coupon") lines = data.get("lines") order = data.get("order") receipt = data.get("receipt") country = pycountry.countries.get(alpha_2=purchaser.get("country")) recipients = [purchaser.get("email")] if cyber_source_provided_email and cyber_source_provided_email not in recipients: recipients.append(cyber_source_provided_email) try: messages = list( api.messages_for_recipients( [ ( recipient, api.context_for_user( user=None, extra_context={ "coupon": coupon, "content_title": lines[0].get("content_title") if lines else None, "lines": lines, "order_total": format( sum(float(line["total_paid"]) for line in lines), ".2f", ), "order": order, "receipt": receipt, "purchaser": { "name": " ".join( [ purchaser.get("first_name"), purchaser.get("last_name"), ] ), "email": purchaser.get("email"), "street_address": purchaser.get("street_address"), "state_code": purchaser.get( "state_or_territory" ).split("-")[-1], "postal_code": purchaser.get("postal_code"), "city": purchaser.get("city"), "country": country.name if country else None, "company": purchaser.get("company"), }, }, ), ) for recipient in recipients ], EMAIL_PRODUCT_ORDER_RECEIPT, ) ) api.send_messages(messages) except: # pylint: disable=bare-except log.exception("Error sending order receipt email.")