From eb6ad9884c684f7d37a9d7f8fa4e03075eaf0e9c Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 10 Aug 2025 11:05:39 -0500 Subject: [PATCH] fix: allow caller to specify default subject for email message we already allow for some config fallbacks but sometimes the caller needs to declare the default, to use as fallback when specific config is not present --- src/wuttjamaican/email.py | 21 ++++++++++++++++----- tests/test_email.py | 12 ++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/wuttjamaican/email.py b/src/wuttjamaican/email.py index 8ae62b5..ab89081 100644 --- a/src/wuttjamaican/email.py +++ b/src/wuttjamaican/email.py @@ -370,7 +370,7 @@ class EmailHandler(GenericHandler): """ return Message(**kwargs) - def make_auto_message(self, key, context={}, **kwargs): + def make_auto_message(self, key, context={}, default_subject=None, **kwargs): """ Make a new email message using config to determine its properties, and auto-generating body from a template. @@ -386,6 +386,9 @@ class EmailHandler(GenericHandler): :param context: Context dict used to render template(s) for the message. + :param default_subject: Optional :attr:`~Message.subject` + template/string to use, if config does not specify one. + :param \**kwargs: Any remaining kwargs are passed as-is to :meth:`make_message()`. More on this below. @@ -408,7 +411,7 @@ class EmailHandler(GenericHandler): if 'sender' not in kwargs: kwargs['sender'] = self.get_auto_sender(key) if 'subject' not in kwargs: - kwargs['subject'] = self.get_auto_subject(key, context) + kwargs['subject'] = self.get_auto_subject(key, context, default=default_subject) if 'to' not in kwargs: kwargs['to'] = self.get_auto_to(key) if 'cc' not in kwargs: @@ -449,7 +452,7 @@ class EmailHandler(GenericHandler): # fall back to global default, if present return self.config.get(f'{self.config.appname}.email.default.replyto') - def get_auto_subject(self, key, context={}, rendered=True, setting=None): + def get_auto_subject(self, key, context={}, rendered=True, setting=None, default=None): """ Returns automatic :attr:`~wuttjamaican.email.Message.subject` line for a message, as determined by config. @@ -470,15 +473,17 @@ class EmailHandler(GenericHandler): instance. This is passed along to :meth:`get_auto_subject_template()`. + :param default: Default subject to use if none is configured. + :returns: Final subject text, either "raw" or rendered. """ - template = self.get_auto_subject_template(key, setting=setting) + template = self.get_auto_subject_template(key, setting=setting, default=default) if not rendered: return template return Template(template).render(**context) - def get_auto_subject_template(self, key, setting=None): + def get_auto_subject_template(self, key, setting=None, default=None): """ Returns the template string to use for automatic subject line of a message, as determined by config. @@ -497,6 +502,8 @@ class EmailHandler(GenericHandler): optimization; otherwise it will be fetched if needed via :meth:`get_email_setting()`. + :param default: Default subject to use if none is configured. + :returns: Final subject template, as raw text. """ # prefer configured subject specific to key @@ -504,6 +511,10 @@ class EmailHandler(GenericHandler): if template: return template + # or use caller-specified default, if applicable + if default: + return default + # or subject from email setting, if defined if not setting: setting = self.get_email_setting(key) diff --git a/tests/test_email.py b/tests/test_email.py index 7e0c062..8cf1623 100644 --- a/tests/test_email.py +++ b/tests/test_email.py @@ -291,7 +291,7 @@ class TestEmailHandler(ConfigTestCase): msg = handler.make_auto_message('foo', subject=None) get_auto_subject.assert_not_called() msg = handler.make_auto_message('foo') - get_auto_subject.assert_called_once_with('foo', {}) + get_auto_subject.assert_called_once_with('foo', {}, default=None) # to with patch.object(handler, 'get_auto_to') as get_auto_to: @@ -376,7 +376,7 @@ class TestEmailHandler(ConfigTestCase): template = handler.get_auto_subject_template('foo') self.assertEqual(template, "Foo Message") - # setting can provide default subject + # EmailSetting can provide default subject providers = { 'wuttatest': MagicMock(email_modules=['tests.test_email']), } @@ -385,6 +385,10 @@ class TestEmailHandler(ConfigTestCase): template = handler.get_auto_subject_template('mock_foo') self.assertEqual(template, "MOCK FOO!") + # caller can provide default subject + template = handler.get_auto_subject_template('mock_foo', default="whatever is clever") + self.assertEqual(template, "whatever is clever") + def test_get_auto_subject(self): handler = self.make_handler() @@ -397,6 +401,10 @@ class TestEmailHandler(ConfigTestCase): subject = handler.get_auto_subject('foo') self.assertEqual(subject, "Wutta Message") + # caller can provide default subject + subject = handler.get_auto_subject('foo', default="whatever is clever") + self.assertEqual(subject, "whatever is clever") + # can configure just for key self.config.setdefault('wutta.email.foo.subject', "Foo Message") subject = handler.get_auto_subject('foo')