| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  | from email.mime.text import MIMEText | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | from unittest import TestCase | 
					
						
							|  |  |  | from unittest.mock import patch, MagicMock | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 14:34:35 -05:00
										 |  |  | import pytest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 18:34:03 -06:00
										 |  |  | from wuttjamaican import email as mod | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | from wuttjamaican.util import resource_path | 
					
						
							|  |  |  | from wuttjamaican.exc import ConfigurationError | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  | from wuttjamaican.testing import ConfigTestCase, FileTestCase | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | class TestEmailSetting(ConfigTestCase): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def test_constructor(self): | 
					
						
							|  |  |  |         setting = mod.EmailSetting(self.config) | 
					
						
							|  |  |  |         self.assertIs(setting.config, self.config) | 
					
						
							|  |  |  |         self.assertIs(setting.app, self.app) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(setting.key, "EmailSetting") | 
					
						
							| 
									
										
										
										
											2024-08-26 14:34:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def test_sample_data(self): | 
					
						
							|  |  |  |         setting = mod.EmailSetting(self.config) | 
					
						
							|  |  |  |         self.assertEqual(setting.sample_data(), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  | class TestMessage(FileTestCase): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def make_message(self, **kwargs): | 
					
						
							|  |  |  |         return mod.Message(**kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 20:32:56 -05:00
										 |  |  |     def test_get_recips(self): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         msg = self.make_message() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # set as list | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         recips = msg.get_recips(["sally@example.com"]) | 
					
						
							|  |  |  |         self.assertEqual(recips, ["sally@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # set as tuple | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         recips = msg.get_recips(("barney@example.com",)) | 
					
						
							|  |  |  |         self.assertEqual(recips, ["barney@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # set as string | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         recips = msg.get_recips("wilma@example.com") | 
					
						
							|  |  |  |         self.assertEqual(recips, ["wilma@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # set as null | 
					
						
							| 
									
										
										
										
											2025-08-30 20:32:56 -05:00
										 |  |  |         recips = msg.get_recips(None) | 
					
						
							|  |  |  |         self.assertEqual(recips, []) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # otherwise error | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertRaises(ValueError, msg.get_recips, {"foo": "foo@example.com"}) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_as_string(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if no body | 
					
						
							|  |  |  |         msg = self.make_message() | 
					
						
							|  |  |  |         self.assertRaises(ValueError, msg.as_string) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # txt body | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = self.make_message(sender="bob@example.com", txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         complete = msg.as_string() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIn("From: bob@example.com", complete) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # html body | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = self.make_message( | 
					
						
							|  |  |  |             sender="bob@example.com", html_body="<p>hello world</p>" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         complete = msg.as_string() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIn("From: bob@example.com", complete) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # txt + html body | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = self.make_message( | 
					
						
							|  |  |  |             sender="bob@example.com", | 
					
						
							|  |  |  |             txt_body="hello world", | 
					
						
							|  |  |  |             html_body="<p>hello world</p>", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         complete = msg.as_string() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIn("From: bob@example.com", complete) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  |         # html + attachment | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         csv_part = MIMEText("foo,bar\n1,2", "csv", "utf_8") | 
					
						
							|  |  |  |         msg = self.make_message( | 
					
						
							|  |  |  |             sender="bob@example.com", | 
					
						
							|  |  |  |             html_body="<p>hello world</p>", | 
					
						
							|  |  |  |             attachments=[csv_part], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  |         complete = msg.as_string() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIn("Content-Type: multipart/mixed; boundary=", complete) | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  |         self.assertIn('Content-Type: text/csv; charset="utf_8"', complete) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if improper attachment | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         csv_path = self.write_file("data.csv", "foo,bar\n1,2") | 
					
						
							|  |  |  |         msg = self.make_message( | 
					
						
							|  |  |  |             sender="bob@example.com", | 
					
						
							|  |  |  |             html_body="<p>hello world</p>", | 
					
						
							|  |  |  |             attachments=[csv_path], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2025-08-10 11:03:59 -05:00
										 |  |  |         self.assertRaises(ValueError, msg.as_string) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             msg.as_string() | 
					
						
							|  |  |  |         except ValueError as err: | 
					
						
							|  |  |  |             self.assertIn("must specify valid MIME attachments", str(err)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         # everything | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         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>", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         complete = msg.as_string() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class mock_foo(mod.EmailSetting): | 
					
						
							|  |  |  |     default_subject = "MOCK FOO!" | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def sample_data(self): | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         return {"foo": "mock"} | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestEmailHandler(ConfigTestCase): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def make_handler(self, **kwargs): | 
					
						
							|  |  |  |         return mod.EmailHandler(self.config, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_constructor_lookups(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty lookup paths by default, if no providers | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new={}): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  |         self.assertEqual(handler.txt_templates.directories, []) | 
					
						
							|  |  |  |         self.assertEqual(handler.html_templates.directories, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # provider may specify paths as list | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_templates=["wuttjamaican:email-templates"]), | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         path = resource_path("wuttjamaican:email-templates") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(handler.txt_templates.directories, [path]) | 
					
						
							|  |  |  |         self.assertEqual(handler.html_templates.directories, [path]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # provider may specify paths as string | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_templates="wuttjamaican:email-templates"), | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         path = resource_path("wuttjamaican:email-templates") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(handler.txt_templates.directories, [path]) | 
					
						
							|  |  |  |         self.assertEqual(handler.html_templates.directories, [path]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def test_get_email_modules(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no providers, no email modules | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new={}): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  |             self.assertEqual(handler.get_email_modules(), []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # provider may specify modules as list | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_modules=["wuttjamaican.email"]), | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  |             modules = handler.get_email_modules() | 
					
						
							|  |  |  |             self.assertEqual(len(modules), 1) | 
					
						
							|  |  |  |             self.assertIs(modules[0], mod) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 19:04:30 -06:00
										 |  |  |         # provider may specify modules as string | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_modules="wuttjamaican.email"), | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             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 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new={}): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  |             self.assertEqual(handler.get_email_settings(), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # provider may define email settings (via modules) | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_modules=["tests.test_email"]), | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  |             settings = handler.get_email_settings() | 
					
						
							|  |  |  |             self.assertEqual(len(settings), 1) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertIn("mock_foo", settings) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_email_setting(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_modules=["tests.test_email"]), | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # as instance | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             setting = handler.get_email_setting("mock_foo") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             self.assertIsInstance(setting, mod.EmailSetting) | 
					
						
							|  |  |  |             self.assertIsInstance(setting, mock_foo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # as class | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             setting = handler.get_email_setting("mock_foo", instance=False) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             self.assertTrue(issubclass(setting, mod.EmailSetting)) | 
					
						
							|  |  |  |             self.assertIs(setting, mock_foo) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |     def test_make_message(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  |         msg = handler.make_message() | 
					
						
							| 
									
										
										
										
											2024-12-19 18:34:03 -06:00
										 |  |  |         self.assertIsInstance(msg, mod.Message) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_make_auto_message(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         # # error if default sender not defined | 
					
						
							|  |  |  |         # self.assertRaises(ConfigurationError, handler.make_auto_message, 'foo') | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         # message is empty by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_auto_message("foo") | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         self.assertIsInstance(msg, mod.Message) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(msg.key, "foo") | 
					
						
							|  |  |  |         self.assertEqual(msg.sender, "root@localhost") | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         self.assertEqual(msg.subject, "Automated message") | 
					
						
							|  |  |  |         self.assertEqual(msg.to, []) | 
					
						
							|  |  |  |         self.assertEqual(msg.cc, []) | 
					
						
							|  |  |  |         self.assertEqual(msg.bcc, []) | 
					
						
							|  |  |  |         self.assertIsNone(msg.replyto) | 
					
						
							|  |  |  |         self.assertIsNone(msg.txt_body) | 
					
						
							|  |  |  |         self.assertIsNone(msg.html_body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # override defaults | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.sender", "bob@example.com") | 
					
						
							|  |  |  |         self.config.setdefault("wutta.email.default.subject", "Attention required") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # message is empty by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_auto_message("foo") | 
					
						
							| 
									
										
										
										
											2024-12-19 18:34:03 -06:00
										 |  |  |         self.assertIsInstance(msg, mod.Message) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(msg.key, "foo") | 
					
						
							|  |  |  |         self.assertEqual(msg.sender, "bob@example.com") | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         self.assertEqual(msg.subject, "Attention required") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(msg.to, []) | 
					
						
							|  |  |  |         self.assertEqual(msg.cc, []) | 
					
						
							|  |  |  |         self.assertEqual(msg.bcc, []) | 
					
						
							|  |  |  |         self.assertIsNone(msg.replyto) | 
					
						
							|  |  |  |         self.assertIsNone(msg.txt_body) | 
					
						
							|  |  |  |         self.assertIsNone(msg.html_body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but if there is a proper email profile configured for key, | 
					
						
							|  |  |  |         # then we should get back a more complete message | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.test_foo.subject", "hello foo") | 
					
						
							|  |  |  |         self.config.setdefault("wutta.email.test_foo.to", "sally@example.com") | 
					
						
							|  |  |  |         self.config.setdefault("wutta.email.templates", "tests:email-templates") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_auto_message("test_foo") | 
					
						
							|  |  |  |         self.assertEqual(msg.key, "test_foo") | 
					
						
							|  |  |  |         self.assertEqual(msg.sender, "bob@example.com") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(msg.subject, "hello foo") | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(msg.to, ["sally@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(msg.cc, []) | 
					
						
							|  |  |  |         self.assertEqual(msg.bcc, []) | 
					
						
							|  |  |  |         self.assertIsNone(msg.replyto) | 
					
						
							|  |  |  |         self.assertEqual(msg.txt_body, "hello from foo txt template\n") | 
					
						
							|  |  |  |         self.assertEqual(msg.html_body, "<p>hello from foo html template</p>\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # *some* auto methods get skipped if caller specifies the | 
					
						
							|  |  |  |         # kwarg at all; others get skipped if kwarg is empty | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sender | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_sender") as get_auto_sender: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", sender=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_sender.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_sender.assert_called_once_with("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # subject | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_subject") as get_auto_subject: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", subject=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_subject.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_subject.assert_called_once_with("foo", {}, default=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # to | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_to") as get_auto_to: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", to=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_to.assert_not_called() | 
					
						
							|  |  |  |             get_auto_to.return_value = None | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_to.assert_called_once_with("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # cc | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_cc") as get_auto_cc: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", cc=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_cc.assert_not_called() | 
					
						
							|  |  |  |             get_auto_cc.return_value = None | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_cc.assert_called_once_with("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # bcc | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_bcc") as get_auto_bcc: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", bcc=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_bcc.assert_not_called() | 
					
						
							|  |  |  |             get_auto_bcc.return_value = None | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_bcc.assert_called_once_with("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # txt_body | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_txt_body") as get_auto_txt_body: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", txt_body=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_txt_body.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_txt_body.assert_called_once_with("foo", {}) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # html_body | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "get_auto_html_body") as get_auto_html_body: | 
					
						
							|  |  |  |             msg = handler.make_auto_message("foo", html_body=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             get_auto_html_body.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             msg = handler.make_auto_message("foo") | 
					
						
							|  |  |  |             get_auto_html_body.assert_called_once_with("foo", {}) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_auto_sender(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 18:02:50 -06:00
										 |  |  |         # basic global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(handler.get_auto_sender("foo"), "root@localhost") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.sender", "bob@example.com") | 
					
						
							|  |  |  |         self.assertEqual(handler.get_auto_sender("foo"), "bob@example.com") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set for key | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.sender", "sally@example.com") | 
					
						
							|  |  |  |         self.assertEqual(handler.get_auto_sender("foo"), "sally@example.com") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def test_get_auto_replyto(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIsNone(handler.get_auto_replyto("foo")) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.replyto", "george@example.com") | 
					
						
							|  |  |  |         self.assertEqual(handler.get_auto_replyto("foo"), "george@example.com") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set for key | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.replyto", "kathy@example.com") | 
					
						
							|  |  |  |         self.assertEqual(handler.get_auto_replyto("foo"), "kathy@example.com") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |     def test_get_auto_subject_template(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         template = handler.get_auto_subject_template("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(template, "Automated message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can configure alternate global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.subject", "Wutta Message") | 
					
						
							|  |  |  |         template = handler.get_auto_subject_template("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(template, "Wutta Message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can configure just for key | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.subject", "Foo Message") | 
					
						
							|  |  |  |         template = handler.get_auto_subject_template("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(template, "Foo Message") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:05:39 -05:00
										 |  |  |         # EmailSetting can provide default subject | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_modules=["tests.test_email"]), | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             template = handler.get_auto_subject_template("mock_foo") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |             self.assertEqual(template, "MOCK FOO!") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:05:39 -05:00
										 |  |  |             # caller can provide default subject | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             template = handler.get_auto_subject_template( | 
					
						
							|  |  |  |                 "mock_foo", default="whatever is clever" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-08-10 11:05:39 -05:00
										 |  |  |             self.assertEqual(template, "whatever is clever") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |     def test_get_auto_subject(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         subject = handler.get_auto_subject("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(subject, "Automated message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can configure alternate global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.subject", "Wutta Message") | 
					
						
							|  |  |  |         subject = handler.get_auto_subject("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(subject, "Wutta Message") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-10 11:05:39 -05:00
										 |  |  |         # caller can provide default subject | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         subject = handler.get_auto_subject("foo", default="whatever is clever") | 
					
						
							| 
									
										
										
										
											2025-08-10 11:05:39 -05:00
										 |  |  |         self.assertEqual(subject, "whatever is clever") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         # can configure just for key | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.subject", "Foo Message") | 
					
						
							|  |  |  |         subject = handler.get_auto_subject("foo") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(subject, "Foo Message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # proper template is rendered | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.bar.subject", "${foo} Message") | 
					
						
							|  |  |  |         subject = handler.get_auto_subject("bar", {"foo": "FOO"}) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(subject, "FOO Message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # unless we ask it not to | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         subject = handler.get_auto_subject("bar", {"foo": "FOO"}, rendered=False) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertEqual(subject, "${foo} Message") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_auto_recips(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if bad type requested | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertRaises(ValueError, handler.get_auto_recips, "foo", "doesnotexist") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can configure global default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.default.to", "admin@example.com") | 
					
						
							|  |  |  |         recips = handler.get_auto_recips("foo", "to") | 
					
						
							|  |  |  |         self.assertEqual(recips, ["admin@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can configure just for key | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.to", "bob@example.com") | 
					
						
							|  |  |  |         recips = handler.get_auto_recips("foo", "to") | 
					
						
							|  |  |  |         self.assertEqual(recips, ["bob@example.com"]) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_auto_body_template(self): | 
					
						
							|  |  |  |         from mako.template import Template | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if bad request | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertRaises(ValueError, handler.get_auto_body_template, "foo", "BADTYPE") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # empty by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         template = handler.get_auto_body_template("foo", "txt") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertIsNone(template) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but returns a template if it exists | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_templates=["tests:email-templates"]), | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         template = handler.get_auto_body_template("test_foo", "txt") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertIsInstance(template, Template) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertEqual(template.uri, "test_foo.txt.mako") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_auto_txt_body(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         body = handler.get_auto_txt_body("some-random-email") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertIsNone(body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but returns body if template exists | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_templates=["tests:email-templates"]), | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         body = handler.get_auto_txt_body("test_foo") | 
					
						
							|  |  |  |         self.assertEqual(body, "hello from foo txt template\n") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_auto_html_body(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # empty by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         body = handler.get_auto_html_body("some-random-email") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertIsNone(body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but returns body if template exists | 
					
						
							|  |  |  |         providers = { | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             "wuttatest": MagicMock(email_templates=["tests:email-templates"]), | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(self.app, "providers", new=providers): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |             handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         body = handler.get_auto_html_body("test_foo") | 
					
						
							|  |  |  |         self.assertEqual(body, "<p>hello from foo html template</p>\n") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  |     def test_get_notes(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # null by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertIsNone(handler.get_notes("foo")) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # configured notes | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.notes", "hello world") | 
					
						
							|  |  |  |         self.assertEqual(handler.get_notes("foo"), "hello world") | 
					
						
							| 
									
										
										
										
											2024-12-23 15:37:37 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |     def test_is_enabled(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # enabled by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertTrue(handler.is_enabled("default")) | 
					
						
							|  |  |  |         self.assertTrue(handler.is_enabled("foo")) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # specific type disabled | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.email.foo.enabled", "false") | 
					
						
							|  |  |  |         self.assertFalse(handler.is_enabled("foo")) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # default is disabled | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.assertTrue(handler.is_enabled("bar")) | 
					
						
							|  |  |  |         self.config.setdefault("wutta.email.default.enabled", "false") | 
					
						
							|  |  |  |         self.assertFalse(handler.is_enabled("bar")) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |     def test_deliver_message(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com", to="sally@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # no smtp session since sending email is disabled by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							|  |  |  |                 smtplib.SMTP.assert_not_called() | 
					
						
							|  |  |  |                 session.login.assert_not_called() | 
					
						
							|  |  |  |                 session.sendmail.assert_not_called() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # now let's enable sending | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.config.setdefault("wutta.mail.send_emails", "true") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # smtp login not attempted by default | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session.login.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # but login attempted if config has credentials | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.config.setdefault("wutta.mail.smtp.username", "bob") | 
					
						
							|  |  |  |             self.config.setdefault("wutta.mail.smtp.password", "seekrit") | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.login.assert_called_once_with("bob", "seekrit") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # error if no sender | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(to="sally@example.com") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertRaises(ValueError, handler.deliver_message, msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # error if no recips | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertRaises(ValueError, handler.deliver_message, msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # can set recips as list | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 handler.deliver_message(msg, recips=["sally@example.com"]) | 
					
						
							|  |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set recips as string | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 handler.deliver_message(msg, recips="sally@example.com") | 
					
						
							|  |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set recips via to | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com", to="sally@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set recips via cc | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com", cc="sally@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # can set recips via bcc | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         msg = handler.make_message(sender="bob@example.com", bcc="sally@example.com") | 
					
						
							|  |  |  |         with patch.object(msg, "as_string", return_value="msg-str"): | 
					
						
							|  |  |  |             with patch.object(mod, "smtplib") as smtplib: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |                 session = MagicMock() | 
					
						
							|  |  |  |                 smtplib.SMTP.return_value = session | 
					
						
							|  |  |  |                 handler.deliver_message(msg) | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |                 smtplib.SMTP.assert_called_once_with("localhost") | 
					
						
							|  |  |  |                 session.sendmail.assert_called_once_with( | 
					
						
							|  |  |  |                     "bob@example.com", {"sally@example.com"}, "msg-str" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_sending_is_enabled(self): | 
					
						
							|  |  |  |         handler = self.make_handler() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # off by default | 
					
						
							|  |  |  |         self.assertFalse(handler.sending_is_enabled()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # but can be turned on | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         self.config.setdefault("wutta.mail.send_emails", "true") | 
					
						
							| 
									
										
										
										
											2024-08-26 13:08:19 -05:00
										 |  |  |         self.assertTrue(handler.sending_is_enabled()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_send_email(self): | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |         handler = self.make_handler() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |         with patch.object(handler, "deliver_message") as deliver_message: | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # specify message w/ no body | 
					
						
							|  |  |  |             msg = handler.make_message() | 
					
						
							|  |  |  |             self.assertRaises(ValueError, handler.send_email, message=msg) | 
					
						
							|  |  |  |             self.assertFalse(deliver_message.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # again, but also specify key | 
					
						
							|  |  |  |             msg = handler.make_message() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertRaises(ValueError, handler.send_email, "foo", message=msg) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertFalse(deliver_message.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # specify complete message | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							|  |  |  |             msg = handler.make_message(txt_body="hello world") | 
					
						
							|  |  |  |             handler.send_email(message=msg) | 
					
						
							|  |  |  |             deliver_message.assert_called_once_with(msg, recips=None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # again, but also specify key | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							|  |  |  |             msg = handler.make_message(txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             handler.send_email("foo", message=msg) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             deliver_message.assert_called_once_with(msg, recips=None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # no key, no message | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							|  |  |  |             self.assertRaises(ValueError, handler.send_email) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # auto-create message w/ no template | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.assertRaises( | 
					
						
							|  |  |  |                 RuntimeError, handler.send_email, "foo", sender="foo@example.com" | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertFalse(deliver_message.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # auto create w/ body | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             handler.send_email("foo", sender="foo@example.com", txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertTrue(deliver_message.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # type is disabled | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.config.setdefault("wutta.email.foo.enabled", False) | 
					
						
							|  |  |  |             handler.send_email("foo", sender="foo@example.com", txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertFalse(deliver_message.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # default is disabled | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             handler.send_email("bar", sender="bar@example.com", txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertTrue(deliver_message.called) | 
					
						
							|  |  |  |             deliver_message.reset_mock() | 
					
						
							| 
									
										
										
										
											2025-08-30 21:25:44 -05:00
										 |  |  |             self.config.setdefault("wutta.email.default.enabled", False) | 
					
						
							|  |  |  |             handler.send_email("bar", sender="bar@example.com", txt_body="hello world") | 
					
						
							| 
									
										
										
										
											2024-12-19 18:20:57 -06:00
										 |  |  |             self.assertFalse(deliver_message.called) |