Files

96 lines
3.3 KiB
Python

from __future__ import annotations
import unittest
from tempfile import TemporaryDirectory
from unittest.mock import patch
from app import create_app
from app.config import Config
from app.email import (
EmailConfigurationError,
password_reset_notice_email,
registration_invitation_email,
send_transactional_email,
verification_code_email,
)
class TransactionalEmailTest(unittest.TestCase):
def test_verification_email_has_branded_code_and_escapes_purpose(self):
html = verification_code_email(
code="123456",
minutes=10,
purpose="登录<script>",
)
self.assertIn("供水管道健康评估系统", html)
self.assertIn("123456", html)
self.assertIn("登录&lt;script&gt;", html)
self.assertNotIn("登录<script>", html)
def test_reset_notice_escapes_username_and_url(self):
html = password_reset_notice_email(
username="<管理员>",
reset_url="https://example.com/reset?x=1&y=2",
minutes=10,
)
self.assertIn("&lt;管理员&gt;", html)
self.assertIn("x=1&amp;y=2", html)
def test_invitation_email_has_one_time_registration_copy(self):
html = registration_invitation_email(
invitation_url="https://example.com/invite/token",
minutes=10,
)
self.assertIn("接受邀请并注册", html)
self.assertIn("仅可使用一次", html)
self.assertIn("https://example.com/invite/token", html)
def create_test_app(self, temp_dir: str, *, configured: bool):
class TestConfig(Config):
TESTING = True
SECRET_KEY = "test-secret"
SECRET_KEY_GENERATED = False
SQLALCHEMY_DATABASE_URI = f"sqlite:///{temp_dir}/test.db"
ADMIN_PASSWORD = None
RESEND_API_KEY = "re_test_key" if configured else ""
RESEND_FROM_EMAIL = "no-reply@auth.example.com" if configured else ""
return create_app(TestConfig, load_model_on_start=False)
def test_send_requires_resend_configuration(self) -> None:
with TemporaryDirectory() as temp_dir:
app = self.create_test_app(temp_dir, configured=False)
with app.app_context(), self.assertRaises(EmailConfigurationError):
send_transactional_email(
to="user@example.com",
subject="测试",
html="<p>测试</p>",
)
@patch("app.email.resend.Emails.send", return_value={"id": "email_123"})
def test_send_uses_configured_sender(self, send):
with TemporaryDirectory() as temp_dir:
app = self.create_test_app(temp_dir, configured=True)
with app.app_context():
result = send_transactional_email(
to="user@example.com",
subject="密码重置",
html="<p>重置链接</p>",
)
self.assertEqual(result, {"id": "email_123"})
send.assert_called_once_with(
{
"from": "no-reply@auth.example.com",
"to": ["user@example.com"],
"subject": "密码重置",
"html": "<p>重置链接</p>",
}
)
if __name__ == "__main__":
unittest.main()