feat: MIME email composer with .ovpn attachment via msmtp/sendmail
Add send_email() function that composes multipart MIME messages with template-based body and .ovpn file attachment, piped to mail binary via subprocess.Popen. Supports Cryptgeon URL insertion and sender metadata. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
47
tests/test_mailer.py
Normal file
47
tests/test_mailer.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
from openvpncertupdate import send_email
|
||||
|
||||
|
||||
def make_popen(returncode=0):
|
||||
proc = MagicMock()
|
||||
proc.communicate.return_value = (b"", b"")
|
||||
proc.returncode = returncode
|
||||
return proc
|
||||
|
||||
|
||||
def test_calls_mail_binary(tmp_path):
|
||||
tmpl = tmp_path / "t.txt"; tmpl.write_text("{cn} {url} {config_name}")
|
||||
att = tmp_path / "c.ovpn"; att.write_text("x")
|
||||
captured = {}
|
||||
def fake_popen(cmd, **kw): captured["cmd"] = cmd; return make_popen()
|
||||
with patch("openvpncertupdate.subprocess.Popen", side_effect=fake_popen):
|
||||
send_email("to@x.com", "alice", "http://u", str(att),
|
||||
"f@x.com", "Subj", str(tmpl), "msmtp")
|
||||
assert captured["cmd"] == ["msmtp", "-t"]
|
||||
|
||||
|
||||
def test_body_contains_cn_and_url(tmp_path):
|
||||
tmpl = tmp_path / "t.txt"; tmpl.write_text("Dear {cn}, see {url} for {config_name}")
|
||||
att = tmp_path / "c.ovpn"; att.write_text("")
|
||||
received = {}
|
||||
def fake_popen(cmd, **kw):
|
||||
p = MagicMock()
|
||||
p.communicate = lambda input=None: (received.update({"data": input}) or b"", b"")
|
||||
p.returncode = 0
|
||||
return p
|
||||
with patch("openvpncertupdate.subprocess.Popen", side_effect=fake_popen):
|
||||
send_email("to@x.com", "bob", "http://secret", str(att),
|
||||
"f@x.com", "s", str(tmpl), "msmtp")
|
||||
body = received["data"].decode()
|
||||
assert "bob" in body
|
||||
assert "http://secret" in body
|
||||
|
||||
|
||||
def test_raises_on_failure(tmp_path):
|
||||
tmpl = tmp_path / "t.txt"; tmpl.write_text("{cn} {url} {config_name}")
|
||||
att = tmp_path / "c.ovpn"; att.write_text("")
|
||||
with patch("openvpncertupdate.subprocess.Popen", return_value=make_popen(returncode=1)):
|
||||
with pytest.raises(RuntimeError, match="mail"):
|
||||
send_email("x@y.com", "cn", "url", str(att),
|
||||
"f@x.com", "s", str(tmpl), "msmtp")
|
||||
Reference in New Issue
Block a user