"""Tests for the email client (mocked SMTP).""" from __future__ import annotations from pathlib import Path from unittest.mock import MagicMock, patch from cheddahbot.email import EmailClient @patch("cheddahbot.email.smtplib.SMTP_SSL") def test_send_plain_email(mock_smtp_cls): """Send a simple email without attachments.""" mock_server = MagicMock() mock_smtp_cls.return_value.__enter__ = MagicMock(return_value=mock_server) mock_smtp_cls.return_value.__exit__ = MagicMock(return_value=False) client = EmailClient("smtp.gmail.com", 465, "bot@test.com", "secret") client.send(to="user@corp.com", subject="Test", body="Hello") mock_smtp_cls.assert_called_once_with("smtp.gmail.com", 465) mock_server.login.assert_called_once_with("bot@test.com", "secret") mock_server.send_message.assert_called_once() # Verify the message contents sent_msg = mock_server.send_message.call_args[0][0] assert sent_msg["To"] == "user@corp.com" assert sent_msg["Subject"] == "Test" assert sent_msg["From"] == "bot@test.com" @patch("cheddahbot.email.smtplib.SMTP_SSL") def test_send_with_attachment(mock_smtp_cls, tmp_path: Path): """Send an email with a file attachment.""" mock_server = MagicMock() mock_smtp_cls.return_value.__enter__ = MagicMock(return_value=mock_server) mock_smtp_cls.return_value.__exit__ = MagicMock(return_value=False) # Create a test file test_file = tmp_path / "report.docx" test_file.write_bytes(b"fake docx content") client = EmailClient("smtp.gmail.com", 465, "bot@test.com", "secret") client.send( to="user@corp.com", subject="Report", body="See attached", attachments=[test_file], ) mock_server.send_message.assert_called_once() sent_msg = mock_server.send_message.call_args[0][0] # Should have 2 parts: body text + 1 attachment payloads = sent_msg.get_payload() assert len(payloads) == 2 assert payloads[1].get_filename() == "report.docx" @patch("cheddahbot.email.smtplib.SMTP_SSL") def test_send_with_multiple_attachments(mock_smtp_cls, tmp_path: Path): """Send an email with multiple attachments.""" mock_server = MagicMock() mock_smtp_cls.return_value.__enter__ = MagicMock(return_value=mock_server) mock_smtp_cls.return_value.__exit__ = MagicMock(return_value=False) file_a = tmp_path / "a.docx" file_b = tmp_path / "b.docx" file_a.write_bytes(b"content a") file_b.write_bytes(b"content b") client = EmailClient("smtp.gmail.com", 465, "bot@test.com", "secret") client.send( to="user@corp.com", subject="Two files", body="Both attached", attachments=[file_a, file_b], ) sent_msg = mock_server.send_message.call_args[0][0] payloads = sent_msg.get_payload() assert len(payloads) == 3 # body + 2 attachments