77from django .test import TestCase , override_settings
88
99from generic_notifications .channels import BaseChannel , EmailChannel
10- from generic_notifications .frequencies import RealtimeFrequency
10+ from generic_notifications .frequencies import DailyFrequency , RealtimeFrequency
1111from generic_notifications .models import DisabledNotificationTypeChannel , Notification , NotificationFrequency
1212from generic_notifications .registry import registry
1313from generic_notifications .types import NotificationType
@@ -167,6 +167,29 @@ def test_process_digest_frequency(self):
167167 notification .refresh_from_db ()
168168 self .assertFalse (notification .is_sent_on_channel (EmailChannel ))
169169
170+ def test_should_send_with_email (self ):
171+ """Test that should_send returns True when user has email"""
172+ notification = create_notification_with_channels (
173+ user = self .user ,
174+ notification_type = "test_type" ,
175+ )
176+
177+ self .assertTrue (EmailChannel .should_send (notification ))
178+
179+ def test_should_send_without_email (self ):
180+ """Test that should_send returns False when user has no email"""
181+ # Create user without email
182+ user_no_email = User .objects .create_user (username = "user2" , password = "testpass" )
183+ user_no_email .email = ""
184+ user_no_email .save ()
185+
186+ notification = create_notification_with_channels (
187+ user = user_no_email ,
188+ notification_type = "test_type" ,
189+ )
190+
191+ self .assertFalse (EmailChannel .should_send (notification ))
192+
170193 @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
171194 def test_send_now_basic (self ):
172195 notification = create_notification_with_channels (
@@ -312,15 +335,6 @@ def test_send_now_template_error_fallback(self):
312335 self .assertEqual (email .subject , "Test Subject" )
313336 self .assertEqual (len (email .alternatives ), 0 ) # type: ignore[attr-defined] # No HTML alternative
314337
315- @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
316- def test_send_digest_emails_empty_queryset (self ):
317- # No notifications exist, so digest should not send anything
318- empty_notifications = Notification .objects .none ()
319- EmailChannel ().send_digest (empty_notifications )
320-
321- # No email should be sent when no notifications exist
322- self .assertEqual (len (mail .outbox ), 0 )
323-
324338 @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
325339 def test_send_digest_emails_basic (self ):
326340 # Set user to daily frequency to prevent realtime sending
@@ -342,13 +356,13 @@ def test_send_digest_emails_basic(self):
342356 )
343357
344358 # Send digest email for this user
345- EmailChannel ().send_digest (notifications )
359+ EmailChannel ().send_digest (notifications , DailyFrequency )
346360
347361 # Check email was sent
348362 self .assertEqual (len (mail .outbox ), 1 )
349363 email = mail .outbox [0 ]
350364 self .assertEqual (email .to , [self .user .email ])
351- self .assertEqual (email .subject , "Digest - 3 new notifications" )
365+ self .assertEqual (email .subject , "Daily digest - 3 new notifications" )
352366
353367 # Check all notifications marked as sent
354368 for notification in notifications :
@@ -371,98 +385,12 @@ def test_send_digest_emails_with_frequency(self):
371385 recipient = self .user ,
372386 channels__channel = "email" ,
373387 channels__sent_at__isnull = True ,
374- )
375- )
376-
377- email = mail .outbox [0 ]
378- self .assertEqual (email .subject , "Digest - 1 new notification" )
379-
380- @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
381- def test_send_digest_emails_without_frequency (self ):
382- # Set user to daily frequency to prevent realtime sending
383- NotificationFrequency .objects .create (user = self .user , notification_type = "test_type" , frequency = "daily" )
384-
385- create_notification_with_channels (
386- user = self .user ,
387- notification_type = "test_type" ,
388- subject = "Test" ,
389- )
390-
391- EmailChannel ().send_digest (
392- Notification .objects .filter (
393- recipient = self .user ,
394- channels__channel = "email" ,
395- channels__sent_at__isnull = True ,
396- )
397- )
398-
399- email = mail .outbox [0 ]
400- self .assertEqual (email .subject , "Digest - 1 new notification" )
401-
402- @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
403- def test_send_digest_emails_text_limit (self ):
404- # Set user to daily frequency to prevent realtime sending
405- NotificationFrequency .objects .create (user = self .user , notification_type = "test_type" , frequency = "daily" )
406-
407- # Create more than 10 notifications to test text limit
408- for i in range (15 ):
409- create_notification_with_channels (
410- user = self .user ,
411- notification_type = "test_type" ,
412- subject = f"Test { i } " ,
413- )
414-
415- EmailChannel ().send_digest (
416- Notification .objects .filter (
417- recipient = self .user ,
418- channels__channel = "email" ,
419- channels__sent_at__isnull = True ,
420- )
388+ ),
389+ DailyFrequency ,
421390 )
422391
423- # The implementation may not have this feature, so we'll just check that email was sent
424- self .assertEqual (len (mail .outbox ), 1 )
425392 email = mail .outbox [0 ]
426- self .assertEqual (email .subject , "Digest - 15 new notifications" )
427-
428- @override_settings (DEFAULT_FROM_EMAIL = "test@example.com" )
429- @patch ("generic_notifications.channels.render_to_string" )
430- def test_send_digest_emails_with_html_template (self , mock_render ):
431- mock_render .return_value = "<html>Digest HTML</html>"
432-
433- # Set user to daily frequency to prevent realtime sending
434- NotificationFrequency .objects .create (user = self .user , notification_type = "test_type" , frequency = "daily" )
435-
436- create_notification_with_channels (
437- user = self .user ,
438- notification_type = "test_type" ,
439- subject = "Test" ,
440- )
441-
442- EmailChannel ().send_digest (
443- Notification .objects .filter (
444- recipient = self .user ,
445- channels__channel = "email" ,
446- channels__sent_at__isnull = True ,
447- )
448- )
449-
450- # Check templates were rendered (subject, HTML, then text)
451- self .assertEqual (mock_render .call_count , 3 )
452-
453- # Check subject template call
454- subject_call = mock_render .call_args_list [0 ]
455- self .assertEqual (subject_call [0 ][0 ], "notifications/email/digest/subject.txt" )
456-
457- # Check HTML template call
458- html_call = mock_render .call_args_list [1 ]
459- self .assertEqual (html_call [0 ][0 ], "notifications/email/digest/message.html" )
460-
461- # Check text template call
462- text_call = mock_render .call_args_list [2 ]
463- self .assertEqual (text_call [0 ][0 ], "notifications/email/digest/message.txt" )
464- self .assertEqual (html_call [0 ][1 ]["user" ], self .user )
465- self .assertEqual (html_call [0 ][1 ]["count" ], 1 )
393+ self .assertEqual (email .subject , "Daily digest - 1 new notification" )
466394
467395 def test_send_now_fallback_includes_url (self ):
468396 """Test that fallback email content includes URL when available"""
@@ -505,7 +433,8 @@ def test_send_digest_emails_fallback_includes_urls(self):
505433 recipient = self .user ,
506434 channels__channel = "email" ,
507435 channels__sent_at__isnull = True ,
508- )
436+ ),
437+ DailyFrequency ,
509438 )
510439
511440 # Check that one email was sent
@@ -584,7 +513,7 @@ def send_email(
584513
585514 # Test the custom channel
586515 custom_channel = TestEmailChannel ()
587- custom_channel .send_digest (notifications )
516+ custom_channel .send_digest (notifications , DailyFrequency )
588517
589518 # Verify the custom _send_email method was called
590519 self .assertEqual (len (custom_channel .sent_emails ), 1 )
0 commit comments