33
44from django .contrib .auth import get_user_model
55from django .core import mail
6+ from django .template import TemplateDoesNotExist
67from django .test import TestCase , override_settings
78
89from generic_notifications .channels import BaseChannel , EmailChannel
@@ -207,19 +208,29 @@ def test_send_now_uses_get_methods(self):
207208 self .assertEqual (email .body , "" )
208209
209210 @override_settings (DEFAULT_FROM_EMAIL = "[email protected] " ) 210- @patch ("generic_notifications.channels.render_to_string" )
211- def test_send_now_with_template (self , mock_render ):
212- # Set up mock to return different values for different templates
213- def mock_render_side_effect (template_name , context ):
214- if template_name .endswith ("_subject.txt" ):
215- return "Test Subject"
216- elif template_name .endswith (".html" ):
217- return "<html>Test HTML</html>"
218- elif template_name .endswith (".txt" ):
219- return "Test plain text"
220- return ""
221-
222- mock_render .side_effect = mock_render_side_effect
211+ @patch ("generic_notifications.channels.select_template" )
212+ def test_send_now_with_template (self , mock_select ):
213+ # Create mock template objects that return the expected content
214+ class MockTemplate :
215+ def __init__ (self , content ):
216+ self .content = content
217+
218+ def render (self , context ):
219+ return self .content
220+
221+ # Set up mock to return different templates based on the template list
222+ def mock_select_side_effect (template_list ):
223+ # Check the first template in the list to determine what to return
224+ first_template = template_list [0 ]
225+ if first_template .endswith ("_subject.txt" ):
226+ return MockTemplate ("Test Subject" )
227+ elif first_template .endswith (".html" ):
228+ return MockTemplate ("<html>Test HTML</html>" )
229+ elif first_template .endswith (".txt" ):
230+ return MockTemplate ("Test plain text" )
231+ return MockTemplate ("" )
232+
233+ mock_select .side_effect = mock_select_side_effect
223234
224235 notification = create_notification_with_channels (
225236 user = self .user ,
@@ -231,25 +242,7 @@ def mock_render_side_effect(template_name, context):
231242 channel = EmailChannel ()
232243 channel .send_now (notification )
233244
234- # Check templates were rendered (subject, HTML, then text)
235- self .assertEqual (mock_render .call_count , 3 )
236-
237- # Check subject template call (first)
238- subject_call = mock_render .call_args_list [0 ]
239- self .assertEqual (subject_call [0 ][0 ], "notifications/email/realtime/test_type_subject.txt" )
240- self .assertEqual (subject_call [0 ][1 ]["notification" ], notification )
241-
242- # Check HTML template call (second)
243- html_call = mock_render .call_args_list [1 ]
244- self .assertEqual (html_call [0 ][0 ], "notifications/email/realtime/test_type.html" )
245- self .assertEqual (html_call [0 ][1 ]["notification" ], notification )
246-
247- # Check text template call (third)
248- text_call = mock_render .call_args_list [2 ]
249- self .assertEqual (text_call [0 ][0 ], "notifications/email/realtime/test_type.txt" )
250- self .assertEqual (text_call [0 ][1 ]["notification" ], notification )
251-
252- # Check email was sent with correct subject
245+ # Check email was sent with correct subject and text
253246 self .assertEqual (len (mail .outbox ), 1 )
254247 email = mail .outbox [0 ]
255248 self .assertEqual (email .subject , "Test Subject" )
@@ -258,6 +251,50 @@ def mock_render_side_effect(template_name, context):
258251 self .assertEqual (len (email .alternatives ), 1 ) # type: ignore
259252 self .assertEqual (email .alternatives [0 ][0 ], "<html>Test HTML</html>" ) # type: ignore
260253
254+ @override_settings (DEFAULT_FROM_EMAIL = "[email protected] " ) 255+ @patch ("generic_notifications.channels.select_template" )
256+ def test_send_now_with_fallback_templates (self , mock_select ):
257+ """Test that fallback templates are used when notification-specific templates don't exist."""
258+
259+ # Create mock template objects
260+ class MockTemplate :
261+ def __init__ (self , content ):
262+ self .content = content
263+
264+ def render (self , context ):
265+ return self .content
266+
267+ # Set up mock to simulate using fallback templates (second in the list)
268+ def mock_select_side_effect (template_list ):
269+ if "subject.txt" in template_list [1 ]:
270+ return MockTemplate ("Fallback Subject" )
271+ elif "body.html" in template_list [1 ]:
272+ return MockTemplate ("<html>Fallback HTML Body</html>" )
273+ elif "body.txt" in template_list [1 ]:
274+ return MockTemplate ("Fallback Text Body" )
275+ raise TemplateDoesNotExist ("No templates found" )
276+
277+ mock_select .side_effect = mock_select_side_effect
278+
279+ notification = create_notification_with_channels (
280+ user = self .user ,
281+ notification_type = "new_type" ,
282+ subject = "Original Subject" ,
283+ text = "Original message" ,
284+ )
285+
286+ channel = EmailChannel ()
287+ channel .send_now (notification )
288+
289+ # Check email was sent with fallback content
290+ self .assertEqual (len (mail .outbox ), 1 )
291+ email = mail .outbox [0 ]
292+ self .assertEqual (email .subject , "Fallback Subject" )
293+ self .assertEqual (email .body , "Fallback Text Body" )
294+ # HTML version should be in alternatives
295+ self .assertEqual (len (email .alternatives ), 1 )
296+ self .assertEqual (email .alternatives [0 ][0 ], "<html>Fallback HTML Body</html>" )
297+
261298 @override_settings (DEFAULT_FROM_EMAIL = "[email protected] " ) 262299 def test_send_now_template_error_fallback (self ):
263300 notification = create_notification_with_channels (
0 commit comments