95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
import pytest
|
|
import os
|
|
import tempfile
|
|
from email.mime.text import MIMEText
|
|
import sys
|
|
import types
|
|
import getpass
|
|
import time
|
|
import glob
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
from slic.utils.sendmail import *
|
|
|
|
|
|
def test_sendmail_local_delivery():
|
|
|
|
# Get the current system user
|
|
user = getpass.getuser()
|
|
|
|
# Define the recipient and email content
|
|
from_addr = f"{user}@localhost"
|
|
to_addr = f"{user}@localhost"
|
|
subject = "Local sendmail test"
|
|
body = "Hello from pytest/local!"
|
|
|
|
# Send the email using the function under test
|
|
msg = sendmail(to_addr, from_addr=f"{user}@localhost", subject=subject, body=body)
|
|
|
|
# Path to the Maildir 'new' folder for this user
|
|
maildir_new = os.path.expanduser("~/Maildir/new")
|
|
|
|
# Clean up the mail
|
|
for f in glob.glob(os.path.join(maildir_new, "*")):
|
|
os.remove(f)
|
|
|
|
# Wait a short time for delivery
|
|
files = []
|
|
for _ in range(50): # Try for ~5 seconds
|
|
time.sleep(0.1)
|
|
files = sorted(glob.glob(os.path.join(maildir_new, "*")))
|
|
if files:
|
|
break
|
|
|
|
# Assert that at least one mail file was delivered
|
|
assert files, f"No email was delivered to {maildir_new}"
|
|
|
|
# Read the most recent mail file
|
|
with open(files[-1], "r", encoding="utf-8", errors="replace") as f:
|
|
content = f.read()
|
|
|
|
# Assert that both the subject and body appear in the delivered email
|
|
assert subject in content, "Email subject not found in delivered message"
|
|
assert body in content, "Email body not found in delivered message"
|
|
|
|
repr_str = repr(msg)
|
|
assert isinstance(repr_str, str), "__repr__() must return str"
|
|
assert f"To: {to_addr}" in repr_str, "To header missing from __repr__()"
|
|
assert f"From: {from_addr}" in repr_str, "From header missing from __repr__()"
|
|
assert f"Subject: {subject}" in repr_str, "Subject header missing from __repr__()"
|
|
assert body in repr_str, "Body missing from __repr__()"
|
|
|
|
def test_sendmail_raises_on_sendmail_failure(monkeypatch):
|
|
# Fake CompletedProcess-like object with a failing return code
|
|
class FakeResult:
|
|
def __init__(self):
|
|
self.returncode = 75 # any non-zero is fine
|
|
self.stderr = b"User unknown or local delivery failed"
|
|
|
|
def check_returncode(self):
|
|
import subprocess
|
|
raise subprocess.CalledProcessError(self.returncode, "sendmail", stderr=self.stderr)
|
|
|
|
# Monkeypatch subprocess.run so no real sendmail is called
|
|
import subprocess
|
|
monkeypatch.setattr(subprocess, "run", lambda *a, **kw: FakeResult())
|
|
|
|
# Trigger the failure path
|
|
to_addr = "nonexistent@localhost"
|
|
subject = "Should fail"
|
|
body = "This is supposed to fail"
|
|
|
|
with pytest.raises(SendMailError) as excinfo:
|
|
sendmail(to_addr, from_addr="tester@localhost", subject=subject, body=body)
|
|
|
|
err = excinfo.value
|
|
# Check structured attributes provided by your exception class
|
|
assert err.err_code == 75
|
|
assert "User unknown" in err.err_msg
|
|
# The stringified exception should include the divider and the full message
|
|
s = str(err)
|
|
assert OUTPUT_DIVIDER in s
|
|
assert OUTPUT_DIVIDER_BAR in s
|
|
assert f"Subject: {subject}" in s
|
|
assert f"To: {to_addr}" in s
|
|
assert body in s
|