3
0
Fork 0

feat: add "email settings" feature for admin, previews

This commit is contained in:
Lance Edgar 2024-12-23 15:37:37 -06:00
parent 6c8f1c973d
commit 491df09f2f
4 changed files with 421 additions and 98 deletions

View file

@ -6,21 +6,102 @@ from unittest.mock import patch, MagicMock
import pytest
from wuttjamaican import email as mod
from wuttjamaican.conf import WuttaConfig
from wuttjamaican.util import resource_path
from wuttjamaican.exc import ConfigurationError
from wuttjamaican.testing import ConfigTestCase
class TestEmailHandler(TestCase):
class TestEmailSetting(ConfigTestCase):
def setUp(self):
try:
import mako
except ImportError:
pytest.skip("test not relevant without mako")
def test_constructor(self):
setting = mod.EmailSetting(self.config)
self.assertIs(setting.config, self.config)
self.assertIs(setting.app, self.app)
self.assertEqual(setting.key, 'EmailSetting')
self.config = WuttaConfig()
self.app = self.config.get_app()
def test_sample_data(self):
setting = mod.EmailSetting(self.config)
self.assertEqual(setting.sample_data(), {})
class TestMessage(TestCase):
def make_message(self, **kwargs):
return mod.Message(**kwargs)
def test_set_recips(self):
msg = self.make_message()
self.assertEqual(msg.to, [])
# set as list
msg.set_recips('to', ['sally@example.com'])
self.assertEqual(msg.to, ['sally@example.com'])
# set as tuple
msg.set_recips('to', ('barney@example.com',))
self.assertEqual(msg.to, ['barney@example.com'])
# set as string
msg.set_recips('to', 'wilma@example.com')
self.assertEqual(msg.to, ['wilma@example.com'])
# set as null
msg.set_recips('to', None)
self.assertEqual(msg.to, [])
# otherwise error
self.assertRaises(ValueError, msg.set_recips, 'to', {'foo': 'foo@example.com'})
def test_as_string(self):
# error if no body
msg = self.make_message()
self.assertRaises(ValueError, msg.as_string)
# txt body
msg = self.make_message(sender='bob@example.com',
txt_body="hello world")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# html body
msg = self.make_message(sender='bob@example.com',
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# txt + html body
msg = self.make_message(sender='bob@example.com',
txt_body="hello world",
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# everything
msg = self.make_message(sender='bob@example.com',
subject='meeting follow-up',
to='sally@example.com',
cc='marketing@example.com',
bcc='bob@example.com',
replyto='sales@example.com',
txt_body="hello world",
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
self.assertIn('Subject: meeting follow-up', complete)
self.assertIn('To: sally@example.com', complete)
self.assertIn('Cc: marketing@example.com', complete)
self.assertIn('Bcc: bob@example.com', complete)
self.assertIn('Reply-To: sales@example.com', complete)
class mock_foo(mod.EmailSetting):
default_subject = "MOCK FOO!"
def sample_data(self):
return {'foo': 'mock'}
class TestEmailHandler(ConfigTestCase):
def make_handler(self, **kwargs):
return mod.EmailHandler(self.config, **kwargs)
@ -53,6 +134,69 @@ class TestEmailHandler(TestCase):
self.assertEqual(handler.txt_templates.directories, [path])
self.assertEqual(handler.html_templates.directories, [path])
def test_get_email_modules(self):
# no providers, no email modules
with patch.object(self.app, 'providers', new={}):
handler = self.make_handler()
self.assertEqual(handler.get_email_modules(), [])
# provider may specify modules as list
providers = {
'wuttatest': MagicMock(email_modules=['wuttjamaican.email']),
}
with patch.object(self.app, 'providers', new=providers):
handler = self.make_handler()
modules = handler.get_email_modules()
self.assertEqual(len(modules), 1)
self.assertIs(modules[0], mod)
# provider may specify modules as list
providers = {
'wuttatest': MagicMock(email_modules='wuttjamaican.email'),
}
with patch.object(self.app, 'providers', new=providers):
handler = self.make_handler()
modules = handler.get_email_modules()
self.assertEqual(len(modules), 1)
self.assertIs(modules[0], mod)
def test_get_email_settings(self):
# no providers, no email settings
with patch.object(self.app, 'providers', new={}):
handler = self.make_handler()
self.assertEqual(handler.get_email_settings(), {})
# provider may define email settings (via modules)
providers = {
'wuttatest': MagicMock(email_modules=['tests.test_email']),
}
with patch.object(self.app, 'providers', new=providers):
handler = self.make_handler()
settings = handler.get_email_settings()
self.assertEqual(len(settings), 1)
self.assertIn('mock_foo', settings)
def test_get_email_setting(self):
providers = {
'wuttatest': MagicMock(email_modules=['tests.test_email']),
}
with patch.object(self.app, 'providers', new=providers):
handler = self.make_handler()
# as instance
setting = handler.get_email_setting('mock_foo')
self.assertIsInstance(setting, mod.EmailSetting)
self.assertIsInstance(setting, mock_foo)
# as class
setting = handler.get_email_setting('mock_foo', instance=False)
self.assertTrue(issubclass(setting, mod.EmailSetting))
self.assertIs(setting, mock_foo)
def test_make_message(self):
handler = self.make_handler()
msg = handler.make_message()
@ -166,6 +310,20 @@ class TestEmailHandler(TestCase):
self.config.setdefault('wutta.email.foo.sender', 'sally@example.com')
self.assertEqual(handler.get_auto_sender('foo'), 'sally@example.com')
def test_get_auto_replyto(self):
handler = self.make_handler()
# null by default
self.assertIsNone(handler.get_auto_replyto('foo'))
# can set global default
self.config.setdefault('wutta.email.default.replyto', 'george@example.com')
self.assertEqual(handler.get_auto_replyto('foo'), 'george@example.com')
# can set for key
self.config.setdefault('wutta.email.foo.replyto', 'kathy@example.com')
self.assertEqual(handler.get_auto_replyto('foo'), 'kathy@example.com')
def test_get_auto_subject_template(self):
handler = self.make_handler()
@ -183,6 +341,15 @@ class TestEmailHandler(TestCase):
template = handler.get_auto_subject_template('foo')
self.assertEqual(template, "Foo Message")
# setting can provide default subject
providers = {
'wuttatest': MagicMock(email_modules=['tests.test_email']),
}
with patch.object(self.app, 'providers', new=providers):
handler = self.make_handler()
template = handler.get_auto_subject_template('mock_foo')
self.assertEqual(template, "MOCK FOO!")
def test_get_auto_subject(self):
handler = self.make_handler()
@ -279,6 +446,16 @@ class TestEmailHandler(TestCase):
body = handler.get_auto_html_body('test_foo')
self.assertEqual(body, '<p>hello from foo html template</p>\n')
def test_get_notes(self):
handler = self.make_handler()
# null by default
self.assertIsNone(handler.get_notes('foo'))
# configured notes
self.config.setdefault('wutta.email.foo.notes', 'hello world')
self.assertEqual(handler.get_notes('foo'), 'hello world')
def test_is_enabled(self):
handler = self.make_handler()
@ -455,74 +632,3 @@ class TestEmailHandler(TestCase):
self.config.setdefault('wutta.email.default.enabled', False)
handler.send_email('bar', sender='bar@example.com', txt_body="hello world")
self.assertFalse(deliver_message.called)
class TestMessage(TestCase):
def make_message(self, **kwargs):
return mod.Message(**kwargs)
def test_set_recips(self):
msg = self.make_message()
self.assertEqual(msg.to, [])
# set as list
msg.set_recips('to', ['sally@example.com'])
self.assertEqual(msg.to, ['sally@example.com'])
# set as tuple
msg.set_recips('to', ('barney@example.com',))
self.assertEqual(msg.to, ['barney@example.com'])
# set as string
msg.set_recips('to', 'wilma@example.com')
self.assertEqual(msg.to, ['wilma@example.com'])
# set as null
msg.set_recips('to', None)
self.assertEqual(msg.to, [])
# otherwise error
self.assertRaises(ValueError, msg.set_recips, 'to', {'foo': 'foo@example.com'})
def test_as_string(self):
# error if no body
msg = self.make_message()
self.assertRaises(ValueError, msg.as_string)
# txt body
msg = self.make_message(sender='bob@example.com',
txt_body="hello world")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# html body
msg = self.make_message(sender='bob@example.com',
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# txt + html body
msg = self.make_message(sender='bob@example.com',
txt_body="hello world",
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
# everything
msg = self.make_message(sender='bob@example.com',
subject='meeting follow-up',
to='sally@example.com',
cc='marketing@example.com',
bcc='bob@example.com',
replyto='sales@example.com',
txt_body="hello world",
html_body="<p>hello world</p>")
complete = msg.as_string()
self.assertIn('From: bob@example.com', complete)
self.assertIn('Subject: meeting follow-up', complete)
self.assertIn('To: sally@example.com', complete)
self.assertIn('Cc: marketing@example.com', complete)
self.assertIn('Bcc: bob@example.com', complete)
self.assertIn('Reply-To: sales@example.com', complete)