201 lines
6.3 KiB
Python
201 lines
6.3 KiB
Python
"""
|
|
邮件服务测试
|
|
"""
|
|
|
|
from unittest.mock import MagicMock, Mock, patch
|
|
|
|
import pytest
|
|
|
|
from packages.domain.auth.email_service import EmailConfig, EmailService
|
|
|
|
|
|
class TestEmailService:
|
|
"""邮件服务测试"""
|
|
|
|
@pytest.fixture
|
|
def email_config(self):
|
|
"""创建测试邮件配置"""
|
|
return EmailConfig(
|
|
smtp_host="smtp.test.com",
|
|
smtp_port=587,
|
|
smtp_user="test@test.com",
|
|
smtp_password="test-password",
|
|
from_email="noreply@test.com",
|
|
from_name="Test Service",
|
|
use_tls=True,
|
|
)
|
|
|
|
@pytest.fixture
|
|
def email_service(self, email_config):
|
|
"""创建邮件服务实例"""
|
|
return EmailService(config=email_config)
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_email_success(self, mock_smtp, email_service):
|
|
"""测试发送邮件成功"""
|
|
# Mock SMTP 服务器
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = email_service.send_email(
|
|
to_email="user@example.com",
|
|
subject="Test Email",
|
|
html_body="<h1>Test</h1>",
|
|
text_body="Test",
|
|
)
|
|
|
|
assert success is True
|
|
assert error is None
|
|
|
|
# 验证 SMTP 调用
|
|
mock_smtp.assert_called_once_with("smtp.test.com", 587)
|
|
mock_server.starttls.assert_called_once()
|
|
mock_server.login.assert_called_once_with("test@test.com", "test-password")
|
|
mock_server.sendmail.assert_called_once()
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_email_with_cc_bcc(self, mock_smtp, email_service):
|
|
"""测试发送邮件带抄送和密送"""
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = email_service.send_email(
|
|
to_email="user@example.com",
|
|
subject="Test Email",
|
|
html_body="<h1>Test</h1>",
|
|
cc=["cc1@example.com", "cc2@example.com"],
|
|
bcc=["bcc@example.com"],
|
|
)
|
|
|
|
assert success is True
|
|
|
|
# 验证收件人列表包含所有人
|
|
call_args = mock_server.sendmail.call_args
|
|
recipients = call_args[0][1]
|
|
assert "user@example.com" in recipients
|
|
assert "cc1@example.com" in recipients
|
|
assert "cc2@example.com" in recipients
|
|
assert "bcc@example.com" in recipients
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_email_smtp_error(self, mock_smtp, email_service):
|
|
"""测试 SMTP 错误处理"""
|
|
# Mock SMTP 抛出异常
|
|
mock_smtp.side_effect = Exception("SMTP connection failed")
|
|
|
|
success, error = email_service.send_email(
|
|
to_email="user@example.com",
|
|
subject="Test",
|
|
html_body="<h1>Test</h1>",
|
|
)
|
|
|
|
assert success is False
|
|
assert error is not None
|
|
assert "SMTP connection failed" in error
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_verification_email(self, mock_smtp, email_service):
|
|
"""测试发送验证邮件"""
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = email_service.send_verification_email(
|
|
to_email="user@example.com",
|
|
username="TestUser",
|
|
verification_url="https://example.com/verify?token=abc123",
|
|
)
|
|
|
|
assert success is True
|
|
assert error is None
|
|
|
|
# 验证发送了邮件
|
|
mock_server.sendmail.assert_called_once()
|
|
call_args = mock_server.sendmail.call_args
|
|
|
|
# 验证收件人
|
|
assert call_args[0][1] == ["user@example.com"]
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_password_reset_email(self, mock_smtp, email_service):
|
|
"""测试发送密码重置邮件"""
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = email_service.send_password_reset_email(
|
|
to_email="user@example.com",
|
|
username="TestUser",
|
|
reset_url="https://example.com/reset?token=xyz789",
|
|
)
|
|
|
|
assert success is True
|
|
assert error is None
|
|
|
|
# 验证发送了邮件
|
|
mock_server.sendmail.assert_called_once()
|
|
call_args = mock_server.sendmail.call_args
|
|
|
|
# 验证收件人
|
|
assert call_args[0][1] == ["user@example.com"]
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_send_workspace_invitation_email(self, mock_smtp, email_service):
|
|
"""测试发送工作空间邀请邮件"""
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = email_service.send_workspace_invitation_email(
|
|
to_email="user@example.com",
|
|
inviter_name="Alice",
|
|
workspace_name="My Workspace",
|
|
role="admin",
|
|
invitation_url="https://example.com/invite?token=inv123",
|
|
)
|
|
|
|
assert success is True
|
|
assert error is None
|
|
|
|
# 验证发送了邮件
|
|
mock_server.sendmail.assert_called_once()
|
|
call_args = mock_server.sendmail.call_args
|
|
|
|
# 验证收件人
|
|
assert call_args[0][1] == ["user@example.com"]
|
|
|
|
@patch("smtplib.SMTP")
|
|
def test_email_without_tls(self, mock_smtp):
|
|
"""测试不使用 TLS 发送邮件"""
|
|
config = EmailConfig(
|
|
smtp_host="smtp.test.com",
|
|
smtp_port=25,
|
|
smtp_user="",
|
|
smtp_password="",
|
|
from_email="test@test.com",
|
|
use_tls=False,
|
|
)
|
|
service = EmailService(config=config)
|
|
|
|
mock_server = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_server
|
|
|
|
success, error = service.send_email(
|
|
to_email="user@example.com",
|
|
subject="Test",
|
|
html_body="Test",
|
|
)
|
|
|
|
assert success is True
|
|
|
|
# 验证不调用 starttls
|
|
mock_server.starttls.assert_not_called()
|
|
# 验证不调用 login(没有用户名密码)
|
|
mock_server.login.assert_not_called()
|
|
|
|
def test_default_config(self):
|
|
"""测试默认配置"""
|
|
service = EmailService()
|
|
|
|
assert service.config.smtp_host == "smtp.gmail.com"
|
|
assert service.config.smtp_port == 587
|
|
assert service.config.use_tls is True
|
|
assert service.config.from_name == "小虾 SaaS"
|