from django.test import TestCase from django.urls import reverse from django.contrib.auth import get_user_model from notifications.models import Discussion, Message User = get_user_model() class DiscussionListTests(TestCase): def setUp(self): self.user1 = User.objects.create_user(username='user1', password='pass') self.user2 = User.objects.create_user(username='user2', password='pass') self.user3 = User.objects.create_user(username='user3', password='pass') def test_discussion_list_filtering_on_inbox(self): # Discussion 1: created by user1 d1 = Discussion.objects.create(title="Discussion 1", created_by=self.user1) d1.participants.add(self.user1, self.user2, self.user3) # Discussion 2: created by user2, user1 wrote a message d2 = Discussion.objects.create(title="Discussion 2", created_by=self.user2) d2.participants.add(self.user1, self.user2, self.user3) Message.objects.create(discussion=d2, author=self.user1, content="Hello from user1") # Discussion 3: created by user2, user1 is tagged d3 = Discussion.objects.create(title="Discussion 3", created_by=self.user2) d3.participants.add(self.user1, self.user2, self.user3) Message.objects.create(discussion=d3, author=self.user2, content=f"Hello @[User 1](u:{self.user1.pk})") # Discussion 4: created by user2, user3 participant but user1 is NOT author and NOT tagged d4 = Discussion.objects.create(title="Discussion 4", created_by=self.user2) d4.participants.add(self.user1, self.user2, self.user3) # Discussion 5: auto-created intervention discussion with created_by=user1, but user1 never posted a message and was never tagged from django.contrib.contenttypes.models import ContentType ct = ContentType.objects.get_for_model(User) d5 = Discussion.objects.create(title="Discussion 5", created_by=self.user1, content_type=ct, object_id=1) Message.objects.create(discussion=d5, author=self.user2, content="Hello user3") self.client.force_login(self.user1) response = self.client.get(reverse('notifications:inbox') + '?tab=discussions') self.assertEqual(response.status_code, 200) self.assertEqual(response.context['active_tab'], 'discussions') discussions_in_context = [item['discussion'] for item in response.context['discussion_items']] self.assertIn(d1, discussions_in_context) self.assertIn(d2, discussions_in_context) self.assertIn(d3, discussions_in_context) self.assertNotIn(d4, discussions_in_context) self.assertNotIn(d5, discussions_in_context) def test_discussion_list_url_redirect(self): self.client.force_login(self.user1) response = self.client.get(reverse('notifications:discussion_list')) self.assertEqual(response.status_code, 302) self.assertIn('tab=discussions', response.url) def test_discussion_create(self): self.client.force_login(self.user1) response = self.client.post(reverse('notifications:discussion_create'), { 'title': 'Sujet test', 'content': f'Bonjour @[User 2](u:{self.user2.pk})', }) self.assertEqual(response.status_code, 302) discussion = Discussion.objects.get(title='Sujet test') self.assertEqual(discussion.created_by, self.user1) self.assertIn(self.user1, discussion.participants.all()) self.assertIn(self.user2, discussion.participants.all()) self.assertEqual(discussion.messages.count(), 1) class InboxTests(TestCase): def setUp(self): self.user = User.objects.create_user(username='test_inbox_user', password='pass') from notifications.models import Notification, NotificationRecipient, Discussion # Create a notification for user notif = Notification.objects.create( title="Test notification", content="Notification content", notification_type=Notification.TYPE_INFO, ) NotificationRecipient.objects.create( notification=notif, user=self.user, ) # Create a discussion for user d = Discussion.objects.create(title="Test discussion", created_by=self.user) d.participants.add(self.user) def test_inbox_renders_both_notifications_and_discussions(self): self.client.force_login(self.user) response = self.client.get(reverse('notifications:inbox')) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['active_tab'], 'notifications') self.assertEqual(response.context['unread_count'], 1) self.assertEqual(len(response.context['notifications']), 1) self.assertEqual(len(response.context['discussion_items']), 1) self.assertContains(response, 'Test notification') self.assertContains(response, 'Test discussion') self.assertContains(response, 'id="pane-notifications"') self.assertContains(response, 'id="pane-discussions"') self.assertContains(response, 'id="tab-notifications-btn"') self.assertContains(response, 'id="tab-discussions-btn"') def test_inbox_tab_discussions_parameter(self): self.client.force_login(self.user) response = self.client.get(reverse('notifications:inbox') + '?tab=discussions') self.assertEqual(response.status_code, 200) self.assertEqual(response.context['active_tab'], 'discussions') class NotificationReminderTests(TestCase): def setUp(self): from common.models import UserConfig self.user = User.objects.create_user(username='testuser', email='test@example.com', password='pass') self.config, _ = UserConfig.objects.get_or_create(user=self.user) def test_notification_settings_view(self): self.client.force_login(self.user) # GET settings page response = self.client.get(reverse('notifications:settings')) self.assertEqual(response.status_code, 200) # POST updated settings response = self.client.post(reverse('notifications:settings'), { 'preferred_language': 'nl', 'notification_reminder_enabled': 'on', 'notification_reminder_emails': 'custom@example.com, other@example.com', 'notification_reminder_delay_hours': 12, }) self.assertEqual(response.status_code, 302) self.config.refresh_from_db() self.assertEqual(self.config.preferred_language, 'nl') self.assertTrue(self.config.notification_reminder_enabled) self.assertEqual(self.config.notification_reminder_emails, 'custom@example.com, other@example.com') self.assertEqual(self.config.notification_reminder_delay_hours, 12) from django.test import override_settings @override_settings(EMAIL_OVERRIDE=None) def test_send_unread_notification_reminders_command(self): from datetime import timedelta from django.utils import timezone from django.core import mail from django.core.management import call_command from notifications.models import Notification, NotificationRecipient # Configure user for reminders self.config.notification_reminder_enabled = True self.config.notification_reminder_delay_hours = 2 self.config.save() # Create unread notification created 3 hours ago (> 2h delay) past_time = timezone.now() - timedelta(hours=3) notif = Notification.objects.create( title="Notification urgente non lue", content="Détail de la notification", notification_type=Notification.TYPE_ALERT, ) recipient = NotificationRecipient.objects.create( notification=notif, user=self.user, ) # Backdate notification creation Notification.objects.filter(pk=notif.pk).update(created_at=past_time) # Run management command call_command('send_unread_notification_reminders') # Check that 1 email was sent self.assertEqual(len(mail.outbox), 1) sent_email = mail.outbox[0] self.assertIn("Notification urgente non lue", sent_email.body) self.assertIn('test@example.com', sent_email.to) # Verify reminder_sent_at is set recipient.refresh_from_db() self.assertIsNotNone(recipient.reminder_sent_at) @override_settings(EMAIL_OVERRIDE=None) def test_send_unread_notification_reminders_multilingual(self): from datetime import timedelta from django.utils import timezone from django.core import mail from django.core.management import call_command from notifications.models import Notification, NotificationRecipient self.config.notification_reminder_enabled = True self.config.notification_reminder_delay_hours = 1 self.config.preferred_language = 'nl' self.config.save() past_time = timezone.now() - timedelta(hours=2) notif = Notification.objects.create( title="Dringende melding", content="Details", notification_type=Notification.TYPE_ALERT, ) recipient = NotificationRecipient.objects.create( notification=notif, user=self.user, ) Notification.objects.filter(pk=notif.pk).update(created_at=past_time) mail.outbox.clear() call_command('send_unread_notification_reminders') self.assertEqual(len(mail.outbox), 1) sent_email = mail.outbox[0] # In Dutch, subject contains 'Herinnering' self.assertIn("Herinnering", sent_email.subject)