~homeworkprod/byceps

6ecf5a342108c3c15d4cefe2e147ab8a4bea541b — Jochen Kupperschmidt a month ago c5a2fb5
Move email assembly, sending to service

`send_email` is just a wrapper now, but it keeps mocking in tests from breaking for now.
D byceps/email.py => byceps/email.py +0 -55
@@ 1,55 0,0 @@
"""
byceps.email
~~~~~~~~~~~~

Send e-mail.

:Copyright: 2014-2022 Jochen Kupperschmidt
:License: Revised BSD (see `LICENSE` file for details)
"""

from __future__ import annotations
from email.message import EmailMessage
from smtplib import SMTP

from flask import current_app


def send(sender: str, recipients: list[str], subject: str, body: str) -> None:
    """Assemble and send an e-mail."""
    if current_app.config.get('MAIL_SUPPRESS_SEND', False):
        current_app.logger.debug('Suppressing sending of email.')
        return

    message = _build_message(sender, recipients, subject, body)

    current_app.logger.debug('Sending email.')
    _send_via_smtp(message)


def _build_message(
    sender: str, recipients: list[str], subject: str, body: str
) -> EmailMessage:
    """Assemble message."""
    message = EmailMessage()
    message['From'] = sender
    message['To'] = ', '.join(recipients)
    message['Subject'] = subject
    message.set_content(body)
    return message


def _send_via_smtp(message: EmailMessage) -> None:
    """Send email via SMTP."""
    config = current_app.config

    host = config.get('MAIL_HOST', 'localhost')
    port = config.get('MAIL_PORT', 25)
    username = config.get('MAIL_USERNAME', None)
    password = config.get('MAIL_PASSWORD', None)

    with SMTP(host, port) as smtp:
        if username and password:
            smtp.login(username, password)

        smtp.send_message(message)

M byceps/services/email/service.py => byceps/services/email/service.py +47 -2
@@ 7,9 7,12 @@ byceps.services.email.service
"""

from __future__ import annotations
from email.message import EmailMessage
from email.utils import parseaddr
from smtplib import SMTP

from flask import current_app

from ... import email
from ...util.jobqueue import enqueue

from .transfer.models import Message, NameAndAddress


@@ 47,4 50,46 @@ def send_email(
    sender: str, recipients: list[str], subject: str, body: str
) -> None:
    """Send e-mail."""
    email.send(sender, recipients, subject, body)
    send(sender, recipients, subject, body)


def send(
    sender: str, recipients: list[str], subject: str, body: str
) -> None:
    """Assemble and send e-mail."""
    if current_app.config.get('MAIL_SUPPRESS_SEND', False):
        current_app.logger.debug('Suppressing sending of email.')
        return

    message = _build_message(sender, recipients, subject, body)

    current_app.logger.debug('Sending email.')
    _send_via_smtp(message)


def _build_message(
    sender: str, recipients: list[str], subject: str, body: str
) -> EmailMessage:
    """Assemble message."""
    message = EmailMessage()
    message['From'] = sender
    message['To'] = ', '.join(recipients)
    message['Subject'] = subject
    message.set_content(body)
    return message


def _send_via_smtp(message: EmailMessage) -> None:
    """Send email via SMTP."""
    config = current_app.config

    host = config.get('MAIL_HOST', 'localhost')
    port = config.get('MAIL_PORT', 25)
    username = config.get('MAIL_USERNAME', None)
    password = config.get('MAIL_PASSWORD', None)

    with SMTP(host, port) as smtp:
        if username and password:
            smtp.login(username, password)

        smtp.send_message(message)

M tests/integration/blueprints/site/user/test_views_create.py => tests/integration/blueprints/site/user/test_views_create.py +2 -2
@@ 86,7 86,7 @@ def newsletter_list(brand):
    brand_settings_service.remove_setting(brand.id, name)


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_create(
    send_email_mock,
    site_app,


@@ 178,7 178,7 @@ bitte bestätige deine E-Mail-Adresse indem du diese URL aufrufst: https://www.a
    )


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_create_without_newsletter_subscription(
    send_email_mock,
    site_app,

M tests/integration/blueprints/site/user_message/test_send.py => tests/integration/blueprints/site/user_message/test_send.py +2 -2
@@ 20,7 20,7 @@ def user_bob(make_user):
    return make_user('Bob', email_address='bob@users.test', locale='en')


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_send_when_logged_in_without_brand_contact_address(
    send_email_mock, site_app, user_alice, user_bob
):


@@ 83,7 83,7 @@ If you have any questions, please contact us via email to: help@acmecon.test\
    )


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_send_when_logged_in_with_brand_contact_address(
    send_email_mock,
    site_app,

M tests/integration/services/shop/order/email/test_email_on_order_canceled.py => tests/integration/services/shop/order/email/test_email_on_order_canceled.py +1 -1
@@ 58,7 58,7 @@ def order(storefront: Storefront, orderer: Orderer, email_footer_snippet_id):
    order_service.delete_order(order.id)


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_email_on_order_canceled(
    send_email_mock, site_app, customer: User, order_admin, order
):

M tests/integration/services/shop/order/email/test_email_on_order_paid.py => tests/integration/services/shop/order/email/test_email_on_order_paid.py +1 -1
@@ 58,7 58,7 @@ def order(storefront: Storefront, orderer: Orderer, email_footer_snippet_id):
    order_service.delete_order(order.id)


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_email_on_order_paid(
    send_email_mock, site_app, customer: User, order_admin, order
):

M tests/integration/services/shop/order/email/test_email_on_order_placed.py => tests/integration/services/shop/order/email/test_email_on_order_placed.py +1 -1
@@ 97,7 97,7 @@ def order(
    order_service.delete_order(order.id)


@patch('byceps.email.send')
@patch('byceps.services.email.service.send')
def test_email_on_order_placed(
    send_email_mock, site_app: Flask, customer: User, order: Order
):