dodil/erp-platform

tests/scenario_bricks/scn_mailer/application/use_cases.py

"""mailer — provides mail.send. A test brick for erp_platform.scenarios: the provider that can fail."""
import hashlib
from contextlib import contextmanager
from datetime import datetime, timezone

from erp_platform.bricks import Brick
from erp_platform.capabilities import Call

MAILER = Brick("mailer", version="0.1.0", instructions="Sends mail for the other bricks.")


@contextmanager
def _repository_default():
    from erp_platform import db
    from scn_mailer.infrastructure.tables import MailerRepository
    with db.engine.begin() as conn:
        yield MailerRepository(conn)


repository = _repository_default


@MAILER.capability("mail.send")
def send(call: Call):
    """Sends through the outbox; the message id is derived from the idempotency key, so a resend is a no-op."""
    mid = "m-" + hashlib.sha256(call.idempotency_key.encode()).hexdigest()[:16]
    with repository() as repo:
        if not repo.sent(mid):
            repo.add({"message_id": mid, "to_addr": call.input["to"][0], "subject": call.input["subject"],
                      "sent_at": datetime.now(timezone.utc)})
    return mid, {"message_id": mid}, "sent"


@MAILER.use_case(kind="query", route="GET /outbox", permission="mailer:outbox:read")
def outbox(caller: dict, to: str) -> dict:
    """The messages sent to one address."""
    with repository() as repo:
        return {"messages": [{"message_id": m["message_id"], "subject": m["subject"]} for m in repo.to(to)]}