mirror of
https://github.com/Sea-Haven-Industries/procurement-ingest.git
synced 2026-09-30 23:33:13 +00:00
Some checks are pending
Deploy / deploy (push) Waiting to run
The repo had no automated tests, so regressions in the email parsing pipeline could only be caught manually. The reusable ci-python-sam workflow already supports a run-tests input at the pinned SHA; enable it and add a first suite covering the pure functions pad_zip and parse_raw_email. tests/conftest.py sets AWS_DEFAULT_REGION and dummy credentials before any handler import because the handlers create boto3 clients at module import time, and loads each handler.py via importlib under a unique module name since the files share a basename. pytest.ini scopes discovery to tests/ so the manual test_local.py script at the repo root is not collected.
91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
"""Tests for parse_raw_email in the PO and WO email processors.
|
|
|
|
Synthetic MIME messages are built with email.message.EmailMessage so the
|
|
tests exercise real multipart parsing without shipping .eml fixtures.
|
|
"""
|
|
|
|
from email.message import EmailMessage
|
|
|
|
SUBJECT = "Amazon.com Services LLC Purchase Order 2D-18206023"
|
|
SENDER = "do_not_reply@coupahost.com"
|
|
TO = "orders@seahavenind.com"
|
|
CC = "ap@seahavenind.com"
|
|
DATE = "Tue, 14 Jul 2026 09:30:00 -0400"
|
|
|
|
PLAIN_BODY = "PO 2D-18206023 issued to Sea Haven Industries."
|
|
HTML_BODY = "<html><body><p>PO 2D-18206023 issued.</p></body></html>"
|
|
|
|
|
|
def _base_message():
|
|
msg = EmailMessage()
|
|
msg["Subject"] = SUBJECT
|
|
msg["From"] = SENDER
|
|
msg["To"] = TO
|
|
msg["Cc"] = CC
|
|
msg["Date"] = DATE
|
|
return msg
|
|
|
|
|
|
def make_plain_email():
|
|
msg = _base_message()
|
|
msg.set_content(PLAIN_BODY)
|
|
return msg.as_bytes()
|
|
|
|
|
|
def make_multipart_alternative_email():
|
|
msg = _base_message()
|
|
msg.set_content(PLAIN_BODY)
|
|
msg.add_alternative(HTML_BODY, subtype="html")
|
|
return msg.as_bytes()
|
|
|
|
|
|
def make_multipart_html_only_email():
|
|
msg = _base_message()
|
|
msg.set_content(HTML_BODY, subtype="html")
|
|
# An attachment forces the message to multipart/mixed
|
|
msg.add_attachment(
|
|
b"%PDF-1.4 fake",
|
|
maintype="application",
|
|
subtype="pdf",
|
|
filename="po.pdf",
|
|
)
|
|
return msg.as_bytes()
|
|
|
|
|
|
def test_headers_extracted(email_handler):
|
|
result = email_handler.parse_raw_email(make_plain_email())
|
|
assert result["subject"] == SUBJECT
|
|
assert result["sender"] == SENDER
|
|
assert result["to"] == TO
|
|
assert result["date"] == DATE
|
|
|
|
|
|
def test_simple_plain_body(email_handler):
|
|
result = email_handler.parse_raw_email(make_plain_email())
|
|
assert result["body"].strip() == PLAIN_BODY
|
|
|
|
|
|
def test_multipart_prefers_text_plain(email_handler):
|
|
result = email_handler.parse_raw_email(make_multipart_alternative_email())
|
|
assert result["body"].strip() == PLAIN_BODY
|
|
assert "<html>" not in result["body"]
|
|
|
|
|
|
def test_multipart_falls_back_to_html(email_handler):
|
|
result = email_handler.parse_raw_email(make_multipart_html_only_email())
|
|
assert "PO 2D-18206023 issued." in result["body"]
|
|
assert "<html>" in result["body"]
|
|
|
|
|
|
def test_wo_handler_extracts_cc(wo_handler):
|
|
result = wo_handler.parse_raw_email(make_plain_email())
|
|
assert result["cc"] == CC
|
|
|
|
|
|
def test_missing_headers_default_to_empty(email_handler):
|
|
msg = EmailMessage()
|
|
msg.set_content(PLAIN_BODY)
|
|
result = email_handler.parse_raw_email(msg.as_bytes())
|
|
assert result["subject"] == ""
|
|
assert result["sender"] == ""
|
|
assert result["to"] == ""
|